Claude-skill-registry android-workflow-internal
Generate GitHub Actions workflows for CI and internal testing track deployment (Option D - Split Workflows)
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/android-workflow-internal" ~/.claude/skills/majiayu000-claude-skill-registry-android-workflow-internal && rm -rf "$T"
skills/data/android-workflow-internal/SKILL.mdAndroid Internal Track Workflows (Option D - Split)
Generates two separate GitHub Actions workflows following Option D architecture:
- build.yml - CI only (build & test on every push/PR)
- release-internal.yml - Manual releases with version management
Clear separation of concerns:
- CI validates code quality automatically
- Releases are always intentional (manual trigger)
- Version management integrated into release process
- No accidental deployments
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 by running
/devtools:android-fastlane-setup first.
Verify setup:
bundle exec fastlane lanes
Expected output should show
deploy_internal lane.
Step 2: Verify Metadata Structure
Ensure Fastlane metadata exists:
ls fastlane/metadata/android/en-US/
If missing, run
/devtools:android-fastlane-setup.
Step 3: Create Workflow Directory
mkdir -p .github/workflows
Step 4: Create Build Workflow (CI)
Create
.github/workflows/build.yml:
name: Build & Test on: push: branches: [main] pull_request: branches: [main] jobs: build: 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: Build run: ./gradlew assembleRelease - name: Run Unit Tests run: ./gradlew test - name: Upload Test Results if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0 with: name: test-results path: app/build/reports/tests/ retention-days: 7
Purpose: CI only - validates code quality, no deployment.
Step 5: Create Release Workflow (Manual)
Create
.github/workflows/release-internal.yml:
name: Release to Internal Track on: workflow_dispatch: inputs: version_bump: description: 'Version bump type' required: true type: choice options: - patch - minor - major default: 'patch' jobs: release: runs-on: ubuntu-latest permissions: contents: write # For pushing commits and tags steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 # Full history for tags token: ${{ secrets.GITHUB_TOKEN }} - 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: Calculate Version id: version run: | chmod +x scripts/gradle-version.sh scripts/gradle-version.sh generate ${{ inputs.version_bump }} - name: Update version.properties run: | scripts/gradle-version.sh update ${{ steps.version.outputs.version }} - name: Commit Version Bump run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add version.properties git commit -m "chore: release v${{ steps.version.outputs.version }}" git push origin main - name: Decode Keystore env: ENCODED_KEYSTORE: ${{ secrets.SIGNING_KEY_STORE_BASE64 }} run: | echo $ENCODED_KEYSTORE | base64 -d > app/release.jks - name: Build Release Bundle 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 }} run: ./gradlew bundleRelease - name: Upload Artifact uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0 with: name: release-${{ steps.version.outputs.tag }} path: app/build/outputs/bundle/release/app-release.aab retention-days: 90 - name: Create Git Tag run: | git tag -a ${{ steps.version.outputs.tag }} -m "Release ${{ steps.version.outputs.version }}" git push origin ${{ steps.version.outputs.tag }} - 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 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_internal - name: Cleanup if: always() run: | rm -f app/release.jks rm -f service-account.json - name: Release Summary run: | echo "## Release Complete" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY echo "| Version | ${{ steps.version.outputs.version }} |" >> $GITHUB_STEP_SUMMARY echo "| Tag | ${{ steps.version.outputs.tag }} |" >> $GITHUB_STEP_SUMMARY echo "| Version Code | ${{ steps.version.outputs.version-code }} |" >> $GITHUB_STEP_SUMMARY echo "| Track | Internal |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Next Steps" >> $GITHUB_STEP_SUMMARY echo "1. Open Play Console - Internal Testing" >> $GITHUB_STEP_SUMMARY echo "2. Verify the new version is available" >> $GITHUB_STEP_SUMMARY echo "3. Add internal testers if needed" >> $GITHUB_STEP_SUMMARY
Purpose: Manual releases with version management - always intentional, never automatic.
Key differences from combined approach:
- ✅ Clear separation: CI validates code, Release deploys
- ✅ Version management integrated into release workflow
- ✅ Commits version bump before building
- ✅ Creates git tags as part of release process
- ✅ Release is always manual (workflow_dispatch only)
- ✅ Build/test runs on every PR and push (no deployment)
- ✅ No accidental deployments on regular commits
Verification
MANDATORY: Validate both workflows:
# Validate YAML syntax yamllint .github/workflows/build.yml yamllint .github/workflows/release-internal.yml # Verify workflows exist test -f .github/workflows/build.yml && echo "✓ Build workflow created" test -f .github/workflows/release-internal.yml && echo "✓ Release workflow created" # Verify Fastlane commands grep "fastlane deploy_internal" .github/workflows/release-internal.yml
Expected output:
- ✓ Build workflow created
- ✓ Release workflow created
- Fastlane deploy command found
Outputs
| Output | Location | Description |
|---|---|---|
| Build workflow | .github/workflows/build.yml | CI: build & test on every push/PR |
| Release workflow | .github/workflows/release-internal.yml | Manual releases with version management |
How to Use
Continuous Integration (Automatic)
Every push to main or PR triggers build.yml:
- Builds the app
- Runs unit tests
- Uploads test results
No deployment - just validation.
Release to Internal Track (Manual)
- Go to Actions → Release to Internal Track
- Click Run workflow
- Select version bump type (patch/minor/major)
- Click Run workflow
What happens:
- Calculates next version from git tags
- Updates
version.properties - Commits version bump
- Creates git tag
- Builds release bundle
- Deploys to Play Store internal track
Workflow Separation Benefits
✅ Clear intent: CI validates, releases deploy ✅ No accidents: Releases are always manual ✅ Version control: Version bumps committed before release ✅ Git tags: Automatic tag creation on release ✅ Fast CI: Build/test runs quickly without deployment overhead ✅ Audit trail: Clear history of releases vs. regular commits
Troubleshooting
"YAML syntax error"
Cause: Invalid YAML format Fix: Check indentation (use spaces, not tabs)
"Workflow not triggering"
Cause: Build workflow not running on push Fix: Verify branch name in workflow matches your main branch (main or master)
"Version calculation fails"
Cause: version-manager.sh script not found or not executable Fix: Run
/devtools:version-management first to setup version scripts
Completion Criteria
-
exists and is valid.github/workflows/build.yml -
exists and is valid.github/workflows/release-internal.yml - Fastlane configured (
works)bundle exec fastlane lanes - Metadata exists in
fastlane/metadata/android/en-US/ - Version management scripts available
- Build workflow runs on push/PR
- Release workflow available for manual trigger