dotnet format - apply changes #1939
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: dotnet format - apply changes | |
on: | |
workflow_run: | |
workflows: ["dotnet format"] | |
types: | |
- completed | |
defaults: | |
run: | |
shell: pwsh | |
env: | |
DOTNET_FORMAT_WORKFLOW_INFO_ARTIFACT : dotnet-format-workflow-info | |
DOTNET_FORMAT_FILES_ARTIFACT : dotnet-format-files | |
DOTNET_FORMAT_LABEL : dotnet-format | |
WORKFLOW_HEAD_SHA : ${{ github.event.workflow_run.head_sha }} | |
jobs: | |
on-push-check: | |
name: Check for dotnet format open PR | |
if: github.event.workflow_run.event == 'push' | |
permissions: | |
contents: read | |
pull-requests: read | |
runs-on: ubuntu-latest | |
outputs: | |
has-changes: ${{ steps.dotnet-format-workflow-info.outputs.has-changes }} | |
workflow: ${{ steps.dotnet-format-workflow-info.outputs.workflow }} | |
workflow-url: ${{ steps.dotnet-format-workflow-info.outputs.workflow-url }} | |
can-create-pr: ${{ steps.open-pr-check.outputs.can-create-pr }} | |
can-apply-changes: ${{ steps.check-can-apply.outputs.can-apply-changes }} | |
steps: | |
- name: Dump github context for debug purposes | |
env: | |
GITHUB_CONTEXT: ${{ toJSON(github) }} | |
run: $env:GITHUB_CONTEXT | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ env.WORKFLOW_HEAD_SHA }} | |
- name: Download dotnet format workflow info artifact | |
uses: dawidd6/action-download-artifact@v6 | |
with: | |
name: ${{ env.DOTNET_FORMAT_WORKFLOW_INFO_ARTIFACT }} | |
run_id: ${{ github.event.workflow_run.id }} | |
- name: Read dotnet format workflow info | |
id: dotnet-format-workflow-info | |
run: | | |
$worfklowInfoFilePath = "./dotnet-format-workflow-info.json" | |
$workflowInfoJson = Get-Content $worfklowInfoFilePath | |
Write-Output $workflowInfoJson | |
$workflowInfo = $workflowInfoJson | ConvertFrom-Json | |
Write-Output "has-changes=$($workflowInfo.hasChanges)" >> $env:GITHUB_OUTPUT | |
Write-Output "workflow=$($workflowInfo.workflow)" >> $env:GITHUB_OUTPUT | |
Write-Output "workflow-url=$($workflowInfo.workflowUrl)" >> $env:GITHUB_OUTPUT | |
- name: Check for open dotnet format PRs | |
id: open-pr-check | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Only create a PR if there isn't any dotnet format PR open. This prevents multiple pull requests being open to fix dotnet format issues. | |
# Once one is merged, the workflows will create more dotnet format PRs if needed. | |
$openPullRequestsResult = gh pr list --state open --label ${{ env.DOTNET_FORMAT_LABEL }} | |
$canCreatePr = [string]::IsNullOrEmpty($openPullRequestsResult) | |
Write-Output "can-create-pr=$canCreatePr" >> $env:GITHUB_OUTPUT | |
- name: Check if can apply changes | |
id: check-can-apply | |
run: | | |
$hasChanges = [System.Convert]::ToBoolean("${{ steps.dotnet-format-workflow-info.outputs.has-changes }}") | |
$canCreatePr = [System.Convert]::ToBoolean("${{ steps.open-pr-check.outputs.can-create-pr }}") | |
$canApplyChanges = $canCreatePr -and $hasChanges | |
Write-Output "can-apply-changes=$canApplyChanges" >> $env:GITHUB_OUTPUT | |
- name: Log info | |
run: | | |
$hasChanges = [System.Convert]::ToBoolean("${{ steps.dotnet-format-workflow-info.outputs.has-changes }}") | |
$canCreatePr = [System.Convert]::ToBoolean("${{ steps.open-pr-check.outputs.can-create-pr }}") | |
$canApplyChanges = [System.Convert]::ToBoolean("${{ steps.check-can-apply.outputs.can-apply-changes }}") | |
if(!$hasChanges) { | |
Write-Output "::notice::dotnet format did NOT detect code guidelines violations." | |
} | |
elseif($hasChanges -and $canCreatePr) { | |
Write-Output "::warning::dotnet format detected code guidelines violations and so a PR will be created with the changes." | |
} | |
elseif($hasChanges -and !$canCreatePr) { | |
Write-Output "::warning::dotnet format detected code guidelines violations but a PR from dotnet format is already open so a new one will not be created. Only one dotnet format PR can be open at a time." | |
} | |
on-push-dotnet-format: | |
name: Process dotnet format changes on push | |
needs: [on-push-check] | |
if: needs.on-push-check.outputs.can-apply-changes == 'true' | |
permissions: | |
contents: write | |
pull-requests: write | |
runs-on: ubuntu-latest | |
env: | |
WORKFLOW: ${{ needs.on-push-check.outputs.workflow }} | |
WORKFLOW_URL: ${{ needs.on-push-check.outputs.workflow-url }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ env.WORKFLOW_HEAD_SHA }} | |
- name: Prepare commit info | |
id: commit-info | |
run: | | |
$date = (Get-Date).ToString("dd-MMM-yyyy") | |
$branchName = "dotnet-format-$date" | |
$commitMessage = "auto dotnet format $date" | |
Write-Output "branch-name=$branchName" >> $env:GITHUB_OUTPUT | |
Write-Output "Branch name set to $branchName" | |
Write-Output "commit-message=$commitMessage" >> $env:GITHUB_OUTPUT | |
Write-Output "Commit message set to $commitMessage" | |
- name: Git checkout new branch | |
run: | | |
git checkout -b ${{ steps.commit-info.outputs.branch-name }} | |
- name: Download dotnet format changed files | |
uses: dawidd6/action-download-artifact@v6 | |
with: | |
name: ${{ env.DOTNET_FORMAT_FILES_ARTIFACT }} | |
run_id: ${{ github.event.workflow_run.id }} | |
- name: Push dotnet format changes to branch | |
id: auto-commit-action | |
uses: stefanzweifel/git-auto-commit-action@v5 | |
with: | |
commit_message: ${{ steps.commit-info.outputs.commit-message }} | |
branch: ${{ steps.commit-info.outputs.branch-name }} | |
- name: Render PR body template | |
uses: yukitsune/template-cli@v0.1.0 | |
with: | |
args: --input .github/workflows/templates/dotnet-format-apply-changes/dotnet-format-found-changes-pr-body.md \ | |
--value "workflow=${{ env.WORKFLOW }}" \ | |
--value "workflowUrl=${{ env.WORKFLOW_URL }}" \ | |
--value "commitSha=${{ env.WORKFLOW_HEAD_SHA }}" \ | |
--output . | |
- name: Set render PR body template as step output | |
id: render-pr-body-template | |
run: | | |
$fileContent = Get-Content ./dotnet-format-found-changes-pr-body.md | |
$random = Get-Random | |
$delimiter = "EOF_$random" | |
Write-Output "result<<$delimiter" >> $env:GITHUB_OUTPUT | |
Write-Output $fileContent >> $env:GITHUB_OUTPUT | |
Write-Output $delimiter >> $env:GITHUB_OUTPUT | |
- name: Create dotnet format PR | |
id: create-pr | |
env: | |
GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_SCOPE_GH_TOKEN }} | |
run: | | |
$title = "${{ steps.commit-info.outputs.branch-name }}: fix code guidelines violations" | |
$body = @' | |
${{ steps.render-pr-body-template.outputs.result }} | |
'@ | |
$prUrl = gh pr create ` | |
--title $title ` | |
--body $body ` | |
--label ${{ env.DOTNET_FORMAT_LABEL }} ` | |
--label bot:robot: | |
Write-Output "pr-url=$prUrl" >> $env:GITHUB_OUTPUT | |
- name: Log info | |
run: | | |
$prUrl = "${{ steps.create-pr.outputs.pr-url }}" | |
Write-Output "::warning title=dotnet format::A PR with the fixes for the code guidelines violations was created at $prUrl." | |
on-pull-request-check: | |
name: Check if there are dotnet format changes for the PR | |
if: github.event.workflow_run.event == 'pull_request' | |
permissions: | |
contents: read | |
runs-on: ubuntu-latest | |
outputs: | |
has-changes: ${{ steps.dotnet-format-workflow-info.outputs.has-changes }} | |
workflow: ${{ steps.dotnet-format-workflow-info.outputs.workflow }} | |
workflow-url: ${{ steps.dotnet-format-workflow-info.outputs.workflow-url }} | |
pr-number: ${{ steps.dotnet-format-workflow-info.outputs.pr-number }} | |
pr-branch-name: ${{ steps.dotnet-format-workflow-info.outputs.pr-branch-name }} | |
steps: | |
- name: Dump github context for debug purposes | |
env: | |
GITHUB_CONTEXT: ${{ toJSON(github) }} | |
run: $env:GITHUB_CONTEXT | |
- name: Download dotnet format workflow info artifact | |
uses: dawidd6/action-download-artifact@v6 | |
with: | |
name: ${{ env.DOTNET_FORMAT_WORKFLOW_INFO_ARTIFACT }} | |
run_id: ${{ github.event.workflow_run.id }} | |
- name: Read dotnet format workflow info | |
id: dotnet-format-workflow-info | |
run: | | |
$worfklowInfoFilePath = "./dotnet-format-workflow-info.json" | |
$workflowInfoJson = Get-Content $worfklowInfoFilePath | |
Write-Output $workflowInfoJson | |
$workflowInfo = $workflowInfoJson | ConvertFrom-Json | |
$hasChanges = $workflowInfo.hasChanges | |
$workflow = $workflowInfo.workflow | |
$workflowUrl = $workflowInfo.workflowUrl | |
$prNumber = $workflowInfo.prNumber | |
$prBranchName = $workflowInfo.prBranchName | |
Write-Output "has-changes=$hasChanges" >> $env:GITHUB_OUTPUT | |
Write-Output "workflow=$workflow" >> $env:GITHUB_OUTPUT | |
Write-Output "workflow-url=$workflowUrl" >> $env:GITHUB_OUTPUT | |
Write-Output "pr-number=$prNumber" >> $env:GITHUB_OUTPUT | |
Write-Output "pr-branch-name=$prBranchName" >> $env:GITHUB_OUTPUT | |
- name: Log info | |
run: | | |
$hasChanges = [System.Convert]::ToBoolean("${{ steps.dotnet-format-workflow-info.outputs.has-changes }}") | |
$prUrl = "https://github.com/${{ github.repository }}/pull/${{ steps.dotnet-format-workflow-info.outputs.pr-number }}" | |
if(!$hasChanges) { | |
Write-Output "::notice title=dotnet format::dotnet format did NOT detect code guidelines violations on the PR at $prUrl." | |
} | |
on-pull-request-format: | |
name: Process dotnet format changes on PR | |
needs: [on-pull-request-check] | |
if: needs.on-pull-request-check.outputs.has-changes == 'true' | |
permissions: | |
pull-requests: write | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ env.WORKFLOW_HEAD_SHA }} | |
# The token gets saved and further git commands will use this token. See https://github.com/marketplace/actions/checkout#usage. | |
# The step that commits the dotnet format changes to the PR will make use of this token and if it's not a custom token then the | |
# PR triggers aren't executed again. See https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow | |
token: ${{ secrets.PUBLIC_REPO_SCOPE_GH_TOKEN }} | |
- name: Download dotnet format changed files | |
uses: dawidd6/action-download-artifact@v6 | |
with: | |
name: ${{ env.DOTNET_FORMAT_FILES_ARTIFACT }} | |
run_id: ${{ github.event.workflow_run.id }} | |
- name: Push dotnet format changes | |
id: auto-commit-action | |
uses: stefanzweifel/git-auto-commit-action@v5 | |
with: | |
branch: ${{ needs.on-pull-request-check.outputs.pr-branch-name }} | |
commit_message: dotnet format from workflow for PR ${{ needs.on-pull-request-check.outputs.pr-number }} | |
- name: Get dotnet format commit SHA | |
id: dotnet-format-commit | |
run: | | |
$commitSha = git rev-parse HEAD | |
Write-Output "commit-sha=$commitSha" >> $env:GITHUB_OUTPUT | |
- name: Render comment template | |
uses: yukitsune/template-cli@v0.1.0 | |
with: | |
args: --input .github/workflows/templates/dotnet-format-apply-changes/dotnet-format-found-changes-pr-comment.md \ | |
--value "workflow=${{ needs.on-pull-request-check.outputs.workflow }}" \ | |
--value "workflowUrl=${{ needs.on-pull-request-check.outputs.workflow-url }}" \ | |
--value "commitSha=${{ env.WORKFLOW_HEAD_SHA }}" \ | |
--value "pushedCommitSha=${{ steps.dotnet-format-commit.outputs.commit-sha }}" \ | |
--value "pushWorkflowUrl=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ | |
--output . | |
- name: Set render comment template as step output | |
id: render-pr-comment-template | |
run: | | |
$fileContent = Get-Content ./dotnet-format-found-changes-pr-comment.md | |
$random = Get-Random | |
$delimiter = "EOF_$random" | |
Write-Output "result<<$delimiter" >> $env:GITHUB_OUTPUT | |
Write-Output $fileContent >> $env:GITHUB_OUTPUT | |
Write-Output $delimiter >> $env:GITHUB_OUTPUT | |
- name: Update PR with dotnet format result | |
uses: edumserrano/find-create-or-update-comment@v3 | |
with: | |
issue-number: ${{ needs.on-pull-request-check.outputs.pr-number }} | |
body-includes: '<!-- on-pr-dotnet-format -->' | |
comment-author: github-actions[bot] | |
body: ${{ steps.render-pr-comment-template.outputs.result }} | |
edit-mode: replace | |
- name: Log info | |
run: | | |
$prUrl = "https://github.com/${{ github.repository }}/pull/${{ needs.on-pull-request-check.outputs.pr-number }}" | |
Write-Output "::warning title=dotnet format::dotnet format detected code guidelines violations and a commit was pushed to the PR at $prUrl." | |
on-pull-request-update-status-check: | |
name: Update PR status check | |
needs: [on-pull-request-check, on-pull-request-format] | |
if: github.event.workflow_run.event == 'pull_request' && always() # only run on PRs but run even if the previous steps weren't all executed/sucessful | |
permissions: | |
statuses: write | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ env.WORKFLOW_HEAD_SHA }} | |
- name: Set status check data | |
id: status-check-data | |
run: | | |
$prCheckJobResult = '${{ needs.on-pull-request-check.result }}' | |
$prFormatJobResult = '${{ needs.on-pull-request-format.result }}' | |
if($prCheckJobResult -eq 'failure' -or $prFormatJobResult -eq 'failure' -or $prCheckJobResult -eq 'cancelled' -or $prFormatJobResult -eq 'cancelled') { | |
$state = 'error' | |
$description = 'Error' | |
} | |
elseif($prFormatJobResult -eq 'skipped') { | |
$state = 'success' | |
$description = 'Skipped' | |
} | |
elseif($prFormatJobResult -eq 'success') { | |
$state = 'success' | |
$description = 'Successful' | |
} | |
else{ | |
Write-Output "::error::Couldn't define the status check for the PR. Unexpected combination of results from dependant jobs." | |
Exit 1 | |
} | |
Write-Output "state=$state" >> $env:GITHUB_OUTPUT | |
Write-Output "description=$description" >> $env:GITHUB_OUTPUT | |
- name: Set PR status | |
uses: ./.github/actions/create-gh-status | |
with: | |
repo: ${{ github.repository }} | |
pr-num: ${{ needs.on-pull-request-check.outputs.pr-number }} | |
context: '${{ github.workflow }} / apply dotnet format (${{ github.event_name }})' # mimic format from github | |
state: '${{ steps.status-check-data.outputs.state }}' | |
description: '${{ steps.status-check-data.outputs.description }}' | |
target-url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
token: ${{ secrets.GITHUB_TOKEN }} |