Issue

[Issue] Xcode Cloud Custom Build Scripts

Hatchling.dev 2024. 2. 27. 21:33

(편의상 편한 말투로 작성하는 점 이해 부탁드립니다.😅)

(부정확한 정보가 있을 수 있습니다. 지적 환영🤗)

 

안녕하세요! Hatchling입니다.

 

오늘은 Xcode Cloud를 활용해 CI/CD를 구축하던 중 생긴 이슈와 어떻게 해결했는지 정리해보도록 하겠습니다!!

이슈는 총 두가지지만 둘 다 custom build scripts를 활용해야 하는 이슈이기 때문에 한 번에 정리하겠습니당

 

 

1. Target '*' must be enabled before it can be used.

해당 이슈는 외부 패키지의 매크로를 사용하기 전에 유효성 검증 과정이 필요한데 이와 관련된 문제입니다.

참고로 Xcode Cloud에서 SPM로 추가된 종속성은 별도 구성 없이 사용할 수 있다고 하며 Cocoa Pods나 Carthage를 사용하기 위해서는 별도 scripts 작성해줘야 합니다. (자세한 내용은 아래 링크를 참고해주세요!)

https://developer.apple.com/documentation/xcode/making-dependencies-available-to-xcode-cloud

 

하지만 저는 SPM을 사용하고 있고 여러 라이브러리를 추가한 상황에서 특정 라이브러리(Composable Architecture)에서 문제가 발생했습니다.

 

정말 하루 꼬박 구글링을 해보았지만 관련 레퍼런스가 많진 않더라구요..? 근본적인 해결 방법은 찾지 못했지만 유효성 검사를 하지 않도록 설정하여 해결하는 방법을 찾아 적용해 해결했습니다ㅠㅠㅠ

(혹시나 근본적인 문제 해결 방법에 대해 아시는 분이 계시다면 알려주십사..)

 

 

먼저 custom build scripts가 무엇인지부터 알아볼까요??

Xcode Cloud에서는 custom build scripts를 작성하여 프로젝트에 필요한 명령줄을 실행할 수 있습니다.

공식문서 : https://developer.apple.com/documentation/xcode/running-custom-scripts-during-a-build

공식문서처럼 xcode에서 target을 지정해 run script를 만들 수 있지만 저는 터미널에서 직접 script를 생성하고 적용해보았습니다.

 

아래 이미지는 Xcode Cloud의 동작 과정입니다.

노란색으로 보이는 부분들에 custom build scripts를 추가해 실행시킬 수 있습니다.

Xcode Cloud 동작 과정

 

Post-clone, Pre-Xcodebuild, Post-Xcodebuid 총 세가지 종류가 있죠?

Post-clone : Github에서 코드를 복제 후에 실행되는 script. 프로젝트를 구축하기 전에 추가 도구 설치나 파일 편집 등을 지정할 수 있습니다.

Pre-Xcodebuild : Xcode Cloud 환경에서 xcodebuild 명령을 실행하기 전에 실행되는 script. 추가 종속성을 컴파일 하는 등을 지정할 수 있습니다.

Post-Xcodebuild : Xcode Cloud 환경에서 xcodebuild 명령이 실행된 후에 실행되는 script. 아티팩트를 다른 서비스에 업로드 하는 등에 사용할 수 있습니다.

 

각 script를 실행하기 위해서는 각 script 마다 정해진 이름의 script를 작성해야 합니다.

Post-clone : ci_post_clone.sh

Pre-Xcodebuild : ci_pre_xcodebuild.sh

Post-Xcodebuild : ci_post_xcodebuild.sh

 

오늘 우리가 사용할 script는 Post-Clone입니다.

 

다시 이슈로 돌아가서 외부 패키지의 매크로를 사용하기 전에 해야하는 유효성 검사를 하지 못해 생긴 문제를 유효성 검증을 하지 않도록 해 해결했다고 했었죠??

 

먼저 ci_post_clone.sh script를 만들어 보겠습니당!

 

1. 터미널에서 Project.xcodeproj이 위치한 곳에 ci_scripts 폴더를 생성 (mkdir "ci_scripts")

2. ci_scripts 안에 ci_post_clone.sh 파일 생성 (vi ci_post_clone.sh)

3. 맨 윗 줄에 #!/bin/sh 작성

4. script 실행 권한 설정 (chmod +x ci_post_clone.sh)

 

 

위 과정을 순서대로 진행하면 custom build script를 활용할 준비가 끝났습니다!

 

ci_post_clone.sh 파일에 아래 명령어를 추가해주면 해결이 됩니다!!!

defaults write cohttp://m.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES

 

 

 

2. Environment Variable

지난번에 포스팅한 Xcode Cloud 글에서 설명했던 Environment Variable입니다.

이게 왜 이슈냐!!!

저는 Environment Variable에 Github에 올라가지 않은 값을 추가하면 된다고 생각했는데 그게 아니었습니다😭

 

 

그럼 Environment Variable을 어떻게 사용할 수 있냐!!

위와 같이 custom build scripts를 활용하여 사용할 수 있습니다!

 

Environment Variable을 사용하는 경우는 많지만 저 같은 경우에는 API Key를 숨기기 위해 gitignore 설정을 해놔 API Key 값이 담긴 .plist 파일 자체가 github에 없는 상황이어서 아래와 같은 에러를 받았습니다.

Build input file cannot be found: '/Volumes/workspace/repository/Selterview/Selterview/Resources/API_Key.plist'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it?

 

에러를 보면 Value를 찾지 못하는 것이 아닌 API_Key.plist 파일 자체를 찾을 수 없다는 문제이기 때문에 CI/CD를 진행하기 전에 해당 파일을 생성해줘야 합니다.

 

위에서 custom build scripts 종류에 대해 설명했는데 파일 편집은 언제 하는지 기억하시나요??

네! post-clone에서 진행하면 됩니다.

그럼 직접 생성해보겠습니다. (ci_post_clone.sh 파일 세팅은 위를 참고해주세요.)

 

아래 이미지와 같이 쉘 스크립트를 작성하면 plist 파일을 생성할 수 있습니다.

ci_post_clone.sh 중 일부

각 라인을 살펴볼까요?

1. PLIST_PATH - plist 파일을 생성할 위치와 plist의 이름을 지정합니다.

2. Add : Key - "Key" 라는 이름의 Key를 추가합니다.

3. Set : Key - "Key"라는 Key의 value에 ci_key를 추가합니다.

4. plutil - 해당 경로의 파일을 출력합니다. (CI/CD 실행 중)

5. exit 0 - 쉘 스크립트를 종료합니다.

 

이렇게 Xcode Cloud 실행 중 plist 파일을 생성하는 스크립트를 작성해 봤습니다.

하지만 저렇게 script 안에 key 값을 넣으면 Github에서 해당 파일을 확인할 수 있기 때문에 제 상황과는 맞지 않았습니다.

그래서 필요한게 Environment Variable입니다!

아래처럼 Environment Variable에 Key-Value를 추가해주면 custom build script에서 해당 값을 가져다 쓸 수 있습니다.

secret을 체크하면 해당 값을 비공개로 숨겨줍니다. (체크를 안한다고 외부에 공개되는 것은 아니고 CI/CD 실행 중이나 결과에서 해당 값을 확인할 수 있습니다.)

 

Environment Variable을 활용하는 방법은 간단합니다!

아래에 'ci_key'를 '$Key'로 바꿔주기만 하면 됩니다. 물론 위처럼 저는 Test App이기 때문에 Environment Variable에 이름을 Key로 지정했기 때문에 이렇게 썼지만 실제로는 좀 더 직관적인 이름을 부여하면 좋겠죠??

 

 

자 이렇게 오늘은 Xcode Cloud를 사용하던 중 겪은 이슈들과 해결 방법(custom build scripts)에 대해 알아보았습니다!

직접 해당 이슈들을 겪고 구글링도 많이 해봤는데 레퍼런스가 많지는 않더라구요😭

누군가에게 도움이 되었으면 좋겠습니다!!

'Issue' 카테고리의 다른 글

[ISSUE] XcodeCloud Archive Error  (1) 2024.04.18
[Issue] SwiftUI NavigationLink의 상태 관리  (0) 2024.02.19