본문으로 바로가기
CI/CD iOS 튜토리얼

Gitea 액션으로 iOS 앱 빌드 및 배포

iOS 앱을 Gitea Actions에서 TestFlight로 빌드, 서명, 업로드하세요: act_runner와 함께 호스트 모드에서 Mac를 실행하거나, Linux runner에서 iOS 빌드를 클라우드 빌드 서비스로 전송하세요.

Gitea Actions로 iOS 앱을 빌드 및 배포하세요

Gitea Actions는 iOS 앱을 빌드할 수 있지만, Xcode는 macOS에서만 실행되기 때문에 Gitea에서 호스트된 러너가 없기 때문에 Mac을 등록하여 호스트 모드에서 실행하거나, 일반 Linux 러너를 사용하여 iOS 빌드를 클라우드 빌드 서비스로 전송하세요. act_runner in host mode, or a normal Linux runner that sends the iOS build to a cloud build service. This guide walks through both for a Capacitor app, with workflow files you can drop into .gitea/workflows/.

팀은 Gitea를 선택하여 code를 제어하는 인프라에서 code를 유지하고 싶기 때문입니다. 앱이 Xcode가 필요하더라도, 두 가지 설정은 아래에 설명되어 있습니다.

Gitea 액션의 작업을 실행하는 방법

Gitea Actions은 GitHub Actions 호환 구문 syntax을 사용하고 작업은 act_runner Gitea Actions uses a __CAPGO_KEEP_0__ Actions compatible syntax, and jobs run on ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest. :job: 이 후에 콜론이 오면 작업이 어떻게 실행되는지 결정합니다.

  • docker://image Gitea Actions uses a __CAPGO_KEEP_0__ Actions compatible syntax, and jobs run on
  • host Gitea Actions uses a __CAPGO_KEEP_0__ Actions compatible syntax, and jobs run on

Gitea Actions uses a __CAPGO_KEEP_0__ Actions compatible syntax, and jobs run on host label. 그에 따라 결과가 나올 것이다.

Gitea Actions uses a GitHub Actions compatible syntax, and jobs run on

  • Gitea는 .gitea/workflows/ Gitea Actions uses a __CAPGO_KEEP_0__ Actions compatible syntax, and jobs run on .github/workflows/ 첫 번째 폴더가 존재하지 않을 때.
  • uses: actions/checkout@v4 Gitea는 GitHub을 기본으로 사용하기 때문에 작동합니다 (설정). 공기 구획된 인스턴스는 사용하는 액션을 미러링하고 URL로 참조해야 합니다. DEFAULT_ACTIONS_URL Gitea는 __CAPGO_KEEP_0__을 기본으로 사용하기 때문에 작동합니다 (설정). 공기 구획된 인스턴스는 사용하는 액션을 미러링하고 URL로 참조해야 합니다.

Option 1: act_runner를 사용하는 맥 실행자

Mac을 등록하세요

macOS (Apple Silicon용 arm64)용 바이너리를 다운로드하여 Gitea 릴리스 페이지에서, 그리고 Site Administration > Actions > Runners (인스턴스 전체)에서 또는 조직 또는 저장소 설정에서 등록 토큰을 얻으세요. act_runner Run the daemon as a launch agent under a dedicated user so it restarts after reboots and has its own login keychain. Install the toolchain on the host Host mode means the job uses the Mac’s own tools. Install:

./act_runner register --no-interactive \
  --instance https://gitea.example.com \
  --token <registration_token> \
  --name mac-mini-01 \
  --labels macos-arm64:host

./act_runner daemon

Xcode 26 (App Store Connect 업로드를 위해 2026년 4월 28일부터 필요함)과 실행

호스트에 도구 체인 설치

Xcode 26 (App Store Connect 업로드를 위해 2026년 4월 28일부터 필요함)과 실행

  • Xcode 26 (App Store Connect 업로드를 위해 2026년 4월 28일부터 필요함)과 실행 sudo xcodebuild -license accept
  • Node.js 22 이상 또는 Bun (Capacitor 8은 Node 22이 필요합니다.)
  • 루비와 fastlane, 또는 __CAPGO_KEEP_0__ 8 프로젝트를 사용하는 경우 Gemfile with bundle exec
  • CocoaPods는 iOS 프로젝트가 여전히 사용 중인 경우에만 사용합니다. 새로운 Capacitor 8 프로젝트는 Swift Package Manager를 사용합니다.

Swift Package Manager를 사용하는 새로운 __CAPGO_KEEP_0__ 8 프로젝트입니다.

# .gitea/workflows/ios-mac.yaml
name: iOS release (Mac runner)

on:
  push:
    tags:
      - 'v*'

jobs:
  ios:
    runs-on: macos-arm64
    env:
      APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
      APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
      APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
      P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
      APP_STORE_CONNECT_TEAM_ID: ${{ vars.APP_STORE_CONNECT_TEAM_ID }}
      PROFILE_NAME: ${{ vars.IOS_PROFILE_NAME }}
    steps:
      - uses: actions/checkout@v4
      - run: bun install --frozen-lockfile
      - run: bun run build
      - run: bunx cap sync ios
      - name: Decode signing files
        run: |
          echo "${{ secrets.IOS_CERTIFICATE_BASE64 }}" | base64 --decode > dist.p12
          echo "${{ secrets.IOS_PROFILE_BASE64 }}" | base64 --decode > profile.mobileprovision
      - run: bundle exec fastlane ios beta
      - name: Clean up
        if: always()
        run: rm -f dist.p12 profile.mobileprovision

워크플로우 beta lane imports the certificate into a temporary keychain, switches the project to manual signing, bumps the build number from TestFlight, archives, and uploads. A full Fastfile for a Capacitor project is in iOS 앱 빌드 및 배포에 Bitbucket Pipelines 사용Bitbucket Pipelines를 사용하여 iOS 앱을 빌드하고 배포하는 방법에 대한 자세한 내용은 GitHub Actions iOS 가이드.

호스트 모드의 비용

워크플로우 act_runner 문서에서는 직접 이에 대해 설명합니다: 호스트 작업은 격리되지 않습니다. 실제로는:

  • 모든 작업은 동일한 사용자, 디스크 및 키 체인에 공유됩니다. 중간에 죽은 작업은 임시 키 체인이나 다음 작업을 깨트리는陈腐된 배포 프로파일을 남길 수 있습니다.
  • 해당 Mac에 사용자의 접근 권한으로 code을 실행하는 워크플로우는 해당 레이블을 대상으로합니다. 호스트 러너를 등록하는 것은 신뢰할 수 있는 저장소만으로 한정하고, 포크에서 Pull Request를 실행하는 것을 피하는 것이 좋습니다.
  • DerivedData, 아카이브 및 시뮬레이터 런타임은 디스크가 가득 차기 전까지 계속해서 증가합니다.
  • Xcode 업그레이드는 사용자의 책임이며, 애플은 매년 봄에 최소 SDK을 높입니다.
  • 한 대의 Mac은 한 번에 하나의 작업만 빌드합니다. 릴리스 일자 큐.

팀이 이미 Mac을 사용하고 alguien이 그들을 소유하고 있다면, 이것은 작동합니다. 그렇지 않다면, 다음 옵션은 Mac을 인프라에서 제거합니다.

옵션 2: Linux 러너에서 Capgo Build를 사용하여 iOS를 빌드합니다.

Capgo 빌드 compiles and signs Capacitor apps on Capgo-managed Macs. Your Gitea job stays on the Linux runner you already have. It checks out the code, builds the web layer, runs cap sync ios, 그리고 호출 build requestCapgo CLI은 준비된 네이티브 프로젝트를 업로드하고 Xcode 로그를 Gitea 작업 로그로 스트리밍하며 실패 시 0이 아닌 값을 반환합니다.

이 모델은 자체 호스팅 Gitea에 잘 맞습니다:

  • 인바운드 접근이 없습니다. Capgo은 저장소 복제를 수행하지 않습니다. 실행자에서는 HTTPS를 통해 준비된 프로젝트를 푸시합니다. 따라서 방화벽이나 VPN 뒤에 있는 Gitea 서버는 변경 없이 작동합니다.
  • 저장소 토큰이 없습니다. Capgo 측에서 Git 연결을 구성할 필요가 없습니다.
  • 웹 소스는 원래 위치에 머물러 있습니다. 자연스럽게 ios/ 폴더, Capacitor 설정, 플러그인 내의 네이티브 부분만 업로드됩니다. src/, .git/, .env 파일은 그렇지 않습니다.

한 번의 설정

개발자 머신에서:

bunx @capgo/cli@latest login
bunx @capgo/cli@latest app add
bunx @capgo/cli@latest build init --platform ios

build init creates or reuses your distribution certificate and App Store provisioning profile and stores the App Store Connect API key. Run one build locally to confirm everything signs:

bun run build && bunx cap sync ios
bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release

그런 다음 인증서를 내보냅니다.

bunx @capgo/cli@latest build credentials manage --appId com.example.app --platform ios
# select "Export to .env"

Gitea

열기 Repository Settings > Actions > Secrets 내보낸 파일에서 각 키를 추가하고, Capgo API 키도 추가합니다.

비밀 목적
CAPGO_TOKEN Capgo API 키(업로드 권한)
BUILD_CERTIFICATE_BASE64 배포 인증서 (.p12)
P12_PASSWORD 인증서 비밀번호
CAPGO_IOS_PROVISIONING_MAP_BASE64 배포 프로파일 매핑
APPLE_KEY_ID 애플 스토어 연결 API 키 ID
APPLE_ISSUER_ID 애플 스토어 연결 발급자 ID
APPLE_KEY_CONTENT Base64 .p8 키
APP_STORE_CONNECT_TEAM_ID 애플 팀 ID

Gitea는 비밀번호와 변수 이름이 시작하는 GITEA_ 또는 GITHUB_context Variables , 따라서 이러한 이름을 그대로 유지하십시오. 비밀번호가 아닌 값, 예를 들어 앱 ID를 아래에 ${{ vars.NAME }}변수

그리고 읽기 위해 사용합니다. 조직 수준에서 설정된 비밀번호는 조직 내의 모든 저장소에 공유되며, 한 애플 팀에서 여러 앱을 배포하는 것이 편리합니다. 내보낸 파일을 삭제할 때까지 사용하십시오.

# .gitea/workflows/ios-release.yaml
name: iOS release

on:
  push:
    tags:
      - 'v*'

jobs:
  release-ios:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
      - run: bun install --frozen-lockfile
      - run: bun run build
      - run: bunx cap sync ios
      - name: Build, sign, and upload to TestFlight
        env:
          CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
          APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
          APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
          APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
          APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
        run: |
          bunx @capgo/cli@latest build request ${{ vars.APP_ID }} \
            --platform ios \
            --build-mode release \
            --ios-distribution app_store \
            --store-release-name "${{ gitea.ref_name }}"

Notes:

  • ${{ gitea.ref_name }} 는 태그 이름입니다. github.* context는 alias로도 작동하며, 워크플로우를 포팅할 때 도움이 됩니다.
  • Gitea에서 CI=true 를 모든 작업에 설정하므로 Capgo CLI는 사용자 입력을 기다리지 않습니다.
  • Capgo는 최신 TestFlight 빌드에서 빌드 번호를 증가시켜, 연속된 두 태그가 충돌하지 않도록 합니다.
  • Without --submit-to-store-review, 빌드는 TestFlight에 도착하고 멈춥니다. App Review 제출도 원할 경우 CI에 플래그를 추가하세요.

배포는 이제 git tag v2.3.0 && git push origin v2.3.0입니다. 태그를 푸시할 수 있는 누구나 배포할 수 있으므로 v* 의 태그에 보호 규칙을 추가하세요. v* under 설정 > 태그 및 릴리스 매니저에게 제한합니다.

테스터용 Ad hoc 빌드

등록된 기기에서 직접 설치하는 QA 빌드에 대해 Ad hoc 모드에서 빌드하고 다운로드 링크를 얻으십시오:

# .gitea/workflows/ios-adhoc.yaml
name: iOS ad hoc build

on:
  workflow_dispatch:

jobs:
  adhoc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
      - run: bun install --frozen-lockfile && bun run build
      - run: bunx cap sync ios
      - name: Ad hoc build
        env:
          CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
          APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
          APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
          APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
        run: |
          echo "${{ secrets.ADHOC_PROFILE_BASE64 }}" | base64 --decode > adhoc.mobileprovision
          bunx @capgo/cli@latest build request ${{ vars.APP_ID }} \
            --platform ios \
            --ios-distribution ad_hoc \
            --ios-provisioning-profile ./adhoc.mobileprovision \
            --output-upload --output-retention 3d \
            --output-record /tmp/build.json
          bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl

Ad hoc 빌드는 테스트 기기를 목록한 Ad hoc 배포 프로파일이 필요합니다. 그 프로파일을 base64로 인코딩하여 secret (ADHOC_PROFILE_BASE64 위의 것)으로 저장하고, 그 프로파일을 job에서 디코딩하고, __CAPGO_KEEP_0__ 플래그를 사용하여 전달하십시오. --ios-provisioning-profile.CLI 플래그는 환경 변수보다 우선되므로, 이 빌드에만 앱 스토어 프로필을 오버라이드합니다. UDID를 수집하는 데 사용하는 를 사용하십시오.테스터용 TestFlight 내부 테스트는 UDIDs가 필요하지 않기 때문에 대부분의 테스터에게 더 간단합니다.

수동 릴리스 승인

GitHub는 환경을 지정하여 리뷰어를 필요로 할 수 있습니다. Gitea Actions는 환경 보호 규칙을 implement하지 않기 때문에, job이 환경을 지정하면 승인 대기하지 않습니다. 대신 두 가지 패턴이 작동합니다:

  1. 보호된 태그. Only release managers can push v* 태그, 태그 워크플로우가 배포된다.
  2. 빌드 후 승인 push를 위해 빌드 main with --ios-distribution ad_hoc or TestFlight 내부 테스트 전용으로 업로드 후, 현재 Gitea 릴리스에서 사용 가능한 워크플로우를 사용하여 승인된 커밋을 재빌드 workflow_dispatch 웹 변경 사항을 새로운 바이너리 없이 배포 --submit-to-store-review.

웹 변경 사항을 새로운 바이너리 없이 배포하세요.

Most commits to a Capacitor app only change JavaScript, CSS, and HTML. Rebuilding iOS for those wastes minutes and App Review time. With Capgo 실시간 업데이트, 하나의 작업이 올바른 경로를 선택할 수 있습니다.

      - name: Live update or native build
        env:
          CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
          # plus the iOS signing secrets from above
        run: |
          if bunx @capgo/cli@latest build needed ${{ vars.APP_ID }} --channel production; then
            bunx @capgo/cli@latest bundle upload ${{ vars.APP_ID }} --channel production
          else
            bunx cap sync ios
            bunx @capgo/cli@latest build request ${{ vars.APP_ID }} --platform ios --build-mode release
          fi

build needed __CAPGO_KEEP_0__ ios/ 또는 capacitor.config.* 변경, 이는 의존성 비교에 포함되지 않습니다. 자동으로 live update 또는 네이티브 빌드.

Mac 실행자 vs 클라우드 빌드

act_runner를 Mac에 설치하세요 Capgo Linux에서 빌드
하드웨어 그것을 구매하고 호스팅하세요 없음
Xcode 업그레이드 수동, 기계별 Capgo에 의해 처리됩니다
작업 간 격리 호스트 모드에서 없음 각 작업당 새로운 빌드 환경
병렬 빌드 1 대 1 다중, Mac에서
파일 서명 Gitea 비밀번호에서 Mac에서 해독 Gitea 비밀번호에서 빌드당 전송
화면 뒤의 방화벽 네 네, 출발 HTTPS만
Native Swift 앱 (no Capacitor) Yes No, Capacitor 앱들만
No, __CAPGO_KEEP_0__ 앱만 Build 시간 제한 Yours to set

10분당 1회 빌드

문제 해결 증상
수정 빌드가 영원히 대기열에 머물러 있습니다 runs-on온라인 빌더 중에 해당 레이블이 없습니다. 빌더 목록과 레이블을 확인하세요.
uses: actions/checkout@v4 다운로드를 실패했습니다. 실행자 GitHub에 접근할 수 없습니다. Gitea에서 액션을 미러링하고 전체 URL로 참조하세요.
작업에서 비밀값이 비어 있습니다. 이름이 시작되거나 GITEA_/GITHUB_또는 다른 저장소에서 정의된 비밀입니다.
security: SecKeychainItemImport: MAC verification failed 잘못되었습니다. .p12 비밀번호, 또는 OpenSSL 3으로 생성된 .p12 . 다시 내보내세요. -legacy비밀값의 프로필이 번들 ID나 인증서와 일치하지 않습니다. 다시 실행하고 다시 내보내세요.
No profiles for 'com.example.app' were found 업로드가 __CAPGO_KEEP_0__ 버전으로 거부되었습니다. build init 다운로드를 실패했습니다.
실행자 SDK에 접근할 수 없습니다. Gitea에서 액션을 미러링하고 전체 URL로 참조하세요. Mac 러너는 아직 Xcode 26보다 이전 버전입니다.
cap sync ios Linux에서 CocoaPods가 있는 경우 경고합니다. 예상됩니다. Capgo 빌드 머신은 pod를 설치합니다.

더 많은 실패 모드에 대한 정보는 CI/CD에 대한 Capacitor: 일반적인 함정 그리고 Capgo 빌드 문제 해결 가이드.

요약

Gitea Actions는 iOS를 처리할 때 Xcode가 실행되는 위치를 결정하면 됩니다. 호스트 모드 Mac 러너는 완전한 제어와 완전한 책임을 제공합니다. Linux 작업이 Capgo 빌드를 호출하면 Gitea 설정을 변경하지 않고, inbound 접근 권한이 필요하지 않으며, 테스트 플라이트 릴리즈를 태그 푸시로 변환합니다. 어떤 방법을 선택하더라도 Gitea 비밀에 서명 자료를 유지하고, 릴리즈 태그를 보호하고, 네이티브 PIPELINE이 실행할 때만 웹 전용 변경 사항을 Live Update로 배포하십시오.

실시간 업데이트 Capacitor 앱

웹-layer 버그가 실시간으로 활성화되면 Capgo을 통해修정을 배포할 수 있습니다. 앱 스토어 승인까지 며칠 기다리지 않고, 사용자는 배경에서 업데이트를 받을 수 있으며, 네이티브 변경은 일반적인 검토 경로를 유지합니다.

최신 블로그

Capgo은 전문적인 모바일 앱을 만들기 위해 필요한 최고의 통찰력을 제공합니다.