我從來都沒有使用過 Gitlab-CI/CD 和 Fastlane,到底要如何使用它們來做集成 (Integration) 呢?
我們 Lodoss 團隊最近就遇到這個問題了。這篇入門指南將分享我們的每一個步驟,從初期的設想到最後的結果,讓你能輕易理解 GitLab-CI/CD 和 Fastlane 兩種工具。
為何我們需要持續集成 (Continuous Integration) 呢?
我們做的每一件事都有個理由。對於自動化,我們有以下幾個要求:
- 自動執行 Swiftlint
- 改善程式碼的品質
- 減少手動作業
- 自動執行 UI 和單元測試的工作
這並不是一個完整列表,但我們可以從這幾點出發。在本篇教學,我們會利用下圖的 GitFlow,我們也會使用它來自動化 CI/CD 程序。
以下這個循序圖 (sequence diagrams) 展示了一些成功案例:
而且,在面對同樣的狀況需求時,這些循序做法就可以協助我們了。(例如: 為了向管理者展示一個新功能,而要從功能分支建立一個緊急的 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
- 在 Xcode 建立一個新的專案。
- 為這個專案命名。
- 到 Project Schemes,並勾選 Shared flag,如下圖所示。
- 將它 Push 到你的 GitLab 儲放區。
這樣一來,第一階段就完成了,我們可以繼續進行後續作業。
安裝並註冊 GitLab Runner
GitLab Runner 是一個開源碼專案,用以執行工作,並將結果送回 GitLab。它亦常被用來作 GitLab CI 的連結點 (conjunction),而 GitLab CI 就是在 GitLab 內的開源持續整合服務,用以配合你的工作。
GitLab 文件資訊簡潔,讓你輕易自己摸索所有功能。請跟著下列的步驟做:
- 建立新使用者。(“Cocoapods” 不能以 Root User 執行,需以指定的 Runner 執行)
- 依照安裝指引來安裝一個 Runner。
- 依照指引來註冊 Runner。
- 設定
/Users/gitlab-runner/.gitlab-runner/config.toml
檔案內的working_directory
設定為 Runner 使用者的根目錄Users/gitlab-runner
。 - 重新啟動 Runner。
osx 使用者請參考下列步驟:
- 下載 Binary 到系統中:
- 授權並執行:
- 請依照指南登錄,並選擇執行模式 Executor 為 Shell,加入
ios
的標籤,(這個標籤不是必要的,本文的程式碼用這個標籤,來辨別執行作業時選用了哪個 Runner。) - 安裝 Runner 為 Service 並啟動它:
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
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 的頁面應如下圖所示:
安裝並設定 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_URL
與 FL_SLACK_CHANNEL
增加到 CI/CD Pipelines 的變數。就這樣我們就完成了,你可以確認一下在開發分支做 Push Commit 的狀況。
結論
我們為自動化建立了很好的解決方案,而且,使用 Fastlane 為主要工具是一個明智的選擇,我們可以從中獲得:
- 品質更好的程式碼
- 可自動執行 Swiftlint 檢查
- 可自動執行 UI 和單元測試作業
- 減少手動作業的數
- 自動傳送 Build 到品管團隊 (QA Team) 與客戶 (Client Team)
謝謝你讀完整篇文章,希望本篇主題能幫助到你,若有任何問題,歡迎向我提問。