Azure Pipeline内でソースを更新してPull Requestを自動生成する
仕事の関係で GitHub Actions よりも Azure Pipeline を色々と試しています。
AutoRest クライアントをパイプラインで自動的に更新しつつ Pull Request を作成して投げるものを作ったのでメモを書き残します。
パイプラインの構成
今回作成したパイプラインは
- Git Checkout して
- UseNode して
- UseDotNet して
- AutoRest 生成用の OpenAPI 定義 JSON をダウンロードして
- AutoRest クライアント生成して
- Git Commit & Push して
- Pull Request 作成して
という構成になっています。やっていることはとてもシンプルです。
実際の YAML はこちらに置いてあります。
https://gist.github.com/noxi515/9bc5749fccd04ebb6f459c2393e2162f
Git Checkout
- checkout: self clean: true persistCredentials: true
ソースをチェックアウトしているだけです。 persistCredentials
を設定することで Git 設定ファイルに OAuth トークンを保存することができ、このタスク以降も Git で Remote Repository に対してアクセス可能になります。
Use Node
- task: UseNode@1 inputs: version: '12.x'
AutoRest クライアントを生成するために使用する Node.js を指定&インストールします。
Use DotNet
- task: UseDotNet@2 inputs: packageType: sdk useGlobalJson: true
以前は DotNetCoreInstaller
タスクだった気がするのですが、いつの間にか名前が変わっていました。おこ。
AutoRest が内部で .NET Core SDK を使用するので .NET Core SDK もインストールします。今回は global.json
をレポジトリー内に用意しているので、そのバージョンを使用するように指定しました。
Download JSON File
- task: PowerShell@2 displayName: Download JSON File inputs: targetType: inline pwsh: true script: | $url = "https://example.com/swagger/v1/swagger.json" $fileName = "${env:AGENT_TEMPDIRECTORY}/${env:BUILD_BUILDNUMBER}_swagger.json" Invoke-RestMethod -Uri $url -OutFile $fileName
Windows でも Ubuntu でも、ホストに関係無く実行出来ることを期待して PowerShell Core なタスクです。
AutoRest の --input-file
に https を指定するとどうにも生成がうまくいかなかったため、一度 TEMP ディレクトリーに JSON ファイルをダウンロードします。
AutoRest クライアント生成
- task: PowerShell@2 displayName: Update ClientLibrary Code inputs: targetType: inline pwsh: true script: | $fileName = "${env:AGENT_TEMPDIRECTORY}/${env:BUILD_BUILDNUMBER}_swagger.json" npx autorest --csharp --add-credentials --clear-output-folder --namespace="ApiClient.Hoge" --input-file="$fileName" --output="./src/ApiClient.Hoge/generated"
AutoRest を使用してクライアントコードを生成します。
PowerShell Core のタスクとして npx から AutoRest のコマンドラインツールを実行しています。
一時ファイルのパスなどタスクを超えて使用する変数は、 Output Variable としてどこかで外に出した方がまとめやすいかもしれません。
Git Commit & Push
- task: PowerShell@2 displayName: Git Commit and Push inputs: targetType: inline pwsh: true script: | $branchName = "pr/client-update/ApiClient.Hoge/${env:BUILD_BUILDNUMBER}" git config --global user.email "tzo.ppl@gmail.com" git config --global user.name "noxi515" git checkout -b $branchName git add . git commit -m "Updaet client library code" git push origin $branchName
Git でビルド番号を元に新しいブランチをチェックアウトしてコミットし、リモートレポジトリーへプッシュをします。この時ユーザー名が未設定だと失敗するのでメールアドレスとユーザー名を Global に設定しています。
また Pipeline を実行する BuildService に対して Create branch
の権限を付与することも必要です(後述します)。
Pull Request の作成
- task: PowerShell@2 displayName: Create PR env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) inputs: targetType: inline pwsh: true script: | $body = @{ sourceRefName = "refs/heads/pr/client-update/ApiClient.Hoge/${env:BUILD_BUILDNUMBER}" targetRefName = "refs/heads/master" title = "Update client library (ApiClient.Hoge)" description = "" } $jsonBody = ConvertTo-Json $body $url = "${env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${env:SYSTEM_TEAMPROJECT}/_apis/git/repositories/${env:BUILD_REPOSITORY_NAME}/pullrequests?api-version=5.0" $headers = @{ Authorization = "Bearer ${env:SYSTEM_ACCESSTOKEN}" } Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $jsonBody -ContentType application/json
Azure DevOps の Pull Request 作成 API を実行します。 API の呼び出しは Pull Request を作成するタスクのソースを参考にしました。
なお API を実行するための AccessToken はタスクに対してこのように環境変数として定義しないと利用できません。
env: SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Pipeline 実行サービスへの権限付与
今回のパイプラインの中では Git の新しいブランチプッシュと Pull Request の生成を行っています。この2つを実行するには前者が Create branch
、 後者が Contribute to pull requests
の権限が必要になります。レポジトリーの設定から Xxx Build Service
に対してこの2つを Allow
に設定します。