Skip to content

dotnet format - apply changes #1932

dotnet format - apply changes

dotnet format - apply changes #1932

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 }}