[GH-ISSUE #24] Phase 6: Submission workflows #1

Closed
opened 2026-02-26 21:32:41 +03:00 by kerem · 1 comment
Owner

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

PRD: Submission Workflows in ASC CLI

Overview

This PRD outlines the implementation of submission workflows for App Store Connect CLI, covering the complete submission lifecycle from finding app store versions to submitting builds for review, checking status, and canceling submissions.

Goals

  1. Enable developers to submit builds for App Store review via CLI
  2. Support finding and managing app store versions
  3. Provide status checking and cancellation capabilities
  4. Maintain AI-first design with JSON output by default
  5. Follow explicit, non-interactive CLI patterns

API Endpoints

Core Submission Endpoints

Method Endpoint Description
POST /v1/appStoreVersionSubmissions Create submission for review
GET /v1/appStoreVersionSubmissions/{id} Get submission status
DELETE /v1/appStoreVersionSubmissions/{id} Cancel submission (Developer Reject)
GET /v1/appStoreVersions/{id}/appStoreVersionSubmission Get submission for a version

Supporting Endpoints

Method Endpoint Description
GET /v1/apps/{id}/appStoreVersions List app store versions (supports filter[versionString], filter[platform])
GET /v1/appStoreVersions/{id} Get app store version details
PATCH /v1/appStoreVersions/{id}/relationships/build Attach build to version
GET /v1/appStoreVersions/{id}/build Get build attached to version

CLI Commands

1. Submit Command (Enhanced)

Command: asc submit

Subcommands:

  • asc submit create - Create a new submission
  • asc submit status - Check submission status
  • asc submit cancel - Cancel a submission

asc submit create

Submit a build for App Store review.

Flags:

  • --app (required) - App Store Connect app ID (or ASC_APP_ID env)
  • --version (optional) - Version string (e.g., "1.0.0") to find/create version
  • --version-id (optional) - Direct app store version ID (alternative to --version)
  • --build (required) - Build ID to attach and submit
  • --platform (optional) - Platform filter: IOS, MAC_OS, TV_OS, VISION_OS (default: IOS)
  • --confirm (required) - Confirmation flag to prevent accidental submissions
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Workflow:

  1. If --version-id provided, use it directly
  2. If --version provided, find app store version:
    • GET /v1/apps/{app}/appStoreVersions?filter[versionString]={version}&filter[platform]={platform}
    • If not found, error with guidance to create via App Store Connect
  3. Attach build to version:
    • PATCH /v1/appStoreVersions/{versionId}/relationships/build with {"data": {"type": "builds", "id": "{buildId}"}}
  4. Create submission:
    • POST /v1/appStoreVersionSubmissions with {"data": {"type": "appStoreVersionSubmissions", "relationships": {"appStoreVersion": {"data": {"type": "appStoreVersions", "id": "{versionId}"}}}}}
  5. Return submission ID and created date

Examples:

# Submit with version string
asc submit create --app "123456789" --version "1.0.0" --build "BUILD_ID" --confirm

# Submit with version ID
asc submit create --app "123456789" --version-id "VERSION_ID" --build "BUILD_ID" --confirm

# Submit for macOS
asc submit create --app "123456789" --version "2.0.0" --build "BUILD_ID" --platform MAC_OS --confirm

JSON Output:

{"submissionId":"abc123","versionId":"xyz789","buildId":"BUILD_ID","createdDate":"2026-01-20T12:00:00Z"}

asc submit status

Check the status of a submission.

Flags:

  • --id (required) - Submission ID
  • --version-id (optional) - App store version ID (alternative to --id)
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Workflow:

  1. If --id provided, fetch directly: GET /v1/appStoreVersionSubmissions/{id}
  2. If --version-id provided, fetch via version: GET /v1/appStoreVersions/{versionId}/appStoreVersionSubmission
  3. Return submission details including state

Examples:

# Check by submission ID
asc submit status --id "SUBMISSION_ID"

# Check by version ID
asc submit status --version-id "VERSION_ID"

JSON Output:

{"id":"abc123","versionId":"xyz789","state":"WAITING_FOR_REVIEW","createdDate":"2026-01-20T12:00:00Z"}

asc submit cancel

Cancel a submission (Developer Reject).

Flags:

  • --id (required) - Submission ID
  • --version-id (optional) - App store version ID (alternative to --id)
  • --confirm (required) - Confirmation flag
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Workflow:

  1. Resolve submission ID (same as status command)
  2. Delete submission: DELETE /v1/appStoreVersionSubmissions/{id}
  3. Return confirmation

Examples:

# Cancel by submission ID
asc submit cancel --id "SUBMISSION_ID" --confirm

# Cancel by version ID
asc submit cancel --version-id "VERSION_ID" --confirm

JSON Output:

{"id":"abc123","cancelled":true,"cancelledDate":"2026-01-20T12:05:00Z"}

2. Versions Command (New)

Command: asc versions

Subcommands:

  • asc versions list - List app store versions
  • asc versions get - Get version details
  • asc versions attach-build - Attach build to version

asc versions list

List app store versions for an app.

Flags:

  • --app (required) - App Store Connect app ID (or ASC_APP_ID env)
  • --version (optional) - Filter by version string
  • --platform (optional) - Filter by platform: IOS, MAC_OS, TV_OS, VISION_OS
  • --state (optional) - Filter by state: PREPARE_FOR_SUBMISSION, READY_FOR_REVIEW, WAITING_FOR_REVIEW, IN_REVIEW, REJECTED, APPROVED, DEVELOPER_REJECTED, DEVELOPER_REMOVED_FROM_SALE, METADATA_REJECTED
  • --limit (optional) - Maximum results per page (1-200)
  • --next (optional) - Fetch next page using links.next URL
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Examples:

# List all versions
asc versions list --app "123456789"

# Find specific version
asc versions list --app "123456789" --version "1.0.0"

# Filter by platform and state
asc versions list --app "123456789" --platform IOS --state READY_FOR_REVIEW

JSON Output:

{"data":[{"id":"xyz789","type":"appStoreVersions","attributes":{"versionString":"1.0.0","platform":"IOS","appStoreState":"READY_FOR_REVIEW"}}],"links":{"self":"...","next":null}}

asc versions get

Get details for a specific app store version.

Flags:

  • --version-id (required) - App store version ID
  • --include-build (optional) - Include attached build information
  • --include-submission (optional) - Include submission information
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Examples:

# Get version details
asc versions get --version-id "VERSION_ID"

# Include build and submission info
asc versions get --version-id "VERSION_ID" --include-build --include-submission

asc versions attach-build

Attach a build to an app store version.

Flags:

  • --version-id (required) - App store version ID
  • --build (required) - Build ID to attach
  • --output (optional) - Output format: json (default), table, markdown
  • --pretty (optional) - Pretty-print JSON output

Examples:

asc versions attach-build --version-id "VERSION_ID" --build "BUILD_ID"

JSON Output Expectations

Submission Create Response

{
  "submissionId": "abc123def456",
  "versionId": "xyz789",
  "buildId": "BUILD_ID",
  "createdDate": "2026-01-20T12:00:00Z"
}

Submission Status Response

{
  "id": "abc123def456",
  "versionId": "xyz789",
  "versionString": "1.0.0",
  "platform": "IOS",
  "state": "WAITING_FOR_REVIEW",
  "createdDate": "2026-01-20T12:00:00Z"
}

Version List Response

{
  "data": [
    {
      "id": "xyz789",
      "type": "appStoreVersions",
      "attributes": {
        "versionString": "1.0.0",
        "platform": "IOS",
        "appStoreState": "READY_FOR_REVIEW",
        "createdDate": "2026-01-15T10:00:00Z"
      }
    }
  ],
  "links": {
    "self": "https://api.appstoreconnect.apple.com/v1/apps/123456789/appStoreVersions",
    "next": null
  }
}

Version Detail Response (with includes)

{
  "id": "xyz789",
  "versionString": "1.0.0",
  "platform": "IOS",
  "appStoreState": "READY_FOR_REVIEW",
  "build": {
    "id": "BUILD_ID",
    "version": "1.0.0",
    "uploadedDate": "2026-01-18T14:30:00Z",
    "processingState": "PROCESSING"
  },
  "submission": {
    "id": "abc123def456",
    "state": "WAITING_FOR_REVIEW",
    "createdDate": "2026-01-20T12:00:00Z"
  }
}

Validation

Input Validation

  1. App ID

    • Required for submit create and versions list
    • Can be provided via --app flag or ASC_APP_ID environment variable
    • Must be a valid UUID format
  2. Version ID

    • Required for submit status, submit cancel, versions get, versions attach-build
    • Must be a valid UUID format
  3. Build ID

    • Required for submit create and versions attach-build
    • Must be a valid UUID format
  4. Version String

    • Optional for submit create and versions list
    • Format: Semantic version (e.g., "1.0.0", "2.1.3")
    • Used for filtering/finding versions
  5. Platform

    • Optional filter
    • Valid values: IOS, MAC_OS, TV_OS, VISION_OS
    • Default: IOS
  6. Confirmation Flags

    • --confirm required for submit create and submit cancel
    • Prevents accidental submissions/cancellations
  7. Limit

    • Must be between 1 and 200 if provided
    • Default: API default (typically 50)

State Validation

  1. Build State

    • Build must be in PROCESSING or PROCESSING_COMPLETE state before attaching
    • Error if build is FAILED or INVALID
  2. Version State

    • Version must be in PREPARE_FOR_SUBMISSION or READY_FOR_REVIEW state for submission
    • Error if version is already IN_REVIEW or APPROVED
  3. Submission State

    • Can only cancel submissions in WAITING_FOR_REVIEW or DEVELOPER_REJECTED states
    • Error if submission is IN_REVIEW or APPROVED

Error Handling

Common Errors

  1. Version Not Found

    Error: app store version not found for version "1.0.0" and platform "IOS"
    Hint: Create the version in App Store Connect or use --version-id to specify an existing version
    
  2. Build Already Attached

    Error: build "BUILD_ID" is already attached to version "VERSION_ID"
    
  3. Version Not Ready

    Error: version "VERSION_ID" is in state "IN_REVIEW" and cannot be submitted
    Current state: IN_REVIEW
    
  4. Submission Not Found

    Error: submission not found for ID "SUBMISSION_ID"
    
  5. Missing Confirmation

    Error: --confirm is required to submit for review
    
  6. Build Not Ready

    Error: build "BUILD_ID" is in state "PROCESSING" and cannot be attached
    Current state: PROCESSING
    Wait for processing to complete or use a different build
    
  7. Metadata Not Complete

    Error: version "VERSION_ID" metadata is not complete
    Required: screenshots, description, keywords, support URL
    Complete metadata in App Store Connect before submitting
    

Error Response Format

All errors follow the existing pattern:

  • Exit code: non-zero
  • Error message to stderr
  • JSON errors include structured details when available
{
  "error": {
    "code": "VERSION_NOT_FOUND",
    "message": "app store version not found",
    "details": {
      "version": "1.0.0",
      "platform": "IOS"
    }
  }
}

Testing Requirements

Unit Tests

Client Layer (internal/asc/client.go)

  1. GetAppStoreVersions

    • Test query parameter building (filter[versionString], filter[platform], filter[appStoreState])
    • Test response parsing
    • Test error handling (404, 400)
  2. GetAppStoreVersion

    • Test with includes (build, appStoreVersionSubmission)
    • Test response parsing
    • Test error handling
  3. AttachBuildToVersion

    • Test request body construction
    • Test PATCH endpoint
    • Test error handling (build already attached, invalid build)
  4. CreateAppStoreVersionSubmission (already exists, enhance tests)

    • Test request body construction
    • Test response parsing
    • Test error handling (version not ready, metadata incomplete)
  5. GetAppStoreVersionSubmission (already exists, enhance tests)

    • Test by submission ID
    • Test by version ID (via relationship endpoint)
    • Test response parsing
  6. DeleteAppStoreVersionSubmission (already exists, enhance tests)

    • Test DELETE endpoint
    • Test error handling (submission not found, cannot cancel)

CLI Layer (cmd/commands.go)

  1. SubmitCreateCommand

    • Test flag validation (missing --app, --build, --confirm)
    • Test version resolution (by --version vs --version-id)
    • Test build attachment workflow
    • Test submission creation
    • Test output formats (json, table, markdown)
  2. SubmitStatusCommand

    • Test flag validation (missing --id or --version-id)
    • Test submission ID resolution
    • Test output formats
  3. SubmitCancelCommand

    • Test flag validation (missing --confirm)
    • Test submission cancellation
    • Test output formats
  4. VersionsListCommand

    • Test flag validation
    • Test filter combinations
    • Test pagination (--next)
    • Test output formats
  5. VersionsGetCommand

    • Test flag validation
    • Test includes (--include-build, --include-submission)
    • Test output formats
  6. VersionsAttachBuildCommand

    • Test flag validation
    • Test build attachment
    • Test output formats

Integration Tests (Opt-in)

Environment Variables:

  • ASC_SUBMIT_APP_ID - App ID for testing
  • ASC_SUBMIT_VERSION_ID - Existing version ID (optional)
  • ASC_SUBMIT_BUILD_ID - Build ID to submit
  • ASC_CONFIRM_SUBMIT=true - Required for actual submissions

Test Scenarios:

  1. List versions for an app
  2. Get version details with includes
  3. Attach build to version
  4. Create submission (if ASC_CONFIRM_SUBMIT=true)
  5. Check submission status
  6. Cancel submission (if ASC_CONFIRM_SUBMIT=true)

Skip Conditions:

  • Skip if ASC_SUBMIT_APP_ID not set
  • Skip submission tests if ASC_CONFIRM_SUBMIT not set to true
  • Skip cancel tests if no active submission exists

Implementation Checklist

Phase 1: Client Methods

  • GetAppStoreVersions(ctx, appID, opts...) - List versions with filters
  • GetAppStoreVersion(ctx, versionID, opts...) - Get version with includes
  • AttachBuildToVersion(ctx, versionID, buildID) - Attach build
  • Enhance CreateAppStoreVersionSubmission error handling
  • GetAppStoreVersionSubmissionByVersion(ctx, versionID) - Get via version relationship
  • Enhance DeleteAppStoreVersionSubmission error handling

Phase 2: CLI Commands

  • SubmitCreateCommand - Enhanced with version finding and build attachment
  • SubmitStatusCommand - New command
  • SubmitCancelCommand - New command
  • VersionsListCommand - New command
  • VersionsGetCommand - New command
  • VersionsAttachBuildCommand - New command
  • Update SubmitCommand parent to include new subcommands

Phase 3: Output Formatting

  • Table output for submission status
  • Table output for version list
  • Table output for version details
  • Markdown output for all new commands
  • JSON output (minified by default)

Phase 4: Error Handling

  • Version not found errors with hints
  • Build state validation errors
  • Version state validation errors
  • Submission state validation errors
  • Metadata incomplete errors

Phase 5: Tests

  • Unit tests for all client methods
  • Unit tests for all CLI commands
  • Integration tests (opt-in)
  • Error case tests

API Reference URLs

Official Documentation

  1. App Store Version Submissions

  2. App Store Versions

  3. Read Submission Information

  4. Delete Submission

  5. API Overview

OpenAPI Specification


Design Decisions

  1. Explicit Flags: All commands use long-form flags (--app, --version-id, --build) following project conventions
  2. JSON-First: Default output is minified JSON for AI agent consumption
  3. Non-Interactive: No prompts; all required information via flags
  4. Confirmation Flags: --confirm required for destructive operations (submit, cancel)
  5. Version Resolution: Support both --version (string) and --version-id (UUID) for flexibility
  6. Error Messages: Include actionable hints (e.g., "Create version in App Store Connect")
  7. State Validation: Validate build/version/submission states before operations
  8. Includes Support: Allow fetching related resources (build, submission) with version details

Future Enhancements

  1. Auto-Create Versions: Automatically create app store versions if not found (requires metadata API)
  2. Submission Polling: --wait flag to poll submission status until completion
  3. Batch Operations: Submit multiple builds/versions in one command
  4. Submission History: List all submissions for an app/version
  5. Metadata Validation: Pre-submission checks for required metadata completeness

Notes

  • The existing SubmitCommand in cmd/commands.go provides a basic implementation that needs enhancement
  • Client methods CreateAppStoreVersionSubmission, GetAppStoreVersionSubmission, and DeleteAppStoreVersionSubmission already exist in internal/asc/client.go
  • Follow existing patterns from BuildsCommand and BetaGroupsCommand for subcommand structure
  • Maintain consistency with existing error handling and output formatting patterns
Originally created by @rudrankriyam on GitHub (Jan 20, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/24 # PRD: Submission Workflows in ASC CLI ## Overview This PRD outlines the implementation of submission workflows for App Store Connect CLI, covering the complete submission lifecycle from finding app store versions to submitting builds for review, checking status, and canceling submissions. ## Goals 1. Enable developers to submit builds for App Store review via CLI 2. Support finding and managing app store versions 3. Provide status checking and cancellation capabilities 4. Maintain AI-first design with JSON output by default 5. Follow explicit, non-interactive CLI patterns --- ## API Endpoints ### Core Submission Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/v1/appStoreVersionSubmissions` | Create submission for review | | GET | `/v1/appStoreVersionSubmissions/{id}` | Get submission status | | DELETE | `/v1/appStoreVersionSubmissions/{id}` | Cancel submission (Developer Reject) | | GET | `/v1/appStoreVersions/{id}/appStoreVersionSubmission` | Get submission for a version | ### Supporting Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/apps/{id}/appStoreVersions` | List app store versions (supports `filter[versionString]`, `filter[platform]`) | | GET | `/v1/appStoreVersions/{id}` | Get app store version details | | PATCH | `/v1/appStoreVersions/{id}/relationships/build` | Attach build to version | | GET | `/v1/appStoreVersions/{id}/build` | Get build attached to version | --- ## CLI Commands ### 1. Submit Command (Enhanced) **Command:** `asc submit` **Subcommands:** - `asc submit create` - Create a new submission - `asc submit status` - Check submission status - `asc submit cancel` - Cancel a submission #### `asc submit create` Submit a build for App Store review. **Flags:** - `--app` (required) - App Store Connect app ID (or `ASC_APP_ID` env) - `--version` (optional) - Version string (e.g., "1.0.0") to find/create version - `--version-id` (optional) - Direct app store version ID (alternative to `--version`) - `--build` (required) - Build ID to attach and submit - `--platform` (optional) - Platform filter: `IOS`, `MAC_OS`, `TV_OS`, `VISION_OS` (default: `IOS`) - `--confirm` (required) - Confirmation flag to prevent accidental submissions - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Workflow:** 1. If `--version-id` provided, use it directly 2. If `--version` provided, find app store version: - `GET /v1/apps/{app}/appStoreVersions?filter[versionString]={version}&filter[platform]={platform}` - If not found, error with guidance to create via App Store Connect 3. Attach build to version: - `PATCH /v1/appStoreVersions/{versionId}/relationships/build` with `{"data": {"type": "builds", "id": "{buildId}"}}` 4. Create submission: - `POST /v1/appStoreVersionSubmissions` with `{"data": {"type": "appStoreVersionSubmissions", "relationships": {"appStoreVersion": {"data": {"type": "appStoreVersions", "id": "{versionId}"}}}}}` 5. Return submission ID and created date **Examples:** ```bash # Submit with version string asc submit create --app "123456789" --version "1.0.0" --build "BUILD_ID" --confirm # Submit with version ID asc submit create --app "123456789" --version-id "VERSION_ID" --build "BUILD_ID" --confirm # Submit for macOS asc submit create --app "123456789" --version "2.0.0" --build "BUILD_ID" --platform MAC_OS --confirm ``` **JSON Output:** ```json {"submissionId":"abc123","versionId":"xyz789","buildId":"BUILD_ID","createdDate":"2026-01-20T12:00:00Z"} ``` #### `asc submit status` Check the status of a submission. **Flags:** - `--id` (required) - Submission ID - `--version-id` (optional) - App store version ID (alternative to `--id`) - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Workflow:** 1. If `--id` provided, fetch directly: `GET /v1/appStoreVersionSubmissions/{id}` 2. If `--version-id` provided, fetch via version: `GET /v1/appStoreVersions/{versionId}/appStoreVersionSubmission` 3. Return submission details including state **Examples:** ```bash # Check by submission ID asc submit status --id "SUBMISSION_ID" # Check by version ID asc submit status --version-id "VERSION_ID" ``` **JSON Output:** ```json {"id":"abc123","versionId":"xyz789","state":"WAITING_FOR_REVIEW","createdDate":"2026-01-20T12:00:00Z"} ``` #### `asc submit cancel` Cancel a submission (Developer Reject). **Flags:** - `--id` (required) - Submission ID - `--version-id` (optional) - App store version ID (alternative to `--id`) - `--confirm` (required) - Confirmation flag - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Workflow:** 1. Resolve submission ID (same as `status` command) 2. Delete submission: `DELETE /v1/appStoreVersionSubmissions/{id}` 3. Return confirmation **Examples:** ```bash # Cancel by submission ID asc submit cancel --id "SUBMISSION_ID" --confirm # Cancel by version ID asc submit cancel --version-id "VERSION_ID" --confirm ``` **JSON Output:** ```json {"id":"abc123","cancelled":true,"cancelledDate":"2026-01-20T12:05:00Z"} ``` ### 2. Versions Command (New) **Command:** `asc versions` **Subcommands:** - `asc versions list` - List app store versions - `asc versions get` - Get version details - `asc versions attach-build` - Attach build to version #### `asc versions list` List app store versions for an app. **Flags:** - `--app` (required) - App Store Connect app ID (or `ASC_APP_ID` env) - `--version` (optional) - Filter by version string - `--platform` (optional) - Filter by platform: `IOS`, `MAC_OS`, `TV_OS`, `VISION_OS` - `--state` (optional) - Filter by state: `PREPARE_FOR_SUBMISSION`, `READY_FOR_REVIEW`, `WAITING_FOR_REVIEW`, `IN_REVIEW`, `REJECTED`, `APPROVED`, `DEVELOPER_REJECTED`, `DEVELOPER_REMOVED_FROM_SALE`, `METADATA_REJECTED` - `--limit` (optional) - Maximum results per page (1-200) - `--next` (optional) - Fetch next page using `links.next` URL - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Examples:** ```bash # List all versions asc versions list --app "123456789" # Find specific version asc versions list --app "123456789" --version "1.0.0" # Filter by platform and state asc versions list --app "123456789" --platform IOS --state READY_FOR_REVIEW ``` **JSON Output:** ```json {"data":[{"id":"xyz789","type":"appStoreVersions","attributes":{"versionString":"1.0.0","platform":"IOS","appStoreState":"READY_FOR_REVIEW"}}],"links":{"self":"...","next":null}} ``` #### `asc versions get` Get details for a specific app store version. **Flags:** - `--version-id` (required) - App store version ID - `--include-build` (optional) - Include attached build information - `--include-submission` (optional) - Include submission information - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Examples:** ```bash # Get version details asc versions get --version-id "VERSION_ID" # Include build and submission info asc versions get --version-id "VERSION_ID" --include-build --include-submission ``` #### `asc versions attach-build` Attach a build to an app store version. **Flags:** - `--version-id` (required) - App store version ID - `--build` (required) - Build ID to attach - `--output` (optional) - Output format: `json` (default), `table`, `markdown` - `--pretty` (optional) - Pretty-print JSON output **Examples:** ```bash asc versions attach-build --version-id "VERSION_ID" --build "BUILD_ID" ``` --- ## JSON Output Expectations ### Submission Create Response ```json { "submissionId": "abc123def456", "versionId": "xyz789", "buildId": "BUILD_ID", "createdDate": "2026-01-20T12:00:00Z" } ``` ### Submission Status Response ```json { "id": "abc123def456", "versionId": "xyz789", "versionString": "1.0.0", "platform": "IOS", "state": "WAITING_FOR_REVIEW", "createdDate": "2026-01-20T12:00:00Z" } ``` ### Version List Response ```json { "data": [ { "id": "xyz789", "type": "appStoreVersions", "attributes": { "versionString": "1.0.0", "platform": "IOS", "appStoreState": "READY_FOR_REVIEW", "createdDate": "2026-01-15T10:00:00Z" } } ], "links": { "self": "https://api.appstoreconnect.apple.com/v1/apps/123456789/appStoreVersions", "next": null } } ``` ### Version Detail Response (with includes) ```json { "id": "xyz789", "versionString": "1.0.0", "platform": "IOS", "appStoreState": "READY_FOR_REVIEW", "build": { "id": "BUILD_ID", "version": "1.0.0", "uploadedDate": "2026-01-18T14:30:00Z", "processingState": "PROCESSING" }, "submission": { "id": "abc123def456", "state": "WAITING_FOR_REVIEW", "createdDate": "2026-01-20T12:00:00Z" } } ``` --- ## Validation ### Input Validation 1. **App ID** - Required for `submit create` and `versions list` - Can be provided via `--app` flag or `ASC_APP_ID` environment variable - Must be a valid UUID format 2. **Version ID** - Required for `submit status`, `submit cancel`, `versions get`, `versions attach-build` - Must be a valid UUID format 3. **Build ID** - Required for `submit create` and `versions attach-build` - Must be a valid UUID format 4. **Version String** - Optional for `submit create` and `versions list` - Format: Semantic version (e.g., "1.0.0", "2.1.3") - Used for filtering/finding versions 5. **Platform** - Optional filter - Valid values: `IOS`, `MAC_OS`, `TV_OS`, `VISION_OS` - Default: `IOS` 6. **Confirmation Flags** - `--confirm` required for `submit create` and `submit cancel` - Prevents accidental submissions/cancellations 7. **Limit** - Must be between 1 and 200 if provided - Default: API default (typically 50) ### State Validation 1. **Build State** - Build must be in `PROCESSING` or `PROCESSING_COMPLETE` state before attaching - Error if build is `FAILED` or `INVALID` 2. **Version State** - Version must be in `PREPARE_FOR_SUBMISSION` or `READY_FOR_REVIEW` state for submission - Error if version is already `IN_REVIEW` or `APPROVED` 3. **Submission State** - Can only cancel submissions in `WAITING_FOR_REVIEW` or `DEVELOPER_REJECTED` states - Error if submission is `IN_REVIEW` or `APPROVED` --- ## Error Handling ### Common Errors 1. **Version Not Found** ``` Error: app store version not found for version "1.0.0" and platform "IOS" Hint: Create the version in App Store Connect or use --version-id to specify an existing version ``` 2. **Build Already Attached** ``` Error: build "BUILD_ID" is already attached to version "VERSION_ID" ``` 3. **Version Not Ready** ``` Error: version "VERSION_ID" is in state "IN_REVIEW" and cannot be submitted Current state: IN_REVIEW ``` 4. **Submission Not Found** ``` Error: submission not found for ID "SUBMISSION_ID" ``` 5. **Missing Confirmation** ``` Error: --confirm is required to submit for review ``` 6. **Build Not Ready** ``` Error: build "BUILD_ID" is in state "PROCESSING" and cannot be attached Current state: PROCESSING Wait for processing to complete or use a different build ``` 7. **Metadata Not Complete** ``` Error: version "VERSION_ID" metadata is not complete Required: screenshots, description, keywords, support URL Complete metadata in App Store Connect before submitting ``` ### Error Response Format All errors follow the existing pattern: - Exit code: non-zero - Error message to stderr - JSON errors include structured details when available ```json { "error": { "code": "VERSION_NOT_FOUND", "message": "app store version not found", "details": { "version": "1.0.0", "platform": "IOS" } } } ``` --- ## Testing Requirements ### Unit Tests #### Client Layer (`internal/asc/client.go`) 1. **GetAppStoreVersions** - Test query parameter building (`filter[versionString]`, `filter[platform]`, `filter[appStoreState]`) - Test response parsing - Test error handling (404, 400) 2. **GetAppStoreVersion** - Test with includes (`build`, `appStoreVersionSubmission`) - Test response parsing - Test error handling 3. **AttachBuildToVersion** - Test request body construction - Test PATCH endpoint - Test error handling (build already attached, invalid build) 4. **CreateAppStoreVersionSubmission** (already exists, enhance tests) - Test request body construction - Test response parsing - Test error handling (version not ready, metadata incomplete) 5. **GetAppStoreVersionSubmission** (already exists, enhance tests) - Test by submission ID - Test by version ID (via relationship endpoint) - Test response parsing 6. **DeleteAppStoreVersionSubmission** (already exists, enhance tests) - Test DELETE endpoint - Test error handling (submission not found, cannot cancel) #### CLI Layer (`cmd/commands.go`) 1. **SubmitCreateCommand** - Test flag validation (missing `--app`, `--build`, `--confirm`) - Test version resolution (by `--version` vs `--version-id`) - Test build attachment workflow - Test submission creation - Test output formats (json, table, markdown) 2. **SubmitStatusCommand** - Test flag validation (missing `--id` or `--version-id`) - Test submission ID resolution - Test output formats 3. **SubmitCancelCommand** - Test flag validation (missing `--confirm`) - Test submission cancellation - Test output formats 4. **VersionsListCommand** - Test flag validation - Test filter combinations - Test pagination (`--next`) - Test output formats 5. **VersionsGetCommand** - Test flag validation - Test includes (`--include-build`, `--include-submission`) - Test output formats 6. **VersionsAttachBuildCommand** - Test flag validation - Test build attachment - Test output formats ### Integration Tests (Opt-in) **Environment Variables:** - `ASC_SUBMIT_APP_ID` - App ID for testing - `ASC_SUBMIT_VERSION_ID` - Existing version ID (optional) - `ASC_SUBMIT_BUILD_ID` - Build ID to submit - `ASC_CONFIRM_SUBMIT=true` - Required for actual submissions **Test Scenarios:** 1. List versions for an app 2. Get version details with includes 3. Attach build to version 4. Create submission (if `ASC_CONFIRM_SUBMIT=true`) 5. Check submission status 6. Cancel submission (if `ASC_CONFIRM_SUBMIT=true`) **Skip Conditions:** - Skip if `ASC_SUBMIT_APP_ID` not set - Skip submission tests if `ASC_CONFIRM_SUBMIT` not set to `true` - Skip cancel tests if no active submission exists --- ## Implementation Checklist ### Phase 1: Client Methods - [ ] `GetAppStoreVersions(ctx, appID, opts...)` - List versions with filters - [ ] `GetAppStoreVersion(ctx, versionID, opts...)` - Get version with includes - [ ] `AttachBuildToVersion(ctx, versionID, buildID)` - Attach build - [ ] Enhance `CreateAppStoreVersionSubmission` error handling - [ ] `GetAppStoreVersionSubmissionByVersion(ctx, versionID)` - Get via version relationship - [ ] Enhance `DeleteAppStoreVersionSubmission` error handling ### Phase 2: CLI Commands - [ ] `SubmitCreateCommand` - Enhanced with version finding and build attachment - [ ] `SubmitStatusCommand` - New command - [ ] `SubmitCancelCommand` - New command - [ ] `VersionsListCommand` - New command - [ ] `VersionsGetCommand` - New command - [ ] `VersionsAttachBuildCommand` - New command - [ ] Update `SubmitCommand` parent to include new subcommands ### Phase 3: Output Formatting - [ ] Table output for submission status - [ ] Table output for version list - [ ] Table output for version details - [ ] Markdown output for all new commands - [ ] JSON output (minified by default) ### Phase 4: Error Handling - [ ] Version not found errors with hints - [ ] Build state validation errors - [ ] Version state validation errors - [ ] Submission state validation errors - [ ] Metadata incomplete errors ### Phase 5: Tests - [ ] Unit tests for all client methods - [ ] Unit tests for all CLI commands - [ ] Integration tests (opt-in) - [ ] Error case tests --- ## API Reference URLs ### Official Documentation 1. **App Store Version Submissions** - https://developer.apple.com/documentation/appstoreconnectapi/appstoreversionsubmission - https://developer.apple.com/documentation/appstoreconnectapi/create_an_app_store_version_submission 2. **App Store Versions** - https://developer.apple.com/documentation/appstoreconnectapi/appstoreversion - https://developer.apple.com/documentation/appstoreconnectapi/list_all_app_store_versions_for_an_app - https://developer.apple.com/documentation/appstoreconnectapi/modify_the_build_for_an_app_store_version 3. **Read Submission Information** - https://developer.apple.com/documentation/appstoreconnectapi/get-v1-appstoreversions-_id_-appstoreversionsubmission 4. **Delete Submission** - https://developer.apple.com/documentation/appstoreconnectapi/delete_an_app_store_version_submission 5. **API Overview** - https://developer.apple.com/documentation/appstoreconnectapi ### OpenAPI Specification - **Official Spec Download**: https://developer.apple.com/news/releases/ - **OpenAPI Mirror**: https://github.com/EvanBacon/App-Store-Connect-OpenAPI-Spec ### Related Documentation - **App Store Connect API Release Notes**: https://developer.apple.com/documentation/appstoreconnectapi/app-store-connect-api-release-notes - **WWDC 2020 - Expanding Automation**: https://developer.apple.com/videos/play/wwdc2020/10004/ --- ## Design Decisions 1. **Explicit Flags**: All commands use long-form flags (`--app`, `--version-id`, `--build`) following project conventions 2. **JSON-First**: Default output is minified JSON for AI agent consumption 3. **Non-Interactive**: No prompts; all required information via flags 4. **Confirmation Flags**: `--confirm` required for destructive operations (submit, cancel) 5. **Version Resolution**: Support both `--version` (string) and `--version-id` (UUID) for flexibility 6. **Error Messages**: Include actionable hints (e.g., "Create version in App Store Connect") 7. **State Validation**: Validate build/version/submission states before operations 8. **Includes Support**: Allow fetching related resources (build, submission) with version details --- ## Future Enhancements 1. **Auto-Create Versions**: Automatically create app store versions if not found (requires metadata API) 2. **Submission Polling**: `--wait` flag to poll submission status until completion 3. **Batch Operations**: Submit multiple builds/versions in one command 4. **Submission History**: List all submissions for an app/version 5. **Metadata Validation**: Pre-submission checks for required metadata completeness --- ## Notes - The existing `SubmitCommand` in `cmd/commands.go` provides a basic implementation that needs enhancement - Client methods `CreateAppStoreVersionSubmission`, `GetAppStoreVersionSubmission`, and `DeleteAppStoreVersionSubmission` already exist in `internal/asc/client.go` - Follow existing patterns from `BuildsCommand` and `BetaGroupsCommand` for subcommand structure - Maintain consistency with existing error handling and output formatting patterns
kerem closed this issue 2026-02-26 21:32:42 +03:00
Author
Owner

@rudrankriyam commented on GitHub (Jan 21, 2026):

Implemented in #30 (submission workflows) and merged.

<!-- gh-comment-id:3776314332 --> @rudrankriyam commented on GitHub (Jan 21, 2026): Implemented in #30 (submission workflows) and merged.
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#1
No description provided.