Xcode 서버와 iOS 지속적인 통합 설명
게시 됨: 2022-03-11소개
Xcode 9 이전에는 Apple 지속적 통합 도구를 사용하는 것은 추가 macOS Server 앱을 구매하고 설치해야 하는 지루하고 복잡한 프로세스였습니다. 이로 인해 많은 개발자가 iOS 프로젝트에 대한 지속적인 통합 아이디어를 포기하거나 매우 다양한 수준의 성공을 거둔 타사 솔루션에 의존하게 되었습니다.
그러나 2017년 9월 Xcode 9.0이 출시된 후 자동화된 코드 서명 옵션을 포함하여 프로세스가 크게 간소화되어 이제 Xcode에 완전히 통합되었습니다. 따라서 추가 앱이나 도구가 필요하지 않습니다.
Fastlane, Bluepill 등과 같은 타사 솔루션이 큰 도움이 되고 많은 번거로운 작업을 수행할 수 있지만 이 기사에서는 지속적인 통합 요구 사항을 위해 Xcode 및 Apple 도구만 사용하는 기능을 살펴봅니다. 우리는 또한 수동 코드 서명을 사용할 것입니다. 왜냐하면 그것이 종종 많은 사람들에게 문제가 되는 것처럼 보이고 자동 서명도 다중 빌드 구성과 관련하여 최적의 솔루션이 아닌 경향이 있기 때문입니다.
참고: 이 문서는 Xcode 9.4.1을 기반으로 하며 iOS 앱 개발에 중점을 두고 있지만 많은 부분이 Xcode 10(현재 베타 5 빌드로 사용 가능) 및 macOS 앱 개발에 적용 가능합니다.
Xcode 서버 설정
실제 통합 프로세스를 단순화하는 것과 함께 Xcode 9는 Xcode 서버 설정 프로세스도 단순화했습니다.
CI 서버로 지정된 macOS 컴퓨터에서 Xcode 앱을 실행하고 기본 설정을 엽니다.
Server & Bots 라는 마지막 탭으로 이동합니다.
오른쪽 상단 모서리에 있는 스위치를 클릭하여 Xcode 서버 기능을 켭니다. 그런 다음 이 시스템에서 빌드 스크립트를 실행하고 실행할 사용자를 선택하라는 메시지가 표시됩니다. 기존 사용자를 사용하는 대신 이 목적을 위한 전용 사용자를 두는 것이 좋습니다.
Xcode 봇을 실행하려면 이 사용자가 시스템에 로그인되어 있어야 합니다. 로그인 후 사용자 이름 옆에 녹색 원이 표시되어야 합니다.
그게 다야! Xcode 봇에 대해 자세히 살펴보겠습니다.
Xcode 봇을 구성하는 방법
이제 이 서버에서 실행할 Xcode 봇 구성을 시작할 준비가 되었습니다. 이는 서버와 동일한 네트워크에 연결된 모든 개발 시스템에서 수행할 수 있습니다.
개발 컴퓨터에서 Xcode를 열고 상단 메뉴에서 Xcode > 기본 설정 을 클릭합니다. 그런 다음 계정 탭으로 이동하여 왼쪽 하단 모서리에 있는 + 아이콘을 클릭합니다. 표시되는 대화 상자에서 Xcode 서버를 선택합니다.
봇을 생성하려면 Xcode에서 프로젝트를 열고 상단 메뉴에서 제품 > 봇 생성… 옵션을 선택하기만 하면 됩니다. 봇 설정에는 여러 단계가 있으며 다음 섹션에서 살펴보겠습니다.
앱 배포 자동화
iOS 앱 빌드 자동화의 가장 빈번한 애플리케이션 중 하나는 TestFlight, Fabric 등과 같은 iOS 배포 플랫폼에 앱을 업로드하도록 봇을 구성하는 것입니다.
앞서 설명했듯이 이 기사에서는 iOS 앱 배포를 위한 Apple의 기본 도구인 App Store Connect에 업로드하고 Xcode 서버에서 직접 다운로드하는 방법만 살펴봅니다.
Xcode를 사용한 App Store Connect 배포
봇을 구성하기 전에 앱 개발 프로젝트의 번들 ID와 일치하는 App Store Connect 앱 레코드가 있는지 확인하십시오. 또한 각 빌드에는 빌드 버전과 빌드 번호로 구성된 고유 식별자가 있어야 합니다. 나중에 Xcode 봇 설정에 대해 논의할 때 이러한 조건이 충족되는지 확인하는 방법을 살펴보겠습니다.
1단계: 올바른 빌드 구성을 설정하는 것은 원하는 것을 얻기 위한 중요한 단계입니다. App Store Connect에 업로드하려는 앱을 생성하는 구성과 구성을 선택했는지 확인하십시오. 여기에는 빌드 구성이 팀의 Apple 개발자 포털(코드 서명에 사용)과 App Store Connect 포털(앱 자동 업로드에 사용)에 등록된 적절한 번들 ID를 사용하는지 확인하는 것이 포함됩니다. .
2단계: "구성" 탭에 있는 동안 내보내기 옵션을 지정해야 합니다. 내보내기 옵션 속성 목록을 탐색할 것이므로 "사용자 지정 내보내기 옵션 목록 사용"이 선택되어 있는지 확인합니다.
3단계: 이제 내보내기 옵션 속성 목록을 만들 차례입니다. xcodebuild --help
를 입력하면 이 파일에서 사용할 전체 키 목록을 볼 수 있지만 여기에서 이 봇 구성에 사용된 키를 살펴보겠습니다.
-
compileBitcode
– Bitcode는 앱 소스 코드에 대한 Apple의 중간 출력 형식입니다. 즉, 특정 아키텍처에 대한 기계어로 컴파일되기 전에 소스 코드가 변환되는 형식입니다. 명령어 세트에서 최적화가 이루어지면 더 최적화될 수 있는 단일 코드 컨테이너를 갖는 것을 목표로 하고 또한 동일한 형식에서 미래 아키텍처로 컴파일할 수 있도록 하는 것을 목표로 합니다. 그러나 이것은 귀하의 응용 프로그램에 영향을 미치지 않습니다. 활성화 여부를 결정하는 것은 사용자의 몫입니다. -
method
– 이 인수는 내보낼 제품의 종류를 지정합니다. Apple은 지정된 대상으로 제품을 구분합니다. 개발 은 프로비저닝 프로파일에 지정된 장치에만 설치할 수 있고 기업 은 모든 사람이 설치할 수 있지만 앱을 실행하기 전에 이 개발 프로파일을 명시적으로 신뢰해야 하며 앱 스토어 는 App Store 또는 App Store Connect에 배포하므로 이 값을 사용할 것입니다. -
provisioningProfiles
– 이것은 자명합니다. 그러나 여기서 몇 가지 주의해야 할 사항이 있습니다. 내보내기 옵션 속성 목록의 프로비저닝 프로필은 키 가 제품의 번들 ID에 해당하고 값 이 코드 서명에 사용되는 프로비저닝 프로필의 이름에 해당하는 사전입니다. -
signingCertificate
– 또 다른 자체 설명 인수입니다. 이 필드의 값은 전체 인증서 이름 또는 SHA-1 해시일 수 있습니다. -
teamID
– 또 다른 자명한 인수입니다. Apple Developer 프로그램에 가입할 때 Apple에서 조직에 발급한 10자 길이의 식별자입니다. -
uploadBitcode
– AppStore Connect에서 새로운 최적화된 빌드 또는 향후 아키텍처용 빌드를 생성하는 데 사용할 수 있도록 비트코드를 업로드할지 여부(컴파일로 선택한 경우). -
uploadSymbols
– 메모리 덤프 및 어셈블리 스택이 아닌 의미 있는 충돌 보고서를 얻을 수 있도록 디버그 기호를 업로드합니다.
이제 내보내기 옵션 속성 목록은 다음과 같을 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>compileBitcode</key> <false/> <key>method</key> <string>app-store</string> <key>provisioningProfiles</key> <dict> <key>com.bundle.id</key> <string>ProvisioningProfileName</string> </dict> <key>signingCertificate</key> <string>Signing Certificate Exact Name or SHA-1 hash value</string> <key>teamID</key> <string>??????????</string> <key>uploadBitcode</key> <false/> <key>uploadSymbols</key> <true/> </dict> </plist>
4단계: 내보내기 옵션 속성 목록으로 생성한 .plist를 선택합니다.
5단계: 다음은 "스케줄" 탭입니다. 기본 설정에 따라 설정합니다.
6단계: 서명 탭에서 "Xcode 서버가 내 인증서 및 프로필을 관리하도록 허용" 옵션을 선택 취소하고 인증서 및 프로필 페이지에서 일치하는 서명 인증서 및 프로비저닝 프로필을 직접 업로드합니다.
7단계: 앱을 테스트하는 것이 아니라 업로드하는 중이므로 기기 탭은 그대로 두어야 합니다.
8단계: 인수 탭을 사용하면 빌드 또는 사전 통합 및 사후 통합 스크립트에서 사용할 수 있는 xcodebuild 인수 또는 환경 변수를 명시적으로 설정할 수 있습니다.
9단계: 마지막으로 Xcode 지속적 통합 봇 구성의 마지막 탭이기도 한 Triggers 탭에 도달합니다. 이것은 Xcode Server 무기고에서 가장 강력한 도구입니다. 우선 다음 두 명령을 사전 통합 스크립트로 추가하고 싶습니다.
#!/bin/sh set printenv
첫 번째 것은 Xcode Server가 현재 통합 실행에서 사용하는 모든 변수와 해당 값을 인쇄합니다. 두 번째 것은 모든 환경 변수와 해당 값을 인쇄합니다. 예상대로 이것은 스크립트 디버깅에 도움이 될 수 있으므로 적절하게 이름을 "디버그 정보"로 지정합니다.

App Store Connect에 업로드된 각 빌드에는 고유한 빌드 버전과 빌드 번호 쌍이 있어야 한다고 언급했음을 기억하십시오. 내장된 PlistBuddy 도구를 사용할 수 있지만 고유한 빌드 번호를 갖는 방법도 필요합니다. Xcode Server 통합 중에 항상 존재하고 편리하게 고유한 한 가지는 자동 증가되기 때문에 통합 번호입니다. 매번 고유한 빌드 번호를 갖도록 하기 위해 다음 내용으로 "set build number"라는 또 다른 사전 통합 스크립트를 생성합니다.
#!/bin/sh buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") buildNumber=$XCS_INTEGRATION_NUMBER /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
CocoaPods를 사용 중이고 Pods 디렉토리를 DVCS에 커밋하지 않기로 선택한 경우 다음 내용이 포함된 사전 통합 스크립트도 포함해야 합니다.
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install
10단계: 거의 완료되었지만 빌드를 AppStore Connect 또는 어떤 계정에 업로드할지 지정하지 않았습니다. 이를 위해 통합 후 스크립트와 Application Loader라는 다른 내장 도구를 추가합니다. 스크립트에 다음을 입력합니다.
#!/bin/sh /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --upload-app -f $XCS_PRODUCT -u $TESTFLIGHT_USERNAME -p $TESTFLIGHT_PASSWORD
$XCS_PRODUCT
는 Xcode 서버 변수이며 현재 통합 실행에서 생성된 앱의 경로를 포함합니다. 그러나 $TESTFLIGHT_USERNAME
및 $TESTFLIGHT_PASSWORD
는 시스템 변수도 아니고 Xcode 서버 변수도 아닙니다. 이는 귀하가 설정해야 하며 귀하의 Apple ID 및 암호 값을 가지고 있어야 합니다. 안타깝게도 Apple은 AppStore Connect 빌드 업로드를 위한 API 키 생성 지원을 중단했습니다. 이것은 기밀 정보이므로 Xcode Server 봇 구성이 아닌 Mac 서버(자신의 것으로 가정)에서 환경 변수로 직접 설정하는 것이 가장 좋습니다.
Xcode 서버 배포
Xcode Server 배포 봇은 통합 후 스크립트를 제외하고 App Store Connect 배포와 동일한 구성을 실제로 사용합니다. 그러나 응용 프로그램을 다운로드하고 설치하는 것은 여전히 까다로울 수 있습니다. 여전히 앱에 서명한 프로비저닝 프로필이 사용 중인 기기에 앱을 설치할 수 있도록 허용해야 합니다.
그 자리에 있으면 iOS 장치에서 Safari를 열고 서버의 Xcode Server 웹 대시보드로 이동해야 합니다. 예를 들어, 서버 이름이 "Mac 서버"인 경우 서버와 동일한 네트워크에 있다면 "mac-server-name.local/xcode"에서 찾을 수 있습니다. 여기에서 모든 Xcode 봇 목록과 가장 최근 통합에 대한 통계를 찾을 수 있습니다.
다운로드하려는 앱을 구축한 앱을 선택합니다. 다음 화면에는 설치 및 프로필 이라는 두 개의 버튼이 있습니다. 이 서버에서 처음 다운로드하는 경우 프로필 을 클릭하여 해당 인증서를 신뢰할 수 있는 출처 목록에 추가해야 합니다. 그런 다음 같은 페이지에서 설치 버튼을 클릭하면 iOS 확인 대화 상자가 나타납니다. "장치에 *를 설치하시겠습니까?" 예 를 클릭하여 확인하면 앱이 설치되고 홈 화면에서 실행할 수 있습니다.
iOS 10.3 이상 에서 "Cannot connect to *.local"과 함께 실패하는 이유는 테스트 장치의 설정에서 자체 서명된 인증서를 수동으로 신뢰해야 하기 때문입니다.
이 단계를 따르세요:
1단계: iPhone의 Xcode 서버 봇 페이지에서 자체 서명된 인증서를 설치합니다.
2단계: iPhone의 설정 > 일반 > 정보 > 인증서 신뢰 설정 으로 이동합니다.
3단계: ENABLE FULL TRUST FOR ROOT CERTIFICATES 섹션에서 서버의 자체 서명된 인증서를 찾아 스위치를 켭니다.
4단계: Xcode Server의 봇 통합 페이지로 돌아가서 설치 를 클릭합니다.
Xcode 서버 자동 앱 테스트
Xcode Server의 또 다른 훌륭한 용도는 단위 테스트이든 UI 테스트이든 자동 앱 테스트입니다. 이렇게 하려면 프로젝트에 적절한 대상을 설정해야 합니다. 즉, 목표에 따라 단위 또는 UI 테스트를 실행하는 대상이 있어야 합니다.
설정 프로세스는 이전 프로세스와 동일하지만 다른 옵션을 선택합니다. 첫 번째 주요 차이점은 구성 탭에 있습니다. 분명히 "분석" 및 "테스트" 상자가 우리의 주요 목표이기 때문에 체크할 것입니다. 또한 이 봇을 사용하여 제품을 보관하거나 내보내지 않는 것이 좋습니다. 동일한 봇 구성으로 테스트와 배포를 모두 달성할 수 있습니다. 그러나 이 두 시나리오는 출력과 일정이 다릅니다. 배포는 종종 주기가 끝날 때 실행됩니다.
스크럼, 칸반 또는 다른 프레임워크에서 작업하든 간에, 미리 정의된 시간 중심 또는 이벤트 중심 주기가 있어야 합니다. 이 주기가 끝나면 제품을 내보내고 사용할 수 있어야 합니다. 반면에, 회귀에 대한 첫 번째 방어선이기 때문에 각 커밋에 대해 테스트 봇을 실행해야 합니다. 테스트 봇은 분명히 더 자주 실행되기 때문에 두 봇을 하나로 병합하면 서버의 디스크 공간을 빠르게 사용할 수 있습니다. 또한 각 통합을 완료하는 데 더 많은 시간이 걸립니다.
그 과정에서 우리는 "일정" 탭으로 이동하고 있으며 이전 단락에서 이미 다루었습니다. 따라서 다음 관심 주제는 코드 서명입니다. 테스트 대상이 프로젝트 설정 페이지에서 프로비저닝 프로필이 필요하지 않다고 명시하더라도 호스트 애플리케이션과 동일한 팀 및 서명 인증서를 사용하도록 설정해야 합니다. 시뮬레이터가 아닌 iOS 기기에서 앱을 테스트하려는 경우에 필요합니다. 이 경우 테스트에 사용된 iOS 장치가 비활성으로 인해 잠기지 않는지 확인해야 합니다. 이렇게 하면 알림 없이 통합 실행이 무기한 중단될 수 있습니다.
이제 특별한 설명이 필요 없는 "장치" 탭에 있습니다. 코드를 테스트할 하나, 여러 장치 또는 모든 장치(iOS 및 시뮬레이터)를 선택하기만 하면 됩니다. 여러 장치에서 테스트를 병렬로 실행할지 아니면 순차적으로 실행할지 여부도 확인할 수 있습니다. 이를 설정하려면 프로젝트 요구 사항(특정 장치 세트를 대상으로 하든 지원되는 모든 iOS 장치를 대상으로 하든)과 서버의 하드웨어 리소스를 고려해야 합니다.
인수 탭에서. 내장 환경 변수만 사용할 것이기 때문에 명시적으로 아무 것도 지정할 필요가 없습니다.
마지막으로 Triggers 탭에서 하나의 사전 통합 및 하나의 사후 통합 스크립트를 소개합니다. 첫 번째 것은 문제가 발생할 경우 디버그하는 데 도움이 됩니다. 그것은 실제로 우리가 이미 사용한 것입니다:
#!/bin/sh set printenv
두 번째는 현재 통합에서 하나 이상의 테스트가 실패하는 경우 알려줄 것입니다. 테스트 실패 시에만 실행되도록 설정되어 있는지 확인하십시오. 그리고 다음을 입력합니다.
#!/bin/sh echo "$XCS_TEST_FAILURE_COUNT test(s) failed for $XCS_BOT_NAME bot on build $XCS_INTEGRATION_NUMBER" echo "You can see bot integration at:" echo "https://$HOSTNAME/xcode/bots/$XCS_BOT_TINY_ID/integrations/$XCS_INTEGRATION_TINY_ID"
여기에서 설명해야 할 몇 가지 사항이 있습니다. 우선 $HOSTNAME 변수는 computer-name.local 형식의 값을 저장합니다. 분명히 링크는 로컬 네트워크를 통해 해당 서버에 연결할 수 있는 경우에만 작동합니다. 또한 신뢰할 수 없는 대상에 대한 https 연결이므로 이 링크를 방문하면 브라우저에서 보안 경고를 받을 가능성이 큽니다. 마지막으로 이것은 "테스트 실패" 스크립트의 시작점일 뿐입니다. 전체 개발 팀에 이메일을 보내거나 API 요청 또는 가장 적절하고 생산적이라고 생각되는 모든 것을 통해 JIRA 문제를 열 수 있습니다.
마무리
이 기사를 통해 단순히 앱을 구축하는 것 외에 시간을 할애하여 Xcode Server 기능을 탐색할 수 있기를 바랍니다. 이 게시물이 여러분이 원하거나 예상한 방식으로 정확히 도움이 되지 않았을 수도 있지만 목표는 더 높은 수준의 자동화를 달성하기 위해 기본 제공 환경과 Xcode Server 변수를 사용하는 개방적인 방법을 소개하는 것이었습니다.
Fabric, Bluepill 및 Fastlane을 포함하여 더 많은 기능을 활성화하고 더 많은 작업을 수행할 수 있는 타사 서비스가 많이 있습니다. 그러나 필연적으로 타사에 의존하면 프로젝트에 새로운 종속성이 도입되고 때로는 간단하고 때로는 복잡한 설정 및 구성이 필요합니다. 여기에 설명된 기술은 모든 Mac에 이미 설치된 도구만 필요하므로 자동화된 빌드를 실행할 바로 봇을 구성하는 것 외에 설정 시간이 필요하지 않습니다!