맥 없이 iOS 빌드하기: GitHub·Codemagic 무료 한도와 직접 막혔던 지점

맥이 없는 상태에서 아이폰 앱을 만들려니, 코드를 고치는 일보다 빌드할 컴퓨터를 마련하는 일이 먼저 걸렸다. Windows에서 개발하던 비트웨이브도 이 문제를 피해 갈 수는 없었다.

방법은 있었다. 소스는 내 PC에서 만들고, Xcode가 필요한 작업은 클라우드의 Mac에 맡기는 것이다. GitHub Actions와 Codemagic이 그 역할을 해준다. 이 글에는 두 서비스의 무료 조건, 처음 연결할 순서, 그리고 직접 진행하다가 막힌 지점을 함께 남긴다.

요금·문서 확인: 2026년 10월 12일. 초기 경험담은 같은 날 오후 2시 53분까지의 기록이며, 마지막에 오후 4시 42분 확인한 후속 결과를 덧붙였다.

Windows에서 작성한 코드를 GitHub에 보관하고 클라우드 Mac에서 빌드한 뒤 App Store Connect로 보내는 흐름
직접 만든 설명 그림. 내 책상 위에 Mac이 없어도 빌드에 쓰이는 Mac 자체가 사라지는 것은 아니다. 이미지를 누르면 원본 크기로 볼 수 있다.

무료라는 말보다, 무엇이 무료인지 먼저 봤다

GitHub는 코드를 보관하는 곳이고, Actions는 그 코드를 받아 작업을 실행하는 기능이다. Codemagic은 모바일 앱 빌드와 배포를 설정하는 서비스다. 둘 다 Mac 환경을 쓸 수 있지만 무료 시간을 계산하는 조건은 같지 않다.

선택공식 무료 포함량같이 볼 조건
GitHub Free · 비공개 저장소월 2,000분, artifact 500MBMac 실사용 2,000분 보장 아님
GitHub 공개 저장소표준 GitHub 호스팅 실행기 무료대형 실행기는 별도 유료
Codemagic 개인 계정macOS M2 월 500분매월 1일 초기화, Team 계정 제외

GitHub 포함량은 저장소마다 새로 생기는 시간이 아니라 소유 계정이나 조직이 함께 쓰는 한도다. 파일 보관 용량도 따로 봐야 한다. 빌드 결과물을 남기는 artifact와 다음 빌드를 빠르게 하는 cache는 다른 항목이고, cache 기본 포함량은 저장소당 10GB다. GitHub 공식 과금 안내에서 확인할 수 있다.

GitHub 공식 문서의 Free 요금제 포함량 표: 월 2000분과 artifact 500MB
GitHub 공식 문서의 무료 포함량 일부. 이 숫자를 그대로 Mac 사용 가능 시간으로 옮기면 안 된다. 이미지를 누르면 원본 크기로 볼 수 있다.

여기서 가장 조심할 숫자가 2,000분이다. GitHub는 실행기 종류에 따라 비용이 다르고, 개별 작업에 표시되는 실행 시간과 계정의 과금 사용량도 구분한다. 예전 글의 배수만 가져와 “Mac으로 정확히 몇 분”이라고 계산하지 않았다. 실제 계정의 Billing 사용량과 선택한 실행기를 함께 확인하는 편이 정확하다. 실행 시간과 과금 사용량을 보는 공식 설명도 이 차이를 안내한다.

Codemagic은 이 부분이 좀 더 직관적이었다. 개인 계정의 M2 Mac에 월 500분이 주어지고, 매월 1일 다시 시작한다. 가입 때 한 번만 받는 시간이 아니다. 다만 Team 계정에는 이 500분이 없고, 개인 계정에는 협업자를 초대할 수 없다. Linux·Windows에도 같은 무료 시간이 주어지는 것은 아니다. Codemagic 공식 요금 안내

Codemagic 공식 Free plan 문서에서 개인 계정 macOS M2 월 500분을 안내하는 문장
무료 500분의 대상은 개인 계정의 macOS M2다. 계정 종류와 머신 종류를 같이 확인해야 한다. 이미지를 누르면 원본 크기로 볼 수 있다.

무료 한도가 있다고 초과 비용까지 없어지는 것은 아니다. GitHub는 등록된 결제수단과 예산 설정을 확인해야 하고, Codemagic도 billing을 켜면 무료 범위 밖의 사용이 유료로 이어진다. 처음 연결할 때 결제 설정까지 습관처럼 넘기지 않는 게 좋다. Codemagic 결제 설정 안내

그리고 이 비용에는 Apple 개발자 멤버십이 들어 있지 않다. TestFlight와 App Store 배포에 사용하는 Apple Developer Program은 일반적으로 연 99달러이며, 지역별 가격은 가입 화면에서 확인해야 한다. 클라우드 빌드 시간을 무료로 쓰는 것과 앱 배포 비용을 모두 없애는 것은 다른 문제다. Apple 공식 가입 안내

시작하기 전에 준비해야 했던 것

GitHub에 웹 파일만 올린다고 아이폰 앱 파일이 바로 나오지는 않는다. 우리처럼 웹 기술로 만든 앱이라면 Capacitor 같은 도구로 iOS 프로젝트를 준비하는 과정이 먼저다. 실제 이번 작업에서 연 것도 웹 화면 폴더가 아니라 ios/App/App.xcodeproj였다. 이 경로는 우리 프로젝트의 예이고, 다른 앱에서는 다를 수 있다.

처음 보는 이름 중에서 scheme은 무엇을 빌드할지 정해 놓은 묶음, 서명은 누가 만든 앱인지 확인하는 절차라고 이해하면 편하다. 프로비저닝 프로파일은 앱 식별자와 배포 조건 등을 연결한다. 클라우드 Mac이 생겼다고 이 준비까지 자동으로 끝나는 건 아니다.

소스와 필요한 설정은 저장소에 넣되 인증서 암호, 비밀키, 토큰은 넣지 않는다. 빌드 서비스의 Secrets나 서명 설정에 보관한다. 공개 저장소가 무료라는 이유로 비공개 앱 코드를 공개하는 선택도 여기서는 권하지 않는다.

GitHub Actions로 시작한다면

저장소에 .github/workflows/ios.yml 파일을 만들고 Mac 실행기를 지정한다. 이 YAML 파일은 “어떤 컴퓨터에서 어떤 순서로 작업할지” 적어 두는 작업표에 가깝다. 처음부터 모든 push마다 빌드하게 하기보다는 workflow_dispatch로 수동 실행부터 시작하는 편을 권한다. 설정이 틀린 채 같은 작업을 계속 돌리는 일을 줄일 수 있다.

아래는 Xcode 버전만 확인하는 출발용 예시다. 앱을 빌드하거나 TestFlight에 올리는 완성 설정은 아니며, 이 예시 자체의 실행 검증은 하지 않았다. 저장소 기본 브랜치에 파일을 넣은 뒤 Actions에서 이 작업을 선택하고 Run workflow로 실행하는 흐름이다.

name: Check iOS build environment
on:
  workflow_dispatch:
permissions:
  contents: read
jobs:
  check-xcode:
    runs-on: macos-latest
    timeout-minutes: 5
    steps:
      - name: Show Xcode version
        run: xcodebuild -version

이 첫 확인도 클라우드 실행 시간을 사용한다. 실제 앱 작업으로 바꿀 때는 소스 가져오기, 프로젝트에 맞는 Node·Flutter 등의 도구와 의존성 설치, 서명 준비, xcodebuild archive, xcodebuild -exportArchive, Apple 업로드를 차례로 구성한다. 안정화한 뒤에는 macos-latest에만 맡기지 말고 프로젝트에 맞는 실행기와 Xcode 버전을 관리하는 편이 좋다.

배포용 인증서와 프로파일을 가져오는 부분은 GitHub의 Xcode 앱 서명 예제를 기준으로 보는 것이 안전하다. 예제에서는 Secrets와 임시 키체인을 사용한다. 다른 사람의 YAML에서 앱 이름만 바꿔 붙이기보다, 내 프로젝트 경로·scheme·서명 방식부터 맞춰야 한다.

어떤 작업이 끝났는지는 Actions의 단계별 로그에서 확인하고, 업로드했다면 App Store Connect에도 실제 빌드가 들어왔는지 확인한다. 이 두 화면을 나눠 봐야 했던 이유가 있었다.

Apple에는 올라갔는데, GitHub에서는 실패라고 나왔다

비트웨이브의 기존 작업에서는 Apple 업로드가 끝난 뒤 GitHub에 결과 파일을 보관하는 단계가 용량 한도 오류로 실패했다. 전체 작업에는 실패 표시가 남았다. 그 표시만 봤다면 앱 업로드도 실패했다고 판단하기 쉬운 상황이었다.

앱 빌드와 Apple 업로드 이후 GitHub artifact 보관 단계에서 실패할 수 있음을 설명하는 그림
실제 작업 기록을 바탕으로 그린 도식이다. 전체 작업의 실패 표시와 Apple이 빌드를 받았는지는 따로 확인해야 했다. 이미지를 누르면 원본 크기로 볼 수 있다.

이 경험 이후에는 빌드, 업로드, 파일 보관을 나눠 확인할 이유가 분명해졌다. 다시 실행하기 전에 어느 단계가 실패했는지 보고, Apple 쪽 결과도 확인해야 불필요하게 같은 작업을 반복하지 않는다.

artifact를 오래 남기는 것도 무료 운영에서는 부담이 된다. 필요한 파일만 보관하고 보존 기간을 짧게 정할 수 있다. 다만 이미 사용한 저장량의 누적 과금까지 삭제 한 번으로 사라지는 것은 아니다. GitHub 저장량 집계 설명도 현재 저장량과 그동안 누적된 사용량을 구분한다.

Codemagic은 저장소 연결부터 시작했다

Codemagic 가입 화면에서 개인 계정으로 시작하고, GitHub 연동으로 빌드할 저장소를 연결한다. 연결 권한은 필요한 저장소를 기준으로 확인한다. Applications에서 Add application을 눌러 저장소와 프로젝트 유형을 선택하면 앱을 추가할 수 있다.

그다음 저장소 맨 위에 codemagic.yaml을 둔다. 이 파일도 작업표다. 아래는 M2 머신에서 Xcode 버전만 확인하는 예시다. 서명·앱 빌드·배포는 포함하지 않았고, 실행 검증 전 예시다.

workflows:
  check-ios-environment:
    name: Check Xcode on M2
    instance_type: mac_mini_m2
    max_build_duration: 10
    scripts:
      - name: Show Xcode version
        script: xcodebuild -version

파일을 저장소에 올린 뒤 Codemagic에서 해당 브랜치의 설정을 읽고, 수동으로 빌드를 시작한다. 실제 앱용 설정에는 의존성 설치와 앱 빌드 단계를 더해야 한다. 프로젝트 유형에 따른 출발점은 공식 iOS 가이드에서 확인할 수 있다.

배포까지 하려면 Apple Developer 서명과 App Store Connect 연동도 준비한다. App Store Connect의 Users and Access → Integrations에서 만드는 API 키는 서비스를 연결하는 열쇠 역할을 한다. Codemagic의 연동·보안 설정에 넣고 YAML에서는 그 연결을 참조하는 방식이다. 키를 본문이나 Git에 붙여 넣는 방식은 아니다. 서명 설정과 App Store Connect 업로드 설정은 별도 문서로 확인하는 편이 낫다.

마지막에는 IPA라는 앱 배포 파일이 만들어졌는지, Apple 업로드가 끝났는지, App Store Connect에서 처리가 끝났는지를 나눠 본다. TestFlight에서 테스트하는 것과 App Store 심사에 제출하거나 공개하는 것도 각각 다른 단계다.

직접 해보니, 원격 Mac을 여는 것과 배포는 달랐다

10월 12일에 처음 진행한 Codemagic 작업은 원격 Mac을 준비하고 Xcode로 프로젝트를 여는 데까지 확인했다. 대기열에서 약 40분을 기다렸고, 작업을 정리한 시점에는 무료 사용량이 50/500분으로 표시됐다. 이 숫자는 그날 내 작업의 기록이지, 누구나 겪는 대기 시간이나 현재 잔여 시간을 뜻하지는 않는다.

중간에는 Xcode를 여는 명령이 설치된 앱 이름을 찾지 못하기도 했다. 실제 설치된 Xcode를 직접 열어 프로젝트를 확인했다. 준비된 Mac이 있다고 프로젝트가 기대한 경로나 버전까지 항상 맞는 것은 아니었다.

그 뒤 Apple의 Xcode Cloud 초기 설정을 시도하면서 기기가 다른 개발자 계정과 연결돼 있다는 인증 오류를 만났다. 결국 이 작업에서는 Xcode Cloud 초기 연결을 마치지 못했다. 오류의 전체 원인이나 확실한 해결 방법도 확인하지 못했으므로, 새 머신에서 다시 하면 무조건 된다고 적을 수는 없다.

여기서 Codemagic과 Xcode Cloud를 구분할 필요가 있다. Codemagic에서 직접 빌드·업로드하는 과정과 Apple의 Xcode Cloud를 처음 연결하는 과정은 서로 다르다. 이번 Xcode Cloud 오류가 Codemagic의 모든 iOS 빌드가 불가능하다는 뜻은 아니다. 이 글의 기준 기록에서는 Codemagic으로 서명된 IPA를 만들고 TestFlight에 올리는 데까지는 아직 확인하지 못했다.

또 당시 사용한 설정은 원격 화면으로 준비 상태를 보기 위해 기다리는 시간이 들어 있었다. 그대로 가져다 쓰면 빌드 없이 시간부터 쓸 수 있다. 정규 자동 빌드에 매번 VNC 화면 접속이 필요한 것은 아니므로, 이 글에는 그 임시 설정을 배포 예제로 넣지 않았다.

같은 날 오후, TestFlight까지 확인했다

10월 12일 오후 4시 42분 작업 기록에서는 Codemagic으로 비트웨이브 1.1.3 빌드 54를 만들고, App Store Connect에서 처리 완료(VALID)와 TestFlight 내부 테스트 상태(IN_BETA_TESTING)를 확인했습니다. 앞서 원격 Mac만 열었던 단계와 달리, 실제 빌드가 Apple에 도착한 후속 결과입니다.

이 과정에서는 Git 저장소를 얕게 가져오는 깊이를 1에서 20으로 바꿔 다시 실행한 기록도 남았습니다. 성공한 작업의 소요 시간은 3분 49초였습니다. 이 한 번의 시간이 모든 빌드의 소요 시간을 보장하지는 않습니다.

여기까지는 TestFlight 확인입니다. 실제 휴대폰에서 오디오 지연과 고난도 입력을 확인한 결과나 App Store 공개 승인으로 확대해 적지 않습니다. 처음 기록에서 확인하지 못했던 서명 빌드·업로드 부분이 이후 확인됐다는 뜻입니다.

지금 다시 시작한다면 이렇게 고르겠다

이미 GitHub Actions로 앱을 빌드하고 있다면, 나는 먼저 기존 작업의 실패 단계와 파일 보관 정책부터 확인하겠다. 서비스가 바뀌어도 앱의 서명이나 프로젝트 설정 문제까지 사라지는 것은 아니기 때문이다.

반대로 모바일 앱용 빌드를 처음 구성하고 M2의 무료 시간을 명확하게 보고 싶다면 Codemagic 개인 계정부터 살펴볼 만하다. 단, 500분 안에서 완성할 수 있다고 장담하기보다는 짧은 환경 확인을 한 번 돌리고 내 프로젝트의 실제 소요 시간을 재는 쪽을 택하겠다.

이번에 확인한 것은 맥을 사기 전에도 시도할 경로가 있다는 점이다. 동시에 “Mac에 접속했다”, “앱을 빌드했다”, “Apple에 올렸다”를 한 문장으로 묶으면 안 된다는 것도 배웠다. 같은 날의 후속 작업도 이 세 단계로 나눠 확인해 기록을 덧붙였다.

앱 등록 자체를 준비 중이라면 App Store 등록 과정에서 막혔던 부분도 함께 볼 수 있다. 조직 등록에 필요한 번호가 궁금하다면 Apple 경로로 D-U-N-S를 무료 신청한 기록을 따로 정리해 두었다.

댓글 남기기