xiaohongshu
xiaohongshu
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.
Full skill instructions
Automate building, testing, and deploying Capacitor apps.
# .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
# .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 }}
# 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/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.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
| 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 |
# iOS certificate
base64 -i certificate.p12 | pbcopy
# iOS provisioning profile
base64 -i profile.mobileprovision | pbcopy
# Android keystore
base64 -i release.keystore | pbcopy
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"
]
}
# .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
- 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 }}-
- 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 }}-
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience