-
Notifications
You must be signed in to change notification settings - Fork 178
Add PowerShell script to add review comments on PRs modifying release notes #2058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Copilot
wants to merge
31
commits into
main
Choose a base branch
from
copilot/comment-release-notes-prs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
9c696ca
Initial plan
Copilot 2c0e4da
Add workflow and script to comment on release notes PRs
Copilot 3804759
Add documentation for release notes PR automation
Copilot 72ddc4e
Add manual workflow to comment on existing release notes PRs
Copilot e43f26b
Auto-detect version from RELEASENOTES.md instead of hardcoding
Copilot 307c1d1
Use more flexible regex pattern for version detection
Copilot 46506c2
Support optional patch version in regex pattern
Copilot 52fd30e
Improve PowerShell script logic and fix syntax errors
Copilot 2f26fb1
Error out if version cannot be detected from RELEASENOTES.md
Copilot 3bb21cd
Refactor to use GitHub CLI and remove workflows per feedback
Copilot 64e0e56
Fix error handling and add security notes per code review
Copilot 10e3d2b
Add finally block for temp file cleanup and simplify jq filter
Copilot c762f5b
Fix regex to use multiline modifier for version detection
Copilot f608059
Handle null result from ConvertFrom-Json on empty arrays
Copilot 7f92ee2
Remove support for vX.Y.Z format, only support vX.Y
Copilot 7a54d94
Simplify array handling with @() operator
Copilot 0cd998e
Move script to _Internal folder and remove separate documentation files
Copilot 434f9af
Change to review comments on RELEASENOTES.md and rephrase message
Copilot cb95a1d
Move script to Internal/Scripts folder at repository root
Copilot 707667d
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez 26de992
Include current version in existing comment check
Copilot a063f9d
Fix trailing whitespace in script
Copilot 0f405e7
Fix file encoding to UTF-8 with BOM for PSScriptAnalyzer
Copilot 5807318
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez e26d8d6
Address PR review comments - fix API payload, error handling, and limits
Copilot f508d16
Remove unused response variable to fix PSScriptAnalyzer alert
Copilot 6a3774f
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez 64373f2
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez 66e4c02
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez 5c9b831
Rename script to PascalCase to match repository convention
Copilot ffcda0e
Merge branch 'main' into copilot/comment-release-notes-prs
mazhelez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # AL-Go Scripts | ||
|
|
||
| This directory contains utility scripts for the AL-Go repository. | ||
|
|
||
| ## comment-on-existing-release-notes-prs.ps1 | ||
|
|
||
| This PowerShell script adds a reminder comment to all open PRs that modify the `RELEASENOTES.md` file. It's a one-time utility script to handle existing PRs. | ||
|
|
||
| ### Usage | ||
|
|
||
| **Option 1: Use the GitHub Workflow (Recommended)** | ||
|
|
||
| The easiest way to add comments to existing PRs is to use the manual workflow: | ||
|
|
||
| 1. Go to the Actions tab in the repository | ||
| 2. Select "Comment on Existing Release Notes PRs" workflow | ||
| 3. Click "Run workflow" | ||
| 4. Choose whether to run in dry-run mode (to preview which PRs will be commented) | ||
| 5. Click "Run workflow" | ||
|
|
||
| **Option 2: Run the PowerShell Script Locally** | ||
|
|
||
| ```powershell | ||
| # Set your GitHub token as an environment variable | ||
| $env:GITHUB_TOKEN = "your-github-token-here" | ||
|
|
||
| # Run the script | ||
| pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 | ||
| ``` | ||
|
|
||
| ### Parameters | ||
|
|
||
| - `Owner` (optional): Repository owner (default: "microsoft") | ||
| - `Repo` (optional): Repository name (default: "AL-Go") | ||
| - `GitHubToken` (optional): GitHub token with PR comment permissions (default: reads from `$env:GITHUB_TOKEN`) | ||
|
|
||
| ### What it does | ||
|
|
||
| 1. Fetches all open pull requests in the repository | ||
| 2. Checks each PR to see if it modifies `RELEASENOTES.md` | ||
| 3. For PRs that do modify the release notes: | ||
| - Checks if a reminder comment already exists | ||
| - If not, adds a comment reminding contributors to place their changes above the new version section | ||
|
|
||
| ### Requirements | ||
|
|
||
| - GitHub token with `pull-requests: write` permission | ||
| - PowerShell 7 or later | ||
|
|
||
| ### Note | ||
|
|
||
| For new PRs, the automated workflow `.github/workflows/check-release-notes-prs.yml` will automatically add the comment. This script/workflow is only needed to handle existing open PRs at the time of deployment. |
136 changes: 136 additions & 0 deletions
136
.github/scripts/comment-on-existing-release-notes-prs.ps1
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| #!/usr/bin/env pwsh | ||
|
|
||
| <# | ||
| .SYNOPSIS | ||
| Adds a comment to all open PRs that modify RELEASENOTES.md | ||
| .DESCRIPTION | ||
| This script searches for all open PRs that have changes to RELEASENOTES.md | ||
| and adds a reminder comment about placing changes above the new version section. | ||
|
|
||
| This is a one-time script to handle existing PRs. New PRs will be handled | ||
| by the check-release-notes-prs.yml workflow. | ||
| .PARAMETER Owner | ||
| The repository owner (default: microsoft) | ||
| .PARAMETER Repo | ||
| The repository name (default: AL-Go) | ||
| .PARAMETER GitHubToken | ||
| GitHub token with permissions to comment on PRs | ||
| .EXAMPLE | ||
| $env:GITHUB_TOKEN = "your-token-here" | ||
| ./comment-on-existing-release-notes-prs.ps1 | ||
| #> | ||
|
|
||
| param( | ||
| [string]$Owner = "microsoft", | ||
| [string]$Repo = "AL-Go", | ||
| [string]$GitHubToken = $env:GITHUB_TOKEN | ||
| ) | ||
|
|
||
| $ErrorActionPreference = "Stop" | ||
| Set-StrictMode -Version 2.0 | ||
|
|
||
| if (-not $GitHubToken) { | ||
| Write-Error "GitHub token is required. Set GITHUB_TOKEN environment variable or pass -GitHubToken parameter." | ||
| exit 1 | ||
| } | ||
|
|
||
| # Detect current version from RELEASENOTES.md | ||
| $currentVersion = "v8.1" # fallback | ||
| $releaseNotesPath = Join-Path $PSScriptRoot "../../RELEASENOTES.md" | ||
| if (Test-Path $releaseNotesPath) { | ||
| $releaseNotesContent = Get-Content -Path $releaseNotesPath -Raw | ||
| if ($releaseNotesContent -match '^##\s*v(\d+\.\d+(?:\.\d+)?)') { | ||
| $currentVersion = "v$($matches[1])" | ||
| Write-Host "Detected current version: $currentVersion" | ||
| } | ||
| } else { | ||
| Write-Host "Could not find RELEASENOTES.md, using fallback version: $currentVersion" | ||
| } | ||
|
|
||
| $comment = @" | ||
| ### ⚠️ Release Notes Update Reminder | ||
|
|
||
| Thank you for updating the release notes! | ||
|
|
||
| Please ensure that your changes are placed **above the new version section** (currently ``## $currentVersion``) in the RELEASENOTES.md file. | ||
|
|
||
| This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version. | ||
| "@ | ||
|
|
||
| $headers = @{ | ||
| "Authorization" = "Bearer $GitHubToken" | ||
| "Accept" = "application/vnd.github+json" | ||
| "X-GitHub-Api-Version" = "2022-11-28" | ||
| } | ||
|
|
||
| Write-Host "Fetching open pull requests for $Owner/$Repo..." | ||
|
|
||
| # Get all open PRs | ||
| $prsUrl = "https://api.github.com/repos/$Owner/$Repo/pulls?state=open&per_page=100" | ||
mazhelez marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| $prs = Invoke-RestMethod -Uri $prsUrl -Headers $headers -Method Get | ||
|
|
||
| Write-Host "Found $($prs.Count) open PRs. Checking which ones modify RELEASENOTES.md..." | ||
|
|
||
| $prsWithReleaseNotes = @() | ||
|
|
||
| foreach ($pr in $prs) { | ||
| $prNumber = $pr.number | ||
| Write-Host "Checking PR #$prNumber..." | ||
|
|
||
| # Get files changed in this PR | ||
| $filesUrl = "https://api.github.com/repos/$Owner/$Repo/pulls/$prNumber/files" | ||
| $files = Invoke-RestMethod -Uri $filesUrl -Headers $headers -Method Get | ||
|
|
||
| # Check if RELEASENOTES.md was modified | ||
| $releaseNotesModified = $files | Where-Object { $_.filename -eq "RELEASENOTES.md" } | ||
|
|
||
| if ($releaseNotesModified) { | ||
| Write-Host " ✓ PR #$prNumber modifies RELEASENOTES.md" | ||
| $prsWithReleaseNotes += $pr | ||
| } else { | ||
| Write-Host " - PR #$prNumber does not modify RELEASENOTES.md" | ||
| } | ||
| } | ||
|
|
||
| if ($prsWithReleaseNotes.Count -eq 0) { | ||
| Write-Host "`nNo PRs found that modify RELEASENOTES.md. Exiting." | ||
| exit 0 | ||
| } | ||
|
|
||
| Write-Host "`nFound $($prsWithReleaseNotes.Count) PRs that modify RELEASENOTES.md" | ||
| Write-Host "`nAdding comments to PRs..." | ||
|
|
||
| foreach ($pr in $prsWithReleaseNotes) { | ||
| $prNumber = $pr.number | ||
| $prTitle = $pr.title | ||
|
|
||
| Write-Host "`nProcessing PR #${prNumber}: $prTitle" | ||
|
|
||
| # Check if we've already commented | ||
| $commentsUrl = "https://api.github.com/repos/$Owner/$Repo/issues/$prNumber/comments" | ||
| $existingComments = Invoke-RestMethod -Uri $commentsUrl -Headers $headers -Method Get | ||
|
|
||
| $alreadyCommented = $existingComments | Where-Object { | ||
| $_.body -like "*Release Notes Update Reminder*" | ||
mazhelez marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if ($alreadyCommented) { | ||
| Write-Host " ℹ️ Comment already exists on PR #$prNumber, skipping..." | ||
| continue | ||
| } | ||
|
|
||
| # Add comment | ||
| try { | ||
| $body = @{ | ||
| body = $comment | ||
| } | ConvertTo-Json | ||
|
|
||
| $response = Invoke-RestMethod -Uri $commentsUrl -Headers $headers -Method Post -Body $body -ContentType "application/json" | ||
| Write-Host " ✓ Comment added to PR #$prNumber" | ||
| } | ||
| catch { | ||
| Write-Error " ✗ Failed to add comment to PR #${prNumber}: $_" | ||
| } | ||
| } | ||
|
|
||
| Write-Host "`n✓ Done! Comments have been added to $($prsWithReleaseNotes.Count) PRs." | ||
mazhelez marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| name: Check Release Notes PRs | ||
|
|
||
| on: | ||
| pull_request: | ||
mazhelez marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| types: [opened, synchronize, reopened] | ||
| paths: | ||
| - 'RELEASENOTES.md' | ||
|
|
||
| permissions: | ||
| pull-requests: write | ||
| contents: read | ||
|
|
||
| jobs: | ||
| check-release-notes: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Check Release Notes and Comment | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const fs = require('fs'); | ||
| const issue_number = context.payload.pull_request.number; | ||
| const repo = context.repo; | ||
|
|
||
| // Read RELEASENOTES.md to detect current version | ||
| let currentVersion = 'v8.1'; // fallback | ||
| try { | ||
| const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); | ||
| const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); | ||
| if (versionMatch) { | ||
| currentVersion = 'v' + versionMatch[1]; | ||
| } | ||
| } catch (error) { | ||
| console.log('Could not read RELEASENOTES.md, using fallback version'); | ||
| } | ||
|
|
||
| // Comment to add | ||
| const comment = `### ⚠️ Release Notes Update Reminder | ||
|
|
||
| Thank you for updating the release notes! | ||
|
|
||
| Please ensure that your changes are placed **above the new version section** (currently \`## ${currentVersion}\`) in the RELEASENOTES.md file. | ||
|
|
||
| This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version.`; | ||
|
|
||
| // Check if we've already commented | ||
| const comments = await github.rest.issues.listComments({ | ||
| owner: repo.owner, | ||
| repo: repo.repo, | ||
| issue_number: issue_number, | ||
| }); | ||
|
|
||
| const botComment = comments.data.find(comment => | ||
| comment.user.type === 'Bot' && | ||
| comment.body.includes('Release Notes Update Reminder') | ||
| ); | ||
|
|
||
| if (!botComment) { | ||
| await github.rest.issues.createComment({ | ||
| owner: repo.owner, | ||
| repo: repo.repo, | ||
| issue_number: issue_number, | ||
| body: comment | ||
| }); | ||
| console.log('Comment added to PR #' + issue_number); | ||
| } else { | ||
| console.log('Comment already exists on PR #' + issue_number); | ||
| } | ||
111 changes: 111 additions & 0 deletions
111
.github/workflows/comment-on-existing-release-notes-prs.yml
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| name: Comment on Existing Release Notes PRs | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
mazhelez marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| inputs: | ||
| dryRun: | ||
| description: 'Dry run mode (only list PRs, do not add comments)' | ||
| required: false | ||
| default: 'false' | ||
| type: choice | ||
| options: | ||
| - 'true' | ||
| - 'false' | ||
|
|
||
| permissions: | ||
| pull-requests: write | ||
| contents: read | ||
| issues: write | ||
|
|
||
| jobs: | ||
| comment-on-prs: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Add Comments to Existing PRs | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const fs = require('fs'); | ||
| const dryRun = '${{ inputs.dryRun }}' === 'true'; | ||
|
|
||
| // PRs that modify RELEASENOTES.md | ||
| const prs = [2056, 2049, 2048, 2047, 2041, 2033, 2031, 2029, 2010, 1994, 1882, 1828, 1824, 1795]; | ||
|
|
||
| // Read RELEASENOTES.md to detect current version | ||
| let currentVersion = 'v8.1'; // fallback | ||
| try { | ||
| const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); | ||
| const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); | ||
| if (versionMatch) { | ||
| currentVersion = 'v' + versionMatch[1]; | ||
| } | ||
| } catch (error) { | ||
| console.log('Could not read RELEASENOTES.md, using fallback version'); | ||
| } | ||
|
|
||
| const comment = `### ⚠️ Release Notes Update Reminder | ||
|
|
||
| Thank you for updating the release notes! | ||
|
|
||
| Please ensure that your changes are placed **above the new version section** (currently \`## ${currentVersion}\`) in the RELEASENOTES.md file. | ||
|
|
||
| This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version.`; | ||
|
|
||
| console.log(`Processing ${prs.length} PRs...`); | ||
| console.log(`Dry run mode: ${dryRun}`); | ||
| console.log(''); | ||
|
|
||
| let commented = 0; | ||
| let skipped = 0; | ||
| let failed = 0; | ||
|
|
||
| for (const prNumber of prs) { | ||
| try { | ||
| console.log(`Checking PR #${prNumber}...`); | ||
|
|
||
| // Check if comment already exists | ||
| const comments = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| }); | ||
|
|
||
| const alreadyCommented = comments.data.some(c => | ||
| c.body && c.body.includes('Release Notes Update Reminder') | ||
| ); | ||
|
|
||
| if (alreadyCommented) { | ||
| console.log(` ℹ️ Comment already exists on PR #${prNumber}, skipping...`); | ||
| skipped++; | ||
| continue; | ||
| } | ||
|
|
||
| if (dryRun) { | ||
| console.log(` [DRY RUN] Would add comment to PR #${prNumber}`); | ||
| commented++; | ||
| } else { | ||
| // Add comment | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| body: comment | ||
| }); | ||
| console.log(` ✓ Comment added to PR #${prNumber}`); | ||
| commented++; | ||
| } | ||
| } catch (error) { | ||
| console.log(` ✗ Failed to process PR #${prNumber}: ${error.message}`); | ||
| failed++; | ||
| } | ||
| } | ||
|
|
||
| console.log(''); | ||
| console.log('Summary:'); | ||
| console.log(` Total PRs processed: ${prs.length}`); | ||
| console.log(` Comments added: ${commented}`); | ||
| console.log(` Skipped (already commented): ${skipped}`); | ||
| console.log(` Failed: ${failed}`); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.