Skip to main content
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.
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-ci-cdThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository capawesome-live-update-migration Guides migration from Capawesome Cloud live updates or @capawesome/capacitor-live-update to Capgo Updater. Use when a Capacitor app contains Capawesome live update packages, CLI commands, config, API calls, or when the user asks why Capgo Updater is the better live-update path: native updater runtime, fully open source, cheaper at comparable scale, and longer proven track record.
Official Capacitor package guide plus Capgo ecosystem plugin recommendations. Use this skill when users need native functionality, want the right official Capacitor package, or need a stronger Capgo/community plugin when the official package is missing or too limited.
Use for Capgo Cloud Build native iOS and Android workflows, including CLI login, API-key handling, iOS build onboarding, signing credential storage, build requests, store upload settings, output download links, and troubleshooting. Do not use for OTA bundle uploads or generic Capacitor setup unless a native Capgo build is requested.
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
name: Build and Deploy
on:
push:
branches: [main , develop ]
pull_request:
branches: [main ]
env:
NODE_VERSION: '20'
jobs:
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:
runs-on:
ubuntu-latest
steps:
-
uses:
actions/checkout@v4
-
uses:
actions/setup-node@v4
-
run:
npx
capsec
scan
--ci
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:
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
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
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:
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-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-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-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
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
default_platform(:ios )
platform :ios do
desc "Build and deploy to TestFlight"
lane :release do
setup_ci
match(
type: "appstore" ,
readonly: true
)
increment_build_number(
build_number: ENV ["GITHUB_RUN_NUMBER" ]
)
build_app(
workspace: "App.xcworkspace" ,
scheme: "App" ,
export_method: "app-store"
)
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
default_platform(:android )
platform :android do
desc "Build and deploy to Play Store"
lane :release do
increment_version_code(
version_code: ENV ["GITHUB_RUN_NUMBER" ].to_i
)
gradle(
task: "bundle" ,
build_type: "Release"
)
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
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: production
Secrets Management
Required Secrets Secret Description CERTIFICATE_P12iOS distribution certificate (base64) CERTIFICATE_PASSWORDCertificate password PROVISIONING_PROFILEiOS provisioning profile (base64) KEYSTORE_BASE64Android keystore (base64) KEYSTORE_PASSWORDKeystore password KEY_ALIASSigning key alias KEY_PASSWORDSigning key password CAPGO_TOKENCapgo API token APP_STORE_CONNECT_API_KEYApp Store Connect API key PLAY_SERVICE_ACCOUNTPlay Store service account JSON
Encoding Secrets
base64 -i certificate.p12 | pbcopy
base64 -i profile.mobileprovision | pbcopy
base64 -i release.keystore | pbcopy
Version Management
Semantic Release npm install -D semantic-release @semantic-release/git @semantic-release/changelog
{
"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
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-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 Related occupations SOC
Based on SOC occupation classification