Skip to content

[기술공유] Swift Continuous Integration with Github Action

박효준 edited this page Nov 14, 2024 · 2 revisions

CI/CD

CI/CD는 뭔가요? (참고로 오늘 해볼 건 CI: continuous integration)

continuous integration, continuous deployment의 약자로

지속적 통합, 지속적 배포를 뜻합니다.

그럼 지속적 통합, 배포는 뭔가요?

빌드, 테스트, 배포 과정의 파이프라인을 구축해

누군가(ex. github action) 자동으로 빌드, 테스트, 배포를 하게 도와주는 과정입니다.

자동화 왜 하는건가요?

commit 이후 반복되는 build, test 등등 … 과정이 귀찮아서?

아래는 CI/CD 파이프라인에 대한 이미지입니다.

스크린샷 2024-11-14 오후 11 28 39

continuous integration를 위한 툴이 정말 많은데 github action으로 진행하겠습니다.

github action에서 Build, Unit tests, Integration tests의 과정을 workflows라고 합니다.

저장소에 .yml파일로 .github/workflows에 저장되고 저장소에 이벤트가 발생했을 때 트리거 됩니다.

.yml파일이 여러 개 존재할 수도 있습니다.

workflow basics(: 반드시 포함되어야하는 components)

파란 글씨는 yml 파일에서 사용되는 components

  1. one or more events(on)
  2. one or more jobs: excute on runner machine(runs-on, ex. macOS), one or more steps
  3. steps run a script or actions 스크린샷 2024-11-14 오후 11 28 54

Components에 대한 자세한 내용은 링크 바로가기

동작방식과 Basic Components을 바탕으로 CI 적용 과정

  1. 프로젝트 저장소의 Actions에 들어가 Swift의 Configure를 클릭합니다
스크린샷 2024-11-14 오후 11 29 32
  1. configure button에서 yml 파일 만들고 아래의 코드를 넣어주면 [on] 조건에 따라 [jobs] 수행
스크린샷 2024-11-14 오후 11 29 43
  1. Basic Components를 사용한 swift.yml (동작 안됨)
name: My Swift Actions 🚗

on: # events
  pull_request: # PR할 때!
    branches: [ "develop" ] # develop branch에!

jobs: # 어떤 작업을 수행할거?
  build: # jobs name

	  runs-on: macos-latest # 작업을 수행할 OS version(Runners)

    steps:
    - uses: actions/checkout@v4 # 저장소로부터 코드 내려받기
        
    - name: Build
      run: |
        xcodebuild -workspace ./MemorialHouse/MemorialHouse.xcworkspace -scheme MemorialHouse

actions/checkout@v4

  • 저장소의 코드 내려받는 actions

xcodebuild -workspace ./MemorialHouse/MemorialHouse.xcworkspace -scheme MemorialHouse

  • xcodebuild command를 통해 build

⚙️ 1 Trouble

** BUILD FAILED ** Error: Error Domain=Xcode3ProjectErrorDomain Code=2 "The project ‘MHDomain’ cannot be opened because it is in a future Xcode project file format (77). Adjust the project format using a compatible version of Xcode to allow it to be opened by this version of Xcode." UserInfo={NSLocalizedDescription=The project ‘MHDomain’ cannot be opened because it is in a future Xcode project file format (77). Adjust the project format using a compatible version of Xcode to allow it to be opened by this version of Xcode.}

대충 project가 xcodebuild version을 앞선 다는 이야기입니다.

💡command line(sudo xcodebuild -version)을 통해 xcode version을 확인해주고 command line(sudo xcode-select -s /Applications/Xcode_16.1.app)을 통해 우리의 xcode version인 16.1로 변경

# ...

- name: 🔨 set up xcode version
  run: |
    sudo xcode-select -s /Applications/Xcode_16.1.app
      
- name: ✅ check xcode version
  run: |
    sudo xcodebuild -version

xcode version 관련 에러는 해결했는데 swift package 관련 에러가 발생

⚙️ 2 Trouble

Validate plug-in “SwiftLintBuildToolPlugin” in package “swiftlintplugins” error: “SwiftLintBuildToolPlugin” must be enabled before it can be used

** BUILD INTERRUPTED ** The following build commands failed: Validate plug-in “SwiftLintBuildToolPlugin” in package “swiftlintplugins”eyJ0eXBlIjp7IndvcmtzcGFjZSI6e319fQ== (2 failures)

swiftlintplugins package의 SwiftLintBuildToolPlugin가 유효하지 않다고 합니다.

이 것 저 것 해보다가 Package Dependencies의 SwiftLintPlugins를 제거 후 다시 등록

그랬더니 … 아래처럼 pbxproj 파일이 변경되었습니다.

스크린샷 2024-11-14 오후 11 30 11

이렇게 swift package 관련 에러를 해결했는데 …

⚙️ 3 Trouble

No signing certificate "iOS Development" found: No "iOS Development" signing certificate matching team ID "B3PWYBKFUK" with a private key was found

certificate 관련 에러입니다.

아래의 영상과 링크 참조해서 해결했습니다.

내용이 길어 링크 첨부했습니다.

https://www.youtube.com/watch?v=Sd7YhlxZrJw

https://docs.github.com/en/actions/use-cases-and-examples/deploying/installing-an-apple-certificate-on-macos-runners-for-xcode-development

코드는 아래와 같습니다.

# This workflow will build a Swift project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift

name: My Swift Actions 🚗

on: # 언제? 어떤 이벤트?
  push: # 푸시할 때!
    branches: [ "ci" ] # ci branch에!

jobs: # 어떤 작업을 수행할거?
  build:

	  runs-on: macos-latest

    steps:
    - uses: actions/checkout@v4
    
    - 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: 🔨 set up xcode version
      run: |
        sudo xcode-select -s /Applications/Xcode_16.1.app
        
    - name: ✅ check xcode version
      run: |
        sudo xcodebuild -version
        
    - name: Build
      run: |
        xcodebuild -workspace ./MemorialHouse/MemorialHouse.xcworkspace -scheme MemorialHouse 

⚙️ 4 Trouble

인증서 관련 에러는 해결했는데 이번엔 Provisioning Profiles 관련 에러가 발생했습니다.

error: No profiles for 'XXX.MemorialHouse' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'XXX.MemorialHouse'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target 'MemorialHouse' from project 'MHApplication')

provisioning profiles가 있어야 실행이 가능하다는 에러가 발생했습니다.

provisioning profiles는 iOS 기기에서 앱을 실행을 도와주는 친구입니다.

-destination을 사용해 가상 기기인 시뮬레이터에서 실행되도록 설정을 해주었습니다. (임시방편)

xcodebuild -workspace ./MemorialHouse/MemorialHouse.xcworkspace -scheme MemorialHouse에 아래의 옵션 추가추가

-destination 'platform=iOS Simulator,name=iPhone 16 Pro'

Script 수정 후 문제 해결가 되고 빌드가 되었습니다.

** BUILD SUCCEEDED **

ps. provisioning profiles를 잘못 가져와서 발생한 에러인데요.

App’s provisioning profiles를 제대로 확인하고 screts에 추가해야합니다.


reference

https://www.wallarm.com/what/what-is-ci-cd-concept-how-can-it-work

https://docs.github.com/en/actions/writing-workflows/about-workflows

https://dzone.com/articles/the-complete-introduction-to-cicd-1

Clone this wiki locally