CI/CD for a Cordova app in 2026 means building and signing the Android AAB on a Linux runner, building and signing the iOS IPA on a macOS runner, and uploading both to the stores from the same pipeline. The managed services Cordova teams used for this are gone or closing, so most teams now run the Cordova CLI on a general-purpose CI. This guide gives you a working GitHub Actions setup, the same steps for other CIs, and an honest look at live updates and long-term options.
변경된 사항
세 가지 사건이 Cordova CI/CD를 형성했습니다.
- PhoneGap Build 2020년 10월 1일부터 종료되었습니다.
- Microsoft App Center 2025년 3월 31일까지 지원되었습니다. 빌드, 배포 및 호스팅된 CodePush 서비스는 종료되었습니다.
- Ionic Appflow 2025년 2월에 새로운 판매가 중단되었습니다. 기존 고객은 2027년 12월 31일까지 접근권한을 유지합니다.
Cordova는 여전히 작동합니다. Apache 프로젝트는 cordova-android 및 cordova-ios 릴리스, 그리고 많은 내부 및 기업 앱이 작동합니다._gap은 관리되는 층: 서명 저장소, 스토어 업로드 및 원격 업데이트입니다. 이제 CI 서비스와 몇 가지 도구를 사용하여 그들을 조립합니다.
CI/CD
| 단계 | 안드로이드 | iOS |
|---|---|---|
| Runner | Linux | macOS Xcode 26 |
| Restore | cordova prepare (플랫폼 및 플러그인에서) package.json) |
same |
| 웹 빌드 | your bundler (Vite, webpack, Angular CLI) into www/ |
same |
| Gradle을 통해 | Gradle via cordova build android --release |
xcodebuild via cordova build ios --release --device |
| 인증 | 업로드 키스토어 (.jks) |
배포 인증서 (.p12) 및 프로비전 프로파일 |
| 아티팩트 | .aab 구글 플레이 |
.ipa 테스트 플라이트 및 앱 스토어 |
| 업로드 | 구글 플레이 개발자 API (서비스 계정) | 앱 스토어 연결 API 키 |
컨텍스트
- 2026년 4월 28일부터 App Store Connect는 Xcode 26과 iOS 26 SDK 이상을 사용하여 만든 빌드만 받아들이고 있습니다. SDK가 지원하는 버전이 있는지 확인하세요.
cordova-iosGoogle Play는 새로운 앱에 대해 AAB 업로드를 요구하고 매년 최소 __CAPGO_KEEP_0__ 수준을 높입니다. 현재 __CAPGO_KEEP_0__ 수준을 유지하여 기본값이 __CAPGO_KEEP_0__가 되도록 합니다. - Google Play는 새로운 앱의 AAB 업로드를 요구하고 매년 최소 목표 API 수준을 높입니다. 유지
cordova-android역할: UI 레이블. 위치: about.astro 페이지. 메시지 키: about_how_step_label (About How Step Label).targetSdkVersionfollows.
커밋
및 lock파일. Cordova는 플랫폼과 플러그인을 저장소의
- 부분에 저장하므로
package.json그것을 복원합니다.cordova버전package.json, socordova prepareStep 3: CI/CD를 테스트하세요 - 변경하지 마십시오.
platforms/또는plugins/Live Update - 코르도바 CLI를 개발 의존성으로 설치하여 모든 기기에서 동일한 버전을 사용하십시오.
bun add -d cordova
- Capgo
config.xmlcodebuild.jsonAPI - SDK
.nvmrc또는package.jsonengines.
CLI
npm build.json bun build.template.json __CAPGO_KEEP_0__ build.json CI에서 시크릿으로 생성된 실제 값을 얻으려면
{
"android": {
"release": {
"keystore": "release.jks",
"storePassword": "${KEYSTORE_STORE_PASSWORD}",
"alias": "upload",
"password": "${KEYSTORE_KEY_PASSWORD}",
"packageType": "bundle"
}
},
"ios": {
"release": {
"codeSignIdentity": "Apple Distribution",
"developmentTeam": "ABCDE12345",
"packageType": "app-store",
"provisioningProfile": "com.example.app AppStore",
"automaticProvisioning": false
}
}
}
The ${...} Capgo는 Cordova에서 __CAPGO_KEEP_0__를 확장하지 않습니다. envsubst.
Capgo 워크플로우는 아래와 같이 실제 값을 작성합니다. keytool Android 키 스토어를 아직 만들지 않은 경우 또는 를 사용하여 생성하세요. iOS의 경우 를 사용하여 인증서를 생성하세요. .p12 인증서를 생성하는 데 Mac이 필요하지 않습니다.
Step 3: GitHub 작업 흐름
이 워크플로우는 버전 태그에서 양쪽 플랫폼을 동시에 빌드하고 내부 테스트 트랙에 업로드합니다.
# .github/workflows/cordova-release.yml
name: Cordova release
on:
push:
tags: ['v*']
jobs:
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- run: bun install --frozen-lockfile
- run: bun run build # outputs to www/
- run: bunx cordova prepare android
- name: Signing files
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
run: |
echo "$KEYSTORE_BASE64" | base64 --decode > release.jks
envsubst < build.template.json > build.json
- run: bunx cordova build android --release --buildConfig=build.json
- uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.example.app
releaseFiles: platforms/android/app/build/outputs/bundle/release/app-release.aab
track: internal
status: completed
ios:
runs-on: macos-26
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cordova prepare ios
- name: Install certificate and profile
env:
P12_BASE64: ${{ secrets.IOS_P12_BASE64 }}
P12_PASSWORD: ${{ secrets.IOS_P12_PASSWORD }}
PROFILE_BASE64: ${{ secrets.IOS_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo "$P12_BASE64" | base64 --decode > dist.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -lut 21600 build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import dist.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
security list-keychains -d user -s build.keychain login.keychain
for dir in "$HOME/Library/MobileDevice/Provisioning Profiles" \
"$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"; do
mkdir -p "$dir"
echo "$PROFILE_BASE64" | base64 --decode > "$dir/app.mobileprovision"
done
cp build.template.json build.json # iOS values hold no secrets
- run: bunx cordova build ios --release --device --buildConfig=build.json
- name: Upload to TestFlight
env:
API_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
API_ISSUER: ${{ secrets.APPLE_ISSUER_ID }}
API_KEY_BASE64: ${{ secrets.APPLE_KEY_CONTENT }}
run: |
mkdir -p ~/.appstoreconnect/private_keys
echo "$API_KEY_BASE64" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
IPA=$(find platforms/ios/build -name '*.ipa' | head -n 1)
xcrun altool --upload-app -f "$IPA" -t ios --apiKey "$API_KEY_ID" --apiIssuer "$API_ISSUER"
- name: Clean up keychain
if: always()
run: security delete-keychain build.keychain || true
왜 일부 줄이 있는가:
- 두 배포 프로파일 폴더. Xcode 16 이상은 프로파일을
~/Library/Developer/Xcode/UserData/Provisioning Profiles오래된 Xcode는~/Library/MobileDevice/Provisioning Profiles두 가지를 모두 작성하여 ‘com.example.app’에 대한 프로파일이 없습니다’라는 오류를 피합니다. set-key-partition-listmacOS가 키체인 접근을 요청하는 것을 막아 CI 작업이 지연되지 않도록 합니다.- JDK 버전. JDK 버전을 사용하세요.
cordova-android최근 릴리스는 JDK 17을 사용합니다. - 빌드 번호. 업데이트
android-versionCode그리고ios-CFBundleVersion에서config.xml빌드 전에, 예를 들어 CI 실행 번호 또는 스토어에서 업로드를 중복으로 거부하는 경우.
스왑할 수 있습니다. altool fastlane의 업로드 upload_to_testflight fastlane의 Play 액션 supply 이미 fastlane을 사용하는 팀이 있다면.
4단계: 다른 CI 서비스에서 동일한 pipeline
명령어는 CI 간에 변경되지 않습니다. 단, 실행자 선택과 비밀 키 구문만 다릅니다.
| CI | Android 실행자 | iOS 실행자 | Notes |
|---|---|---|---|
| GitHub 작업 | ubuntu-latest |
macos-26 / macos-latest |
macOS는 개인 저장소에서 Linux보다 더 비싸다. |
| GitLab CI | 어떤 Linux 실행자든 | 호스팅된 macOS 실행자(베타, 프리미엄 및 초고급) 또는 자체 호스팅 | 이미지들 macos-26-xcode-26 |
| Bitbucket Pipelines | Linux Docker 이미지 | 자체 호스팅 Mac만 | 보세요 Bitbucket iOS 안내서 |
| Gitea / Forgejo | Linux 실행자 | 자체 호스팅 Mac (호스트 모드) | 보기 Gitea iOS 가이드 |
| Bitrise | Linux 스택 | macOS 스택 | Cordova 단계를 포함하여 (준비, 보관) |
| Codemagic | Linux | Mac mini 인스턴스 | Ionic Cordova 빌드 문서 codemagic.yaml |
| Azure DevOps | ubuntu-latest |
macOS-latest |
인증서 및 프로파일을 설치하는 작업 |
기능별 보기로 읽으려면 Cordova 앱용 CI/CD 플랫폼 비교.
5단계: Cordova Live 업데이트
Live updates let you ship HTML, CSS, and JavaScript fixes without a store review. App Center CodePush ended in March 2025, Appflow Live Updates end on December 31, 2027, and the old community hot code push plugins are unmaintained. A maintained option is Capgo 실시간 업데이트 Live 업데이트 @capgo/cordova-updater 플러그인은 동일한 백엔드, 채널, 및 CLI을 사용하는 Capacitor 업데이터와 동일한 업데이트를 제공합니다.
Cordova Live 업데이트
- Cordova CLI 12+
cordova-android13+ 이상 및/또는cordova-ios7+ (플러그인은 기본적으로 의존)https://localhost/및app://localhost/스키마- 사용하지 마십시오
cordova-plugin-ionic-webview그것과 함께 사용하지 마십시오. Ionic WebView는 Cordova의 스키마 핸들러를 우회하기 때문에 다운로드한 번들을 로드하지 않습니다.
플러그인을 설치하십시오
앱을 Capgo와 Capacitor에서 동일한 방법으로 생성한 다음 플러그인을 Capgo 앱 ID와 함께 설치하십시오:
cordova plugin add @capgo/cordova-updater \
--variable APP_ID=com.example.app \
--variable DEFAULT_CHANNEL=production
cordova prepare android ios
DEFAULT_CHANNEL, UPDATE_URL, 및 AUTO_UPDATE 는 선택적 설치 변수입니다. cordova prepare 변경할 때마다 다시 실행하십시오.
각각의 런칭을 확인하십시오
After devicereadyplugin은 cordova.plugins.Updater호출 notifyAppReady() launch마다
document.addEventListener('deviceready', async () => {
const { Updater } = cordova.plugins
await Updater.notifyAppReady()
const latest = await Updater.getLatest()
if (latest.url && !latest.error) {
const bundle = await Updater.download({
url: latest.url,
version: latest.version,
checksum: latest.checksum,
})
await Updater.next({ id: bundle.id })
}
})
호출
CI에서
live-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx @capgo/cli@latest bundle upload --channel=production
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
Live updates only replace the web bundle. Adding, removing, or upgrading a Cordova plugin still needs a new store build. Capgo compares the native plugins recorded for the live bundle with your project and flags incompatible uploads; see live update 호환성Live Update는 web bundle만 업데이트합니다..
Cordova 플러그인 추가, 제거, 업그레이드도 새로운 스토어 빌드를 필요로합니다. Capgo 빌드 문서는 Capacitor 프로젝트만을 대상으로합니다. ( Cordova 바이너리에서 생성된 네이티브 프로젝트를 업로드합니다.) cap sync Cordova 바이너리는 CI에서 위와 같이 계속 빌드됩니다.
Optional: Capacitor로 마이그레이션하는 경우
Cordova를 떠나지 않아도 작동하는 pipeline과 라이브 업데이트 를 얻을 수 있습니다. 마이그레이션은 별도의 결정이며, 다음과 같은 경우에 가치가 있습니다:
- iOS 빌드가 macOS 런너를 유지하지 않고 싶을 때. Capgo 빌드는 Linux CI 작업에서 Capacitor 앱을 컴파일합니다.
- Cordova 업데이트를 받지 않는 플러그인이 Capacitor에 해당하는 버전이 있는 경우
- Swift Package Manager 지원과 최신 Android Gradle Plugin 버전을 원할 때 패치하지 않고도.
마이그레이션은 __CAPGO_KEEP_0__를 유지합니다. __CAPGO_KEEP_1__을 추가하고, 플러그인을 이동하고 (대부분 Cordova 플러그인은 그대로 작동합니다), __CAPGO_KEEP_2__-네이티브 버전이 있는 플러그인에 대해 몇 가지를 대체합니다. __CAPGO_KEEP_3__ 앱 ID와 채널은 그대로 유지되며, 업데이트 플러그만 __CAPGO_KEEP_0__에서 __CAPGO_KEEP_1__으로 변경됩니다. www code. You add Capacitor, move plugins over (most Cordova plugins work as is), and replace a few that have Capacitor-native equivalents. Your Capgo app ID and channels stay the same; only the updater plugin changes from @capgo/cordova-updater to @capgo/capacitor-updater. The steps are in Capacitor, 그리고 Cordova 에서 Capacitor 솔루션 페이지 마이그레이션 후 CI는 웹 빌드로 축소되며, 플랫폼당 하나의 호출만 발생합니다. cap sync, 그리고 하나 build request Cordova 빌드 문제 해결 Capacitor 앱의 CI/CD 플랫폼 비교.
원인과 해결
| 또는 | Cordova 빌드 문제가 없습니다. 웹 빌드를 Cordova 명령 전에 실행하거나 빈 |
|---|---|
Current working directory is not a Cordova-based project |
config.xml or www/ 또는 www/. |
No platforms added to this project |
Platforms are not listed in package.json. 로컬에서 실행 cordova platform add 로컬에서 한번 실행하고 커밋 package.json. |
Could not find an installed version of Gradle |
최근 cordova-android Gradle wrapper를 사용합니다. 플랫폼을 업데이트하는 대신 글로벌로 Gradle을 설치하지 않습니다. |
Unsupported class file major version |
실행자에 설치된 JDK가 기대하는 JDK와 일치하지 않습니다. 다음 명령어를 사용하여 고정하세요. cordova-android 사용 setup-java. |
No signing certificate "iOS Distribution" found |
사용자 이름으로 Apple Distribution 인증서가 포함되어 있는지 확인하세요. .p12 잠금된 키 체인 또는 분할 목록이 누락된 경우 키 체인 설정 명령어를 다시 실행하세요. |
errSecInternalComponent |
__CAPGO_KEEP_0__이 너무 오래된 경우 업로드가 거부됩니다. |
| 업로드 거부: SDK 버전이 너무旧함 | locally once and commit macos-26 또는 Xcode를 설정하세요. xcode-select. |
Play 업로드: Version code has already been used |
업데이트 android-versionCode 업로드마다. |
요약
2026년 Cordova pipeline은 플랫폼별 CI 작업입니다: Android AAB를 위한 Linux 실행자, IPA를 위한 macOS 실행자와 Xcode 26, 스토어의 __CAPGO_KEEP_0__ 키와 함께 비밀번호를 해독한 키를 생성합니다. mainstream CI는 이를 실행할 수 있습니다. 추가 build.jsonCI/CD를 위한 Cordova 앱에 대한 API 키를 설정하세요. 모든 주요 CI 도구에서 작동합니다. @capgo/cordova-updater 그리고 하나 bundle upload job for web-only fixes, and you have the build, store, and over-the-air pieces Appflow and App Center used to provide. Moving to Capacitor stays an option for later, not a requirement.