前回はこちら。

GitHubへのコミット
前回作成したPower Platformのデプロイ用のパイプラインを拡張し、GitHubにソリューションをコミットしてみる。 基本的には以下の公式の手順と一緒だけど、一部変更が必要。公式

構築
- EntraIDへのアプリ登録
- Power Platform環境にアプリケーションユーザーの登録
- GitHub:リポジトリ作成→Actionsの作成
- GitHub:アクセストークン作成
- Power Automate構築:GitHubのAPIコール
EntraIDへの登録
- クライアントシークレット
- クライアントID(アプリID)
- テナントID








Power Platform環境にアプリケーションユーザーの登録
続いて、Power Platformの環境にアプリケーションユーザーを作成し、GitHubへDataverseへのセキュリティロールを与える。



※セキュリティロールはSystem Customizerで確実に動作するけど、権限を最低限にしたい場合はカスタムロールの作成を推奨。

GitHub:リポジトリ作成→Actionsの作成
リポジトリ作成

Actions設定


# 変更前
# 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
# 変更後(unpack-solutionがv0だと動かなかったので、v1を使用)
# Install PAC
- name: Install Power Platform Tools
uses: microsoft/powerplatform-actions/actions-install@v1
# Unpack the solution
- name: unpack solution
uses: microsoft/powerplatform-actions/unpack-solution@v1
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
以下全文。
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)
# Install PAC
- name: Install Power Platform Tools
uses: microsoft/powerplatform-actions/actions-install@v1
# Unpack the solution
- name: unpack solution
uses: microsoft/powerplatform-actions/unpack-solution@v1
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 }}
}
リポジトリにシークレットを登録

- CLIENT_ID : クライアントID
- CLIENT_SECRET:シークレット
- TENANT_ID:テナントID

GitHub:アクセストークンの作成





Power Automate構築:GitHubのAPIコール

※公式リファレンスに記載のある「OnDeploymentRequested」だと問題が発生する場合があるけど、ひとまずこれで。


URL:~~~/repos/【テナント(ユーザー)名】/【リポジトリ名】/actions/workflows/【ワークフローファイル名】/dispatches
ヘッダ:Authorization : Bearer 【Githubアクセストークン】
Bodyは以下の通り。 ※source_branchとtarget_branchは必要に応じて設定を変えてください。
{
"ref": "main",
"inputs": {
"artifact_url": "@{triggerOutputs()?['body/OutputParameters/ArtifactFileDownloadLink']}",
"solution_name": "@{triggerOutputs()?['body/OutputParameters/ArtifactName']}",
"user_name": "@{triggerOutputs()?['body/OutputParameters/DeployAsUser']}",
"source_branch": "main",
"commit_message": "@{outputs('ID_で行を取得する')?['body/deploymentnotes']}"
}
}
動作確認






Actionsが失敗することもある



ちょっと長くなってしまったので、もしこれが起きた場合の対処方法については次回。
コメント