
Capacitor Ci Cd
- 530 installs
- 57 repo stars
- Updated July 13, 2026
- cap-go/capgo-skills
capacitor-ci-cd is a Capgo agent skill that automates Capacitor iOS and Android builds, tests, signing, and store uploads in GitHub Actions and GitLab CI pipelines for hybrid mobile apps.
About
capacitor-ci-cd is a Capgo skill providing a complete CI/CD guide for Capacitor hybrid apps across GitHub Actions and GitLab CI. The skill documents end-to-end workflows: lint and unit tests on Node 20, capsec security scans, web asset builds, macOS iOS archives with CocoaPods and certificate import, Android APK and AAB signing with Gradle, Capgo CLI uploads, and deployments to App Store Connect and Google Play. It includes Fastlane Fastfiles for iOS TestFlight and Android Play Store tracks, GitLab CI stage definitions, semantic-release version bumping, Gradle and CocoaPods caching, and a secrets table covering 10 required credentials such as CERTIFICATE_P12, KEYSTORE_BASE64, CAPGO_TOKEN, and PLAY_SERVICE_ACCOUNT. Developers reach for capacitor-ci-cd when automating Capacitor release pipelines instead of manual Xcode or Android Studio uploads.
- GitHub Actions and CI templates for Capacitor
- Automated native build and sync steps
- Code signing and artifact publishing guidance
- Multi-platform iOS and Android pipeline patterns
- Release branch and environment promotion workflows
Capacitor Ci Cd by the numbers
- 530 all-time installs (skills.sh)
- Ranked #259 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-ci-cdAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 530 |
|---|---|
| repo stars | ★ 57 |
| Last updated | July 13, 2026 |
| Repository | cap-go/capgo-skills ↗ |
How do you automate Capacitor mobile releases in CI?
Automate Capacitor iOS/Android builds, tests, signing, and store uploads in CI pipelines for hybrid mobile apps.
Who is it for?
Capacitor mobile developers who need automated iOS and Android builds, signing, Capgo updates, and store uploads in CI.
Skip if: Skip capacitor-ci-cd when you ship native Swift or Kotlin apps without Capacitor or only need local manual Xcode builds.
When should I use this skill?
Trigger when a developer asks to automate Capacitor builds, set up GitHub Actions for iOS/Android, configure app signing, or deploy to Capgo or app stores.
What you get
GitHub Actions or GitLab CI pipelines, signed IPA and AAB artifacts, Capgo uploads, and store deployment configs.
- CI workflow YAML
- signed mobile artifacts
- Fastlane configuration
By the numbers
- Documents 10 required CI secrets for signing and store deployment
- Provides GitHub Actions workflow with 8 jobs from test through store deploy
Files
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: actions/setup-node@v4
- name: Install dependencies
run: npm install
- name: Lint
run: npm run lint
- name: Type check
run: npm run typecheck
- name: Unit tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
# Security scan
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npx capsec scan --ci
# Build web assets
build-web:
runs-on: ubuntu-latest
needs: [test, security]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install dependencies
run: npm install
- name: Build
run: npm 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: actions/setup-node@v4
- name: Download web build
uses: actions/download-artifact@v4
with:
name: web-build
path: dist/
- name: Install dependencies
run: npm install
- name: Sync Capacitor
run: npx 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: actions/setup-node@v4
- 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: npm install
- name: Sync Capacitor
run: npx 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: actions/setup-node@v4
- name: Download web build
uses: actions/download-artifact@v4
with:
name: web-build
path: dist/
- name: Deploy to Capgo
run: npx @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: internalFastlane 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
endAndroid 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
endGitLab CI
# .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
NODE_VERSION: "20"
.npm-cache: &npm-cache
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- ~/.npm
test:
stage: test
image: node:20
<<: *npm-cache
script:
- npm install
- npm run lint
- npm test -- --coverage
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
security:
stage: test
image: node:20
script:
- npx capsec scan --ci --output json --output-file security.json
artifacts:
reports:
security: security.json
build-web:
stage: build
image: node:20
<<: *npm-cache
script:
- npm install
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 day
build-ios:
stage: build
tags:
- macos
needs: [build-web]
script:
- npm install
- npx 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:
- npm install
- npx cap sync android
- cd android && ./gradlew assembleRelease
artifacts:
paths:
- android/app/build/outputs/apk/release/*.apk
only:
- main
- tags
deploy-capgo:
stage: deploy
image: node:20
needs: [build-web]
script:
- npx @capgo/cli upload --channel production
only:
- main
environment:
name: productionSecrets 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
# iOS certificate
base64 -i certificate.p12 | pbcopy
# iOS provisioning profile
base64 -i profile.mobileprovision | pbcopy
# Android keystore
base64 -i release.keystore | pbcopyVersion Management
Semantic Release
npm install -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: actions/setup-node@v4
- run: npm install
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-releaseBuild 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
{
"version": "1.0.0",
"organization": "Capgo",
"date": "January 2026",
"abstract": "Complete CI/CD guide for Capacitor apps covering GitHub Actions, GitLab CI, Fastlane, app signing, secrets management, and automated deployment to app stores and Capgo.",
"triggers": [
"ci/cd",
"github actions",
"gitlab ci",
"fastlane",
"automate build",
"release pipeline",
"app signing",
"deploy automatically"
],
"references": [
"https://docs.github.com/actions",
"https://fastlane.tools",
"https://capgo.app/docs/cli"
]
}
Related skills
How it compares
Use capacitor-ci-cd for Capacitor hybrid release automation; use native mobile CI skills when the app is pure Swift or Kotlin without a web Capacitor shell.
FAQ
Which CI systems does capacitor-ci-cd cover?
capacitor-ci-cd covers GitHub Actions and GitLab CI with complete Capacitor workflows spanning test, security scan, web build, native iOS and Android builds, Capgo upload, and store deployment steps.
How many secrets does capacitor-ci-cd document?
capacitor-ci-cd documents 10 required CI secrets—including iOS CERTIFICATE_P12, PROVISIONING_PROFILE, Android KEYSTORE_BASE64, CAPGO_TOKEN, and PLAY_SERVICE_ACCOUNT—for automated signing and store uploads.
Does capacitor-ci-cd include Fastlane examples?
capacitor-ci-cd includes Fastlane Fastfiles and GitHub workflow samples for iOS TestFlight release lanes and Android Play Store bundle uploads alongside raw xcodebuild and Gradle commands.