使用可重複使用的工作流程來處理環境之間的相似處
當您將變更部署到多個環境時,部署到每個環境所涉及的步驟都很類似,或甚至相同。 在此單元中,您將了解如何設計工作流程以避免重複,並讓工作流程的程式碼可重複使用。
部署到多個環境
與網站小組的同事談過之後,您決定將下列工作流程用在您玩具公司的網站上:
工作流程會執行 Bicep Linter,來檢查 Bicep 程式碼是否有效且遵循最佳做法。
對 Bicep 程式碼執行 Lint 分析不需要連線至 Azure,因此部署至多少個環境無所謂。 它只會執行一次。
工作流程會部署到測試環境,並要求:
- 執行 Azure Resource Manager 預檢驗證。
- 部署 Bicep 程式碼。
- 對測試環境執行一些測試。
如果工作流程的任何部分失敗,則整個工作流程就會停止,以方便您調查並解決問題。 但若一切順利,工作流程就會繼續部署到實際執行環境:
- 工作流程包含一個預覽步驟,其會在實際執行環境上執行假設狀況作業,以列出將對您生產 Azure 資源所做的變更。 假設狀況作業也會驗證部署,因此不需要對實際執行環境另外執行驗證步驟。
- 工作流程會暫停,以進行手動驗證。
- 如果獲准,工作流程就會對實際執行環境執行部署和煙霧測試。
這其中一些工作會在測試與實際執行環境之間重複,而有些僅會針對特定環境執行:
Task | 環境 |
---|---|
Lint | 兩者皆否 - 不會對環境執行 Lint 分析 |
Validate | 僅測試 |
預覽 | 僅生產 |
部署 | 這兩個環境 |
煙霧測試 | 這兩個環境 |
若您必須在工作流程中重複步驟,複製再貼上步驟定義不是很好的做法。 當您複製工作流程的程式碼時,一不小心就會發生難以察覺的錯誤,或造成不同步的情況。 日後需要變更步驟時,您必須想起在很多地方套用變更。 較佳的做法是利用可重複使用的工作流程。
可重複使用的工作流程
GitHub Actions 讓您能夠透過建立可定義步驟或作業的個別工作流程 YAML 檔案,來建立可重複使用的工作流程定義區段。 您可以建立 YAML 檔案,以便在單一工作流程內,甚至在多個工作流程中,多次重複使用工作流程的各個部分。 您重複使用的工作流程是「已呼叫的工作流程」,而包含該工作流程的工作流程為「呼叫者工作流程」。 以概念來看,您可以將它們視為類似於 Bicep 模組。
當您建立可重複使用的工作流程時,可以使用 workflow_call
觸發程序來告訴 GitHub Actions,可透過其他工作流程呼叫該工作流程。 以下是可重複使用工作流程的基本範例,其儲存於名為 script.yml 的檔案中:
on:
workflow_call:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello world!
在呼叫者工作流程中,您可以透過包含 uses:
關鍵字並指定已在目前存放庫中呼叫的工作流程路徑,來參考已呼叫的工作流程:
on:
workflow_dispatch:
jobs:
job:
uses: ./.github/workflows/script.yml
您也可以參考另一個存放庫中的工作流程定義檔。
已呼叫的工作流程輸入和祕密
您可以使用「輸入」和「祕密」,讓您的已呼叫工作流程更容易重複使用,因為您可以在使用它們時允許工作流程中的微小差異。
當您建立已呼叫的工作流程時,可以在檔案頂端註明其輸入和祕密:
on:
workflow_call:
inputs:
environmentType:
required: true
type: string
secrets:
AZURE_CLIENT_ID:
required: true
AZURE_TENANT_ID:
required: true
AZURE_SUBSCRIPTION_ID:
required: true
您可以視需要定義任意多個的輸入和祕密。 但就像 Bicep 參數一樣,盡量不要過度使用工作流程輸入。 您應該讓其他人不需指定太多設定,就能輕鬆地重複使用您的工作流程。
輸入可以有數個屬性,包括:
- 輸入「名稱」,您用來表示工作流程定義中的輸入。
- 輸入「類型」。 輸入支援「字串」、「數字」和「布林值」的值。
- 輸入的「預設值」,這是選用的。 如果您未指定預設值,則必須在呼叫者工作流程中使用工作流程時提供值。
祕密具有名稱,但沒有類型或預設值。
在範例中,工作流程會定義名為 environmentType
的強制字串輸入,以及三個名為 AZURE_CLIENT_ID
、AZURE_TENANT_ID
及 AZURE_SUBSCRIPTION_ID
的強制祕密。
在您的工作流程中,使用了特殊語法來參考參數的值,如下列範例所示:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello ${{ inputs.environmentType }}!
您使用 with
關鍵字,將輸入的值傳入已呼叫的工作流程。 您必須定義 with
區段中每個輸入的值,您無法使用 env
關鍵字來參考工作流程的環境變數。 您使用 secrets
關鍵字,將祕密值傳入已呼叫的工作流程。
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
job-test:
uses: ./.github/workflows/script.yml
with:
environmentType: Test
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
job-production:
uses: ./.github/workflows/script.yml
with:
environmentType: Production
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
使用來自已呼叫工作流程的工作負載身分識別
當您使用已呼叫的工作流程時,通常會在多個工作流程定義檔案之間定義一些部署動作。 您必須將權限授與呼叫者工作流程,然後確保每個已呼叫的工作流程都能存取工作流程的身分識別,並向 Azure 進行驗證:
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
job-test:
uses: ./.github/workflows/script.yml
with:
environmentType: Test
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
job-production:
uses: ./.github/workflows/script.yml
with:
environmentType: Production
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
條件
您可以使用工作流程「條件」,來指定步驟或作業是否應根據您指定的規則來執行。 您可以合併輸入和工作流程條件來自訂部署流程,以因應多種情況。
例如,假設您定義了一個用於執行指令碼步驟的工作流程。 您打算對每個環境重複使用範本。 當您部署實際執行環境時,您希望執行另一個步驟。 以下是可對步驟使用 if
條件來達成該目標的方式:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello ${{ inputs.environmentType }}!
- run: |
echo This step only runs for production deployments.
if: inputs.environmentType == 'Production'
此處的條件可翻譯為:「如果 environmentType 參數的值等於 'Production',則執行步驟」。
雖然條件可以增加工作流程的彈性,但太多條件可能會使工作流程複雜化而難以理解。 如果您在所謂的工作流程中有許多條件,您可能會想要重新設計工作流程。
此外,請使用 YAML 註解說明您使用的條件,以及工作流程中可能需要進一步說明的其他任何層面。 註解有助於讓工作流程變得更加簡單易懂,日後更易於使用。 在這整個課程模組的練習中,提供了一些 YAML 註解範例。