<< All versions
Skill v1.0.1
currentAutomated scan100/100majiayu000/claude-skill-registry/capacitor-ci-cd
3 files
──Details
PublishedMay 18, 2026 at 11:37 PM
Content Hashsha256:92d998639eff7e82...
Git SHA64830a98256c
Bump Typepatch
──Files
Files (1 file, 14.7 KB)
SKILL.md14.7 KBactive
SKILL.md · 664 lines · 14.7 KB
version: "1.0.1" name: capacitor-ci-cd description: 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.
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
yaml
# .github/workflows/build.ymlname: Build and Deployon:push:branches: [main, develop]pull_request:branches: [main]env:NODE_VERSION: '20'jobs:# Run tests and lintingtest:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- name: Install dependenciesrun: bun install- name: Lintrun: bun run lint- name: Type checkrun: bun run typecheck- name: Unit testsrun: bun test --coverage- name: Upload coverageuses: codecov/codecov-action@v4# Security scansecurity:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- run: bunx capsec scan --ci# Build web assetsbuild-web:runs-on: ubuntu-latestneeds: [test, security]steps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- name: Install dependenciesrun: bun install- name: Buildrun: bun run build- name: Upload build artifactsuses: actions/upload-artifact@v4with:name: web-buildpath: dist/# Build iOSbuild-ios:runs-on: macos-latestneeds: build-websteps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- name: Download web builduses: actions/download-artifact@v4with:name: web-buildpath: dist/- name: Install dependenciesrun: bun install- name: Sync Capacitorrun: bunx cap sync ios- name: Setup Rubyuses: ruby/setup-ruby@v1with:ruby-version: '3.2'bundler-cache: trueworking-directory: ios/App- name: Install CocoaPodsrun: cd ios/App && pod install- name: Import certificatesenv:CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }}CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}run: |# Create keychainsecurity create-keychain -p "" build.keychainsecurity default-keychain -s build.keychainsecurity unlock-keychain -p "" build.keychainsecurity set-keychain-settings -t 3600 -u build.keychain# Import certificateecho "$CERTIFICATE_P12" | base64 --decode > certificate.p12security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesignsecurity set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain# Install provisioning profilemkdir -p ~/Library/MobileDevice/Provisioning\ Profilesecho "$PROVISIONING_PROFILE" | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision- name: Build iOSrun: |cd ios/Appxcodebuild -workspace App.xcworkspace \-scheme App \-configuration Release \-archivePath build/App.xcarchive \archive- name: Export IPArun: |cd ios/Appxcodebuild -exportArchive \-archivePath build/App.xcarchive \-exportPath build/ \-exportOptionsPlist ExportOptions.plist- name: Upload IPAuses: actions/upload-artifact@v4with:name: ios-buildpath: ios/App/build/*.ipa# Build Androidbuild-android:runs-on: ubuntu-latestneeds: build-websteps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- name: Download web builduses: actions/download-artifact@v4with:name: web-buildpath: dist/- name: Setup Javauses: actions/setup-java@v4with:java-version: '17'distribution: 'temurin'- name: Setup Android SDKuses: android-actions/setup-android@v3- name: Install dependenciesrun: bun install- name: Sync Capacitorrun: bunx cap sync android- name: Decode keystoreenv:KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}run: |echo "$KEYSTORE_BASE64" | base64 --decode > android/app/release.keystore- name: Build APKenv: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 AABenv: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 APKuses: actions/upload-artifact@v4with:name: android-apkpath: android/app/build/outputs/apk/release/*.apk- name: Upload AABuses: actions/upload-artifact@v4with:name: android-aabpath: android/app/build/outputs/bundle/release/*.aab# Deploy to Capgodeploy-capgo:runs-on: ubuntu-latestneeds: build-webif: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- uses: oven-sh/setup-bun@v1- name: Download web builduses: actions/download-artifact@v4with:name: web-buildpath: dist/- name: Deploy to Capgorun: bunx @capgo/cli uploadenv:CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}# Deploy to App Storedeploy-ios:runs-on: macos-latestneeds: build-iosif: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- name: Download IPAuses: actions/download-artifact@v4with:name: ios-buildpath: build/- name: Upload to App Store Connectenv: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 Storedeploy-android:runs-on: ubuntu-latestneeds: build-androidif: github.ref == 'refs/heads/main'steps:- uses: actions/checkout@v4- name: Download AABuses: actions/download-artifact@v4with:name: android-aabpath: build/- name: Upload to Play Storeuses: r0adkll/upload-google-play@v1with:serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT }}packageName: com.yourapp.idreleaseFiles: build/*.aabtrack: internal
Fastlane Integration
yaml
# .github/workflows/fastlane.ymlname: Fastlane Buildon:push:tags: ['v*']jobs:ios:runs-on: macos-lateststeps:- uses: actions/checkout@v4- uses: ruby/setup-ruby@v1with:ruby-version: '3.2'bundler-cache: true- name: Install Fastlanerun: gem install fastlane- name: Build and Deployrun: fastlane ios releaseenv:MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}android:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: ruby/setup-ruby@v1with:ruby-version: '3.2'bundler-cache: true- name: Install Fastlanerun: gem install fastlane- name: Build and Deployrun: fastlane android releaseenv:PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
Fastlane Setup
iOS Fastfile
ruby
# ios/App/fastlane/Fastfiledefault_platform(:ios)platform :ios dodesc "Build and deploy to TestFlight"lane :release dosetup_ci# Match for code signingmatch(type: "appstore",readonly: true)# Increment build numberincrement_build_number(build_number: ENV["GITHUB_RUN_NUMBER"])# Buildbuild_app(workspace: "App.xcworkspace",scheme: "App",export_method: "app-store")# Upload to TestFlightupload_to_testflight(skip_waiting_for_build_processing: true)enddesc "Build for development"lane :build domatch(type: "development", readonly: true)build_app(workspace: "App.xcworkspace",scheme: "App",export_method: "development")endend
Android Fastfile
ruby
# android/fastlane/Fastfiledefault_platform(:android)platform :android dodesc "Build and deploy to Play Store"lane :release do# Increment version codeincrement_version_code(version_code: ENV["GITHUB_RUN_NUMBER"].to_i)# Build AABgradle(task: "bundle",build_type: "Release")# Upload to Play Storeupload_to_play_store(track: "internal",aab: lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH])enddesc "Build APK"lane :build dogradle(task: "assemble",build_type: "Release")endend
GitLab CI
yaml
# .gitlab-ci.ymlstages:- test- build- deployvariables:BUN_VERSION: "1.0".bun-cache: &bun-cachecache:key: ${CI_COMMIT_REF_SLUG}paths:- node_modules/- ~/.bun/install/cachetest:stage: testimage: oven/bun:${BUN_VERSION}<<: *bun-cachescript:- bun install- bun run lint- bun test --coveragecoverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'artifacts:reports:coverage_report:coverage_format: coberturapath: coverage/cobertura-coverage.xmlsecurity:stage: testimage: oven/bun:${BUN_VERSION}script:- bunx capsec scan --ci --output json --output-file security.jsonartifacts:reports:security: security.jsonbuild-web:stage: buildimage: oven/bun:${BUN_VERSION}<<: *bun-cachescript:- bun install- bun run buildartifacts:paths:- dist/expire_in: 1 daybuild-ios:stage: buildtags:- macosneeds: [build-web]script:- bun install- bunx cap sync ios- cd ios/App && fastlane buildartifacts:paths:- ios/App/build/*.ipaonly:- main- tagsbuild-android:stage: buildimage: thyrlian/android-sdkneeds: [build-web]script:- bun install- bunx cap sync android- cd android && ./gradlew assembleReleaseartifacts:paths:- android/app/build/outputs/apk/release/*.apkonly:- main- tagsdeploy-capgo:stage: deployimage: oven/bun:${BUN_VERSION}needs: [build-web]script:- bunx @capgo/cli upload --channel productiononly:- mainenvironment:name: production
Secrets Management
Required Secrets
| Secret | Description | |
|---|---|---|
CERTIFICATE_P12 | iOS distribution certificate (base64) | |
CERTIFICATE_PASSWORD | Certificate password | |
PROVISIONING_PROFILE | iOS provisioning profile (base64) | |
KEYSTORE_BASE64 | Android keystore (base64) | |
KEYSTORE_PASSWORD | Keystore password | |
KEY_ALIAS | Signing key alias | |
KEY_PASSWORD | Signing key password | |
CAPGO_TOKEN | Capgo API token | |
APP_STORE_CONNECT_API_KEY | App Store Connect API key | |
PLAY_SERVICE_ACCOUNT | Play Store service account JSON |
Encoding Secrets
bash
# iOS certificatebase64 -i certificate.p12 | pbcopy# iOS provisioning profilebase64 -i profile.mobileprovision | pbcopy# Android keystorebase64 -i release.keystore | pbcopy
Version Management
Semantic Release
bash
bun add -D semantic-release @semantic-release/git @semantic-release/changelog
json
// .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
yaml
# .github/workflows/release.ymlname: Releaseon:push:branches: [main]jobs:release:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4with:fetch-depth: 0persist-credentials: false- uses: oven-sh/setup-bun@v1- run: bun install- name: Releaseenv:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}run: bunx semantic-release
Build Caching
Gradle Cache
yaml
- name: Cache Gradleuses: actions/cache@v4with:path: |~/.gradle/caches~/.gradle/wrapperkey: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}restore-keys: gradle-${{ runner.os }}-
CocoaPods Cache
yaml
- name: Cache CocoaPodsuses: actions/cache@v4with:path: ios/App/Podskey: 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