共用方式為


使用 GitHub Actions 擴充管線

本文示範如何使用 GitHub Actions 和 Power Automate 雲端流程來擴充 Power Platform 中的管線。 提交管線部署時,雲端流程會觸發 GitHub 工作流程下載、解壓縮成品的原始程式碼,並將其認可到 GitHub 分支。

工作流程詳細資料

工作流程會透過 workflow_dispatch 事件觸發。 工作流程在 ubuntu-latest 上執行,並具有能夠將變更認可到 GitHub 存放庫分支的 contents: write 權限。

工作流程包含下列步驟:

  1. actions/checkout@v3:檢出存放庫。
  2. create new branch if specified:如果在輸入中指定了 target_branch,則建立一個新的分支。
  3. download solution from artifact:從管線建立的成品下載解決方案。
  4. unpack solution:解壓縮解決方案。
  5. commit changes:將變更提交到現有或新的分支。
  6. push to branch:將已提交的變更推送至來源分支。

工作流程輸入

以下工作流程輸入是必要的或選擇性的:

  • artifact_url (必要):管線建立的成品的 Microsoft Dataverse 資料列 (記錄) ID 的 URL。
  • solution_name (必要):Dataverse 環境中解決方案的名稱。
  • source_branch (必要):解決方案提交的分支。
  • target_branch (選用):為解決方案提交建立的分支。 如果未指定,系統會使用 source_branch
  • commit_message (必要):提供提交的訊息。

工作流程密碼

使用在 Dataverse 和 Microsoft Entra ID (AD) 中設定的應用程式使用者連線到 Dataverse需要以下密碼。 在 GitHub 存放庫設定中設定這些密碼。

  • CLIENT_ID:已註冊 Microsoft Entra 應用程式的用戶端ID。
  • TENANT_ID:與 Microsoft Entra 應用程式關聯的 Microsoft Entra 目錄的租用戶 ID。
  • CLIENT_SECRET:已註冊 Microsoft Entra 應用程式的用戶端密碼。

有關更多資訊,請前往建立和使用加密密碼建立應用程式使用者

工作流程程式碼

下面列出的是 GitHub Actions 工作流程程式碼。

name: Download, unpack and commit the solution to git
run-name: Getting ${{ github.event.inputs.solution_name }} from pipelines host environment and committing
on:
  workflow_dispatch:
    inputs:
      artifact_url:
        description: "The url of the Dataverse record ID for the artifact created by the pipelines (Example: https://[your-env].crm.dynamics.com/api/data/v9.0/deploymentartifacts([your-artifact-id])/artifactfile/$value)."
        required: true
      solution_name:
        description: "Name of the Solution in Dataverse environment"
        required: true
      user_name: 
        description: "User name for the commit"
        required: true
      source_branch:
        description: "Branch for the solution commit"
        required: true
      target_branch:
        description: "Branch to create for the solution commit"
        required: false
      commit_message:
        description: "Message to provide for the commit"
        required: true
permissions:
  contents: write
jobs:
  export-unpack-commit:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
            ref: ${{ github.event.inputs.source_branch }}

      # Commit changes to the existing or new branch
      - name: create new branch if specified
        shell: pwsh
        run: |
            if('${{ github.event.inputs.target_branch }}' -ne '') {
                git checkout -b ${{ github.event.inputs.target_branch }} ${{ github.event.inputs.source_branch }}
            }

      # Export the solution from the artifact created by pipelines
      - name: download solution from artifact
        env:
            CLIENT_ID: ${{secrets.CLIENT_ID}}   
            TENANT_ID: ${{secrets.TENANT_ID}}   
            CLIENT_SECRET: ${{secrets.CLIENT_SECRET}}
        shell: pwsh
        run: |
            $aadHost = "login.microsoftonline.com"
            $url = "${{ github.event.inputs.artifact_url }}"
            $options = [System.StringSplitOptions]::RemoveEmptyEntries
            $dataverseHost = $url.Split("://", $options)[1].Split("/")[0]

            $body = @{client_id = $env:CLIENT_ID; client_secret = $env:CLIENT_SECRET; grant_type = "client_credentials"; scope = "https://$dataverseHost/.default"; }
            $OAuthReq = Invoke-RestMethod -Method Post -Uri "https://$aadHost/$env:TENANT_ID/oauth2/v2.0/token" -Body $body
            $spnToken = $OAuthReq.access_token
            $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
            $headers.Add("Authorization", "Bearer $spnToken")
            $headers.Add("Content-Type", "application/json")

            # Download the managed solution
            $response = Invoke-RestMethod "${{ github.event.inputs.artifact_url }}" -Method 'GET' -Headers $headers
            $bytes = [Convert]::FromBase64String($response.value)
            [IO.File]::WriteAllBytes("${{ github.event.inputs.solution_name }}_managed.zip", $bytes)

            # Download the unmanaged solution (for now we will need to use string manipulation to get the unmanaged solution URL, until the API provides this value)
            $unmanaged_artifact_url = "${{ github.event.inputs.artifact_url }}".Replace("artifactfile", "artifactfileunmanaged")
            $response = Invoke-RestMethod "$unmanaged_artifact_url" -Method 'GET' -Headers $headers
            $bytes = [Convert]::FromBase64String($response.value)
            [IO.File]::WriteAllBytes("${{ github.event.inputs.solution_name }}.zip", $bytes)

      # Unpack the solution
      - name: unpack solution
        uses: microsoft/powerplatform-actions/unpack-solution@v0
        with:
          solution-file: "${{ github.event.inputs.solution_name }}.zip"
          solution-folder: "${{ github.event.repository.name }}"
          solution-type: 'Both'
          process-canvas-apps: false
          overwrite-files: true

      # Commit changes to the existing or new branch
      - name: commit changes
        shell: pwsh
        run: |
          rm -rf ${{ github.event.inputs.solution_name }}.zip
          rm -rf ${{ github.event.inputs.solution_name }}_managed.zip
          git config user.name ${{ github.event.inputs.user_name }}
          git pull 
          git add --all
          git commit -am "${{ github.event.inputs.commit_message }}" --allow-empty

      # Push the committed changes to the source branch
      - name: push to branch
        shell: pwsh
        run: |
          if('${{ github.event.inputs.target_branch }}' -ne '') {
              git push origin ${{ github.event.inputs.target_branch }}
          } else {
              git push origin ${{ github.event.inputs.source_branch }}
          }

注意

用於下載解決方案成品的 Dataverse Web API,其最大檔案大小限制為 16 MB。

Power Automate 流程範例

若要呼叫 GitHub 工作流程,您可以建立在 Dataverse 中發出部署要求時觸發的 Power Automate 流程。 可以將該流程設定為將所需的輸入傳遞給 GitHub 工作流程。 有關如何建立 Power Automate 流程的更多資訊,請前往建立流程

流程詳細資料

當在 Dataverse 中執行 OnDeploymentRequested 動作時會觸發該流程。 該流程會呼叫 HTTP 連接器來觸發 GitHub 工作流程。 該流程會將所需的輸入傳遞給 GitHub 工作流程。 在要求本文包含以下輸入:

  • artifact_url:管線建立的 Dataverse 解決方案成品的 URL。
  • solution_name:Dataverse 環境中解決方案的名稱。
  • user_name:提交的使用者名。
  • source_branch:解決方案提交的來源分支。
  • target_branch:為解決方案提交已建立的分支。
  • commit_message:提供提交的訊息。

傳遞給 artifact_urlsolution_nameuser_name 的值是從觸發管線之動作的輸出中提取的。 commit_message 是從 Dataverse 中的部署階段執行資料列中提取的。

  • artifact_url@{triggerOutputs()?['body/OutputParameters/ArtifactFileDownloadLink']}
  • solution_name@{triggerOutputs()?['body/OutputParameters/ArtifactName']}
  • user_name@{triggerOutputs()?['body/OutputParameters/DeployAsUser']}
  • commit_message@{outputs('Retrieve_the_Deployment_Stage_Run')?['body/deploymentnotes']}

該流程還使用個人存取權杖 (PAT) 向 GitHub 進行驗證。 有關如何建立 GitHub 個人存取權杖的更多資訊,請前往建立個人存取權杖。 PAT 在 HTTP 要求的 Authorization 標題中傳遞。

更新流程中的以下值:

  • [GitHub Personal Access Token] - 替換為您的 GitHub 個人存取權權杖。
  • [GitHub Organization] - 替換為您的 GitHub 組織名稱。
  • [GitHub Repository] - 替換為您的 GitHub 存放庫名稱。
  • [GitHub Workflow YAML File] - 替換為您的 GitHub 工作流程 YAML 檔案名稱。
  • [Source Branch] - 用 Git 分支替換來提交解決方案。
  • [Target Branch] - 替換為 Git 分支來為解決方案提交建立。 Target Branch 是選擇性的。 如果未指定目標分支,則解決方案將認可到 Source Branch

Power Automate 流程顯示 OnDeploymentRequested 觸發程序 ,其中包含擷取關聯的部署階段執行,並使用 HTTP 連接器呼叫 GitHub 工作流程的步驟

後續步驟

執行 Power Platform 中的管線

另請參閱

GitHub Actions 快速入門
在 Power Platform 中擴充管線
什麼是雲端流程?