Skip to main content

Official Bitrise Step

The setup-asc Bitrise step provides seamless integration for App Store Connect automation:
  • Install mode - Set up asc for subsequent steps
  • Run mode - Install and execute commands in one step
  • Environment variable support - Automatic authentication via Bitrise secrets
Repository: github.com/rudrankriyam/steps-setup-asc

Quick Start

Basic Workflow

bitrise.yml
format_version: '13'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git

workflows:
  deploy_testflight:
    steps:
      - git-clone: {}
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          title: Setup App Store Connect CLI
          inputs:
            - mode: install
            - version: latest
      
      - script:
          title: Upload to TestFlight
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                asc builds upload \
                  --app "$APP_ID" \
                  --file "$BITRISE_IPA_PATH"

Step Configuration

Inputs

InputDescriptionRequiredDefault
modeOperation mode: install or runYesinstall
versionVersion to install (latest, 1.0.0, etc.)Nolatest
commandCommand to run (only for run mode)No*-
*Required when mode: run

Install Mode

Installs asc and makes it available for subsequent steps:
- git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
    inputs:
      - mode: install
      - version: latest

Run Mode

Installs and executes a command in one step:
- git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
    inputs:
      - mode: run
      - version: latest
      - command: asc apps list

Complete Workflows

TestFlight Distribution

bitrise.yml
format_version: '13'

workflows:
  testflight_release:
    envs:
      - ASC_DEFAULT_OUTPUT: json
      - ASC_TIMEOUT: 2m
      - ASC_UPLOAD_TIMEOUT: 10m
    
    steps:
      - git-clone: {}
      
      - certificate-and-profile-installer: {}
      
      - xcode-archive:
          inputs:
            - scheme: MyApp
            - distribution_method: app-store
            - configuration: Release
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          title: Setup ASC CLI
          inputs:
            - mode: install
            - version: latest
      
      - script:
          title: Upload to TestFlight
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                echo "Uploading build to TestFlight..."
                asc builds upload \
                  --app "$APP_ID" \
                  --file "$BITRISE_IPA_PATH"
                
                echo "Upload completed successfully"
      
      - slack:
          inputs:
            - webhook_url: $SLACK_WEBHOOK_URL
            - text: "TestFlight build uploaded successfully"
          run_if: .IsCI

App Store Submission

bitrise.yml
workflows:
  app_store_submit:
    steps:
      - git-clone: {}
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: install
            - version: latest
      
      - script:
          title: Validate Version
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                VERSION="$BITRISE_GIT_TAG"
                
                echo "Validating version $VERSION..."
                asc validate \
                  --app "$APP_ID" \
                  --version "$VERSION"
      
      - script:
          title: Submit for Review
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                VERSION="$BITRISE_GIT_TAG"
                
                echo "Submitting version $VERSION for review..."
                asc submit \
                  --app "$APP_ID" \
                  --version "$VERSION"
                
                echo "Submission successful"
          is_always_run: false

Metadata Sync

bitrise.yml
workflows:
  sync_metadata:
    steps:
      - git-clone: {}
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: install
      
      - script:
          title: Update Description
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                DESCRIPTION=$(cat metadata/en-US/description.txt)
                
                asc app-info update \
                  --app "$APP_ID" \
                  --locale en-US \
                  --description "$DESCRIPTION"
      
      - script:
          title: Upload Screenshots
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                for screenshot in metadata/en-US/screenshots/iphone67/*.png; do
                  echo "Uploading $screenshot..."
                  asc screenshots upload \
                    --app "$APP_ID" \
                    --version "$VERSION" \
                    --locale en-US \
                    --display-type APP_IPHONE_67 \
                    --file "$screenshot"
                done

Crash and Feedback Monitoring

bitrise.yml
workflows:
  monitor_crashes:
    steps:
      - git-clone: {}
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: |
                asc crashes \
                  --app "$APP_ID" \
                  --sort -createdDate \
                  --limit 20 \
                  --output json > crashes.json
      
      - deploy-to-bitrise-io:
          inputs:
            - deploy_path: crashes.json
            - is_compress: 'false'
      
      - script:
          title: Check Critical Crashes
          inputs:
            - content: |
                #!/bin/bash
                
                CRASH_COUNT=$(jq 'length' crashes.json)
                echo "Found $CRASH_COUNT recent crashes"
                
                if [ "$CRASH_COUNT" -gt 10 ]; then
                  echo "WARNING: High crash count detected!"
                  envman add --key CRASH_ALERT --value "true"
                fi
      
      - slack:
          inputs:
            - webhook_url: $SLACK_WEBHOOK_URL
            - text: "High crash count detected in $APP_NAME"
          run_if: |
            {{enveq "CRASH_ALERT" "true"}}

Authentication Setup

Bitrise Secrets

  1. Navigate to your app’s Workflow Editor
  2. Select the Secrets tab
  3. Add the following secrets:
Secret KeyDescriptionExample
ASC_KEY_IDApp Store Connect Key IDABC12345
ASC_ISSUER_IDApp Store Connect Issuer ID12345678-1234-1234-1234-123456789012
ASC_PRIVATE_KEY_B64Base64-encoded private keyLS0tLS1CRUdJTi...
APP_IDYour app’s ID (optional)123456789

Base64 Encoding Private Key

# Encode and copy to clipboard (macOS)
base64 -i AuthKey_ABC123.p8 | tr -d '\n' | pbcopy

# Encode and output to terminal
base64 -i AuthKey_ABC123.p8 | tr -d '\n'

# Verify encoding
echo "$ENCODED" | base64 -d | head -1
# Should show: -----BEGIN PRIVATE KEY-----

Environment Variables in Workflow

Secrets are automatically exposed as environment variables:
workflows:
  deploy:
    envs:
      - ASC_APP_ID: $APP_ID  # Reference Bitrise secret
    steps:
      - script:
          inputs:
            - content: |
                asc apps list
                # Uses ASC_KEY_ID, ASC_ISSUER_ID, ASC_PRIVATE_KEY_B64 automatically

Advanced Patterns

Conditional Workflows

workflows:
  # Main workflow with conditional triggers
  primary:
    steps:
      - script:
          title: Determine Workflow
          inputs:
            - content: |
                #!/bin/bash
                
                if [[ "$BITRISE_GIT_BRANCH" == "main" ]]; then
                  envman add --key DEPLOY_TARGET --value "production"
                elif [[ "$BITRISE_GIT_BRANCH" == "develop" ]]; then
                  envman add --key DEPLOY_TARGET --value "staging"
                fi
      
      - build-router-start:
          inputs:
            - workflows: |
                deploy_$DEPLOY_TARGET

  deploy_production:
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: |
                asc submit --app "$PROD_APP_ID" --version "$VERSION"

  deploy_staging:
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: |
                asc builds upload --app "$STAGING_APP_ID" --file "$BITRISE_IPA_PATH"

Multiple App Deployment

workflows:
  deploy_all_apps:
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: install
      
      - script:
          title: Deploy MyApp
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                asc builds upload --app "$MYAPP_ID" --file "builds/MyApp.ipa"
      
      - script:
          title: Deploy MyAppPro
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                asc builds upload --app "$MYAPP_PRO_ID" --file "builds/MyAppPro.ipa"

Retry Logic

workflows:
  upload_with_retry:
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: install
      
      - script:
          title: Upload with Retry
          inputs:
            - content: |
                #!/bin/bash
                set -e
                
                MAX_RETRIES=3
                RETRY_DELAY=30
                
                for i in $(seq 1 $MAX_RETRIES); do
                  echo "Upload attempt $i/$MAX_RETRIES"
                  
                  if asc builds upload --app "$APP_ID" --file "$BITRISE_IPA_PATH"; then
                    echo "Upload successful"
                    exit 0
                  fi
                  
                  if [ $i -lt $MAX_RETRIES ]; then
                    echo "Upload failed, retrying in ${RETRY_DELAY}s..."
                    sleep $RETRY_DELAY
                  fi
                done
                
                echo "Upload failed after $MAX_RETRIES attempts"
                exit 1

Stack Configuration

Required Stack

Use the Xcode stack for iOS/macOS builds:
stacks:
  xcode-15.2.x:
    - deployment_target: iOS 17.0

Linux Stack for Metadata Only

For metadata-only operations, Linux stacks work:
workflows:
  sync_metadata_linux:
    meta:
      bitrise.io:
        stack: linux-docker-android-22.04
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: asc app-info update --app "$APP_ID" --locale en-US

Debugging

Enable Debug Logging

workflows:
  debug_deploy:
    envs:
      - ASC_DEBUG: api
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: asc builds upload --app "$APP_ID" --file "$BITRISE_IPA_PATH"

Test Authentication

workflows:
  test_auth:
    steps:
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: install
      
      - script:
          title: Verify Credentials
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                
                echo "Testing App Store Connect authentication..."
                echo "Key ID: ${ASC_KEY_ID:0:8}..."
                echo "Issuer ID: ${ASC_ISSUER_ID:0:8}..."
                
                asc apps list --limit 1
                echo "Authentication successful"

Troubleshooting

  • Verify the step URL: git::https://github.com/rudrankriyam/steps-setup-asc.git@main
  • Check your Bitrise stack supports Git-based steps
  • Ensure you have network connectivity to GitHub
  • Verify secrets are set in Bitrise Secrets tab
  • Check “Expose for Pull Requests” if testing PRs
  • Ensure private key is properly base64-encoded without newlines
  • Test credentials locally with the same key
  • Verify mode: install was run before using asc
  • Check step order in workflow
  • Use mode: run to combine install and execution
  • Increase timeout in workflow:
    envs:
      - ASC_UPLOAD_TIMEOUT: 15m
    
  • Check IPA file size and network speed
  • Consider splitting large uploads

Best Practices

Use install mode for multiple commands

Install once, run many commands:
- mode: install
# Then multiple script steps

Set timeouts

Configure appropriate timeouts:
envs:
  - ASC_UPLOAD_TIMEOUT: 10m

Use Bitrise secrets

Never hardcode credentials. Always use secrets.

Enable retry for uploads

Implement retry logic for network-dependent operations.

Bitrise-Specific Features

Expose for Pull Requests

Allow PR builds to use secrets (use with caution):
  1. Go to Secrets tab
  2. Enable Expose for Pull Requests for required secrets
  3. Consider using separate staging credentials for PRs

Stack Selector

Choose appropriate stack based on operation:
  • Xcode stack: iOS/macOS builds and uploads
  • Linux stack: Metadata, monitoring, API-only operations

Build Artifacts

Store outputs using deploy-to-bitrise-io:
- deploy-to-bitrise-io:
    inputs:
      - deploy_path: crashes.json
      - is_compress: 'false'