Xcode

GitLab 初學者指南: 輕鬆為 iOS 專案設定持續集成(CI/CD)

我從來都沒有使用過 Gitlab-CI/CD 和 Fastlane,到底要如何使用它們來做集成 (Intergration) 呢?我們 Lodoss 團隊最近就遇到這個問題了。這篇入門指南將分享我們的每一個步驟,從初期的設想到最後的結果,讓你能輕易理解 GitLab-CI/CD 和 Fastlane 兩種工具。
GitLab 初學者指南: 輕鬆為 iOS 專案設定持續集成(CI/CD)
GitLab 初學者指南: 輕鬆為 iOS 專案設定持續集成(CI/CD)
In: Xcode
本篇原文 (標題: How to set up GitLab Continuous Integration for iOS projects without a hassle) 刊登於作者 Medium,由 Viktor Peschenkov 所著,並授權翻譯及轉載。

我從來都沒有使用過 Gitlab-CI/CDFastlane,到底要如何使用它們來做集成 (Integration) 呢?

我們 Lodoss 團隊最近就遇到這個問題了。這篇入門指南將分享我們的每一個步驟,從初期的設想到最後的結果,讓你能輕易理解 GitLab-CI/CD 和 Fastlane 兩種工具。

為何我們需要持續集成 (Continuous Integration) 呢?

我們做的每一件事都有個理由。對於自動化,我們有以下幾個要求:

  • 自動執行 Swiftlint
  • 改善程式碼的品質
  • 減少手動作業
  • 自動執行 UI 和單元測試的工作

這並不是一個完整列表,但我們可以從這幾點出發。在本篇教學,我們會利用下圖的 GitFlow,我們也會使用它來自動化 CI/CD 程序。

以下這個循序圖 (sequence diagrams) 展示了一些成功案例:

Sequence for master branch using Gitlab-CI/CD

Sequence for develop, feature & release branches using Gitlab-CI/CD

而且,在面對同樣的狀況需求時,這些循序做法就可以協助我們了。(例如: 為了向管理者展示一個新功能,而要從功能分支建立一個緊急的 build 的時候)

為什麼是 GitLab-CI ?

我們選用 GitLab,就只是因為沒有原因驅使我們使用其他工具。對我來說,GitLab-CI/CD 比 Jenkins 更注重開發者導向的功能,它支援了 pipeline、tags 和 branch 等功能,而我們正正就需要使用這些來完成所需的工作。GitLab-CI/CD 像是一個工具,在搖控的機器上執行腳本,功能並不多,但已經足夠了。

使用 Fastlane 後,我們發現用甚麼工具都沒有所謂,因為 Fastlane 已經可以完成所有我們想要做的事,讓我們在使用其他工具時有更大的自由度。所以,我們強烈建議使用 Fastlane 來取代其他需要手動設定腳本的工具。

為什麼是 Fastlane ?

Fastlane 是一個非常易於使用的工具,可以自動為 iOS 和 Android Apps 進行 Beta Deployment 與上傳,它可以處理所有乏味的工作,像是螢幕擷取、程式碼簽署、與上傳應用程式。

我們決定使用 Fastlane 的原因有:

  • 讓生活更美好
  • 利用自動化加速效率
  • 文件資訊簡潔

這些原因亦讓團隊中的其他開發者也可以輕鬆學習;而且,簡單的程序當然比複雜的好吧!

設定 GitLab-CI 與 Fastlane

設定你的 Xcode Project

  1. 在 Xcode 建立一個新的專案。
  2. 為這個專案命名。
  3. 到 Project Schemes,並勾選 Shared flag,如下圖所示。
  4. Setting up Xcode project

  5. 將它 Push 到你的 GitLab 儲放區。

這樣一來,第一階段就完成了,我們可以繼續進行後續作業。

安裝並註冊 GitLab Runner

GitLab Runner 是一個開源碼專案,用以執行工作,並將結果送回 GitLab。它亦常被用來作 GitLab CI 的連結點 (conjunction),而 GitLab CI 就是在 GitLab 內的開源持續整合服務,用以配合你的工作。

GitLab 文件資訊簡潔,讓你輕易自己摸索所有功能。請跟著下列的步驟做:

  1. 建立新使用者。(“Cocoapods” 不能以 Root User 執行,需以指定的 Runner 執行)
  2. 依照安裝指引來安裝一個 Runner。
  3. 依照指引來註冊 Runner。
  4. 設定 /Users/gitlab-runner/.gitlab-runner/config.toml 檔案內的 working_directory 設定為 Runner 使用者的根目錄 Users/gitlab-runner
  5. 重新啟動 Runner。

osx 使用者請參考下列步驟:

  1. 下載 Binary 到系統中:
  2. sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
    
  3. 授權並執行:
  4. sudo chmod +x /usr/local/bin/gitlab-runner
    
  5. 請依照指南登錄,並選擇執行模式 Executor 為 Shell,加入 ios 的標籤,(這個標籤不是必要的,本文的程式碼用這個標籤,來辨別執行作業時選用了哪個 Runner。)
  6. 安裝 Runner 為 Service 並啟動它:
gitlab-runner install
gitlab-runner start

config.toml 的範例檔如下:

concurrent = 2
[[runners]]
  name = "The runner name"
  url = "Your gitlab url"
  token = "The runner token"
  executor = "shell"
  working_directory = "Path to user home directory"

正確執行上述步驟,Runner 在 GitLab 的頁面應如下圖所示:

Runners activated

安裝並設定 Fastlane

你可以自行依照官方指引來執行步驟 (因為真正的工程師會喜歡靠自己找出對的方向)。在這裡,我只與大家分享在開發分支合併提交 (Merge Commit) 的 fastlane 設定檔原始碼:

default_platform(:ios)

platform :ios do
  def install_pods
    cocoapods(
      clean: true,
      podfile: "Podfile",
      try_repo_update_on_error: true
    )
  end

  def build_notes(environment)
    # Build the notes
    commit = last_git_commit
    notes = "#{environment} at #{Time.now.strftime('%d/%m/%Y')}."
    notes.concat("\n")
    notes.concat("##{ENV['CI_JOBENV_ID']}")
    notes.concat("\n")
    notes.concat("SHA: #{commit[:commit_hash]}")
    return notes
  end
  
  lane :lint do
    swiftlint(
      reporter: "html",
      output_file: "fastlane/swiftlint.html"
    )
  end

  lane :test do
    install_pods()
    scan(
      scheme: ENV['XCODE_SCHEME'],
      output_directory: "fastlane/tests",
      clean: true
    )
  end

  lane :develop do
    install_pods()

    # Incerment the buid number
    increment_build_number(
      build_number: ENV['CI_JOBENV_ID'],
      xcodeproj: ENV['XCODE_PROJECT']
    )

    # Build
    gym(
      scheme: ENV['XCODE_SCHEME'],
      configuration: ENV['DEVELOP_CONFIGURATION'],
      export_method: ENV['DEVELOP_EXPORT_METHOD'],
      export_xcargs: ENV['DEVELOP_XCARGS'],
      silent: true,
      clean: true
    )

    # Send to Fabric
    crashlytics(
      groups: ENV['DEVELOP_CRASHLYTICS_GROUPS'],
      notes: build_notes("Develop")
    )
  end
end

這腳本主要是用 Swiftint 的,所以,請記得安裝 Runner 到所有機型時都要一併安裝它。

順帶一提,你可以使用 Gemfile 檔案來安裝一些很棒的工具,如 Cocoapods 等,我們可以使用這個程式碼:

source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"

利用這個方法,你就不必擔心在使用的機型中,有什麼必要的應用工具沒安裝或設定到。

增加 .gitlab-ci.yml

你可以跟從官方指引去探索需要執行的步驟 (剛剛我已經說過原因了吧!)。這裡我只與大家分享在開發分支合併提交的 fastlane 設定檔原始碼:

stages:
  - lint
  - test
  - develop

variables:
  LANG: "en_US.UTF-8"
  LC_ALL: "en_US.UTF-8"

before_script:
  - sudo gem install bundler && bundle update

lint:
  tags:
    - ios
  stage: lint
  script:
    - bundle exec fastlane lint
  only:
    - branches
  except:
    - tags
  artifacts:
    paths:
      - fastlane/swiftlint.html
  allow_failure: false

test:
  tags:
    - ios
  stage: test
  script:
    - bundle exec fastlane test
  only:
    - branches
  except:
    - tags
  artifacts:
    paths:
      - fastlane/tests/
  allow_failure: false

develop:
  tags:
    - ios
  stage: develop
  script:
    - bundle exec fastlane develop
  only:
    - /^develop-.*/
    - develop
  environment:
    name: develop

讓我來解釋一下這些作業:

  • 根據 Fastlne 規範設定,在任何分支做 Push Commit 時,lint 會執行 Swifting。

  • 根據 Fastlne 的規範設定,在任何分支做 Push Commit 時,tests 會執行 test。

  • 根據 Fastlne 的規範設定,只有在開發分支做 Push Commit、merge 或 tag 的時候,develop 執行 Build。

在做上述所有測試前,我們要解決先解決 Code Signing 的問題,我會建議你閱讀這篇文章來了解更多,並看看哪種方法最適合你。然而,初次使用者可以先手動做 Code Signing。之後當 Runners 數量多過一個時,其他方式就會比較適合。

另外,如果你希望由 Slack 發送有關 Fastlane 作業狀況的通知,你可以把 SLACK_URLFL_SLACK_CHANNEL 增加到 CI/CD Pipelines 的變數。就這樣我們就完成了,你可以確認一下在開發分支做 Push Commit 的狀況。

結論

我們為自動化建立了很好的解決方案,而且,使用 Fastlane 為主要工具是一個明智的選擇,我們可以從中獲得:

  • 品質更好的程式碼
  • 可自動執行 Swiftlint 檢查
  • 可自動執行 UI 和單元測試作業
  • 減少手動作業的數
  • 自動傳送 Build 到品管團隊 (QA Team) 與客戶 (Client Team)

謝謝你讀完整篇文章,希望本篇主題能幫助到你,若有任何問題,歡迎向我提問

本篇原文 (標題: How to set up GitLab Continuous Integration for iOS projects without a hassle) 刊登於作者 Medium,由 Viktor Peschenkov 所著,並授權翻譯及轉載。
作者簡介: Viktor,IT 專業人員,擁有超過 5 年開發相關 iOS 應用程式的經驗,專注於行動通訊科技、CI/CD、軟體架構、原始碼開發等。他也是 Open-Source iOS Apps 內 Collaborative List 的 Active Maintainer。閒瑕時,他喜歡閱讀、和老婆出外走走。你可以在 GitHubTwitterLinkedIn 追蹤他。
譯者簡介:Oliver Chen-工程師,喜歡美麗的事物,所以也愛上 Apple,目前在 iOS 程式設計上仍是新手,正研讀 Swift 與 Sketch 中。生活另一個身份是兩個孩子的爸,喜歡和孩子一起玩樂高,幻想著某天自己開發的 App,可以讓孩子覺得老爸好棒!。聯絡方式:電郵[email protected]
作者
AppCoda 編輯團隊
此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。
評論
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。