Skip to main content

Official CircleCI Orb

The asc orb provides reusable commands and jobs for CircleCI pipelines:
  • Install command - Set up asc in your jobs
  • Pre-built jobs - Ready-to-use workflows for common tasks
  • Caching support - Automatic binary caching for faster builds
Repository: github.com/rudrankriyam/asc-orb

Quick Start

Basic Configuration

.circleci/config.yml
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

workflows:
  deploy:
    jobs:
      - asc/testflight:
          context: app-store-connect
          app-id: "123456789"
          ipa-path: "build/MyApp.ipa"

Orb Commands

Install Command

Installs the asc CLI:
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

jobs:
  custom-deploy:
    macos:
      xcode: 15.2.0
    steps:
      - checkout
      
      - asc/install:
          version: latest
      
      - run:
          name: Upload to TestFlight
          command: |
            asc builds upload \
              --app "$APP_ID" \
              --file build/MyApp.ipa

workflows:
  deploy:
    jobs:
      - custom-deploy
Parameters:
ParameterDescriptionDefault
versionVersion to installlatest

Run Command

Installs and executes an asc command:
jobs:
  list-apps:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/run:
          command: apps list
Parameters:
ParameterDescriptionRequired
commandCommand to executeYes
versionVersion to installNo

Pre-Built Jobs

TestFlight Upload Job

workflows:
  deploy:
    jobs:
      - build-ipa:
          # Your build job
      
      - asc/testflight:
          requires:
            - build-ipa
          context: app-store-connect
          app-id: "123456789"
          ipa-path: "build/MyApp.ipa"
Parameters:
ParameterDescriptionRequired
app-idApp Store Connect app IDYes
ipa-pathPath to IPA fileYes
versionasc version to useNo

App Store Submit Job

workflows:
  release:
    jobs:
      - asc/submit:
          context: app-store-connect
          app-id: "123456789"
          version: "1.0.0"
          filters:
            tags:
              only: /^v.*/
Parameters:
ParameterDescriptionRequired
app-idApp Store Connect app IDYes
app-versionVersion to submitYes
asc-versionasc CLI version to useNo

Complete Workflows

Full TestFlight Pipeline

.circleci/config.yml
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

executors:
  macos-executor:
    macos:
      xcode: 15.2.0
    resource_class: macos.m1.medium.gen1

jobs:
  build:
    executor: macos-executor
    steps:
      - checkout
      
      - restore_cache:
          keys:
            - v1-deps-{{ checksum "Podfile.lock" }}
      
      - run:
          name: Install Dependencies
          command: pod install
      
      - save_cache:
          key: v1-deps-{{ checksum "Podfile.lock" }}
          paths:
            - Pods
      
      - run:
          name: Build Archive
          command: |
            xcodebuild -workspace MyApp.xcworkspace \
              -scheme MyApp \
              -configuration Release \
              -archivePath build/MyApp.xcarchive \
              archive
      
      - run:
          name: Export IPA
          command: |
            xcodebuild -exportArchive \
              -archivePath build/MyApp.xcarchive \
              -exportPath build \
              -exportOptionsPlist ExportOptions.plist
      
      - persist_to_workspace:
          root: build
          paths:
            - MyApp.ipa
  
  deploy:
    executor: macos-executor
    steps:
      - attach_workspace:
          at: build
      
      - asc/install
      
      - run:
          name: Upload to TestFlight
          command: |
            asc builds upload \
              --app "$ASC_APP_ID" \
              --file build/MyApp.ipa
      
      - run:
          name: Add to Beta Group
          command: |
            # Wait for processing
            sleep 120
            
            # Get latest build ID
            BUILD_ID=$(asc testflight builds list \
              --app "$ASC_APP_ID" \
              --output json \
              --limit 1 | jq -r '.[0].id')
            
            # Add to external testers
            asc testflight builds add-to-group \
              --build "$BUILD_ID" \
              --group "External Testers"

workflows:
  build-and-deploy:
    jobs:
      - build:
          filters:
            branches:
              only: main
      
      - deploy:
          requires:
            - build
          context: app-store-connect

App Store Release Pipeline

.circleci/config.yml
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

jobs:
  validate:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/install
      
      - run:
          name: Validate Version
          command: |
            asc validate \
              --app "$ASC_APP_ID" \
              --version "$CIRCLE_TAG"
  
  submit:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/install
      
      - run:
          name: Submit for Review
          command: |
            asc submit \
              --app "$ASC_APP_ID" \
              --version "$CIRCLE_TAG"
  
  monitor:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/install
      
      - run:
          name: Check Review Status
          command: |
            asc review status \
              --app "$ASC_APP_ID" \
              --version "$CIRCLE_TAG" \
              --output json > review-status.json
      
      - store_artifacts:
          path: review-status.json

workflows:
  release:
    jobs:
      - validate:
          context: app-store-connect
          filters:
            tags:
              only: /^v.*/
            branches:
              ignore: /.*/
      
      - approve-submission:
          type: approval
          requires:
            - validate
          filters:
            tags:
              only: /^v.*/
      
      - submit:
          context: app-store-connect
          requires:
            - approve-submission
          filters:
            tags:
              only: /^v.*/
      
      - monitor:
          context: app-store-connect
          requires:
            - submit
          filters:
            tags:
              only: /^v.*/

Metadata Sync Workflow

.circleci/config.yml
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

jobs:
  sync-description:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      
      - asc/install
      
      - run:
          name: Update Description
          command: |
            asc app-info update \
              --app "$ASC_APP_ID" \
              --locale en-US \
              --description "$(cat metadata/en-US/description.txt)"
  
  sync-screenshots:
    macos:
      xcode: 15.2.0
    steps:
      - checkout
      
      - asc/install
      
      - run:
          name: Upload Screenshots
          command: |
            for screenshot in metadata/en-US/screenshots/iphone67/*.png; do
              asc screenshots upload \
                --app "$ASC_APP_ID" \
                --version "$VERSION" \
                --locale en-US \
                --display-type APP_IPHONE_67 \
                --file "$screenshot"
            done

workflows:
  metadata-update:
    jobs:
      - sync-description:
          context: app-store-connect
          filters:
            branches:
              only: main
      
      - sync-screenshots:
          context: app-store-connect
          filters:
            branches:
              only: main

Scheduled Monitoring

.circleci/config.yml
version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

jobs:
  monitor-crashes:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/install
      
      - run:
          name: Fetch Crashes
          command: |
            asc crashes \
              --app "$ASC_APP_ID" \
              --sort -createdDate \
              --limit 20 \
              --output json > crashes.json
      
      - run:
          name: Analyze Crash Count
          command: |
            CRASH_COUNT=$(jq 'length' crashes.json)
            echo "Found $CRASH_COUNT recent crashes"
            
            if [ "$CRASH_COUNT" -gt 10 ]; then
              echo "WARNING: High crash count detected!"
            fi
      
      - store_artifacts:
          path: crashes.json
  
  monitor-feedback:
    docker:
      - image: cimg/base:stable
    steps:
      - asc/install
      
      - run:
          name: Fetch Feedback
          command: |
            asc feedback \
              --app "$ASC_APP_ID" \
              --paginate \
              --output json > feedback.json
      
      - store_artifacts:
          path: feedback.json

workflows:
  daily-monitoring:
    triggers:
      - schedule:
          cron: "0 9 * * *"  # Daily at 9 AM UTC
          filters:
            branches:
              only: main
    jobs:
      - monitor-crashes:
          context: app-store-connect
      
      - monitor-feedback:
          context: app-store-connect

Authentication Setup

CircleCI Contexts

  1. Navigate to Organization Settings > Contexts
  2. Create a new context: app-store-connect
  3. Add environment variables:
VariableDescription
ASC_KEY_IDApp Store Connect Key ID
ASC_ISSUER_IDApp Store Connect Issuer ID
ASC_PRIVATE_KEY_B64Base64-encoded private key
ASC_APP_IDYour app ID (optional)

Base64 Encoding

# Encode private key
base64 -i AuthKey_ABC123.p8 | tr -d '\n'

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

Using Contexts in Workflows

workflows:
  deploy:
    jobs:
      - deploy-job:
          context: app-store-connect  # References the context

Project-Level Variables

Alternatively, set variables at the project level:
  1. Go to Project Settings > Environment Variables
  2. Add the same variables as above

Advanced Patterns

Matrix Builds

version: 2.1

orbs:
  asc: rudrankriyam/asc@1.0

parameters:
  apps:
    type: string
    default: |
      [
        {"name": "MyApp", "id": "123456789", "scheme": "MyApp"},
        {"name": "MyAppPro", "id": "987654321", "scheme": "MyAppPro"}
      ]

jobs:
  deploy-app:
    parameters:
      app-name:
        type: string
      app-id:
        type: string
      scheme:
        type: string
    macos:
      xcode: 15.2.0
    steps:
      - checkout
      
      - run:
          name: Build << parameters.app-name >>
          command: |
            xcodebuild -scheme << parameters.scheme >> \
              -archivePath build/<< parameters.app-name >>.xcarchive \
              archive
            
            xcodebuild -exportArchive \
              -archivePath build/<< parameters.app-name >>.xcarchive \
              -exportPath build \
              -exportOptionsPlist ExportOptions.plist
      
      - asc/install
      
      - run:
          name: Upload << parameters.app-name >>
          command: |
            asc builds upload \
              --app "<< parameters.app-id >>" \
              --file build/<< parameters.app-name >>.ipa

workflows:
  deploy-all:
    jobs:
      - deploy-app:
          name: deploy-myapp
          app-name: MyApp
          app-id: "123456789"
          scheme: MyApp
          context: app-store-connect
      
      - deploy-app:
          name: deploy-myapp-pro
          app-name: MyAppPro
          app-id: "987654321"
          scheme: MyAppPro
          context: app-store-connect

Conditional Execution

jobs:
  conditional-deploy:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      
      - asc/install
      
      - when:
          condition:
            equal: [ main, << pipeline.git.branch >> ]
          steps:
            - run:
                name: Deploy to Production
                command: |
                  asc submit --app "$PROD_APP_ID" --version "$VERSION"
      
      - when:
          condition:
            equal: [ develop, << pipeline.git.branch >> ]
          steps:
            - run:
                name: Deploy to Staging
                command: |
                  asc builds upload --app "$STAGING_APP_ID" --file "build/MyApp.ipa"

Executors

macOS Executor

For build operations:
executors:
  macos-executor:
    macos:
      xcode: 15.2.0
    resource_class: macos.m1.medium.gen1
    environment:
      ASC_DEFAULT_OUTPUT: json
      ASC_TIMEOUT: 2m

Docker Executor

For API-only operations:
executors:
  docker-executor:
    docker:
      - image: cimg/base:stable
    environment:
      ASC_DEFAULT_OUTPUT: json

Caching

Cache dependencies and build artifacts:
jobs:
  build:
    steps:
      - checkout
      
      - restore_cache:
          keys:
            - v1-asc-{{ arch }}-{{ checksum "go.sum" }}
            - v1-asc-{{ arch }}
      
      - asc/install
      
      - save_cache:
          key: v1-asc-{{ arch }}-{{ checksum "go.sum" }}
          paths:
            - ~/.cache/asc

Troubleshooting

  • Verify orb is published: circleci orb list rudrankriyam
  • Check CircleCI version is 2.1+
  • Ensure organization allows third-party orbs
  • Verify context variables are set correctly
  • Check job references the correct context
  • Ensure private key is base64-encoded without newlines
  • Test credentials locally
  • Check available macOS resource classes for your plan
  • Use macos.m1.medium.gen1 for M1 builds
  • Consider using macos.x86.medium.gen2 for Intel
  • Increase job timeout:
    jobs:
      deploy:
        no_output_timeout: 30m
    
  • Set environment variables:
    environment:
      ASC_UPLOAD_TIMEOUT: 15m
    

Best Practices

Use contexts for secrets

Centralize credentials in contexts instead of project variables.

Cache dependencies

Speed up builds with caching:
- restore_cache
- save_cache

Pin orb versions

Use specific versions for stability:
orbs:
  asc: rudrankriyam/asc@1.0.0

Use approval jobs

Require manual approval for production:
- approve:
    type: approval