在這個章節選擇介紹 Github Actions 是因為,後續我們會將我們撰寫的 Robot Framework 自動化測試做整合,讓測試能夠與當前的 DevOps 流程做串接,因此花了些篇幅來介紹一下 Github Actions。
在現代軟體開發中,自動化是不可或缺的一環。從程式碼測試、自動化部署到持續整合(CI)和持續交付(CD),自動化工具的使用能夠大幅提升開發效率與品質。GitHub Actions 作為 GitHub 平台上的一個功能強大且靈活的 CI/CD 工具,已經成為許多開發團隊的重要工具。本章節將介紹 GitHub Actions,介紹其基本概念、語法,讓我們一起看下去吧!
在開始前我們先來簡單的提一下,什麼是 CI/CD,CI/CD 是由兩個詞彙,持續整合 (Continuous Integration) 與持續交付 (Continuous Deployment) 組合而來,簡單來說就是流程自動化
GitHub Actions 是 GitHub 提供的一個 CI/CD 平台,允許開發者在每次程式碼變更時,自動化執行工作流(workflows)。這些工作流可以包括測試、構建、部署,以及其他自定義的腳本操作。GitHub Actions 的最大優勢在於其深度整合 GitHub 平台,無縫支援版本控制、拉取請求(Pull Requests)、分支管理等功能。
.github/workflows/
目錄下。上面幾點是關於 GitHub Actions 的核心組成,Workflow、Job、Step 是我們在撰寫 yaml 時很重要的觀念,Runner 則是我們執行 Workflow 的機器,下面我們將透過圖片針對這幾點有更多的說明:
要導入 Github Actions 相當的容易,我們只需要在 Repository 目錄的下新增 .github/workflow
的路徑,接著在 workflow 中撰寫 .yaml
的檔案後推上 Github,這時候我們就完成創立 Github Actions 啦,我們只要根據我們撰寫 .yaml
時,定義的觸發行為來觸發 workflow 便可以在 repository 的 Actions 介面中看到被觸發的 workflow。
透過上方圖片我們可以發現,在 workflow 底下我們可以有許多的 .yaml
,像是在專案中,我可能會有發 PR 時需要觸發測試的 auto_test.yaml
,需要部署到測試環境時的 deploy.yaml
,以及發佈到正式環境的 release.yaml
,每個 yaml 檔案負責各自的工作流程,或是我們也可以定義好共用的 workflow,讓我們團隊間的 repository 可以誇 repository 互相引用同一個 workflow 範本。
如同圖片所述,一個 Workflow 裡頭可以有多個 Job,Job 之間可以平行執行,或是在 yaml 中指定依序執行,需要注意的是,如果今天是依序執行的話,在 self-host 中並不會說一個 Workflow 做完才會接下一個,由於每個 Job 可以指定要執行的機器,因此這邊會是先取得機器資源的先跑,至於什麼是 self-host 我們保留到下個章節再說明。
Step 則是 github actions workflow 的最小單位,這裡我們可以透過 Step 來組成說這個 Job 需要執行哪些步驟,可以透過 command line 來執行,或是引用網路上其他大神提供的工具,例如 slack-github-action 引用這個工具我們便可以在 github actions 中傳送 slack 消息,或是我們也可以透過自行包好的 composite 來執行。
在了解些關於 github actions 的基礎觀念後,我們可以來看看該如何實際撰寫 workflow,github actions 主要是透過在 YAML 檔案中撰寫的,下面我們來看一個範例,並且說明每個區塊個字的含義為何,欲知道詳細,可以參考官方文件 workflow-syntax,因為可以客製化的太多了,因此這邊只挑了比較經典的來說明。
name: Robot Framework Tests
on:
push: # 當程式碼推送到 main 分支時
branches:
- main
pull_request: # 當有針對 main 分支的拉取請求(Pull Request)時
branches:
- main
schedule: # 定時觸發
- cron: '30 5,17 * * *'
workflow_dispatch: # 手動觸發
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12' # 你可以根據需要指定 Python 版本
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Robot Framework tests
run: |
robot tests/ # 指測試目錄
- name: Archive test results
if: always()
uses: actions/upload-artifact@v3
with:
name: robot-results
path: output/ # 指定你的輸出目錄
通過上方的設定,我們可以一個個區塊來解讀:
name 用於在 GitHub 的「Actions」頁面中,目的在標識和區分不同的工作流程。如果沒有提供名稱,系統會自動顯示工作流程文件的相對路徑,以方便定位。
on 是用來指定觸發 workflow 的時機點可以是事件、時間排程,或依據特定條件(如文件、標籤、分支變更)來觸發工作流程的執行。這些設定讓工作流程更加靈活,並且可以根據需求進行限制或調整,下面我們針對幾個觸發事件來做介紹:
push
:當程式碼推送到特定的分支時觸發。例如當有人將程式碼推送到 main
或其他分支時,workflow 會自動執行。pull_request
:當有 Pull Request 被建立、更新、或合併時觸發,用來在合併之前檢查程式碼品質或進行自動測試。schedule
:定時觸發 workflow,使用 cron 表達式來設定執行的時間間隔,適合用來執行定期任務,如夜間構建或自動備份。workflow_dispatch
:手動觸發 workflow,允許使用者通過 GitHub UI 點擊來啟動 workflow,並且可以設置輸入參數。release
:當發佈新的 Release 或修改 Release 時觸發,通常用來處理自動化部署或發佈的流程。issue_comment
:當有人在 Issue 中新增或更新評論時觸發,適合用來自動化回應或處理特定指令。fork
:當倉庫被 fork 時觸發,通常用於監控倉庫被 fork 的活動。除此之外 github actions 還有提供像是 on.<event_name>.types
這個更進階的用法,用於細化觸發工作流程的活動類型,像是 pull_request
這樣的觸發時機,還可以更細分到,pull_request
的哪類型行為才會觸發,因為我們可能會希望說 PR 更新或是新增時才觸發,close 時不要觸發,這時候我們便可以透過 on.<event_name>.types
來進行更細緻的設定。
on:
pull_request:
types: [opened, synchronize, reopened]
關於更多的觸發方式,可以查看官方文件的:Events that trigger workflows
這個是指定測試的 workflow 要跑在哪個 OS 的機器上,github 提供 Linux、Windows、macOS 的裝置可以選擇,不過會依照帳號的付費情況規範使用時間限制,或是我們可以透過 self-host 的裝置來節省運行的成本。
在 runs-on 可以用單一字串、變數或陣列來選擇合適的 runner,如下面所示:
# 單一字串
runs-on: ubuntu-latest
# 變數
runs-on: "${{ inputs.machine }}"
# 陣列
runs-on: [self-hosted, linux, x64, gpu]
uses
是用來引用現有的 actions 或 workflows 的指令。目的在提供重複利用網路上第三方或自定義的 actions 來簡化 workflow。以下是 uses
的主要功能:
uses
可以直接引用 GitHub Marketplace 上的現成 actions,例如 actions/checkout@v4
來取用程式碼。uses: ./path/to/action
來引用專案中的自定義 action,這些 action 也存放在我們建立的 .github/ 的資料夾中。uses
允許從其他 repo 中引用 actions,這使得可以在不同專案間重複使用相同的 workflows。在上面的案例中,我們有使用 actions/checkout@v4
先將我們的 repository clone 下來,再來則是設定 python 執行的版本。
run 用來在操作系統的 shell 中運行命令,,可以想要是我們平常在終端機怎麼做輸入,這邊就怎麼輸入,每個 run 代表一個新的進程,並且可以使用默認或自定義的 shell 來執行命令。如果沒有明確指定步驟名稱,默認會使用命令內容作為步驟名稱。
眼尖的夥伴可能發現,在 run:
後面有 |
的符號,這是什麼意思呢?這用於區分是不是多行的 shell 指令:
單行:
- name: Install Dependencies
run: pip install -r requirements.txt
多行:
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
是 GitHub Actions 中的一個條件語句,if: always()
表示無論之前的步驟是否成功,都會執行該步驟。
是 GitHub Actions 中的一個官方操作,用於將生成的文件或目錄(稱為 "artifact")上傳到 GitHub。這些 artifact 可以是測試結果、構建產物、日誌文件等,供後續步驟使用或供用戶在工作流程完成後下載查看,需要注意的是,這個儲存的空間限制是有的,一樣需要查看自己的帳號可以有多少的額度。
上傳後的成果如下圖:
在經過上面的分享後,相信大家對於 Github Actions 已經有基礎的認識了,接下來我們只需要針對專案的需求,對照官方的文件找尋我們需要的內容將流程拼接起來即可!