CI/CD平臺(tái)遷移實(shí)踐:從Travis-CI轉(zhuǎn)移到Github Action
LCTT 的 CI 已經(jīng)在 Travis CI 上運(yùn)轉(zhuǎn)了多年,一致保持著良好的使用體驗(yàn)。自 2019 年 Github 推出了自家的 CI 工具 Github Action 后,我們就在考慮將 CI 從 Travis-CI 遷移到 Github,以降低維護(hù)和溝通的成本,并借助于 GitHub Action Marketplace 實(shí)現(xiàn)更強(qiáng)的功能。
項(xiàng)目首頁(yè)
最近,因?yàn)?TravisCI 屢屢部署出錯(cuò),而我們的賬戶因?yàn)槭褂玫妮^多,已經(jīng)超出了免費(fèi)使用的限制,以此為契機(jī),將 CI 從 Travis CI 遷移到 GitHub Action。
Travis CI 的提醒
項(xiàng)目介紹
Translate Project 是 LCTT 翻譯組的主要協(xié)作項(xiàng)目,幾百位譯者通過 GitHub 進(jìn)行圍繞開源、Linux、軟件工程等領(lǐng)域的文章翻譯,從 2013 年來(lái),累計(jì)了大量的提交,致使項(xiàng)目下有非常多的文件。
Translate Project 借助于 CI 幫助譯者對(duì)基本的文章格式和拉取請(qǐng)求進(jìn)行檢查;并定時(shí)執(zhí)行命令,以進(jìn)行所有的申請(qǐng)檢查,對(duì)于超時(shí)未完成翻譯的工作進(jìn)行回收;對(duì)于文章的狀態(tài)進(jìn)行標(biāo)記,生成相應(yīng)的徽章。
生成徽章
遷移思路
Travis CI 和 Github Action 在使用方面,其實(shí)總體差異不會(huì)太大,都是基于 YAML 文件格式來(lái)編寫配置文件。不過,和 Travis CI 不同的是,Github Action 支持多個(gè)不同的配置文件,因此,你可以根據(jù)不同的場(chǎng)景,設(shè)定不同的配置文件,降低單個(gè)配置的文件的復(fù)雜度。
此外,由于我們的腳本中依賴了一些 Travis CI 的環(huán)境變量,也需要將其替換為 Github Action 中的相應(yīng)環(huán)境變量,從而確保腳本可以運(yùn)轉(zhuǎn)。
改造實(shí)踐
1. 分析之前的 CI 流程
我們?cè)?TravisCI 上的 CI 配置文件如圖:
配置文件
總體可以分為三塊:
- 命令區(qū):說(shuō)明了安裝階段和執(zhí)行階段的操作有哪些
- 條件區(qū):指定了這個(gè)配置文件在哪些條件下會(huì)生效
- 部署區(qū):寫明了構(gòu)建產(chǎn)物如何進(jìn)行部署
在命令區(qū)中,有預(yù)置的安裝過程和后續(xù)的執(zhí)行過程。在安裝過程中,安裝了一些依賴,并將當(dāng)前的 pages 資源克隆到本地,以繼承上一次構(gòu)建生成的資料。
在條件區(qū)則指明了僅作用于 master
分支。
在部署區(qū)便是將前面命令區(qū)的執(zhí)行結(jié)果進(jìn)行部署。
基本流程
在實(shí)際的執(zhí)行過程中,還會(huì)根據(jù)環(huán)境變量不同,決定是否要執(zhí)行特定的命令,這部分在后續(xù)的改造過程中,就可以調(diào)整部署,拆分到不同的文件中。
構(gòu)建流程
2. 直接套用配置文件
在完成了基本的分析后,就可以建立新的 Action 配置文件了。由于基本的語(yǔ)法很類似,對(duì)于其中的不少內(nèi)容可以進(jìn)行直接套用。
比如,我們的配置文件在直接套用后,結(jié)果如下
直接套用后的結(jié)果
直接套用的文件已經(jīng)可以直接運(yùn)行,不過,這里有很多不滿足需要的地方,所以需要做一些修改。
3. 恢復(fù) Travis CI 的環(huán)境變量
由于我們使用的 Badge 等生成腳本并非我所編寫,所以在這一次的遷移中,并不打算對(duì)齊進(jìn)行調(diào)整,以避免出現(xiàn)故障。而腳本中依賴了一些變量,需要將其重新設(shè)置出來(lái)。
Github Action 提供了一些方法,可以讓你手動(dòng)設(shè)置環(huán)境變量。你可以在你的構(gòu)建的步驟中,加入如下代碼,從而在構(gòu)建環(huán)境中設(shè)定 TRAVIS_BRANCH
和 TRAVIS_EVENT_TYPE
環(huán)境變量,確保你可以使用這個(gè)環(huán)境變量。
- name: Set ENV variables run: | echo "::set-env name=TRAVIS_BRANCH::${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}" echo "::set-env name=TRAVIS_EVENT_TYPE::$(if [ "schedule" == "${{ github.event_name }}" ]; then echo "cron"; else echo "${{ github.event_name }}"; fi)"
此外,由于 set-env
這個(gè)方法相對(duì)比較危險(xiǎn),你還需要在環(huán)境變量中,開啟危險(xiǎn)函數(shù)的執(zhí)行。
jobs: build: runs-on: ubuntu-latest env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true
4. 拆分配置文件
Github Action 和 TravisCI 不同的一點(diǎn)是你可以將你的 CI 文件拆分成多個(gè)文件,從而降低每一個(gè)單獨(dú)的配置文件的復(fù)雜度。
根據(jù)前面對(duì)于流程的分析,可以將我們的 CI 流程拆分成三個(gè)部分:
- 生成
badge
文件,應(yīng)當(dāng)跟隨每一次提交進(jìn)行 - 生成
status
文件,執(zhí)行時(shí)間較長(zhǎng),可以定期執(zhí)行 - 根據(jù)拉取請(qǐng)求內(nèi)容進(jìn)行整理,做核驗(yàn)
則將我們的配置文件拆分成三個(gè)不同的文件:
也得益于拆分開,則在 checker
中就可以免于安裝一些必要的依賴,從而精簡(jiǎn) CI 流程,提升 CI 的執(zhí)行時(shí)間。
5. 測(cè)試 CI 的運(yùn)行情況
在完成了配置文件的編寫和拆分后,就可以進(jìn)行本地的執(zhí)行測(cè)試。Github Action 寫完了,難免要執(zhí)行一下,確保整個(gè)流程是正常的。
這個(gè)時(shí)候你可以安裝工具(https://github.com/nektos/act),來(lái)在本地執(zhí)行 Action ,從而確認(rèn)你的代碼執(zhí)行是正確的。
如果你是 macOS ,只需要執(zhí)行 brew install act
就可以安裝 act
工具,來(lái)完成 act
的安裝。
安裝完成 act
,就可以通過執(zhí)行 act
命令來(lái)在本地執(zhí)行 Action ,比如,執(zhí)行 act pull_request
來(lái)觸發(fā) GitHub 的拉取請(qǐng)求事件
通過本地測(cè)試后,再將你的配置文件推送到 GitHub 上,進(jìn)行生產(chǎn)環(huán)境的測(cè)試即可。
6. 移除 Travis-CI
通過上述的一些步驟,我們完成了從 Travis CI 到 GitHub Action 的遷移,此時(shí),就可以移除項(xiàng)目根目錄中的 .travis.yml
文件,徹底關(guān)閉 Travis CI。
7. 替換環(huán)境變量
在完成了基本的遷移后,需要對(duì)代碼中的一些歷史問題進(jìn)行修復(fù)。在第三步中,我們對(duì)于 Travis-CI 的環(huán)境變量進(jìn)行替換,但長(zhǎng)期維護(hù)的項(xiàng)目應(yīng)當(dāng)盡量將這些未標(biāo)注上下文的信息替換為有文檔標(biāo)注的,因此,我們需要將其替換。
替換環(huán)境變量主要依賴 Github 官方的環(huán)境變量說(shuō)明,你可以參考官方文檔。
簡(jiǎn)化后,配置文件從之前的 27 行,減少至 17 行,變得更加的精簡(jiǎn)、易懂。
name: LCTT Article Checker
on:
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
env:
PULL_REQUEST_ID: ${{ github.event.number }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: "checkout master branch & return to pull request branch"
run: CURRENT=$(echo ${{github.ref}} | sed "s|refs/|refs/remotes/|") && git checkout master && git checkout $CURRENT
- name: run check
run: sh ./scripts/check.sh;
8. 修改 GitHub 的分支保護(hù)條件
為了確保修改符合標(biāo)準(zhǔn),我們限制了新的拉取請(qǐng)求必須通過 CI 檢查,才能合并進(jìn)入 master
分支,因此,也需要修改相應(yīng)的分支保護(hù)規(guī)則,確保設(shè)定相應(yīng)的保護(hù)。
一些注意事項(xiàng)
1. 環(huán)境變量不同
如果你依賴了環(huán)境變量,則需要進(jìn)行相應(yīng)的修改。或者可以像我一樣,先通過 set-env
來(lái)讓本地?fù)碛信R時(shí)的環(huán)境變量,后續(xù)再逐步進(jìn)行遷移。
2. Action 運(yùn)行依賴要注意安全
Action 執(zhí)行過程中會(huì)有兩個(gè)部分。Action 本身流程依賴于 master
分支,但執(zhí)行過程中調(diào)用的腳本是根據(jù)源決定的,因此,從安全角度來(lái)看,你應(yīng)當(dāng)盡可能將所有的流程放在 Action 中,而不是放在你的源碼目錄中。
3. 如何觸發(fā) CI 的拉取請(qǐng)求檢查?
在進(jìn)行拉取請(qǐng)求測(cè)試的時(shí)候,需要不斷觸發(fā)不同的提交 ,你可以通過執(zhí)行 git commit --allow-empty -m "Trigger notification" && git push
來(lái)觸發(fā)一個(gè)空白的提交, 推送到 Github 后,就可以再次觸發(fā)拉取請(qǐng)求的構(gòu)建,提升構(gòu)建的效率。
總結(jié)
通過對(duì) TravisCI 的流程整理、代碼修改等流程,我們將之前的 Travis-CI 遷移至速度更快、性能更好的 GitHub Action ,一方面可以優(yōu)化我們的工作流,另一方面,也讓我們的代碼更加簡(jiǎn)潔明了。
對(duì)于還在使用 Travis CI 的項(xiàng)目來(lái)說(shuō),也可以考慮遷移到 GitHub Action 中,來(lái)優(yōu)化自己的工作流。