home / skills / hitoshura25 / claude-devtools / android-workflow-beta

android-workflow-beta skill

/skills/android-workflow-beta

This skill generates a GitHub Actions workflow to deploy Android beta tracks via Fastlane, with full or staged rollout.

npx playbooks add skill hitoshura25/claude-devtools --skill android-workflow-beta

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
8.9 KB
---
name: android-workflow-beta
description: Generate GitHub Actions workflow for beta testing track deployment
category: android
version: 1.0.0
inputs:
  - package_name: Android app package name
outputs:
  - .github/workflows/deploy-beta.yml
verify: "yamllint .github/workflows/deploy-beta.yml"
---

# Android Beta Track Workflow

Generates GitHub Actions workflow for manual deployment to Play Store beta (closed testing) track.

## Prerequisites

- Service account setup complete
- Package name known

## Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| package_name | Yes | - | App package name |

## Process

### Step 1: Verify Fastlane Setup

Ensure Fastlane is configured:
```bash
bundle exec fastlane lanes
```

Expected output should show `deploy_beta` lane.

### Step 2: Generate Beta Testing Workflow

Create `.github/workflows/deploy-beta.yml`:

```yaml
name: Deploy to Beta Testing

on:
  workflow_dispatch:
    inputs:
      track:
        description: 'Beta track'
        required: true
        type: choice
        options:
          - alpha
          - beta
        default: 'beta'
      rollout_type:
        description: 'Rollout type'
        required: true
        type: choice
        options:
          - full
          - staged
        default: 'full'
      rollout_percentage:
        description: 'Rollout percentage (only for staged: 0.05-1.0, e.g., 0.5 for 50%)'
        required: false
        default: '0.5'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

      - name: Set up JDK 17
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00  # v4.7.0
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Setup Gradle cache
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
            .gradle/configuration-cache
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            gradle-${{ runner.os }}-

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Run unit tests
        run: ./gradlew test

      - name: Upload test reports
        if: always()
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.0
        with:
          name: test-reports
          path: app/build/reports/tests/
          retention-days: 7

  deploy:
    needs: test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

      - name: Set up JDK 17
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00  # v4.7.0
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Setup Gradle cache
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
            .gradle/configuration-cache
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            gradle-${{ runner.os }}-

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Decode keystore
        run: |
          echo "${{ secrets.SIGNING_KEY_STORE_BASE64 }}" | base64 -d > app/release.jks
        env:
          SIGNING_KEY_STORE_BASE64: ${{ secrets.SIGNING_KEY_STORE_BASE64 }}

      - name: Build Release Bundle
        run: ./gradlew bundleRelease
        env:
          SIGNING_KEY_STORE_PATH: ${{ github.workspace }}/app/release.jks
          SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
          SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
          SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true

      - name: Create Service Account File
        run: echo "${{ secrets.SERVICE_ACCOUNT_JSON_PLAINTEXT }}" > service-account.json

      - name: Deploy with Fastlane (Full Rollout)
        if: github.event.inputs.rollout_type == 'full'
        env:
          SIGNING_KEY_STORE_PATH: ${{ github.workspace }}/app/release.jks
          SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
          SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
          SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
          PLAY_STORE_SERVICE_ACCOUNT: service-account.json
        run: bundle exec fastlane deploy_beta

      - name: Deploy with Fastlane (Staged Rollout)
        if: github.event.inputs.rollout_type == 'staged'
        env:
          SIGNING_KEY_STORE_PATH: ${{ github.workspace }}/app/release.jks
          SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
          SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
          SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
          PLAY_STORE_SERVICE_ACCOUNT: service-account.json
        run: bundle exec fastlane deploy_beta rollout:${{ github.event.inputs.rollout_percentage }}

      - name: Cleanup Service Account
        if: always()
        run: rm -f service-account.json

      - name: Clean up keystore
        if: always()
        run: rm -f app/release.jks

      - name: Upload AAB artifact
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.0
        with:
          name: beta-aab-${{ github.event.inputs.track }}
          path: app/build/outputs/bundle/release/app-release.aab
          retention-days: 90

      - name: Upload mapping file
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02  # v4.6.0
        with:
          name: mapping-file-${{ github.event.inputs.track }}
          path: app/build/outputs/mapping/release/mapping.txt
          retention-days: 90

      - name: Summary
        run: |
          echo "βœ… Deployed to ${{ github.event.inputs.track }} track"
          if [ "${{ github.event.inputs.rollout_type }}" = "staged" ]; then
            echo "πŸ“Š Rollout: Staged (${{ github.event.inputs.rollout_percentage }})"
          else
            echo "πŸ“Š Rollout: Full (100%)"
          fi
          echo ""
          echo "πŸ”— View in Play Console:"
          echo "   https://play.google.com/console/developers/tracks/${{ github.event.inputs.track }}"
```

**Key features:**
- βœ… Uses Fastlane for deployment
- βœ… Supports full and staged rollouts
- βœ… Pinned all actions to commit SHAs
- βœ… Test job runs before deployment

### Step 2: Update Workflows README

Add to `.github/workflows/README.md`:

```markdown
### deploy-beta.yml
- **Trigger:** Manual only
- **Tracks:** Alpha or Beta (closed testing)
- **Approval:** None (manual trigger is the approval)
- **Rollout:** Configurable (5-100%)

## Usage - Beta Deployment

**Deploy to Beta:**
1. Go to: Actions β†’ Deploy to Beta Testing
2. Click "Run workflow"
3. Select track: "beta"
4. Set rollout: "100" (or lower for staged beta)
5. Click "Run workflow"

**Deploy to Alpha (for smaller group):**
1. Same as above, but select track: "alpha"
2. Useful for pre-beta testing with smaller group

## Beta Testing Best Practices

1. **Use Alpha for Pre-Beta**
   - Test with small group (10-50 users)
   - Catch major issues before wider beta
   - Quick feedback loop

2. **Beta for Broader Testing**
   - Larger group (100-1000+ users)
   - Diverse devices and OS versions
   - Real-world usage patterns
   - 1-2 week minimum period

3. **Staged Beta Rollout**
   - Start at 50% for critical updates
   - Monitor for 24 hours
   - Increase to 100% if stable
   - Can halt and fix if issues found

4. **Collect Feedback**
   - Monitor crash reports in Play Console
   - Review user feedback
   - Check ANR (Application Not Responding) rate
   - Address critical issues before production
```

## Verification

**MANDATORY:** Validate workflow:

```bash
# Validate YAML syntax
yamllint .github/workflows/deploy-beta.yml

# Verify package name
grep "packageName:" .github/workflows/deploy-beta.yml
```

**Expected output:**
- No YAML syntax errors
- Package name matches your app

## Outputs

| Output | Location | Description |
|--------|----------|-------------|
| Workflow | .github/workflows/deploy-beta.yml | Beta track deployment |

## Troubleshooting

### "Track not found"
**Cause:** Beta track not created in Play Console
**Fix:** Create closed testing track in Play Console first

### "Invalid rollout percentage"
**Cause:** Value not between 5-100
**Fix:** Use valid percentage (5, 10, 20, 50, 100)

## Completion Criteria

- [ ] `.github/workflows/deploy-beta.yml` exists
- [ ] YAML syntax is valid
- [ ] Package name is correct
- [ ] Workflow supports both alpha and beta tracks

Overview

This skill generates a GitHub Actions workflow for manual deployment to the Play Store beta (closed testing) track. It creates a deploy-beta.yml that runs tests, builds an AAB, and uses Fastlane to push either a full or staged rollout. The workflow includes artifact uploads, keystore handling, and service account injection for Play Console access.

How this skill works

The skill scaffolds a workflow with two jobs: test and deploy. The test job runs unit tests and uploads reports. The deploy job builds a release bundle, decodes the keystore from a secret, creates a service account file, and invokes Fastlane deploy lanes for full or staged rollouts. It cleans up sensitive files and uploads the AAB and mapping artifacts after deployment.

When to use it

  • When you need a manual, auditable process for beta/alpha Play Store releases
  • When you already use Fastlane lanes for Play Store deployments
  • When you want configurable rollout types (full or staged) from the Actions UI
  • When you require pinned action SHAs and CI test gating before deploy
  • When you need artifact retention for AABs and mapping files for debugging

Best practices

  • Ensure a Fastlane lane named deploy_beta exists and is verified locally with bundle exec fastlane lanes
  • Store signing keystore and Play service account JSON in GitHub Secrets (base64 for keystore)
  • Pin sensitive operations to run only after successful test job to avoid bad releases
  • Start staged rollouts at a lower percentage and monitor Play Console crash and ANR reports for 24 hours
  • Remove service account and keystore files in cleanup steps to avoid leaking secrets

Example use cases

  • Run a manual beta release to validate a new feature with 100+ testers via the beta track
  • Deploy a small alpha build to a limited group for early validation before wider beta
  • Perform a staged rollout (e.g., 50%) to monitor stability before a full rollout
  • Archive the built AAB and mapping file for future debugging or repeater builds
  • Use as a template in CI to standardize Play Store beta deployments across multiple apps

FAQ

What prerequisites are required?

Fastlane configured with a deploy_beta lane, package name known, and GitHub Secrets for keystore and service account.

How do I run a staged rollout?

Trigger the workflow manually, set rollout_type to staged and specify rollout_percentage (0.05-1.0 values supported for fractional percentages).

What if the workflow reports 'Track not found'?

Create the corresponding alpha or beta closed testing track in the Play Console before running the workflow.