> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asccli.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Bitrise

# Bitrise Integration

> Integrate App Store Connect CLI into Bitrise workflows using the official step

## 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](https://github.com/rudrankriyam/steps-setup-asc)

## Quick Start

### Basic Workflow

```yaml bitrise.yml theme={null} theme={null}
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" \
                  --ipa "$BITRISE_IPA_PATH"
```

## Step Configuration

### Inputs

| Input     | Description                                  | Required | Default   |
| --------- | -------------------------------------------- | -------- | --------- |
| `mode`    | Operation mode: `install` or `run`           | Yes      | `install` |
| `version` | Version to install (`latest`, `1.0.0`, etc.) | No       | `latest`  |
| `command` | Command to run (only for `run` mode)         | No\*     | -         |

\*Required when `mode: run`

### Install Mode

Installs `asc` and makes it available for subsequent steps:

```yaml theme={null} theme={null}
- 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:

```yaml theme={null} theme={null}
- git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
    inputs:
      - mode: run
      - version: latest
      - command: asc apps list
```

## Complete Workflows

### TestFlight Distribution

```yaml bitrise.yml theme={null} theme={null}
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" \
                  --ipa "$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

```yaml bitrise.yml theme={null} theme={null}
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 "Publishing version $VERSION with the canonical App Store publish command..."
                asc publish appstore \
                  --app "$APP_ID" \
                  --ipa "./build/MyApp.ipa" \
                  --version "$VERSION" \
                  --submit \
                  --confirm
                
                echo "Submission successful"
          is_always_run: false
```

### Metadata Sync

```yaml bitrise.yml theme={null} theme={null}
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 apps info edit \
                  --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 \
                    --version-localization "$VERSION_LOCALIZATION_ID" \
                    --device-type "IPHONE_65" \
                    --path "$screenshot"
                done
```

### Crash and Feedback Monitoring

```yaml bitrise.yml theme={null} theme={null}
workflows:
  monitor_crashes:
    steps:
      - git-clone: {}
      
      - git::https://github.com/rudrankriyam/steps-setup-asc.git@main:
          inputs:
            - mode: run
            - command: |
                asc testflight crashes list \
                  --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 Key            | Description                 | Example                                |
| --------------------- | --------------------------- | -------------------------------------- |
| `ASC_KEY_ID`          | App Store Connect Key ID    | `ABC12345`                             |
| `ASC_ISSUER_ID`       | App Store Connect Issuer ID | `12345678-1234-1234-1234-123456789012` |
| `ASC_PRIVATE_KEY_B64` | Base64-encoded private key  | `LS0tLS1CRUdJTi...`                    |
| `APP_ID`              | Your app's ID (optional)    | `123456789`                            |

### Base64 Encoding Private Key

```bash theme={null} theme={null}
# 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:

```yaml theme={null} theme={null}
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

```yaml theme={null} theme={null}
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 publish appstore --app "$PROD_APP_ID" --ipa "build/MyApp.ipa" --version "$VERSION" --submit --confirm

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

### Multiple App Deployment

```yaml theme={null} theme={null}
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" --ipa "builds/MyApp.ipa"
      
      - script:
          title: Deploy MyAppPro
          inputs:
            - content: |
                #!/bin/bash
                set -ex
                asc builds upload --app "$MYAPP_PRO_ID" --ipa "builds/MyAppPro.ipa"
```

### Retry Logic

```yaml theme={null} theme={null}
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" --ipa "$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:

```yaml theme={null} theme={null}
stacks:
  xcode-15.2.x:
    - deployment_target: iOS 17.0
```

### Linux Stack for Metadata Only

For metadata-only operations, Linux stacks work:

```yaml theme={null} theme={null}
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 apps info edit --app "$APP_ID" --locale en-US
```

## Debugging

### Enable Debug Logging

```yaml theme={null} theme={null}
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" --ipa "$BITRISE_IPA_PATH"
```

### Test Authentication

```yaml theme={null} theme={null}
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

<AccordionGroup>
  <Accordion title="Step not found">
    * 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
  </Accordion>

  <Accordion title="Authentication failed">
    * 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
  </Accordion>

  <Accordion title="Command not found">
    * Verify `mode: install` was run before using `asc`
    * Check step order in workflow
    * Use `mode: run` to combine install and execution
  </Accordion>

  <Accordion title="Upload timeout">
    * Increase timeout in workflow:
      ```yaml theme={null} theme={null}
      envs:
        - ASC_UPLOAD_TIMEOUT: 15m
      ```
    * Check IPA file size and network speed
    * Consider splitting large uploads
  </Accordion>
</AccordionGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Use install mode for multiple commands" icon="layer-group">
    Install once, run many commands:

    ```yaml theme={null} theme={null}
    - mode: install
    # Then multiple script steps
    ```
  </Card>

  <Card title="Set timeouts" icon="clock">
    Configure appropriate timeouts:

    ```yaml theme={null} theme={null}
    envs:
      - ASC_UPLOAD_TIMEOUT: 10m
    ```
  </Card>

  <Card title="Use Bitrise secrets" icon="lock">
    Never hardcode credentials. Always use secrets.
  </Card>

  <Card title="Enable retry for uploads" icon="rotate">
    Implement retry logic for network-dependent operations.
  </Card>
</CardGroup>

## 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`:

```yaml theme={null} theme={null}
- deploy-to-bitrise-io:
    inputs:
      - deploy_path: crashes.json
      - is_compress: 'false'
```

## Related Resources

* [CI/CD Overview](/cicd/overview)
* [Authentication Guide](/authentication)
* [Commands Reference](/commands/overview)
* [steps-setup-asc Repository](https://github.com/rudrankriyam/steps-setup-asc)
