From dc1c637ea67a82288ab57d9b0913d3d20baa6f38 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 27 Sep 2024 17:03:52 +0200 Subject: [PATCH] [devops] Rework how we hide GitHub comments. * Whenever we add a GitHub comment, also provide a comment id. * When adding a GitHub comment, use that comment id to hide any previous comments with the same id. It turns out this simplifies the code a lot, and additionally we now correctly hide every comment we report whenever a step or stage is re-executed. --- tools/devops/automation/scripts/GitHub.psm1 | 63 ++++++++++++++++--- .../scripts/clean_past_comments.ps1 | 36 ----------- .../automation/templates/api-diff-stage.yml | 12 ---- .../build/api-diff-process-results.yml | 2 +- .../automation/templates/build/build.yml | 2 +- .../automation/templates/common/clean.yml | 36 ----------- .../devops/automation/templates/mac/build.yml | 4 +- .../automation/templates/main-stage.yml | 15 ----- .../artifact-github-comment.yml | 2 +- .../automation/templates/tests-stage.yml | 12 ---- .../templates/tests/publish-html.yml | 8 +-- .../templates/tests/publish-results.yml | 2 +- .../automation/templates/windows/build.yml | 6 +- 13 files changed, 65 insertions(+), 135 deletions(-) delete mode 100644 tools/devops/automation/scripts/clean_past_comments.ps1 delete mode 100644 tools/devops/automation/templates/common/clean.yml diff --git a/tools/devops/automation/scripts/GitHub.psm1 b/tools/devops/automation/scripts/GitHub.psm1 index db3636044d8c..8225b4e4b0c2 100644 --- a/tools/devops/automation/scripts/GitHub.psm1 +++ b/tools/devops/automation/scripts/GitHub.psm1 @@ -294,7 +294,8 @@ class GitHubComments { } [void] WriteCommentFooter( - [object] $stringBuilder + [object] $stringBuilder, + [string] $commentId ) { $targetUrl = Get-TargetUrl $stringBuilder.AppendLine("[Pipeline]($targetUrl) on Agent $Env:TESTS_BOT") # Env:TESTS_BOT is added by the pipeline as a variable coming from the execute tests job @@ -308,12 +309,17 @@ class GitHubComments { $hashUrl= "https://github.com/$($this.Org)/$($this.Repo)/commit/$($this.Hash)" $hashSource = " [CI build]" } - $ciComment = "[comment]: <> (This is a comment added by Azure DevOps)" + $ciComment = $this.GetCommentIdentifier($commentId) $stringBuilder.AppendLine("Hash: [$($this.Hash)]($hashUrl) $hashSource") $stringBuilder.AppendLine("") $stringBuilder.AppendLine($ciComment) } + [string] GetCommentIdentifier([string] $commentId) + { + return "[comment]: <> (This is a comment added by Azure DevOps, id: $commentId)" + } + [string] GetCommentUrl() { # if the build was due to PR, we want to write the comment in the PR rather than in the commit if ([GitHubComments]::IsPR()) { @@ -360,11 +366,46 @@ class GitHubComments { return $request } + [void] HideComments( + [string] $commentId + ) { + if (!$commentId) { + Write-Host "Not hiding comments, because no comment id provided" + return + } + + if (![GitHubComments]::IsPR()) { + Write-Host "Not hiding comments, because we're not in a pull request" + return + } + + $prId = "$Env:BUILD_SOURCEBRANCH".Replace("refs/pull/", "").Replace("/merge", "") + $prComments = $this.GetCommentsForPR($prId) + + $botComments = [System.Collections.ArrayList]@() + $commentToHide = $this.GetCommentIdentifier($commentId) + + foreach ($c in $prComments) { + if ($c.Author -eq "vs-mobiletools-engineering-service2") { + if ($c.Body.Contains($CommentToHide)) { + $botComments.Add($c) + } + } + } + + Write-Host "Hiding $($botComments.Count) comments for PR #$prId with comment id '$commentId'" + + $this.MinimizeComments($botComments) + } + [object] NewCommentFromObject( [string] $commentTitle, [string] $commentEmoji, - [object] $commentObject + [object] $commentObject, + [string] $commentId ) { + $this.HideComments($commentId) + # build the message, which will be sent to github, users can use markdown $msg = [System.Text.StringBuilder]::new() @@ -376,7 +417,7 @@ class GitHubComments { $msg.AppendLine() # footer - $this.WriteCommentFooter($msg) + $this.WriteCommentFooter($msg, $commentId) return $this.NewComment($msg) } @@ -384,8 +425,11 @@ class GitHubComments { [object] NewCommentFromFile( [string] $commentTitle, [string] $commentEmoji, - [string] $filePath + [string] $filePath, + [string] $commentId ) { + $this.HideComments($commentId) + # build the message, which will be sent to github, users can use markdown $msg = [System.Text.StringBuilder]::new() @@ -404,7 +448,7 @@ class GitHubComments { $msg.AppendLine() # footer - $this.WriteCommentFooter($msg) + $this.WriteCommentFooter($msg, $commentId) return $this.NewComment($msg) } @@ -412,8 +456,11 @@ class GitHubComments { [object] NewCommentFromMessage( [string] $commentTitle, [string] $commentEmoji, - [string] $content + [string] $content, + [string] $commentId ) { + $this.HideComments($commentId) + $msg = [System.Text.StringBuilder]::new() # header @@ -424,7 +471,7 @@ class GitHubComments { $msg.AppendLine() # footer - $this.WriteCommentFooter($msg) + $this.WriteCommentFooter($msg, $commentId) return $this.NewComment($msg) } diff --git a/tools/devops/automation/scripts/clean_past_comments.ps1 b/tools/devops/automation/scripts/clean_past_comments.ps1 deleted file mode 100644 index c24e1be430ce..000000000000 --- a/tools/devops/automation/scripts/clean_past_comments.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -param -( - - [Parameter(Mandatory)] - [String] - $GithubToken, - - [Parameter(Mandatory)] - [String] - $RepositoryUri, - - [Parameter(Mandatory)] - [String] - $SourceBranch, - - [Parameter(Mandatory)] - [String] - $CommentToHide -) - -Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1 - -$comments = New-GitHubCommentsObjectFromUrl -Url "$RepositoryUri" -Token $GithubToken - -$prId = "$SourceBranch".Replace("refs/pull/", "").Replace("/merge", "") -$prComments = $comments.GetCommentsForPR($prId) - -$botComments = [System.Collections.ArrayList]@() -foreach ($c in $prComments) { - if ($c.Author -eq "vs-mobiletools-engineering-service2") { - if ($c.Body.Contains($CommentToHide)) { - $botComments.Add($c) - } - } -} -$comments.MinimizeComments($botComments) diff --git a/tools/devops/automation/templates/api-diff-stage.yml b/tools/devops/automation/templates/api-diff-stage.yml index 081a1f58e172..3fb0a7a00cb9 100644 --- a/tools/devops/automation/templates/api-diff-stage.yml +++ b/tools/devops/automation/templates/api-diff-stage.yml @@ -33,18 +33,6 @@ parameters: stages: -- ${{ if parameters.isPR }}: - - stage: clean - displayName: 'Clean up' - dependsOn: [] - jobs: - - job: - displayName: 'Clean comments' - pool: - vmImage: windows-latest - steps: - - template: ./common/clean.yml - - stage: configure_build displayName: 'Configure' jobs: diff --git a/tools/devops/automation/templates/build/api-diff-process-results.yml b/tools/devops/automation/templates/build/api-diff-process-results.yml index a73bcb9e572f..c8b3bf3cc8bb 100644 --- a/tools/devops/automation/templates/build/api-diff-process-results.yml +++ b/tools/devops/automation/templates/build/api-diff-process-results.yml @@ -84,7 +84,7 @@ steps: $converted = $inputContents + "`n`nUnable to convert markdown: $_`n`n" } $githubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $Env:GITHUB_TOKEN -Hash $Env:COMMENT_HASH - $result = $githubComments.NewCommentFromMessage("", "", $converted) + $result = $githubComments.NewCommentFromMessage("", "", $converted, "api diff") displayName: 'Publish GitHub comment for change detection' timeoutInMinutes: 10 continueOnError: true # don't let any failures here stop us diff --git a/tools/devops/automation/templates/build/build.yml b/tools/devops/automation/templates/build/build.yml index 7838afd4894c..a3e04f4ab466 100644 --- a/tools/devops/automation/templates/build/build.yml +++ b/tools/devops/automation/templates/build/build.yml @@ -205,7 +205,7 @@ steps: - pwsh: | Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1 $githubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $(GitHub.Token) -Hash $Env:COMMENT_HASH - $githubComments.NewCommentFromMessage("Build failed", ":fire:", "Build failed for the job '$(System.JobDisplayName)'") + $githubComments.NewCommentFromMessage("Build failed", ":fire:", "Build failed for the job '$(System.JobDisplayName)'", "build") condition: failed() displayName: 'Report build failure' env: diff --git a/tools/devops/automation/templates/common/clean.yml b/tools/devops/automation/templates/common/clean.yml deleted file mode 100644 index ea5849595778..000000000000 --- a/tools/devops/automation/templates/common/clean.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Perform gihub cleaning steps - -parameters: -- name: commentToHide - type: string - default: '[comment]: <> (This is a comment added by Azure DevOps)' - -- name: checkoutCode - type: boolean - default: true - -- name: repositoryAlias - type: string - default: self - -- name: commit - type: string - default: HEAD - -steps: - -- ${{ if parameters.checkoutCode }}: - - template: checkout.yml - parameters: - isPR: false # always use the latests version of the script - repositoryAlias: ${{ parameters.repositoryAlias }} - commit: ${{ parameters.commit }} - -- pwsh: >- - ./clean_past_comments.ps1 - -GithubToken "$(GitHub.Token)" - -RepositoryUri "$(Build.Repository.Uri)" - -SourceBranch "$(Build.SourceBranch)" - -CommentToHide "${{ parameters.commentToHide }}" - displayName: Clear past comments - workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts diff --git a/tools/devops/automation/templates/mac/build.yml b/tools/devops/automation/templates/mac/build.yml index 00e08489a799..504c68d79372 100644 --- a/tools/devops/automation/templates/mac/build.yml +++ b/tools/devops/automation/templates/mac/build.yml @@ -213,10 +213,10 @@ steps: $githubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $(GitHub.Token) -Hash $Env:COMMENT_HASH if (Test-Path -Path "$Env:GITHUB_FAILURE_COMMENT_FILE" -PathType Leaf) { - $githubComments.NewCommentFromFile("Tests on macOS ${{ parameters.statusContext }} failed", ":x:", "$Env:GITHUB_FAILURE_COMMENT_FILE") + $githubComments.NewCommentFromFile("Tests on macOS ${{ parameters.statusContext }} failed", ":x:", "$Env:GITHUB_FAILURE_COMMENT_FILE", "macOS ${{ parameters.statusContext }}") } else { $message = ":white_check_mark: **All** tests on macOS ${{ parameters.statusContext }} passed." - $githubComments.NewCommentFromMessage("Tests on macOS ${{ parameters.statusContext }} passed", ":computer:", $message) + $githubComments.NewCommentFromMessage("Tests on macOS ${{ parameters.statusContext }} passed", ":computer:", $message, "macOS ${{ parameters.statusContext }}") } displayName: 'Report results to GitHub' timeoutInMinutes: 5 diff --git a/tools/devops/automation/templates/main-stage.yml b/tools/devops/automation/templates/main-stage.yml index 47009cd3be4d..fe218dcc51e9 100644 --- a/tools/devops/automation/templates/main-stage.yml +++ b/tools/devops/automation/templates/main-stage.yml @@ -202,21 +202,6 @@ stages: commit: ${{ parameters.commit }} stageDisplayNamePrefix: ${{ parameters.stageDisplayNamePrefix }} - - ${{ if parameters.isPR }}: - - stage: clean - displayName: '${{ parameters.stageDisplayNamePrefix }}Clean up' - dependsOn: [] - jobs: - - job: - displayName: 'Clean comments' - pool: - name: AzurePipelines-EO - demands: - - ImageOverride -equals 1ESPT-Windows2022 - - steps: - - template: ./common/clean.yml - - stage: configure_build displayName: '${{ parameters.stageDisplayNamePrefix }}Configure' dependsOn: ${{ parameters.dependsOn }} diff --git a/tools/devops/automation/templates/sign-and-notarized/artifact-github-comment.yml b/tools/devops/automation/templates/sign-and-notarized/artifact-github-comment.yml index ca16f53215e2..75a7a6ae8731 100644 --- a/tools/devops/automation/templates/sign-and-notarized/artifact-github-comment.yml +++ b/tools/devops/automation/templates/sign-and-notarized/artifact-github-comment.yml @@ -29,7 +29,7 @@ steps: Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1 $artifact = New-ArtifactsFromJsonFile -Path "$Env:ARTIFACTS_JSON_PATH" $gihubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $Env:GITHUB_TOKEN -Hash $Env:COMMENT_HASH - $result = $gihubComments.NewCommentFromObject("Artifacts", ":books:", $artifact) + $result = $gihubComments.NewCommentFromObject("Artifacts", ":books:", $artifact, "artifacts") Write-Host $result env: GITHUB_TOKEN: $(GitHub.Token) diff --git a/tools/devops/automation/templates/tests-stage.yml b/tools/devops/automation/templates/tests-stage.yml index e54a23ee9cd7..8916e575cf35 100644 --- a/tools/devops/automation/templates/tests-stage.yml +++ b/tools/devops/automation/templates/tests-stage.yml @@ -163,18 +163,6 @@ parameters: stages: -- ${{ if parameters.isPR }}: - - stage: clean - displayName: '${{ parameters.stageDisplayNamePrefix }}Clean up' - dependsOn: [] - jobs: - - job: - displayName: 'Clean comments' - pool: - vmImage: windows-latest - steps: - - template: ./common/clean.yml - - stage: configure_build displayName: '${{ parameters.stageDisplayNamePrefix }}Configure' dependsOn: ${{ parameters.dependsOn }} diff --git a/tools/devops/automation/templates/tests/publish-html.yml b/tools/devops/automation/templates/tests/publish-html.yml index 7b0926fad01b..79d44e48d23f 100644 --- a/tools/devops/automation/templates/tests/publish-html.yml +++ b/tools/devops/automation/templates/tests/publish-html.yml @@ -49,12 +49,6 @@ steps: - template: download-artifacts.yml -- ${{ if parameters.isPR }}: - - template: ../common/clean.yml - parameters: - commentToHide: '[comment]: <> (This is a test result report added by Azure DevOps)' - checkoutCode: false # we already execute the 'clean.yml' template elsewhere in this job, and running 'checkout' again is useless (it also leads to duplicate step names which Azure DevOps doesn't like). - - pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 displayName: 'Show Environment' @@ -83,7 +77,7 @@ steps: } $gihubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $Env:GITHUB_TOKEN -Hash $Env:COMMENT_HASH -Debug - $result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults) + $result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults, "test results") } catch { Write-Host "##vso[task.complete result=Failed;]Failed to compute test summaries: $_" New-GitHubComment -Header "Failed to compute test summaries on $Env:CONTEXT" -Emoji ":fire:" -Description "Failed to compute test summaries: $_." diff --git a/tools/devops/automation/templates/tests/publish-results.yml b/tools/devops/automation/templates/tests/publish-results.yml index 02729046d4a2..a02fa11d5911 100644 --- a/tools/devops/automation/templates/tests/publish-results.yml +++ b/tools/devops/automation/templates/tests/publish-results.yml @@ -119,7 +119,7 @@ stages: $githubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $Env:GITHUB_TOKEN -Hash $Env:COMMENT_HASH -Debug $sb = [System.Text.StringBuilder]::new() $sb.AppendLine("All tests have been skipped because the label 'skip-all-tests' was set.") - $result = $githubComments.NewCommentFromMessage("Test results", ":seedling:", $sb.ToString()) + $result = $githubComments.NewCommentFromMessage("Test results", ":seedling:", $sb.ToString(), "test results") displayName: 'Set comment' env: CONTEXT: ${{ parameters.statusContext }} diff --git a/tools/devops/automation/templates/windows/build.yml b/tools/devops/automation/templates/windows/build.yml index 6f83e39da959..c8c39389992f 100644 --- a/tools/devops/automation/templates/windows/build.yml +++ b/tools/devops/automation/templates/windows/build.yml @@ -342,13 +342,13 @@ steps: $githubComments = New-GitHubCommentsObjectFromUrl -Url "$(Build.Repository.Uri)" -Token $(GitHub.Token) -Hash $Env:COMMENT_HASH if (Test-Path -Path "$Env:GITHUB_FAILURE_COMMENT_FILE" -PathType Leaf) { - $githubComments.NewCommentFromFile("${{ parameters.statusContext }} failed", ":x:", "$Env:GITHUB_FAILURE_COMMENT_FILE") + $githubComments.NewCommentFromFile("${{ parameters.statusContext }} failed", ":x:", "$Env:GITHUB_FAILURE_COMMENT_FILE", "windows tests") } elseif ("$($Env:AGENT_JOBSTATUS)" -ne "Succeeded") { $message = ":x: $($Env:AGENT_JOBSTATUS) :x:" - $githubComments.NewCommentFromMessage("${{ parameters.statusContext }} failed", ":x:", $message) + $githubComments.NewCommentFromMessage("${{ parameters.statusContext }} failed", ":x:", $message, "windows tests") } else { $message = ":white_check_mark: **All** ${{ parameters.statusContext }} passed." - $githubComments.NewCommentFromMessage("${{ parameters.statusContext }} passed", ":computer:", $message) + $githubComments.NewCommentFromMessage("${{ parameters.statusContext }} passed", ":computer:", $message, "windows tests") } displayName: 'Report results to GitHub' timeoutInMinutes: 5