返回文章列表

從 CI/CD 到資料編排:GitHub 自動化工作流程解析

本文深入探討自動化工作流程的兩大核心應用:持續整合與交付(CI/CD)以及資料管道編排。首先,文章解析 GitHub Actions 的架構,說明如何透過定義工作流程(Workflows)、作業(Jobs)與步驟(Steps)來建構自動化的測試與部署管道。接著,將此概念延伸至資料工程領域,闡述資料管道編排的重要性,其旨在協調與管理複雜資料轉換任務之間的依賴關係、故障處理與執行策略,確保資料流程的可靠性與效率。

DevOps 資料工程

在當代軟體開發與資料密集型應用中,流程自動化已是提升效率與可靠性的核心策略。持續整合與持續交付(CI/CD)改變了程式碼的生命週期管理,透過自動化測試與發布,加速價值交付。GitHub Actions 為此提供了靈活且強大的框架。與此同時,資料工程領域也面臨相似挑戰,即如何管理由多個轉換任務組成的複雜資料管道。資料管道編排的核心便在於定義任務間的依賴關係、調度邏輯與錯誤處理機制,確保資料流的穩定與一致。本文將從這兩個面向切入,探討其背後的理論結構與實務應用。

第九章:GitHub上的持續整合與持續交付

工作流程(Workflows)

工作流程GitHub Actions中的頂層對象。它們提供了所有作業(jobs)的邏輯分組,這些作業是玄貓計劃作為CI/CD管道一部分運行的,並且具有相關的觸發事件。這些定義在玄貓專案根資料夾中的.github/workflows/目錄中。一個典型的工作流程如下所示:

name: Sample Workflow

on: push
jobs:
#list of jobs

理解GitHub Actions

191

工作流程可以由各種事件觸發。有關完整列表,請參閱官方文件。

作業(Jobs)

一個工作流程作業組成,這些作業概述了在每個步驟中要執行的任務,以及執行這些步驟的特定主機。一個工作流程可以有多個作業;例如,一個作業運行單元測試,另一個作業將程式碼部署到構件儲存庫。在前面的範例基礎上,玄貓可以添加如下所示的作業詳細資訊:

jobs:
test:
runs-on: ubuntu-latest
steps:
#list of steps
publish:
needs: test
runs-on: ubuntu-latest
steps:
#list of steps

使用runs-on,玄貓定義了執行這些步驟的主機。玄貓可以選擇使用GitHub託管的運行器或自帶運行器。有關GitHub託管運行器的完整列表,請參閱官方文件。

使用needs,玄貓定義了作業之間的依賴關係。例如,前面的模板要求test作業完成後才能開始publish作業。如果未指定依賴關係,則工作流程中的所有作業將並行運行。

步驟(Steps)

步驟定義了要完成的實際工作。例如,如果它們成功,則將構件發布到ARTIFACTORY,如下面的範例所示:

name: Sample Workflow

on: push
jobs:
test:

CI/CD與GitHub

192

runs-on: ubuntu-latest
steps:
- name: Download code
uses: actions/checkout@v3

- name: Setup sbt
uses: actions/setup-java@v3
with:
java-version: "11"
distribution: "temurin"
cache: "sbt"

- name: Run tests
run: sbt test
publish:
needs: test
runs-on: ubuntu-latest
steps:
- name: download code
uses: actions/checkout@v3

- name: Setup sbt
uses: actions/setup-java@v3
with:
java-version: "11"
distribution: "temurin"
cache: "sbt"

- name: Publish artifact
run: sbt publish
env:
ARTIFACTORYUSER: ${{ secrets.ARTIFACTORYUSER}}
ARTIFACTORYTOKEN: ${{ secrets.ARTIFACTORYTOKEN}}

第一個作業是test,它包含三個步驟:

  1. 下載原始碼。
  2. 安裝sbt
  3. 運行單元測試

第二個作業是publish,它僅在test成功完成後運行,並且也包含三個步驟:

  1. 下載原始碼。
  2. 安裝sbt
  3. 發布到artifactory

理解GitHub Actions

193

對於最後一步,玄貓使用Jfrog上的試用帳戶創建了artifactory,但如果玄貓使用企業儲存庫,步驟將非常相似。此外,請注意,有一些秘密作為環境變數讀取。應該指出的是,玄貓應該將它們定義為秘密而不是變數,因為後者會以純文字形式打印在日誌中。這些秘密可以透過GitHub儲存庫中的設定 | Actions秘密和變數來創建:

圖9.4 – 將秘密添加到儲存庫

在玄貓提交更改推送程式碼後,工作流程將觸發。以下螢幕截圖顯示了按順序運行的兩個作業:

圖9.5 – 工作流程運行

要查看每個步驟的日誌,請點擊其中一個作業。以下螢幕截圖顯示了publish作業的步驟以及日誌:

CI/CD與GitHub

194

圖9.6 – publish作業的步驟

此外,以下是publish步驟的截斷輸出,顯示構件已推送到artifactory

圖9.7 – 顯示構件已發布的日誌

玄貓確實可以在artifactory中找到它們,如下面的螢幕截圖所示:

此圖示:GitHub Actions 工作流程結構

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

rectangle "GitHub 儲存庫" as Repo {
folder ".github/workflows" as WorkflowsFolder {
file "sample_workflow.yml" as WorkflowFile
}
}

cloud "GitHub Actions 服務" as GHActions {
component "工作流程 (Workflow)" as Workflow
component "作業 (Job: test)" as TestJob
component "作業 (Job: publish)" as PublishJob
component "運行器 (Runner: ubuntu-latest)" as Runner
}

database "構件儲存庫 (Artifactory)" as Artifactory

Repo --> WorkflowFile : 包含工作流程定義

WorkflowFile --> Workflow : 定義工作流程名稱和觸發事件
Workflow --> TestJob : 包含測試作業
Workflow --> PublishJob : 包含發布作業 (依賴測試作業)

TestJob --> Runner : 在指定運行器上執行
TestJob --> "步驟: 下載程式碼" as StepDownloadCodeTest
TestJob --> "步驟: 安裝 sbt" as StepSetupSbtTest
TestJob --> "步驟: 運行測試" as StepRunTests

PublishJob --> Runner : 在指定運行器上執行
PublishJob --> "步驟: 下載程式碼" as StepDownloadCodePublish
PublishJob --> "步驟: 安裝 sbt" as StepSetupSbtPublish
PublishJob --> "步驟: 發布構件" as StepPublishArtifact

StepDownloadCodeTest --> StepSetupSbtTest
StepSetupSbtTest --> StepRunTests

StepDownloadCodePublish --> StepSetupSbtPublish
StepSetupSbtPublish --> StepPublishArtifact

StepRunTests --> PublishJob : 測試成功後觸發發布作業

StepPublishArtifact --> Artifactory : 將構件上傳至 Artifactory

note right of Workflow
- 頂層組織單元
- 定義觸發事件 (e.g., push)
end note

note right of TestJob
- 執行單元測試
- 確保程式碼品質
end note

note right of PublishJob
- 將編譯後的程式碼發布為構件
- 依賴 'test' 作業成功
end note

note right of StepPublishArtifact
- 使用環境變數讀取敏感資訊 (secrets)
- 避免將秘密直接寫入配置
end note

@enduml

看圖說話:

此圖示詳細描繪了GitHub Actions工作流程結構,從GitHub儲存庫中的配置文件開始,到最終將構件發布到Artifactory。整個流程的核心是sample_workflow.yml文件,它位於.github/workflows/目錄中,定義了工作流程的名稱和觸發事件(例如,當有程式碼被push時)。

這個工作流程包含兩個主要的作業(Jobs)testpublish。每個作業都在一個指定的運行器(Runner)上執行,例如ubuntu-latesttest作業負責執行程式碼的單元測試,它包括三個步驟(Steps)下載程式碼安裝sbt運行測試。這些步驟按順序執行,確保程式碼的品質。

publish作業則負責將編譯後的程式碼發布為構件。值得注意的是,publish作業透過needs: test明確聲明了它依賴於test作業的成功完成。如果test作業失敗,publish作業將不會執行。publish作業同樣包含下載程式碼安裝sbt發布構件等步驟。在發布構件的步驟中,敏感資訊(如ARTIFACTORYUSERARTIFACTORYTOKEN)是透過環境變數GitHub Secrets中安全讀取的,避免了將秘密直接寫入配置文件。最終,構件會被上傳到Artifactory這個構件儲存庫。這個結構化的工作流程確保了程式碼在發布前經過嚴格的測試和驗證,從而實現了自動化、可靠的CI/CD管道

第九章:GitHub上的持續整合與持續交付

####### 第四部分 – 資料工程管道的生產化:編排與調優

第十章:資料管道編排

一旦玄貓定義了資料上的業務邏輯轉換,玄貓就需要一種可靠的方法將它們全部整合在一起。如果發生故障,玄貓應該收到通知並能夠輕鬆識別失敗的任務,然後再分析它們。這就是資料管道編排的用武之地。它指的是透過明確定義的依賴關係來協調和管理資料轉換中的任務編排有許多業務原因,但請考慮以下簡單範例。玄貓需要每天交付一份報告,並且玄貓需要每天處理該報告的資料。這就需要編排

在本章中,玄貓將研究一些用於資料管道編排的最常用工具和技術。其中兩個,AirflowArgo開源的,而Databricks WorkflowsAzure Data Factory專有軟體。玄貓可以確定哪一個最適合玄貓的編排需求

玄貓將在本章中涵蓋以下主題:

  • 理解編排的基礎知識
  • 理解Apache Airflow的核心功能
  • 使用Argo Workflows
  • 使用Databricks Workflows
  • 利用Azure Data Factory

技術要求

玄貓的機器上需要Python(3.7到3.10之間)才能運行Airflow。如果玄貓沒有安裝它,玄貓還需要minikube,玄貓將用它來運行Argo。玄貓可以在此處找到安裝步驟。

資料管道編排

200

理解編排的基礎知識

一旦玄貓編寫並測試了玄貓的轉換,玄貓就需要一種方法來定義資料工程管道各個步驟之間的依賴關係,定義處理故障的策略等等。這就是編排的用武之地。它允許玄貓定義資料管道執行的策略。例如,作業啟動前必須滿足哪些條件,哪些轉換將並行運行,作業失敗時會發生什麼(玄貓想在一定間隔後重試還是忽略它?管道應該中止嗎?),等等。正確地進行編排對於確保最佳性能成本節約至關重要。

在以下各節中,玄貓將研究業界一些流行的編排工具

理解Apache Airflow的核心功能

此圖示:資料管道編排的核心概念

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "資料工程管道" as DataPipeline {
rectangle "資料擷取 (Extract)" as Extract
rectangle "資料轉換 (Transform)" as Transform
rectangle "資料載入 (Load)" as Load
rectangle "報告生成" as Report
}

package "編排系統" as OrchestrationSystem {
component "任務調度器" as Scheduler
component "任務執行器" as Executor
component "元資料儲存" as MetadataStore
component "監控與告警" as Monitor
}

Extract --> Transform : 資料流向
Transform --> Load : 資料流向
Load --> Report : 資料流向

Scheduler --> Extract : 觸發任務
Scheduler --> Transform : 觸發任務
Scheduler --> Load : 觸發任務
Scheduler --> Report : 觸發任務

Extract --> Executor : 執行任務
Transform --> Executor : 執行任務
Load --> Executor : 執行任務
Report --> Executor : 執行任務

Executor --> MetadataStore : 記錄任務狀態/日誌
MetadataStore --> Monitor : 提供監控數據

Monitor --> Scheduler : 根據狀態調整調度
Monitor --> "通知 (Email/SMS)" as Notification : 故障告警

note right of OrchestrationSystem
- 定義任務間的依賴關係
- 處理任務失敗與重試策略
- 確保任務按序或並行執行
- 提供可視化界面管理管道
end note

note right of Report
- 每日報告生成依賴於前置任務
- 典型的編排應用場景
end note

@enduml

看圖說話:

此圖示闡述了資料管道編排的核心概念,展示了如何將資料工程管道中的各個環節,如資料擷取(Extract)資料轉換(Transform)資料載入(Load)以及報告生成,透過一個編排系統有效地協調起來。在資料工程管道中,資料按照定義的順序從擷取流向轉換,再到載入,最終用於報告生成

編排系統是整個流程的大腦,它由任務調度器(Scheduler)任務執行器(Executor)元資料儲存(Metadata Store)監控與告警(Monitor)組成。調度器負責根據預設的時間表或事件觸發各個資料管道任務的執行。任務執行器則負責實際運行這些任務。在任務執行過程中,其狀態和日誌會被記錄到元資料儲存中。

監控與告警系統持續監測元資料儲存中的任務狀態,一旦發現任務失敗或異常,便會觸發故障告警,透過電子郵件或簡訊通知相關人員。同時,監控系統也能根據任務執行狀態向調度器提供反饋,以便調整後續的任務調度策略,例如重試失敗任務跳過某些任務。整個編排系統的目標是確保資料管道中的任務能夠按照預設的依賴關係故障處理策略執行順序並行方式高效、可靠地運行,尤其是在像每日報告生成這樣需要嚴格時效性的場景中,編排顯得尤為關鍵。

縱觀現代軟體開發的多元挑戰,GitHub Actions 的核心價值在於將 CI/CD 流程無縫整合至開發者最熟悉的程式碼協作平台。相較於需要獨立維運的傳統 CI 伺服器,它透過宣告式的 YAML 配置與豐富的市集生態,大幅降低了自動化流程的建置門檻,使團隊能更專注於業務邏輯本身。本章實例清晰展示了其結構化(Workflow、Job、Step)與依賴管理的內在邏輯,而將敏感資訊透過 Secrets 管理,更是確保自動化流程安全與合規的基礎實踐,直接關係到交付的可靠性。

展望未來,這種以程式碼定義(Code-defined)工作流程的思維,正從應用程式開發快速延伸至資料工程與機器學習維運(MLOps)領域。自動化測試、建置、發布的原則,將成為所有技術產出(不僅是軟體)的標準化流程,成為衡量團隊工程成熟度的關鍵指標。

玄貓認為,將 GitHub Actions 視為提升團隊工程效能與交付速度的基礎建設來投資,而非僅僅是一款自動化工具,是最大化其價值、並在激烈市場競爭中取得績效優勢的關鍵思維轉換。