-
Swift Package에 GitHub Actions 사용하기iOS 2023. 5. 5. 16:08
GitHub Actions는 빌드, 테스트, 배포 파이프라인을 자동화할 수 있는 CI/CD(continuous integration & continuous delivery) 플랫폼입니다. 이 글의 아래에서는 GitHub Actions를 사용해서 간단한 Swift Package에 CI를 적용해보려고 합니다. 쉽게 말해서, 깃허브 저장소에 새로운 내용을 push 할 때, 트리거 되어 실행되는 스크립트를 작성해보겠습니다.
GitHub Actions의 컴포넌트로는 다음과 같은 것들이 있습니다.
- Workflow
- Event
- Job
- Action
- Runner
Workflows
Workflow는 하나 이상의 job으로 구성되어 그것들을 수행하는 자동화 프로세스입니다. YAML 파일(형식: *.yml)에 정의되어 이벤트가 발생했을 때 트리거되어 수행되며, 수동으로 또는 스케쥴을 통해 실행할 수도 있습니다. .github/workflows 디렉터리에 정의되며, 저장소는 다수의 Workflow를 가질 수 있습니다.
Jobs
Job은 순차적으로 또는 병렬 수행이 가능하며 workflow 내에서, 같은 runner에서 실행되는, 스크립트를 실행하는 하나 이상의 step으로 구성됩니다.
Events
Event는 workflow 실행을 트리거 하는 저장소의 특정한 활동입니다. 예를 들면 저장소에 새로운 내용을 push 하거나, pull request를 생성하거나, 새로운 issue를 작성하는 것들이 events입니다. GitHub 문서를 보면, 다양한 Events가 있습니다.
Actions
Action은 복잡하지만 자주 반복되는 작업을 수행하는 GitHub Actions 플랫폼 전용 애플리케이션입니다. workflow 파일에 반복되는 코드를 커스텀 action으로 만들어서 재사용할 수도 있고, GitHub의 Marketplace에서 기존의 다양한 action을 가져와 사용할 수도 있습니다. 아래에서 그 예시를 보여드리겠습니다.
Runners
Runner는 workflow를 실행하는 서버입니다. 각 runner는 한 번에 하나의 job을 실행할 수 있습니다.
Github Actions 사용하기
Swift Package의 코드는 다음과 같이 작성했습니다.
public struct MyNumbers { private let a = 10 private let b = 20 public var isThirty: Bool { a + b == 30 ? true : false } }
테스트 코드
import XCTest @testable import ActionsPractice final class MyNumbersTests: XCTestCase { func testExample() throws { XCTAssertEqual(MyNumbers().isThirty, true) } }
저장소 페이지에서, Actions 탭으로 갑니다.
Actions Tab 그러면, 아래의 사진과 같이 저장소에 맞는 템플릿을 추천해줍니다. Swift Package에 적용하기 위해서, 첫 번째 Configure 버튼을 눌러줍니다.
다음과 같이 YAML 파일 편집기가 나타납니다.
- 파일 이름입니다. *.yml 형식으로 원하는 대로 입력해주시면 됩니다.
- Actions 탭을 눌렀을 때, 나타나는 workflow의 이름입니다.
- 'on: '에는 workflow를 실행할 trigger를 입력해줍니다. 기본적으로 push 및 pull request, 두 가지 events가 입력되어 있습니다.
- 'jobs: '에는 하나 이상의 job을 입력해줍니다. 기본적으로 최신 버전의 macOS runner에서 수행하는 'build'라는 이름의 job에서 Checkout 후 빌드 및 테스트를 실행합니다. swift build 및 swift test는 Swift Package Manager를 사용해서 빌드하고 테스트하는 명령어입니다. 따라서 기본적으로 Swift Package에 종속성이 없으면, 위의 템플릿만으로도 빌드 및 테스트가 가능합니다.
- Marketplace 탭에서는 사용할만한 action을 둘러볼 수 있습니다.
YAML 파일을 만들면 자동으로 .github/workflows 디렉터리에 생성됩니다. 그리고 다시 Actions 탭으로 가면, workflow의 실행 상황 및 결과를 확인할 수 있습니다.
그런데 빌드를 하는 과정에서 다음과 같은 오류가 발생했습니다.
Actions Tab 빌드 실패 로그
Run swift build -v error: 'actionspractice': package 'actionspractice' is using Swift tools version 5.8.0 but the installed version is 5.7.1 Error: Process completed with exit code 1.
Swift package의 swift tools version과 Runner의 swift 버전이 일치하지 않아서 오류가 발생하고, 빌드 및 테스트를 수행하지 못한 것 같습니다. 문제를 해결하기 위해서 다음과 같이 Marketplace에서 탐색을 통해 해당하는 action을 찾고, 사용법대로 스크립트에 추가해줬습니다.
Action을 어떻게 사용하면 되는지 설명이 되어있습니다. 아래는 jobs를 빌드와 테스트로 나누어 정리하고, 'Setup Swift' action을 사용한 workflow 스크립트입니다.
name: Swift Package CI on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: build: runs-on: macos-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Swift uses: swift-actions/setup-swift@v1.23.0 with: swift-version: 5.8 - name: Build run: swift build -v test: runs-on: macos-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Swift uses: swift-actions/setup-swift@v1.23.0 with: swift-version: 5.8 - name: Run tests run: swift test -v
다시 Actions 탭으로 가면, 빌드 및 테스트 수행 과정과 결과를 확인할 수 있습니다. 빌드에 성공하고 작성해놓은 테스트 코드가 성공적으로 실행을 마쳤다는 것을 알 수 있습니다.
아래 사진의 '...'을 누르고 'Create status badge'를 클릭하면 README.md에 추가할 수 있는 배지도 줍니다.
최근 workflow의 수행을 성공적으로 마쳤을 때 배지
이번에는 테스트에 실패하도록 아래와 같이 코드를 수정해보겠습니다.
public struct MyNumbers { private let a = 10 private let b = 30 // 수정 public var isThirty: Bool { a + b == 30 ? true : false // false를 반환 } }
수정하고 push(event 발생) 하면, 다시 workflow를 실행합니다. 그리고 아래 사진과 같이 빌드는 성공하지만, 테스트는 실패하게 됩니다.
최근 workflow의 수행을 성공적으로 마치지 못했을 때 배지 테스트 실패 로그
Test Suite 'All tests' started at 2023-05-05 06:34:33.846 Test Suite 'ActionsPracticePackageTests.xctest' started at 2023-05-05 06:34:33.848 Test Suite 'MyNumbersTests' started at 2023-05-05 06:34:33.848 Test Case '-[ActionsPracticeTests.MyNumbersTests testExample]' started. /Users/runner/work/ActionsPractice/ActionsPractice/Tests/ActionsPracticeTests/MyNumbersTests.swift:6: error: -[ActionsPracticeTests.MyNumbersTests testExample] : XCTAssertEqual failed: ("false") is not equal to ("true") Test Case '-[ActionsPracticeTests.MyNumbersTests testExample]' failed (0.970 seconds). Test Suite 'MyNumbersTests' failed at 2023-05-05 06:34:34.818. Executed 1 test, with 1 failure (0 unexpected) in 0.970 (0.970) seconds Test Suite 'ActionsPracticePackageTests.xctest' failed at 2023-05-05 06:34:34.818. Executed 1 test, with 1 failure (0 unexpected) in 0.970 (0.970) seconds Test Suite 'All tests' failed at 2023-05-05 06:34:34.818. Executed 1 test, with 1 failure (0 unexpected) in 0.970 (0.972) seconds Error: Process completed with exit code 1.
모든 테스트를 수행했을 때, 하나의 테스트를 수행했고 하나의 테스트에 실패했다고 알려줍니다.
코드
github
(https://github.com/ehddnr3473/ActionsPractice)
참고
github document
(https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions)
'iOS' 카테고리의 다른 글
Swift를 사용해서 Cordova Custom Plugin 만들기 (2) (0) 2023.05.25 Swift를 사용해서 Cordova Custom Plugin 만들기 (1) (0) 2023.05.25 Class와 Performance in Swift (0) 2023.02.02 UIButton 커스텀(Image & Title) (0) 2023.02.01 UIKit에서 SwiftUI View 활용하기 (0) 2023.01.02