본문 바로가기
CI와CD

[iOS] CI/CD 도입 Fastlane + AzureDevOps [2]

by 최지철 2024. 3. 20.
728x90
반응형

AzureDevOps로고가 유독 이쁘것 같기도 ㅎ.ㅎ

 

Fastlane Match를 하면 깃에 이런형식으로 파일이 올라갔을겁니다 ㅎ.ㅎ

AzureDevOps CI환경에서의 Fastlane실행 구축

  • 들어가기 앞서 전체적인 흐름을 설명해드리겠습니다! 크게 보면 Auzre DevOps CI환경에서 Fastlane 실행 -> Fastlane이 빌드 후, 배포 하는 방식으로 진행됩니다.
    1. AzureDevOps Pipeline 실행
    2. Pipeline 1단계 : 원격 Git 리포지토리에서 특정 커밋으로 코드를 가져와(checkout) 로컬 리포지토리를 업데이트하는 작업. 
      이 단계에서는 자동화된 빌드 및 테스트 작업을 시작하기 전의 초기 과정입니다
    3. Pipeline 2단계 : CI환경에서의 Xcode 버전 선택, 로컬에서 돌아가는 버전과 CI환경에서 돌아가는 버전을 통일 시켜야합니다. 통일 되지 않을 경우, Swift버전 문제 혹은 라이브러리 간의 버전 이슈로 오류가 발생할 확률이 매우매우 높습니다!
    4. Pipeline 3단계 : 환경변수 설정 값 세팅, 저 같은 경우는 이 단계에서 CI환경안에서 실행되는 경로에 미리 .p8이라던지, 키체인에 대한 경로를 환경변수로 설정을 다 하였습니다. 
    5. Pipeline 4단계 : Fastlane 스크립트 실행 -> 완료되면 배포 및 슬랙에 알림이 가도록 하였습니다.

     

파이프라인 단계

Step 1 : Fastlane이 AzureDevOps에 접근할 수 있도록 하자!

우선, PAT(Personal access tokens)를 발급 받아 CI환경에서 Fastlane이 레포지를 읽을 수 있게 해줍니다.

 

그 후, Match 파일에 넣을  Git URL 에 PAT 값을 같이 넣던지 아니면 환경변수로 설정해서 같이 넣어주셔야합니다. *이건 Private Repo라는 전제하에 말씀드리는겁니다!

 

git_url("") # https://{PAT값}@나머지 URL

storage_mode("git")

type("appstore") # The default type, can be: appstore, adhoc, enterprise or development

app_identifier("")
username("") # 배포가능한 애플 디벨로퍼ID

# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options

# The docs are available on https://docs.fastlane.tools/actions/match

 

 

Step 2 :  Xcode 버전 선택

Azure Pipeline 에서 맥 OS 및 Xcode Version을 선택해준다.

pool:
  vmImage: 'macos-13'

steps:  
- script: |
    echo "Mac OS version:"
    sw_vers -productVersion
    echo "Installed Xcode versions:"
    ls /Applications | grep 'Xcode'
    echo "Currently selected Xcode:"
    xcrun xcode-select --print-path
    echo "Selecting Xcode 15.1..."
    sudo xcode-select -s /Applications/Xcode_15.1.app/Contents/Developer
    xcrun xcode-select --print-path
    xcodebuild -version
  displayName: 'Azure CI환경에서 Xcode 15.1 버전 선택'

FastFile에도 잊지 않고 해준다.

 

이점을 꼭 기억하자 CI환경, 로컬, FastFile을 항상 삼위일체 시켜야 한다는 것을.

before_all do
  xcversion(version: "15.1") # Fastlane이 사용할 Xcode 버전을 지정 
end

 

 

Step 3 :  .p8등 파일에 대한 경로 환경 변수 설정

 

- script: |
    # .p8 파일 찾기
    P8_FILE=$(find $(Build.SourcesDirectory) -name '*.p8' | head -n 1)
    echo "Found p8 file at: $P8_FILE"
    
    # 절대 경로에 ./ 추가
    MODIFIED_PATH="$(Build.SourcesDirectory)/./AuthKey_{key값}.p8"
    echo "Modified path: $MODIFIED_PATH"
    
    # 수정된 파일 경로를 환경변수로 설정
    echo "##vso[task.setvariable variable=FASTLANE_KEY_FILEPATH]$MODIFIED_PATH"
  displayName: 'Find .p8 file and set path with ./ prefix'

Azure DevOps CI환경에서 Authkey 값을 찾아 환경변수로 매치시켜준다. 이걸 FastFile에 삽입

    echo "작업 디렉토리: $(System.DefaultWorkingDirectory)"
    echo "소스 디렉토리: $(Build.SourcesDirectory)"
    echo "아티팩트 디렉토리: $(Build.ArtifactStagingDirectory)"

이건 참고하면 유용할만한 디렉토리 경로!

 

    app_store_connect_api_key(
      key_id: "",
      issuer_id: "",
      key_filepath: ENV['FASTLANE_KEY_FILEPATH'],# <- 요로콤 환경변수를 넣어 줬슴다 전
      in_house: false, # true if you're part of the Apple Developer Enterprise Program
    )

 

 

Step 4: 대망의 CI에서 Fastlane 실행

이건 간단하다. 그냥 Fastlane 설치하고 fastlane 실행을 하면 되기 때문이다. 관건은 FastFile 스크립트에서의 문제가 발생안하도록 해야한다.

- script: |
    echo "Installing Fastlane..."
    gem install fastlane
    echo "Running Fastlane..."
    fastlane beta
  displayName: 'Fastlane Beta Lane 실행'

 

 

전체 FastFile 스크립트

default_platform(:ios)
before_all do
  xcversion(version: "15.1") # Fastlane이 사용할 Xcode 버전을 지정
  ENV["MATCH_PASSWORD"] = ""
  ENV["FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"] = ""
  ENV["FASTLANE_PASSWORD"] = ""
  create_keychain(
    name: "",
    password: "",
    default_keychain: true,
    unlock: true,
    timeout: 3600,
    lock_when_sleeps: true
  )
end

platform :ios do

  desc "인증서 및 프로비저닝 프로파일 설치"
  lane :certificates do
    app_store_connect_api_key(
      key_id: "",
      issuer_id: "",
      key_filepath: ENV['FASTLANE_KEY_FILEPATH'],
      in_house: false, # true if you're part of the Apple Developer Enterprise Program
    )
   match(
	readonly:"true", # readonly로 해서 계속 인증서 갱신 안되게 하는걸 추천 유효기간은 1년이니
	type: "appstore",
        keychain_name: "", # 여기에 원하는 키체인 이름을 지정
        keychain_password: "")
  end


  desc "베타테스트 TestFlight 빌드"
  lane :beta do
    certificates
    current_version = get_version_number(xcodeproj: "프로젝트명.xcodeproj")
    increment_build_number(
        build_number: latest_testflight_build_number + 1
    )    
    ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"
    build_app(
     scheme: "스키마명",
     export_method: "app-store",
     clean: "true"
    )

    upload_to_testflight(
      skip_waiting_for_build_processing: true
    )
    # 슬랙에 메시지 전달
    slack(
      username: "", # 메시지 보내는 이의 이름 설정
      icon_url: "" # 사용하고 싶은 이미지 URL
      message: "버전: #{current_version} 빌드 성공 및 테스트 통과 후, Testflight 배포에 성공했습니다☺️",
      slack_url: ""
    )
  end
end



글을 마무리하며... (뒤에 제가 부딪혔던 오류들 모아놓았슴다)

 

총 시도 횟수....

 

147트 만에 성공했다. 물론 처음 혼자서 CI/CD를 구축하는바람에 오래걸렸지만, 이제 인증서 및 CI환경에 대한 이해가 생겨 어렵지 않게 구축 할 수 있을 것 같다. 💪🏻  

2주동안 회사에서 이걸 붙잡고 있었다.. 2/3쯤 되었을즘.. 우리팀 전원에게 내가 빌드 실패할때마다.. 메일이 날라간단 사실을 알았을 땐... 정말... 숨고 싶었지만.. 그리고 포기하고 싶었지만... 포기하기 싫어 끝까지 잡고 다행히 잘 마무리하였다. AzureDevOps에 대한 정보가 거의 없어서 공식문서를 정말 많이 봤다. 그리고 Fastlane 공식 깃헙에 이슈 등록까지 휴우우.. 좋은경험이였다! 🤩

 

 

오류모음( Error Archive)

fatal: could not read Password for
[02:19:23]: Error cloning certificates repo, please make sure you have read access to the repository you want to use
[02:19:23]: Run the following command manually to make sure you're properly authenticated: 

 

해당 문제는 나같은 경우는 Private Repository에 대한 접근권한이 없어 생긴 문제다 위에도 적었지만 PAT 값을 발급받아, Match파일에 넣어 해결하였다.

 

[08:13:53]: xcodebuild -showBuildSettings timed out after 4 retries with a base timeout of 3. You can override the base timeout value with the environment variable FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT, and the number of retries with the environment variable FASTLANE_XCODEBUILD_SETTINGS_RETRIES 

 

ㅎ.ㅎ 해당문제는 프로젝트가 아마 커서 타임아웃 리밋에 걸려서 생긴 오류다.

 ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"

Fastfile에 위의 환경변수를 추가해서 해결하엿다.

 

 

해당 문제는 그냥 인증서 갯수 초과 문제 ㅎ.ㅎ 배포용 인증서는 최대 2개인걸 몰랐다... ㅎ.ㅎ

 

fastlane match nuke development
fastlane
match nuke distribution
위의 명령어로 인증서를 날릴 수 있다.

 

여러 인증서 및 Singing 관련 에러 문제

 

❌ /Users/runner/work/1/s/.xcodeproj: No profiles for '' were found: Xcode couldn't find any iOS App Development provisioning profiles matching ''. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target '' from project '') 

Match 파일은 Development로 FastFile에서는 Appstore로 설정해서 생긴문제 요건 둘중 하나를 통일 시켜주면된다.

그리고 또 Match파일을 쓰는데 Xcode에 AutomaticSigning이 설정되어 있으면 생길 수 있다. 전 글에도 적었는데 꼭 유의하고 Match인증서를 잘 선택해야한다.

이 놈이 최고의 문제아였다.

나 같은 경우 네이버 맵을 사이닝 하는데 여기서 50분을 기다려도 다음 단계로 넘어가질 않았다. 그렇다고 --verbose 를 했을 때, 로그가 찍힌다거나, 어떠한 에러로 실패조차 안하고 계속 Signing중이였다. 
공식 깃헙에 올라온 이슈로는 최신 fastlane으로 업글 하면 해당문제가 사라진다고 했지만, 난 이미 최신 버전이었다.

키체인과 CI환경에서 사이닝이 제대로 되지 않았다면, 해당 사이닝부분에 계속 갇힐 수 있다.

 

위의 문제들은 결국 fastlane match를 이용해서 다 해결했다!

 

 

Azure DevOps 관련 문제

pool vmimage 'macos-latest'

위와 같이 macos를 제일 최신으로 설정하게 했음에도 불구하고 Xcode 버전이 13까지만 되어서 Swift가 5.7.1로 설정되어서 라이브러리가 실행이 안되는 문제가 발생 

 

pool vmimage 'macos-13'

이렇게 직접 macos버전을 지정해줬다.

아직까지는 AzureDevops에서는 벤투라까지만 지원을 해줘서 이게 가장 최신이다.

728x90
반응형

'CI와CD' 카테고리의 다른 글

[iOS] CI/CD 도입 Fastlane + AzureDevOps [1]  (0) 2024.03.19
CI/CD 란 무엇일까?  (0) 2024.03.18