capacitor-ci-cd
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCI/CD for Capacitor Applications
Capacitor应用的CI/CD实现
Automate building, testing, and deploying Capacitor apps.
自动化Capacitor应用的构建、测试与部署。
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
- 用户希望自动化构建流程
- 用户需要搭建CI/CD流水线
- 用户咨询GitHub Actions相关问题
- 用户需要应用签名自动化
- 用户希望实现自动化发布
GitHub Actions
GitHub Actions
Complete Workflow
完整工作流
yaml
undefinedyaml
undefined.github/workflows/build.yml
.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@v4Security 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/*.ipaBuild 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/*.aabDeploy 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: internalundefinedname: 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@v4Security 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/*.ipaBuild 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/*.aabDeploy 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: internalundefinedFastlane Integration
Fastlane集成
yaml
undefinedyaml
undefined.github/workflows/fastlane.yml
.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 }}undefinedname: 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 }}undefinedFastlane Setup
Fastlane配置
iOS Fastfile
iOS Fastfile
ruby
undefinedruby
undefinedios/App/fastlane/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
undefineddefault_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
undefinedAndroid Fastfile
Android Fastfile
ruby
undefinedruby
undefinedandroid/fastlane/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
undefineddefault_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
undefinedGitLab CI
GitLab CI
yaml
undefinedyaml
undefined.gitlab-ci.yml
.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
undefinedstages:
- 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
undefinedSecrets 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 |
| 密钥名称 | 说明 |
|---|---|
| iOS发布证书(base64编码) |
| 证书密码 |
| iOS配置文件(base64编码) |
| Android密钥库(base64编码) |
| 密钥库密码 |
| 签名密钥别名 |
| 签名密钥密码 |
| Capgo API令牌 |
| App Store Connect API密钥 |
| Play Store服务账号JSON |
Encoding Secrets
密钥编码
bash
undefinedbash
undefinediOS certificate
iOS证书
base64 -i certificate.p12 | pbcopy
base64 -i certificate.p12 | pbcopy
iOS provisioning profile
iOS配置文件
base64 -i profile.mobileprovision | pbcopy
base64 -i profile.mobileprovision | pbcopy
Android keystore
Android密钥库
base64 -i release.keystore | pbcopy
undefinedbase64 -i release.keystore | pbcopy
undefinedVersion Management
版本管理
Semantic Release
Semantic Release配置
bash
bun add -D semantic-release @semantic-release/git @semantic-release/changelogjson
// .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"
]
}bash
bun add -D semantic-release @semantic-release/git @semantic-release/changelogjson
// .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
undefinedyaml
undefined.github/workflows/release.yml
.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-releaseundefinedname: 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-releaseundefinedBuild Caching
构建缓存
Gradle Cache
Gradle缓存
yaml
- 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 }}-yaml
- 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
CocoaPods缓存
yaml
- 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 }}-yaml
- 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
- 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