Post

This required changing the approach from v2 quite a lot — it now uses a fixed list of known operations, with a JSON-based DAG language to let you describe rich flows (while sparing me the pain of having to parse and understand shell commands...).

If you're wondering all the extra complexity: well, usually only part of a build needs access to a device; thus, it can optimise the usage of resources by letting assemble-style tasks run while other agents hold a device.

Parsing shell was the wrong layer. A fixed op list plus a JSON DAG lets the controller prove two tasks will not fight over the same device before either starts, which a raw ./gradlew string can never tell you.