[GH-ISSUE #760] builds: add wait subcommand for blocking until processing completes #202

Closed
opened 2026-02-26 21:33:59 +03:00 by kerem · 0 comments
Owner

Originally created by @mithileshchellappan on GitHub (Feb 24, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/760

Summary

Add a builds wait subcommand that blocks until a specific build transitions from PROCESSING to a terminal state (VALID, FAILED, INVALID), with configurable timeout and polling interval.

Problem

The publish testflight --wait flag already implements processing-wait semantics, but it is only available as part of the full publish workflow. When a build has already been uploaded externally (e.g., via xcodebuild -exportArchive -exportOptionsPlist with destination: upload, which handles automatic signing and provisioning profile resolution), there is no standalone way to wait for processing to complete before running distribution commands.

This forces agents into manual polling loops:

# Current workaround — manual poll loop
BUILD_ID="4d23cb4c-..."
while true; do
    STATE=$(asc builds info --build "$BUILD_ID" --output json | jq -r '.data.attributes.processingState')
    [ "$STATE" = "VALID" ] && break
    sleep 30
done
asc builds add-groups --build "$BUILD_ID" --group "$GROUP_ID"

This is error-prone (no timeout, no failure handling) and verbose for a common workflow step.

Proposal

# Wait for a specific build to finish processing
asc builds wait --build BUILD_ID

# With custom timeout and poll interval
asc builds wait --build BUILD_ID --timeout 10m --poll-interval 15s

# Wait for the latest build of an app (useful right after upload)
asc builds wait --app APP_ID --version 28

# Exit with non-zero if build fails processing
asc builds wait --build BUILD_ID --fail-on-invalid

Behavior

  1. Poll the build's processingState at --poll-interval (default: 30s)
  2. Exit 0 when state becomes VALID
  3. Exit non-zero when state becomes FAILED or INVALID (if --fail-on-invalid)
  4. Exit non-zero on --timeout expiry (default: 15m)
  5. Print progress updates to stderr: Waiting for build 28... (PROCESSING, 1m elapsed)

Flags

Flag Default Description
--build Build ID to wait for
--app App ID (alternative to --build, used with --version)
--version Build number to wait for (used with --app)
--timeout 15m Maximum wait duration
--poll-interval 30s Polling interval
--fail-on-invalid false Exit non-zero if processing fails
--output json Output format for final build state

API Support

Uses existing /v1/builds/{id} endpoint to poll processingState. The --app + --version variant would use filter[app] + filter[version] on /v1/builds to resolve the build ID first.

Scope

  • internal/cli/builds/builds_wait.go: new subcommand implementation
  • Reuse polling logic from publish testflight --wait if applicable
  • Tests: timeout behavior, terminal state detection, flag validation

Acceptance Criteria

  • asc builds wait --build BUILD_ID blocks until build is VALID and exits 0
  • asc builds wait --build BUILD_ID --timeout 1s exits non-zero on timeout
  • asc builds wait --app APP_ID --version 28 resolves build by app + version
  • Progress output on stderr does not interfere with --output json on stdout
  • Tests pass with ASC_BYPASS_KEYCHAIN=1

Use Case

This is the most common missing primitive for agents that use xcodebuild for archiving/uploading (which provides better automatic signing support) but want to use asc for the TestFlight distribution step. The workflow becomes:

xcodebuild -exportArchive ... -allowProvisioningUpdates  # upload
asc builds wait --app APP_ID --version 28                 # wait
asc builds add-groups --build BUILD_ID --group GROUP_ID   # distribute
Originally created by @mithileshchellappan on GitHub (Feb 24, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/760 ## Summary Add a `builds wait` subcommand that blocks until a specific build transitions from `PROCESSING` to a terminal state (`VALID`, `FAILED`, `INVALID`), with configurable timeout and polling interval. ## Problem The `publish testflight --wait` flag already implements processing-wait semantics, but it is only available as part of the full publish workflow. When a build has already been uploaded externally (e.g., via `xcodebuild -exportArchive -exportOptionsPlist` with `destination: upload`, which handles automatic signing and provisioning profile resolution), there is no standalone way to wait for processing to complete before running distribution commands. This forces agents into manual polling loops: ```bash # Current workaround — manual poll loop BUILD_ID="4d23cb4c-..." while true; do STATE=$(asc builds info --build "$BUILD_ID" --output json | jq -r '.data.attributes.processingState') [ "$STATE" = "VALID" ] && break sleep 30 done asc builds add-groups --build "$BUILD_ID" --group "$GROUP_ID" ``` This is error-prone (no timeout, no failure handling) and verbose for a common workflow step. ## Proposal ```bash # Wait for a specific build to finish processing asc builds wait --build BUILD_ID # With custom timeout and poll interval asc builds wait --build BUILD_ID --timeout 10m --poll-interval 15s # Wait for the latest build of an app (useful right after upload) asc builds wait --app APP_ID --version 28 # Exit with non-zero if build fails processing asc builds wait --build BUILD_ID --fail-on-invalid ``` ### Behavior 1. Poll the build's `processingState` at `--poll-interval` (default: 30s) 2. Exit `0` when state becomes `VALID` 3. Exit non-zero when state becomes `FAILED` or `INVALID` (if `--fail-on-invalid`) 4. Exit non-zero on `--timeout` expiry (default: 15m) 5. Print progress updates to stderr: `Waiting for build 28... (PROCESSING, 1m elapsed)` ### Flags | Flag | Default | Description | |------|---------|-------------| | `--build` | — | Build ID to wait for | | `--app` | — | App ID (alternative to --build, used with --version) | | `--version` | — | Build number to wait for (used with --app) | | `--timeout` | `15m` | Maximum wait duration | | `--poll-interval` | `30s` | Polling interval | | `--fail-on-invalid` | `false` | Exit non-zero if processing fails | | `--output` | `json` | Output format for final build state | ## API Support Uses existing `/v1/builds/{id}` endpoint to poll `processingState`. The `--app` + `--version` variant would use `filter[app]` + `filter[version]` on `/v1/builds` to resolve the build ID first. ## Scope - `internal/cli/builds/builds_wait.go`: new subcommand implementation - Reuse polling logic from `publish testflight --wait` if applicable - Tests: timeout behavior, terminal state detection, flag validation ## Acceptance Criteria - `asc builds wait --build BUILD_ID` blocks until build is `VALID` and exits 0 - `asc builds wait --build BUILD_ID --timeout 1s` exits non-zero on timeout - `asc builds wait --app APP_ID --version 28` resolves build by app + version - Progress output on stderr does not interfere with `--output json` on stdout - Tests pass with `ASC_BYPASS_KEYCHAIN=1` ## Use Case This is the most common missing primitive for agents that use `xcodebuild` for archiving/uploading (which provides better automatic signing support) but want to use `asc` for the TestFlight distribution step. The workflow becomes: ```bash xcodebuild -exportArchive ... -allowProvisioningUpdates # upload asc builds wait --app APP_ID --version 28 # wait asc builds add-groups --build BUILD_ID --group GROUP_ID # distribute ```
kerem closed this issue 2026-02-26 21:33:59 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#202
No description provided.