Claude-skill-registry capacitor-ci-cd
Complete CI/CD guide for Capacitor apps covering GitHub Actions, GitLab CI, build automation, app signing, and deployment pipelines. Use this skill when users need to automate their build and release process.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/other/capacitor-ci-cd-cap-go-capacitor-skills" ~/.claude/skills/majiayu000-claude-skill-registry-capacitor-ci-cd && rm -rf "$T"
manifest:
skills/other/capacitor-ci-cd-cap-go-capacitor-skills/SKILL.mdsafety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
CI/CD for Capacitor Applications
Automate building, testing, and deploying Capacitor apps.
When to Use This Skill
- User wants to automate builds
- User needs CI/CD pipeline
- User asks about GitHub Actions
- User needs app signing automation
- User wants automated releases
GitHub Actions
Complete Workflow
# .github/workflows/build.yml name: Build and Deploy on: push: branches: [main, develop] pull_request: branches: [main] env: NODE_VERSION: '20' jobs: # Run tests and linting test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Install dependencies run: bun install - name: Lint run: bun run lint - name: Type check run: bun run typecheck - name: Unit tests run: bun test --coverage - name: Upload coverage uses: codecov/codecov-action@v4 # Security scan security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bunx capsec scan --ci # Build web assets build-web: runs-on: ubuntu-latest needs: [test, security] steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Install dependencies run: bun install - name: Build run: bun run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: web-build path: dist/ # Build iOS build-ios: runs-on: macos-latest needs: build-web steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Download web build uses: actions/download-artifact@v4 with: name: web-build path: dist/ - name: Install dependencies run: bun install - name: Sync Capacitor run: bunx cap sync ios - name: Setup Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true working-directory: ios/App - name: Install CocoaPods run: cd ios/App && pod install - name: Import certificates env: CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }} CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }} run: | # Create keychain security create-keychain -p "" build.keychain security default-keychain -s build.keychain security unlock-keychain -p "" build.keychain security set-keychain-settings -t 3600 -u build.keychain # Import certificate echo "$CERTIFICATE_P12" | base64 --decode > certificate.p12 security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain # Install provisioning profile mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles echo "$PROVISIONING_PROFILE" | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision - name: Build iOS run: | cd ios/App xcodebuild -workspace App.xcworkspace \ -scheme App \ -configuration Release \ -archivePath build/App.xcarchive \ archive - name: Export IPA run: | cd ios/App xcodebuild -exportArchive \ -archivePath build/App.xcarchive \ -exportPath build/ \ -exportOptionsPlist ExportOptions.plist - name: Upload IPA uses: actions/upload-artifact@v4 with: name: ios-build path: ios/App/build/*.ipa # Build Android build-android: runs-on: ubuntu-latest needs: build-web steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Download web build uses: actions/download-artifact@v4 with: name: web-build path: dist/ - name: Setup Java uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Setup Android SDK uses: android-actions/setup-android@v3 - name: Install dependencies run: bun install - name: Sync Capacitor run: bunx cap sync android - name: Decode keystore env: KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} run: | echo "$KEYSTORE_BASE64" | base64 --decode > android/app/release.keystore - name: Build APK env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} run: | cd android ./gradlew assembleRelease \ -Pandroid.injected.signing.store.file=release.keystore \ -Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD \ -Pandroid.injected.signing.key.alias=$KEY_ALIAS \ -Pandroid.injected.signing.key.password=$KEY_PASSWORD - name: Build AAB env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} run: | cd android ./gradlew bundleRelease \ -Pandroid.injected.signing.store.file=release.keystore \ -Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD \ -Pandroid.injected.signing.key.alias=$KEY_ALIAS \ -Pandroid.injected.signing.key.password=$KEY_PASSWORD - name: Upload APK uses: actions/upload-artifact@v4 with: name: android-apk path: android/app/build/outputs/apk/release/*.apk - name: Upload AAB uses: actions/upload-artifact@v4 with: name: android-aab path: android/app/build/outputs/bundle/release/*.aab # Deploy to Capgo deploy-capgo: runs-on: ubuntu-latest needs: build-web if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - name: Download web build uses: actions/download-artifact@v4 with: name: web-build path: dist/ - name: Deploy to Capgo run: bunx @capgo/cli upload env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} # Deploy to App Store deploy-ios: runs-on: macos-latest needs: build-ios if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - name: Download IPA uses: actions/download-artifact@v4 with: name: ios-build path: build/ - name: Upload to App Store Connect env: APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} run: | xcrun altool --upload-app \ --type ios \ --file build/*.ipa \ --apiKey ${{ secrets.API_KEY_ID }} \ --apiIssuer ${{ secrets.API_ISSUER_ID }} # Deploy to Play Store deploy-android: runs-on: ubuntu-latest needs: build-android if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - name: Download AAB uses: actions/download-artifact@v4 with: name: android-aab path: build/ - name: Upload to Play Store uses: r0adkll/upload-google-play@v1 with: serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT }} packageName: com.yourapp.id releaseFiles: build/*.aab track: internal
Fastlane Integration
# .github/workflows/fastlane.yml name: Fastlane Build on: push: tags: ['v*'] jobs: ios: runs-on: macos-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true - name: Install Fastlane run: gem install fastlane - name: Build and Deploy run: fastlane ios release env: MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} android: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true - name: Install Fastlane run: gem install fastlane - name: Build and Deploy run: fastlane android release env: PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
Fastlane Setup
iOS Fastfile
# ios/App/fastlane/Fastfile default_platform(:ios) platform :ios do desc "Build and deploy to TestFlight" lane :release do setup_ci # Match for code signing match( type: "appstore", readonly: true ) # Increment build number increment_build_number( build_number: ENV["GITHUB_RUN_NUMBER"] ) # Build build_app( workspace: "App.xcworkspace", scheme: "App", export_method: "app-store" ) # Upload to TestFlight upload_to_testflight( skip_waiting_for_build_processing: true ) end desc "Build for development" lane :build do match(type: "development", readonly: true) build_app( workspace: "App.xcworkspace", scheme: "App", export_method: "development" ) end end
Android Fastfile
# android/fastlane/Fastfile default_platform(:android) platform :android do desc "Build and deploy to Play Store" lane :release do # Increment version code increment_version_code( version_code: ENV["GITHUB_RUN_NUMBER"].to_i ) # Build AAB gradle( task: "bundle", build_type: "Release" ) # Upload to Play Store upload_to_play_store( track: "internal", aab: lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH] ) end desc "Build APK" lane :build do gradle( task: "assemble", build_type: "Release" ) end end
GitLab CI
# .gitlab-ci.yml stages: - test - build - deploy variables: BUN_VERSION: "1.0" .bun-cache: &bun-cache cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ - ~/.bun/install/cache test: stage: test image: oven/bun:${BUN_VERSION} <<: *bun-cache script: - bun install - bun run lint - bun test --coverage coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xml security: stage: test image: oven/bun:${BUN_VERSION} script: - bunx capsec scan --ci --output json --output-file security.json artifacts: reports: security: security.json build-web: stage: build image: oven/bun:${BUN_VERSION} <<: *bun-cache script: - bun install - bun run build artifacts: paths: - dist/ expire_in: 1 day build-ios: stage: build tags: - macos needs: [build-web] script: - bun install - bunx cap sync ios - cd ios/App && fastlane build artifacts: paths: - ios/App/build/*.ipa only: - main - tags build-android: stage: build image: thyrlian/android-sdk needs: [build-web] script: - bun install - bunx cap sync android - cd android && ./gradlew assembleRelease artifacts: paths: - android/app/build/outputs/apk/release/*.apk only: - main - tags deploy-capgo: stage: deploy image: oven/bun:${BUN_VERSION} needs: [build-web] script: - bunx @capgo/cli upload --channel production only: - main environment: name: production
Secrets Management
Required Secrets
| Secret | Description |
|---|---|
| iOS distribution certificate (base64) |
| Certificate password |
| iOS provisioning profile (base64) |
| Android keystore (base64) |
| Keystore password |
| Signing key alias |
| Signing key password |
| Capgo API token |
| App Store Connect API key |
| Play Store service account JSON |
Encoding Secrets
# iOS certificate base64 -i certificate.p12 | pbcopy # iOS provisioning profile base64 -i profile.mobileprovision | pbcopy # Android keystore base64 -i release.keystore | pbcopy
Version Management
Semantic Release
bun add -D semantic-release @semantic-release/git @semantic-release/changelog
// .releaserc.json { "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/npm", { "npmPublish": false } ], [ "@semantic-release/git", { "assets": ["package.json", "CHANGELOG.md"], "message": "chore(release): ${nextRelease.version}" } ], "@semantic-release/github" ] }
Version Bumping
# .github/workflows/release.yml name: Release on: push: branches: [main] jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - uses: oven-sh/setup-bun@v1 - run: bun install - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bunx semantic-release
Build Caching
Gradle Cache
- name: Cache Gradle uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: gradle-${{ runner.os }}-
CocoaPods Cache
- name: Cache CocoaPods uses: actions/cache@v4 with: path: ios/App/Pods key: pods-${{ runner.os }}-${{ hashFiles('ios/App/Podfile.lock') }} restore-keys: pods-${{ runner.os }}-
Resources
- GitHub Actions: https://docs.github.com/actions
- Fastlane: https://fastlane.tools
- Capgo CLI: https://capgo.app/docs/cli
- App Store Connect API: https://developer.apple.com/documentation/appstoreconnectapi
- Google Play API: https://developers.google.com/android-publisher