
모바일 앱 CI/CD를 처음 구성할 때 가장 번거로운 부분 중 하나가 빌드 머신이다.
특히 iOS는 Xcode와 macOS가 필요하기 때문에 예전에는 이런 구성을 많이 만들었다.
개발 Mac
↓
GitHub
↓
회사 Mac mini
↓
GitHub Self-hosted Runner
↓
Fastlane
↓
TestFlight
문제는 Mac PC를 계속 켜놔야 한다는 것이다.
Runner가 멈추면 빌드도 멈춘다.
Xcode가 업데이트되면 직접 들어가서 업데이트해야 한다.
인증서가 꼬이면 Keychain을 다시 확인한다.
GitHub Actions Runner가 오래되면 업데이트한다.
CI 서버가 필요해서
Mac 한 대를 개발 장비가 아니라
배포 서버로 묶어두는 구조
가 된다.
Android까지 운영하면 또 다른 Workflow가 생긴다.
Android
GitHub Actions
→ Gradle
→ AAB
→ Google Play
iOS는
iOS
GitHub Actions
→ Xcode
→ Fastlane
→ TestFlight
로 따로 관리한다.
그런데 2026년 모바일 CI/CD 환경에서는 굳이 이렇게 운영할 이유가 많이 줄었다.
GitHub는 Apple Silicon 기반 macos-26 Hosted Runner를 제공하고 있고, Self-hosted Runner가 꼭 필요하다면 macOS까지 지원하는 Runner Scale Set 방식과 Ephemeral Runner를 이용해 작업이 있을 때만 Runner를 생성하고 작업이 끝나면 없애는 구조를 만들 수 있다.
여기에 최근 Public Preview로 들어온 GitHub Agentic Workflows를 붙이면 AI Agent가 다음 작업까지 맡을 수 있다.
Workflow 상태 확인
CI 실패 원인 분석
Release 준비 상태 확인
Version 변경 확인
Release Note 작성
누락된 테스트 확인
Fastlane / Action 설정 점검
Runner 설정 변경 PR 생성
배포 가능 여부 보고
다만 여기서 중요한 원칙이 하나 있다.
AI Agent에게 Production 배포 권한까지 직접 주는 것은 좋은 자동화가 아니다.
가장 현실적인 구조는 이것이다.
AI Agent
→ 판단과 관리
GitHub Actions
→ 실행
Fastlane
→ 서명·업로드
Environment Gate
→ 승인
App Store / Play Store
→ 실제 배포
이번 글에서는 iOS와 Android를 하나의 Mobile Release Pipeline으로 구성하고, 개발용 Test Build부터 TestFlight·Google Play Internal Testing, Production Release 준비까지 AI Agent가 관리하게 만드는 방법을 정리한다.
목표는 다음 구조다.
Developer
│
▼
Pull Request
│
├───────────────┐
│ │
▼ ▼
iOS CI Android CI
macos-26 ubuntu
│ │
▼ ▼
Build / Test Build / Test
│ │
└───────┬───────┘
│
▼
AI Release Agent
CI 결과
Version
변경 범위
Test
Release Note
위험 분석
│
▼
Release Ready?
│
┌────┴────┐
│ │
NO YES
│ │
▼ ▼
Report Beta Pipeline
│
┌──────┴──────┐
│ │
TestFlight Play Internal
Production은 한 단계 더 둔다.
Release Tag
v2.4.0
│
▼
Release Readiness
│
▼
Build
│
▼
Store Artifact
│
▼
GitHub Environment
production-ios
production-android
│
▼
Human Approval
│
▼
App Store Connect
Google Play Production
즉 Test Build는 최대한 자동화하고, Production만 Gate를 둔다.
GitHub Hosted Runner를 사용하면 GitHub가 Job이 실행될 때 VM을 준비한다.
iOS:
runs-on: macos-26
Android:
runs-on: ubuntu-24.04
Workflow가 끝나면 Runner도 사라진다.
Job 없음
Runner 없음
↓
PR 생성
↓
GitHub가 Runner 생성
↓
Build
↓
Runner 삭제
개발자가 별도의 Mac PC를 계속 켜놓을 필요가 없다.
현재 macos-26은 Apple Silicon 기반 GitHub-hosted Runner로 사용할 수 있다.
대부분의 소규모·중규모 앱이라면 이 구조부터 검토하는 것이 좋다.
지금 새 모바일 프로젝트를 만든다면 다음처럼 시작한다.
iOS
GitHub-hosted
macos-26
Android
GitHub-hosted
ubuntu-24.04
Self-hosted Runner는 다음 이유가 있을 때만 검토한다.
사내 Network 접근 필요
특수 Hardware 필요
큰 Build Cache 필요
GitHub Hosted 비용이 지나치게 큼
특수 Xcode Environment
사내 보안 정책
예전처럼
CI니까 일단 Mac mini 하나 사자.
부터 시작하지 않는다.
모바일 앱이 iOS와 Android 각각 존재한다고 가정해보자.
mobile/
├── ios/
│ ├── App.xcodeproj
│ ├── fastlane/
│ │ ├── Fastfile
│ │ └── Appfile
│ └── Gemfile
│
├── android/
│ ├── app/
│ ├── fastlane/
│ │ ├── Fastfile
│ │ └── Appfile
│ └── Gemfile
│
├── .github/
│ ├── workflows/
│ │ ├── mobile-ci.yml
│ │ ├── beta-ios.yml
│ │ ├── beta-android.yml
│ │ ├── release-ios.yml
│ │ ├── release-android.yml
│ │ └── release-readiness.md
│ │
│ └── release/
│ └── policy.yml
│
├── .ai/
│ └── release/
│ ├── release-plan.json
│ ├── readiness.schema.json
│ └── instructions.md
│
└── AGENTS.md
중요한 것은 AI 설정과 실제 배포 Workflow를 분리하는 것이다.
AI
release-readiness.md
release-plan.json
Deterministic CI
beta-ios.yml
beta-android.yml
release-ios.yml
release-android.yml
AI가 Store Credential을 직접 가지고 배포하지 않는다.
PR이 올라왔다고 TestFlight까지 매번 올릴 필요는 없다.
PR 단계의 목적은
Merge해도 되는가?
를 검증하는 것이다.
.github/workflows/mobile-ci.yml
name: Mobile CI
on:
pull_request:
branches:
- main
- develop
jobs:
ios:
runs-on: macos-26
defaults:
run:
working-directory: ios
steps:
- uses: actions/checkout@v4
- name: Install Ruby dependencies
run: bundle install
- name: Build and test
run: bundle exec fastlane ci
android:
runs-on: ubuntu-24.04
defaults:
run:
working-directory: android
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
- name: Install Ruby dependencies
run: bundle install
- name: Build and test
run: bundle exec fastlane ci
PR 단계에서는 Store Credential을 주지 않는 것이 좋다.
PR Runner
Source
Test
Lint
Build
O
App Store Key
Google Play Key
Production Secret
X
CI와 Release 권한을 분리한다.
ios/fastlane/Fastfile
default_platform(:ios)
platform :ios do
lane :ci do
scan(
scheme: "App",
clean: true
)
end
private_lane :asc_api_key do
app_store_connect_api_key(
key_id: ENV.fetch("ASC_KEY_ID"),
issuer_id: ENV.fetch("ASC_ISSUER_ID"),
key_filepath: ENV.fetch("ASC_KEY_FILE")
)
end
lane :beta do
setup_ci
api_key = asc_api_key
match(
type: "appstore",
readonly: true,
api_key: api_key
)
build_app(
scheme: "App",
export_method: "app-store"
)
upload_to_testflight(
api_key: api_key,
skip_waiting_for_build_processing: true
)
end
end
CI에서는 match를 readonly로 사용하는 것이 중요하다.
CI Runner가 마음대로 새로운 인증서를 만들거나 기존 인증서를 변경하게 하지 않는다.
개발자 관리
Certificate 생성
Provisioning 변경
↓
CI
읽기만
구조가 된다.
Fastlane도 CI 환경에서는 match readonly 사용을 권장한다.
예전 Fastlane 설정에서는 Apple ID와 Session을 많이 사용했다.
문제는
2FA
Session 만료
로그인 실패
Cookie 문제
가 있었다.
현재는 가능한 작업에서는 App Store Connect API Key를 사용하는 편이 좋다.
필요한 정보는 다음이다.
Key ID
Issuer ID
.p8 Private Key
GitHub Secret 예:
ASC_KEY_ID
ASC_ISSUER_ID
ASC_API_KEY_P8
.p8 파일을 Repository에 올리면 안 된다.
Workflow 실행 중 임시 파일로 만든다.
- name: Create App Store Connect key
shell: bash
run: |
printf '%s' "${{ secrets.ASC_API_KEY_P8 }}" \
> "$RUNNER_TEMP/AuthKey.p8"
echo "ASC_KEY_FILE=$RUNNER_TEMP/AuthKey.p8" >> "$GITHUB_ENV"
Job이 끝나면 Hosted Runner 자체가 폐기된다.
이것이 Ephemeral CI의 장점이다.
예를 들어 팀 규칙을 다음처럼 만들 수 있다.
PR
→ Build + Test
develop merge
→ TestFlight
vX.Y.Z tag
→ Production Candidate
beta-ios.yml
name: iOS Beta
on:
push:
branches:
- develop
workflow_dispatch:
concurrency:
group: ios-beta
cancel-in-progress: true
jobs:
beta:
runs-on: macos-26
environment: ios-beta
defaults:
run:
working-directory: ios
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: bundle install
- name: Prepare App Store Connect key
run: |
printf '%s' "${{ secrets.ASC_API_KEY_P8 }}" \
> "$RUNNER_TEMP/AuthKey.p8"
echo "ASC_KEY_FILE=$RUNNER_TEMP/AuthKey.p8" >> "$GITHUB_ENV"
- name: Upload TestFlight
env:
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: bundle exec fastlane beta
이제 개발자가
Archive
Organizer
Distribute App
TestFlight Upload
을 직접 할 필요가 없다.
develop에 Merge하면 TestFlight Build가 생성된다.
Android Fastlane은 supply를 이용한다.
android/fastlane/Fastfile
default_platform(:android)
platform :android do
lane :ci do
gradle(
task: "test",
build_type: "Debug"
)
end
lane :internal do
gradle(
task: "bundle",
build_type: "Release"
)
upload_to_play_store(
track: "internal",
aab: lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH],
json_key_data: ENV.fetch("PLAY_SERVICE_ACCOUNT_JSON"),
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end
end
Google Play Console에서 Service Account를 준비하고 필요한 권한만 준다.
GitHub Secret:
PLAY_SERVICE_ACCOUNT_JSON
을 사용한다.
beta-android.yml
name: Android Beta
on:
push:
branches:
- develop
workflow_dispatch:
concurrency:
group: android-beta
cancel-in-progress: true
jobs:
beta:
runs-on: ubuntu-24.04
environment: android-beta
defaults:
run:
working-directory: android
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
- name: Install Ruby dependencies
run: bundle install
- name: Upload Google Play internal build
env:
PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
run: bundle exec fastlane internal
결과는
develop Merge
│
├── iOS
│ └── TestFlight
│
└── Android
└── Google Play Internal
이 된다.
Google Play Internal Testing은 최대 100명의 내부 테스터에게 빠르게 배포하는 초기 QA 용도로 사용할 수 있다.
Firebase App Distribution도 선택지가 된다.
Firebase App Distribution은 iOS와 Android를 모두 지원한다.
GitHub Actions
├── iOS IPA
│
└── Android APK/AAB
↓
Firebase App Distribution
↓
QA Team
장점은 하나의 QA 배포 플랫폼에서 두 OS를 관리할 수 있다는 것이다.
다만 다음처럼 역할을 분리하는 편을 선호한다.
빠른 사내 QA
→ Firebase App Distribution
스토어 환경에 가까운 Beta
iOS
→ TestFlight
Android
→ Play Internal
Firebase가 TestFlight와 Google Play Release Pipeline을 대체하는 것은 아니다.
여기서부터 최근 흐름이다.
GitHub Agentic Workflows는 2026년 6월 Public Preview에 들어갔다.
기존 GitHub Actions가 이런 작업을 한다면
명령 실행
Build
Test
Upload
Agentic Workflow는 이런 일을 담당한다.
이번 PR이 Release에 어떤 영향을 주는가?
Version 변경이 필요한가?
Release Note에 무엇을 넣어야 하는가?
CI 실패 원인이 코드인가 환경인가?
이번 변경으로 추가 Test가 필요한가?
Release를 막아야 할 위험이 있는가?
즉
GitHub Actions
Deterministic Automation
위에
AI Agent
Reasoning Automation
이 추가되는 것이다.
좋지 않은 구조:
AI
"Release 가능해 보임"
↓
Production Upload
추천 구조:
AI
Release 상태 분석
↓
release-readiness 작성
↓
GitHub Actions
Build / Test
↓
Environment Approval
↓
Store Upload
AI는 판단 자료를 만든다.
실행 여부는 정책이 결정한다.
예를 들어 Agent에게 다음을 확인하게 한다.
PR 모두 Merge됐는가
필수 CI가 성공했는가
iOS Build가 성공했는가
Android Build가 성공했는가
Version이 변경됐는가
Release Note가 존재하는가
Migration이 포함됐는가
권한 변경이 있는가
결제 코드 변경이 있는가
로그인 변경이 있는가
새 Dependency가 추가됐는가
테스트가 누락됐는가
결과를 구조화한다.
{
"status": "ready",
"version": "2.4.0",
"ios": {
"build": "passed",
"tests": "passed"
},
"android": {
"build": "passed",
"tests": "passed"
},
"risk": "medium",
"blockingIssues": [],
"requiresHumanApproval": true
}
AI가
문제없어 보입니다.
라고 말하는 것보다 훨씬 유용하다.
예를 들어
.github/workflows/release-readiness.md
를 만든다.
---
on:
workflow_dispatch:
schedule: weekly
permissions:
contents: read
actions: read
pull-requests: read
safe-outputs:
create-issue:
title-prefix: "[release-readiness] "
labels:
- release
- ai-report
---
# Mobile Release Readiness
Analyze the current mobile release readiness.
Check:
- latest successful iOS CI
- latest successful Android CI
- version changes
- merged pull requests since the previous release
- breaking changes
- dependency updates
- authentication changes
- payment changes
- missing tests
- release notes
Do not trigger a production deployment.
Produce:
- candidate version
- release summary
- blocking issues
- risk level
- recommended next action
gh aw가 이 Markdown을 일반 GitHub Actions Workflow로 Compile한다.
Agent Engine은 환경에 따라
GitHub Copilot
Claude Code
OpenAI Codex
Gemini
등을 사용할 수 있다.
최근 Agentic CI/CD에서 가장 중요한 원칙 중 하나다.
AI Agent가 이런 Secret을 읽어서는 안 된다.
Apple .p8
Google Play Service Account
Match Password
Signing Certificate
Production Token
GitHub Agentic Workflows는 기본적으로 Agent가 Read-only 권한에서 동작하고, Agent Sandbox에 Secret을 직접 넘기지 않는 Zero-Secret 구조와 Safe Output Gate를 제공한다.
따라서 구조를 이렇게 만든다.
AI Agent
No Store Secret
↓
release-ready 결과
↓
Deterministic Workflow
↓
GitHub Environment
↓
Secret Injection
↓
Fastlane
↓
Store
이 구분이 중요하다.
Production Pipeline Trigger를 AI 판단 하나에 연결하지 않는다.
다음처럼 명시적인 이벤트를 둔다.
v2.4.0
Tag 생성:
git tag v2.4.0
git push origin v2.4.0
Workflow:
on:
push:
tags:
- "v*"
Tag는
Release 의도
를 표현한다.
AI는
Release 가능 여부
를 검토한다.
둘을 분리한다.
예를 들어
ios-production
android-production
Environment를 만든다.
그리고 필요한 Secret을 Environment Secret으로 옮긴다.
ios-production
ASC_KEY_ID
ASC_ISSUER_ID
ASC_API_KEY_P8
MATCH_PASSWORD
android-production
PLAY_SERVICE_ACCOUNT_JSON
Workflow Job:
environment: ios-production
Environment Approval을 설정하면 승인 전에는 Production Secret이 Job에 전달되지 않는다.
구조가 이렇게 된다.
Build
↓
Release Ready
↓
Waiting for Approval
↓
사람 승인
↓
Production Secret 사용 가능
↓
Upload
GitHub Plan과 Repository 공개 여부에 따라 Required Reviewer 지원 범위가 달라질 수 있으므로 실제 조직 플랜에서 확인한다.
나쁜 구조:
Build
↓
Upload Production
↓
Test
좋은 구조:
Build
↓
Test
↓
Artifact
↓
Approval
↓
Upload
Release Candidate가 먼저 만들어져야 한다.
v2.4.0 Tag
↓
macos-26
↓
Fastlane
↓
match readonly
↓
Archive
↓
Test
↓
App Store Connect Upload
↓
Review 준비
가능하면 Production Store Submission과 실제 Release 시점도 별도로 관리한다.
Binary Upload
≠
App Store 즉시 공개
가 되게 만드는 편이 안전하다.
v2.4.0
↓
ubuntu
↓
Gradle Bundle
↓
AAB
↓
Test
↓
Environment Approval
↓
Google Play Production
운영 규모가 커지면 바로 100% Production으로 올리는 대신 Play Console의 단계적 Rollout 정책을 함께 사용할 수도 있다.
핵심은 AI가 Rollout 숫자를 즉흥적으로 결정하게 하지 않는 것이다.
release-policy.yml
같은 정책 파일에 둔다.
.github/release/policy.yml
version: 1
beta:
ios:
auto_on_develop: true
destination: testflight
android:
auto_on_develop: true
destination: internal
production:
require_tag: true
require_ci: true
require_release_readiness: true
require_human_approval: true
auto_publish: false
risk:
require_manual_review:
- authentication
- payment
- signing
- database_migration
- privacy
AI Agent도 이 파일을 읽는다.
하지만 마음대로 수정하지 않는다.
변경이 필요하면 PR을 만든다.
여기서 Agent를 꽤 적극적으로 사용할 수 있다.
예를 들어 매주 확인한다.
GitHub Action 버전이 오래됐는가?
macOS Runner Image가 Deprecated 예정인가?
Xcode 버전이 바뀌었는가?
Fastlane 업데이트가 필요한가?
Android Gradle Plugin이 오래됐는가?
Java Version 변경이 필요한가?
Signing Certificate 만료가 다가오는가?
CI 실패율이 증가했는가?
Build 시간이 갑자기 늘었는가?
Agent는 바로 main을 수정하는 대신 PR을 만든다.
Agent
↓
CI Maintenance Report
↓
Config Update PR
↓
Developer Review
↓
Merge
예를 들어 iOS Build가 실패했다.
xcodebuild exit 65
기존에는 개발자가 GitHub Actions Log를 직접 연다.
Agent Workflow가 있으면 다음을 수행할 수 있다.
실패 Job 확인
↓
Build Log 분석
↓
최근 Diff 확인
↓
이전 성공 Build 비교
↓
원인 후보 정리
↓
Issue / PR Comment 생성
결과:
가능성 높음
Signing 문제가 아니라
MainActor isolation compile error
관련 파일:
CameraSession.swift
최근 변경:
PR #842
추천:
해당 PR의 concurrency 변경 확인
정도로 받아볼 수 있다.
위험도가 낮은 경우에는
CI 실패 분석
↓
수정 후보 생성
↓
Branch 생성
↓
Fix PR
까지 가능하다.
하지만 Mobile Release Pipeline에서는 다음을 자동 수정 대상에서 제외하는 편이 좋다.
Signing
Provisioning
Production Environment
Store Credential
Bundle ID
Application ID
Package Signing
Production Track
이 영역은 인간 Review가 필요하다.
GitHub Hosted Runner가 모든 상황에 맞는 것은 아니다.
예를 들어 사내 Network에만 접근해야 한다.
Private CocoaPods
사내 Git
Private API
Hardware Device Farm
VPN
이 경우 Self-hosted macOS Runner가 필요할 수 있다.
하지만 그래도 항상 켜놓는 Runner부터 만들 필요는 없다.
GitHub는 Autoscaling Self-hosted Runner에서는 Ephemeral Runner 사용을 권장한다.
현재 GitHub의 Runner Scale Set Client는
Linux
Windows
macOS
환경에서 Custom Autoscaler를 만들 수 있게 한다.
구조는 다음과 같다.
GitHub Actions
workflow_job queued
│
▼
Runner Control Plane
│
▼
macOS VM Start
│
▼
Just-in-time Runner 등록
│
▼
Build 1개 실행
│
▼
Runner 자동 Deregister
│
▼
VM Shutdown / Destroy
필요할 때만 돈을 쓴다.
등록 시 Ephemeral Mode를 사용하면 Runner는 한 Job이 끝나면 자동 등록 해제된다.
개념적으로:
./config.sh \
--url https://github.com/company \
--token "$RUNNER_TOKEN" \
--ephemeral
실제 Production Autoscaler에서는 장기 Registration Token을 Script에 저장하기보다 GitHub App이나 Runner Scale Set/JIT Registration을 통해 단기 설정을 공급하는 방식이 더 적합하다.
목표는 이것이다.
Reusable CI Server
X
Disposable Build Machine
O
가능은 하다.
하지만 다음 구조는 권하지 않는다.
내 개발 Mac
+
항상 등록된 Self-hosted Runner
내가 개발 중인데 CI Job이 갑자기 들어올 수 있다.
또 Mac을 꺼두면 Job이 Queue에 계속 남을 수 있다.
GitHub 문서상 조건에 맞는 Runner가 없으면 Job은 Queue에서 최대 24시간 기다릴 수 있다.
따라서 개발 Mac을 공유한다면 최소한 다음 구조가 낫다.
평소
Runner OFF
필요할 때
Runner Start
→ Ephemeral 등록
→ Job 1개
→ 자동 해제
여기에는 한계가 있다.
AI Agent가 소프트웨어적으로
Runner 등록
Runner 중지
GitHub Workflow 실행
Cloud VM Start
Cloud VM Stop
를 하는 것은 가능하다.
하지만 전원이 완전히 꺼진 사무실 Mac PC를 AI가 무조건 켤 수 있는 것은 아니다.
다음과 같은 별도 관리 수단이 필요하다.
MDM
Wake-on-LAN
Smart Power / Remote Management
Cloud macOS Provider API
Out-of-band Management
따라서 정말 On-demand CI를 만들고 싶다면 Physical Mac보다 Cloud macOS + Ephemeral Runner가 자연스럽다.
GitHub-hosted Runner를 사용할 수 있다면 더 단순하다.
가장 먼저:
GitHub Hosted
iOS
macos-26
Android
ubuntu
두 번째:
Xcode Cloud
iOS 전용 Pipeline
세 번째:
Ephemeral Self-hosted macOS
특수 환경이 필요할 때
마지막:
항상 켜놓는 회사 Mac mini
이다.
iOS 전용 팀이라면 Xcode Cloud도 검토할 만하다.
Apple이 직접
Build
Test
Archive
TestFlight
App Store Connect
를 연결한다.
특히 TestFlight 배포가 간단하다.
PR
↓
Xcode Cloud
↓
Build / Test
develop
↓
Archive
↓
TestFlight
구조를 만들 수 있다.
그리고 App Store Connect API를 통해 Xcode Cloud Workflow와 Build를 자동 관리할 수도 있다.
두 Platform을 같이 관리하면
GitHub
│
┌──────┴──────┐
│ │
iOS Android
│ │
Fastlane Fastlane
│ │
TestFlight Play
구조가 보기 좋다.
AI Release Agent도 한 Repository에서 두 Platform을 같이 판단할 수 있다.
iOS Ready
Android Ready
Version 동일
Release Note 동일
Feature Flag 동일
같은 Cross-platform 검증도 가능하다.
예를 들어 Release version이
2.4.0
이라면 Agent가 확인한다.
iOS
CFBundleShortVersionString
2.4.0
Android
versionName
2.4.0
불일치:
iOS
2.4.0
Android
2.3.9
이면
RELEASE BLOCKED
처리한다.
단순하지만 실제 Release 사고를 많이 줄일 수 있다.
iOS:
CFBundleVersion
Android:
versionCode
는 CI에서 자동 증가시키는 편이 좋다.
예를 들어 GitHub Run Number를 기반으로 사용할 수 있다.
중요한 것은 사람이 매번
Build 142
Build 143
Build 144
를 수정하지 않는 것이다.
Release Version:
2.4.0
은 사람이 의미를 결정한다.
Build Number:
1842
은 CI가 관리한다.
역할을 나눈다.
이건 Agent가 잘하는 일이다.
지난 Release 이후 Merge된 PR:
#821 Login 개선
#824 Camera Crash 수정
#829 Dark Mode 수정
#835 Analytics 이벤트 추가
Agent가 이를
사용자 변경
Bug Fix
내부 개선
주의사항
으로 분류한다.
예:
## 2.4.0
### 새로운 기능
- 로그인 복구 흐름을 개선했습니다.
### 개선
- 카메라 안정성을 개선했습니다.
- 다크 모드 화면을 개선했습니다.
### 내부 변경
- Analytics 이벤트 구조를 정리했습니다.
개발자가 최종 확인한다.
Agent에게 Output Contract를 준다.
{
"version": "2.4.0",
"ios": {
"ko": "",
"en": ""
},
"android": {
"ko": "",
"en": ""
},
"internal": {
"breakingChanges": [],
"migration": []
}
}
하나의 Merge History에서 두 Store Release Note를 생성한다.
단순한 YES/NO보다 다음처럼 만들 수도 있다.
CI
25 / 25
Test
20 / 25
Crash
20 / 20
Store Metadata
10 / 10
High-risk Change
10 / 20
총:
85 / 100
하지만 AI가 만든 점수 자체를 Production 승인 기준으로 단독 사용하면 안 된다.
점수는 판단 보조다.
Hard Gate는 별도로 둔다.
CI Fail
→ 무조건 Block
Test Not Run
→ Block
Version 불일치
→ Block
Signing Failure
→ Block
이런 것은 코드로 판단한다.
AI에게 적합:
Release Note 작성
Risk 요약
CI Log 분석
변경 범위 분류
누락 Test 후보
Dependency 영향 분석
코드가 적합:
Test Passed 여부
Build 성공 여부
Version 일치
Artifact 존재
Tag 존재
Required Approval
Secret 사용
Store Upload
이 구분이 매우 중요하다.
iOS Build / Test
+
Android Build / Test
+
AI PR Risk Review
iOS
→ TestFlight Internal
Android
→ Play Internal
AI Release Agent
→ CI 상태
→ 최근 PR
→ 실패 Build
→ Release 준비도
Report 생성
v2.4.0
↓
Full Build
↓
Full Test
↓
AI Release Readiness
↓
Environment Approval
↓
App Store Connect
Google Play
Agent
Release Note 확인
Crash / CI 확인
Hotfix 후보 정리
예를 들어 매주 Agent에게 다음을 검사시킨다.
.github/workflows/
ios/Fastfile
android/Fastfile
Gemfile.lock
Gradle Version
Xcode Runner
Action Versions
문제가 있으면 Report.
명확한 변경이면 PR.
macos-26 Runner 변경 필요
↓
Agent PR
Fastlane minor update
↓
Agent PR
하지만 CI 설정 변경 PR에는 반드시 Review를 둔다.
AI가 자신의 실행 환경을 스스로 변경하고 바로 Merge하도록 만들면 안 된다.
Agent가 직접 다음을 할 수 있게 만들 필요는 없다.
Secret 생성
Secret 조회
Production Environment 변경
Required Reviewer 제거
Branch Protection 해제
Runner Admin
Store Credential 생성
Agent가 필요한 것은 보통
Repository Read
Actions Read
PR Read
Issue Write
PR 생성
정도다.
최소 권한을 적용한다.
2026년 GitHub Agentic Workflows의 방향이 바로 이것이다.
기존 Deterministic CI/CD를 없애는 것이 아니다.
GitHub Actions
그대로 유지
그 위에
Continuous AI
를 추가한다.
CI 실패 이유 분석
문서 갱신
Release Note 생성
Test 개선
Repository Maintenance
같은 판단 작업을 Agent에게 준다.
Mobile Release Pipeline에서도 같은 구조가 적합하다.
당신은 Mobile Release Manager Agent다.
Release를 직접 실행하지 않는다.
다음 정보를 분석한다.
- iOS CI
- Android CI
- merged PRs
- version
- dependencies
- authentication changes
- payment changes
- privacy changes
- test coverage
- release notes
Hard Block 조건:
- required CI failure
- required test not run
- iOS / Android release version mismatch
- missing release artifact
- unresolved signing issue
다음 결과만 반환한다.
- release status
- blocking issues
- warnings
- release notes draft
- recommended next action
Production deploy를 호출하지 않는다.
Secret을 요청하지 않는다.
AI의 책임이 명확하다.
이런 Workflow 하나는 피한다.
mobile-everything.yml
안에
PR
Beta
Production
TestFlight
Play
Release Note
Signing
AI
가 다 들어 있으면 관리가 어렵다.
분리한다.
mobile-ci.yml
beta-ios.yml
beta-android.yml
release-ios.yml
release-android.yml
release-readiness.md
실패 범위가 줄어든다.
iOS
.xcresult
IPA
Archive Log
Test Result
Android
AAB
Test Report
Lint Report
Mapping File
공통
release-plan.json
release-notes.json
release-readiness.json
Agent에게 Raw Log 전체를 Context로 던지지 않는다.
필요한 Artifact만 읽게 한다.
TestFlight나 Internal Track은 꽤 강하게 자동화해도 된다.
develop merge
→ 자동 Beta
Production은 조금 다르다.
최소한 다음 영역이 있는 앱이라면 사람 승인을 유지하는 것이 좋다.
결제
금융
로그인
의료
개인정보
구독
Database Migration
Backend API 변경
AI Agent가 발전했다고 Release 사고 비용이 줄어드는 것은 아니다.
개인 앱이라면 다음 정도면 충분하다.
PR
→ Build / Test
main Merge
→ TestFlight
→ Play Internal
Release Tag
→ Store Build
→ GitHub Environment 승인
→ Store Upload
AI Agent는
CI 실패 분석
Release Note
Version 확인
Store 준비 상태
만 담당한다.
별도의 DevOps Server가 필요하지 않다.
2026년 기준 개인·소규모 팀이라면 다음 순서로 추천한다.
GitHub Actions
iOS
→ macos-26
Android
→ ubuntu-24.04
↓
Fastlane
iOS
→ TestFlight
Android
→ Play Internal
↓
GitHub Agentic Workflow
→ Release Readiness
→ CI Failure Analysis
→ Release Notes
↓
GitHub Environments
→ Production Approval
Self-hosted가 정말 필요할 때만
Runner Scale Set Client
+
Ephemeral macOS Runner
를 추가한다.
예전 모바일 CI/CD는 이런 그림이었다.
회사 Mac mini
24시간 ON
↓
Self-hosted Runner
↓
Fastlane
↓
Store
지금은 굳이 그렇게 시작할 필요가 없다.
PR / Tag
↓
On-demand Runner
↓
Build / Test
↓
Fastlane
↓
TestFlight / Play Internal
↓
AI Release Readiness
↓
Human Approval
↓
Production
그리고 Self-hosted Runner가 필요한 경우에도
항상 켜진 Runner
보다
Job이 생기면 Runner 생성
↓
Job 하나 실행
↓
Runner 삭제
↓
Machine 종료
하는 Ephemeral 방식이 더 자연스럽다.
여기에 AI Agent를 붙이면 자동화 범위도 넓어진다.
하지만 역할을 잘 나눠야 한다.
AI Agent
생각한다.
분석한다.
관리한다.
문제를 찾는다.
PR을 제안한다.
GitHub Actions + Fastlane
빌드한다.
테스트한다.
서명한다.
업로드한다.
Human Gate
Production 출시를 승인한다.
한 줄로 정리하면 이렇다.
2026년 모바일 배포 자동화의 핵심은
AI가 앱을 마음대로 출시하게 만드는 것이 아니라,
AI가 Release Manager가 되고,
Ephemeral CI가 Build Worker가 되며,
Store 배포는 정책으로 통제하는 구조를 만드는 것이다.
이렇게 구성하면 개발자는 Mac PC 한 대를 CI Server로 계속 묶어둘 필요 없이 평소에는 개발에 집중하고, PR·Merge·Tag가 발생했을 때만 필요한 Build 환경을 사용하면서 iOS와 Android의 테스트 배포와 출시 준비를 상당 부분 자동화할 수 있다.
GitHub — Agentic Workflows Public Preview
자연어 Markdown으로 AI Workflow를 정의하고 GitHub Actions Workflow로 Compile하며, Copilot·Claude Code·OpenAI Codex 등의 Coding Agent를 CI 안에서 사용하는 최신 Agentic CI 흐름.
GitHub — GitHub-hosted macOS Runners
Apple Silicon 기반 macos-26과 대형 Runner를 이용해 별도 Mac Server 없이 iOS Build와 Test를 수행하는 공식 Runner 환경.
GitHub — Self-hosted Runner Autoscaling / Runner Scale Set Client
macOS·Windows·Linux VM을 필요할 때 생성하고 Ephemeral Runner로 한 Job만 실행한 뒤 폐기하는 On-demand Runner 구조.
GitHub — Environments and Deployment Protection Rules
Production Secret을 Environment에 격리하고 Required Reviewer 또는 Deployment Protection Rule을 통과한 뒤에만 Release Job이 Secret에 접근하도록 만드는 공식 기능.
Apple — App Store Connect API
App Store Connect 작업을 자동화하기 위한 공식 API와 Role 기반 API Key 관리 방식.
Apple — Xcode Cloud / TestFlight Distribution
iOS 전용 CI/CD에서 Build·Test·Archive·TestFlight·App Store Connect를 연결하는 Apple 공식 Cloud Pipeline.
fastlane — App Store Connect API / pilot / match
App Store Connect API Key를 이용한 TestFlight 업로드와 CI 환경에서의 match readonly 기반 Code Signing 자동화.
fastlane — supply
Android App Bundle을 Google Play의 Internal·Testing·Production Track으로 자동 업로드하기 위한 공식 Fastlane Action.
Google Play — Internal Testing
최대 100명의 내부 테스터에게 Play Store를 통해 빠르게 테스트 Build를 배포하는 공식 Test Track.
Firebase — App Distribution
iOS와 Android의 사전 QA Build를 하나의 Cross-platform 배포 시스템에서 관리할 수 있는 공식 테스트 배포 서비스.
GitHub Hosted Runner는 Job 시작 시 새로운 VM을 자동으로 준비하므로, 일반적인 iOS CI를 위해 별도의 Mac PC를 24시간 운영할 필요가 없다. 현재 macos-26 Runner는 Apple Silicon 기반으로 제공되며 최신 Xcode 기반 앱 Build와 Test에 사용할 수 있다.
Self-hosted Runner가 필요한 환경에서는 GitHub가 Persistent Runner를 껐다 켜는 방식보다 Ephemeral Runner 기반 Autoscaling을 권장한다. Runner Scale Set Client는 현재 macOS까지 지원하므로 Cloud macOS VM을 Job Queue에 맞춰 Provision하고 한 Job 실행 후 폐기하는 구조를 직접 만들 수 있다.
GitHub Agentic Workflows는 기존 CI/CD를 대체하는 기능이 아니라 그 위에 AI 판단을 추가하는 구조다. Release Readiness, CI Failure Analysis, Release Note 생성 같은 Reasoning 작업은 Agent에게 맡기고 실제 Build·Signing·Store Upload는 기존 Actions와 Fastlane으로 유지하는 것이 적절하다.
Production 배포에는 GitHub Environment를 사용하는 것이 좋다. Environment에 Required Approval이 설정되어 있으면 승인되기 전까지 해당 Environment의 Secret을 Job이 사용할 수 없으므로 App Store·Google Play Production Credential을 Agent와 일반 PR Workflow에서 분리할 수 있다.