[Popcorn] iOS CI 적용기 with GitHub Actions

Minw·2025년 2월 15일

프로젝트-팝콘

목록 보기
3/5
post-thumbnail

본 포스팅은 GitHub Actions를 이용해 iOS 프로젝트의 CI를 적용한 과정을 담고 있습니다.

CI와 관련된 내용은 해당 포스트에서 확인하실 수 있습니다.

GitHub Actions와 관련하여 정리한 내용은 해당 링크에서 확인하실 수 있습니다.

1. GitHub Actions란?

https://docs.github.com/ko/actions/about-github-actions/understanding-github-actions
https://zzsza.github.io/development/2020/06/06/github-action/

GitHub Action은 GitHub에서 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화 할 수 있는 CI/CD 플랫폼입니다.

레포지토리에 대한 Pull Request를 빌드 및 테스트하거나 merge된 Pull Request를 프로덕션에 배포하는 워크플로우를 만들 수 있습니다.

Jenkins, fastlane과 같은 CI/CD 도구들도 있지만, GitHub 레포지토리에서 바로 설정할 수 있고, 설정 과정이 간단하다는 장점이 있습니다.

2. CI 스크립트 (빌드 + 테스트)

Popcorn iOS 팀은 GitHub Actions를 이용해 빌드 / 테스트 workflow 스크립트를 아래와 같이 구성하였습니다.

# GitHub의 액션 탭에서 표시되는 워크플로우의 이름
name: Build and Test

on:
  # develop 브랜치에 push 나 pull request 이벤트가 일어났을때 해당 workflow를 트리거
  push:
		branches: [ develop ]
	pull_request:
		branches: [ develop ]

# workflow의 실행은 하나 이상의 job으로 구성 됨. 여기서는 "build" 라는 single job 으로 구성
jobs:
  build:
    runs-on: macos-15
    # Step은 job의 일부로 실행될 일련의 task들을 나타냄
    steps:
    # uses 키워드를 통해 Github Actions에서 기본으로 제공하는 액션을 사용 가능. 아래 액션은 repository 에 체크아웃하는 것
    - uses: actions/checkout@v4
    
    # 해당 가상 머신 환경에서의 사용 가능한 Xcode 버전을 출력
    - name: List available Xcode versions
      run: ls /Applications | grep Xcode

    # 현재 Xcode 버전 출력
    - name: Show current version of Xcode
      run: xcodebuild -version

    # Xcode 버전 직접 설정 후 확인
    - name: Set up Xcode version
      run: |
        sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer
        xcodebuild -version
        
    # shell 이용해서 command 수행
    - name: Build the project 🛠
      run: |
        xcodebuild clean build -project Popcorn-iOS.xcodeproj -scheme Popcorn-iOS -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' -skipPackagePluginValidation -skipMacroValidation
    
    - name: Run tests 🧪
      run: |
        xcodebuild test -project Popcorn-iOS.xcodeproj -scheme Popcorn-iOS -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' -skipPackagePluginValidation -skipMacroValidation

Event

Event란 workflow의 실행을 트리거하는 저장소의 특정 활동을 의미합니다. 그 예로 누군가가 Pull Request를 생성하거나, 이슈를 열거나, 푸쉬 할 때 이벤트가 발생할 수 있습니다.

Popcorn-iOS 팀은 개발 단계에서 develop 브랜치에 PushPull Request 발생 시 해당 코드에 대해 빌드와 테스트를 하는 것이 목적이었기에 아래와 같이 설정하였습니다.

on:
  # develop 브랜치에 push 나 pull request 이벤트가 일어났을때 해당 workflow를 트리거
  push:
    branches: [ chore/githubAction ]
  pull_request:
    branches: [ chore/githubAction ]

Jobs

jobs(작업)은 동일한 실행기(워크플로우를 실행하는 서버)에서 실행되는 워크플로우의 step들의 집합입니다. 각 step은 실행되는 셸 스크립트 또는 실행되는 jobs로 정의됩니다.

저희 팀의 로컬 작업환경은 Xcode 16.1, macos-15.1 입니다. 따라서 비슷한 환경으로 빌드와 테스트를 진행하기 위해 GitHub Actions에서 지원하는 최신 가장 최선 버전으로 설정하였습니다.

그러나 2024.11.14 기준 macos-latest로 설정할 경우, macos - 14.7.1 버전으로 설정되어, Xcode 16.0 버전이 사용되지 않는 문제가 있었습니다.

따라서 macos-latest가 아닌 macos-15로 runner의 OS 버전을 명시적으로 지정해두었습니다.

jobs:
  build:
    runs-on: macos-15

Steps

저희 팀은 총 6단계의 Step을 구성하였습니다.

1. Checkout

저장소의 코드를 실행 환경(가상 머신)으로 가져오는 작업을 의미합니다.

- uses: actions/checkout@v4

2. 사용 가능한 Xcode 버전 출력

오류 발생 시 가상 머신의 Xcode 버전으로 인한 에러인지 파악하기 위해 2, 3, 4 단계를 추가하였습니다.

# 해당 가상 머신 환경에서의 가용 Xcode 버전을 출력
- name: List available Xcode versions
  run: ls /Applications | grep Xcode

3. 현재 가상머신이 사용하는 Xcode 버전 출력

# 현재 Xcode 버전 출력
- name: Show current version of Xcode
  run: xcodebuild -versio

4. Xcode 버전을 16.0으로 설정

# Xcode 버전 직접 설정 후 확인
- name: Set up Xcode version
  run: |
    sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer
    xcodebuild -version

5. Build

- name: Build the project 🛠
  run: |
    xcodebuild clean build -project Popcorn-iOS.xcodeproj -scheme Popcorn-iOS -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' -skipPackagePluginValidation -skipMacroValidation

Build 시 설정한 옵션은 clean, skipPackagePluginValidation, skipMacroValidation 세 가지가 있습니다.

프로젝트에 SwiftLintPlugins가 SPM 플러그인으로 설정되었기 때문에, skipPackagePluginValidation -skipMacroValidation을 설정하였습니다.

관련 내용은 아래에 자세히 설명하겠습니다.

  1. 📌 clean 옵션
    clean 옵션을 적용하여 이전 빌드 데이터(build products 및 intermediate 파일)를 build root(SIMROOT)에서 제거하도록 하였습니다.

    clean 옵션을 적용하는 이유는 종속성, 파일 경로, 환경 변수 등에 변경 발생 시 예상치 못한 오류가 발생할 수 있으므로, 이전 빌드의 결과물이나 캐시를 삭제하여 예상치 못한 오류 발생을 방지하기 위함입니다.

  2. 📌 skipPackagePluginValidation
    이 옵션은 SwiftLint와 같은 패키지 플러그인을 검증하지 않고 넘어가도록 합니다. SwiftLint 플러그인의 설치가 정상적으로 되어있기 때문에 매번 트리거 시 검증을 할 필요가 없다고 생각하여 이 옵션을 통해 CI 빌드 시간을 줄일 수 있습니다.

  3. 📌 skipMacroValidation
    Swift 매크로는 Swift에서 코드를 컴파일할 때 적용되는 추가 기능으로, 코드를 간단히 줄여주거나 반복 작업을 줄여주는 역할을 합니다.
    Xcode는 CI 빌드 시 Swift 코드에 사용된 매크로들이 제대로 설정되었는지 확인하는 매크로 검증을 진행하는데, 이 옵션을 사용하여 Lint 적용 검증을 스킵하도록 설정하였습니다.

SwiftLint 플러그인(SPM) 설치와 CI에서의 유효성 검증
CI 환경에서 빌드 시, Xcode는 SwiftLint 플러그인을 올바르게 설치했는지 검증하고, 종속성이나 코드가 정상적으로 작동하는지 확인하는 과정을 거칩니다.
이러한 검증은 프로젝트의 빌드 성능을 저하시킬 수 있으므로, CI 환경에서는 검증을 생략하도록 설정하였습니다.

📌 용어 정리

  • build products: 빌드가 완료된 후 생성된 최종 산출물(예: 실행 파일, 라이브러리 등)을 의미합니다. 빌드 결과물은 Build Products 디렉터리에 저장됩니다.
  • intermediate 파일: 컴파일러와 링커가 빌드 중에 생성하는 임시 파일(예: 오브젝트 파일, 중간 코드 등)입니다.
  • build root(SIMROOT): 빌드 제품과 임시 파일을 포함한 모든 빌드 아티팩트가 저장되는 루트 디렉터리입니다.

6. Test

Build와 동일하게 skipPackagePluginValidation -skipMacroValidation 옵션을 설정하였습니다.

- name: Run tests 🧪
  run: |
    xcodebuild test -project Popcorn-iOS.xcodeproj -scheme Popcorn-iOS -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' -skipPackagePluginValidation -skipMacroValidation

후기

CI를 처음 적용하다보니 생소한 개념과 용어 때문에 매우 힘들었습니다.
그러나 GitHub Actions를 통해 나름..? 간단하게 적용할 수 있었습니다.

프로젝트의 규모가 커질 수록, 테스트 코드의 양이 많아질 수록 생산성 향상에 많은 도움을 줄 것이라고 생각됩니다.

테스트 코드는 또 언제 짤까요..?ㅠㅠ

0개의 댓글