Xcode 개발을 위해 macOS 러너에 Apple 인증서 설치하기

Xcode 개발을 위해 macOS 러너에 Apple 인증서 설치하기

지속적 통합(CI) 워크플로에서 Apple 코드 서명 인증서를 GitHub Actions 러너에 설치해 Xcode 앱에 서명하는 방법을 알아봐요. 인증서와 프로비저닝 프로필을 시크릿으로 저장하고 러너로 전송·가져와 빌드에 사용하는 전체 과정을 살펴봐요.

출처: 문서

본문

사전 요구 사항

YAML과 GitHub Actions 구문에 익숙해야 해요. 자세한 내용은 다음을 참고하세요:

Xcode 앱 빌드와 서명에 대한 이해가 있어야 해요. 자세한 내용은 Apple 개발자 문서를 참고하세요.

인증서와 프로비저닝 프로필용 시크릿 만들기

서명 과정은 인증서와 프로비저닝 프로필을 저장하고, 러너로 전송하며, 러너의 키체인으로 가져오고, 빌드에 사용하는 작업을 포함해요.

러너에서 인증서와 프로비저닝 프로필을 사용하려면 GitHub 시크릿을 사용하는 것을 강력히 권장해요. 시크릿을 만들고 워크플로에서 사용하는 방법에 대한 자세한 내용은 GitHub Actions에서 시크릿 사용하기를 참고하세요.

저장소나 조직에 다음 항목에 대한 시크릿을 만들어요:

  • Apple 서명 인증서.

    • 이는 p12 인증서 파일이에요. Xcode에서 서명 인증서를 내보내는 방법에 대한 자세한 내용은 Xcode 문서를 참고하세요.

    • 인증서를 시크릿으로 저장할 때는 Base64로 변환해야 해요. 이 예제에서 시크릿 이름은 BUILD_CERTIFICATE_BASE64예요.

    • 다음 명령을 사용해 인증서를 Base64로 변환하고 클립보드에 복사해요:

      base64 -i BUILD_CERTIFICATE.p12 | pbcopy
      
  • Apple 서명 인증서의 비밀번호.

    • 이 예제에서 시크릿 이름은 P12_PASSWORD예요.
  • Apple 프로비저닝 프로필.

    • Xcode에서 프로비저닝 프로필을 내보내는 방법에 대한 자세한 내용은 Xcode 문서를 참고하세요.

    • 프로비저닝 프로필을 시크릿으로 저장할 때는 Base64로 변환해야 해요. 이 예제에서 시크릿 이름은 BUILD_PROVISION_PROFILE_BASE64예요.

    • 다음 명령을 사용해 프로비저닝 프로필을 Base64로 변환하고 클립보드에 복사해요:

      base64 -i PROVISIONING_PROFILE.mobileprovision | pbcopy
      
  • 키체인 비밀번호.

    • 러너에 새 키체인이 생성되므로, 새 키체인의 비밀번호는 어떤 새 임의 문자열이든 될 수 있어요. 이 예제에서 시크릿 이름은 KEYCHAIN_PASSWORD예요.

워크플로에 단계 추가하기

이 예제 워크플로는 GitHub 시크릿에서 Apple 인증서와 프로비저닝 프로필을 가져와 러너에 설치하는 단계를 포함해요.

name: App build
on: push

jobs:
  build_with_signing:
    runs-on: macos-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      - name: Install the Apple certificate and provisioning profile
        env:
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          # create variables
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

          # import certificate and provisioning profile from secrets
          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH

          # create temporary keychain
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

          # import certificate to keychain
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH

          # apply provisioning profile
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
      - name: Build app
          # ...

Note

iOS 빌드 대상의 경우 프로비저닝 프로필은 확장자가 .mobileprovision이어야 해요. macOS 빌드 대상의 경우 확장자는 .provisionprofile이어야 해요. 위 예제 워크플로는 대상 플랫폼에 맞게 업데이트해야 해요.

자체 호스팅 러너에서 필수 정리하기

GitHub 호스팅 러너는 작업 실행이 끝나면 자동으로 파괴되는 격리된 가상 머신이에요. 즉, 작업 중 러너에서 사용된 인증서와 프로비저닝 프로필은 작업이 완료되면 러너와 함께 파괴돼요.

자체 호스팅 러너에서는 작업 실행이 끝나면 $RUNNER_TEMP 디렉토리가 정리되지만, 키체인과 프로비저닝 프로필은 여전히 러너에 남아 있을 수 있어요.

자체 호스팅 러너를 사용한다면 작업이 끝날 때 이러한 민감한 파일이 삭제되도록 워크플로에 마지막 단계를 추가해야 해요. 아래 표시된 워크플로 단계는 이를 수행하는 방법의 예시예요.

- name: Clean up keychain and provisioning profile
  if: ${{ always() }}
  run: |
    security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
    rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision