From 9c696cad8bd3eaf2bdb4dc167f7e1421e268c66a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:37:36 +0000 Subject: [PATCH 01/25] Initial plan From 2c0e4dabe30cf77f0cfe2d834e8244154409c9d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:41:29 +0000 Subject: [PATCH 02/25] Add workflow and script to comment on release notes PRs Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/README.md | 40 ++++++ .../comment-on-existing-release-notes-prs.ps1 | 124 ++++++++++++++++++ .github/workflows/check-release-notes-prs.yml | 55 ++++++++ 3 files changed, 219 insertions(+) create mode 100644 .github/scripts/README.md create mode 100644 .github/scripts/comment-on-existing-release-notes-prs.ps1 create mode 100644 .github/workflows/check-release-notes-prs.yml diff --git a/.github/scripts/README.md b/.github/scripts/README.md new file mode 100644 index 0000000000..15e8f4f8be --- /dev/null +++ b/.github/scripts/README.md @@ -0,0 +1,40 @@ +# 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 + +```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 is only needed to handle existing open PRs at the time of deployment. diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 new file mode 100644 index 0000000000..e7c162d676 --- /dev/null +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -0,0 +1,124 @@ +#!/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 +} + +$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 ``## v8.1``) 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" +$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" + } +} + +Write-Host "`nFound $($prsWithReleaseNotes.Count) PRs that modify RELEASENOTES.md" + +if ($prsWithReleaseNotes.Count -eq 0) { + Write-Host "No PRs found that modify RELEASENOTES.md. Exiting." + exit 0 +} + +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 { + $_.user.type -eq "Bot" -and $_.body -like "*Release Notes Update Reminder*" + } + + 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." diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml new file mode 100644 index 0000000000..c13c43b822 --- /dev/null +++ b/.github/workflows/check-release-notes-prs.yml @@ -0,0 +1,55 @@ +name: Check Release Notes PRs + +on: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'RELEASENOTES.md' + +permissions: + pull-requests: write + contents: read + +jobs: + check-release-notes: + runs-on: ubuntu-latest + steps: + - name: Check Release Notes and Comment + uses: actions/github-script@v7 + with: + script: | + const issue_number = context.payload.pull_request.number; + const repo = context.repo; + + // 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 \`## v8.1\`) 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); + } From 3804759403d264281d4411c4790243593b7d7ec1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:42:38 +0000 Subject: [PATCH 03/25] Add documentation for release notes PR automation Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- docs/release-notes-pr-automation.md | 146 ++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 docs/release-notes-pr-automation.md diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md new file mode 100644 index 0000000000..aec96497e1 --- /dev/null +++ b/docs/release-notes-pr-automation.md @@ -0,0 +1,146 @@ +# Release Notes PR Automation + +## Overview + +This automation ensures that contributors are reminded to place their release note changes in the correct location within the `RELEASENOTES.md` file. + +## Problem + +When multiple contributors update the release notes, there's a risk that changes might be added to different version sections or in the wrong location. To maintain a clear and organized changelog, all new changes should be added under the latest/upcoming version section. + +## Solution + +The solution consists of two components: + +### 1. Automated Workflow for New PRs + +**File**: `.github/workflows/check-release-notes-prs.yml` + +This workflow automatically triggers when a PR is opened, updated, or reopened if it modifies the `RELEASENOTES.md` file. It: + +- Detects when `RELEASENOTES.md` has been changed in a PR +- Checks if a reminder comment already exists +- If not, adds a friendly comment reminding the contributor to place changes above the new version section + +**Trigger Conditions:** +- `pull_request` events: `opened`, `synchronize`, `reopened` +- Only when `RELEASENOTES.md` is modified + +**Permissions Required:** +- `pull-requests: write` - to add comments +- `contents: read` - to read the repository content + +### 2. One-Time Script for Existing PRs + +**File**: `.github/scripts/comment-on-existing-release-notes-prs.ps1` + +This PowerShell script is designed to be run once to add comments to all currently open PRs that modify `RELEASENOTES.md`. After the initial run, the automated workflow handles new PRs. + +**Usage:** +```powershell +$env:GITHUB_TOKEN = "your-token-here" +pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 +``` + +The script: +1. Fetches all open PRs +2. Checks which ones modify `RELEASENOTES.md` +3. Adds the reminder comment (if not already present) + +## Comment Content + +The comment added to PRs is: + +```markdown +### ⚠️ Release Notes Update Reminder + +Thank you for updating the release notes! + +Please ensure that your changes are placed **above the new version section** (currently `## v8.1`) in the RELEASENOTES.md file. + +This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version. +``` + +## Customization + +To update the comment for a new version: + +1. **Workflow**: Edit `.github/workflows/check-release-notes-prs.yml` and update the version number in the comment +2. **Script**: Edit `.github/scripts/comment-on-existing-release-notes-prs.ps1` and update the version number in the `$comment` variable + +## Implementation Details + +### Workflow Implementation + +The workflow uses `actions/github-script@v7` which provides: +- GitHub API access via `github` object +- Context information via `context` object +- No need for checkout or separate authentication + +**Key Features:** +- Only triggers on `RELEASENOTES.md` changes (path filter) +- Checks for existing comments to avoid duplicates +- Uses Bot user type to identify its own comments +- Minimal permissions (read content, write comments) + +### Script Implementation + +The PowerShell script: +- Uses GitHub REST API directly +- Requires a GitHub token with PR comment permissions +- Implements duplicate detection +- Provides detailed progress output +- Handles errors gracefully + +## Maintenance + +### When to Update + +Update the version number in both files when: +- A new major/minor version is released +- The current version section in `RELEASENOTES.md` changes + +### Monitoring + +You can monitor the automation by: +1. Checking PR comments for the reminder message +2. Reviewing workflow runs in the Actions tab +3. Checking for any workflow failures + +### Troubleshooting + +**Workflow doesn't trigger:** +- Verify the PR modifies `RELEASENOTES.md` +- Check workflow permissions are correct +- Review the workflow run logs in Actions tab + +**Script fails:** +- Ensure `GITHUB_TOKEN` is set and valid +- Verify token has `pull-requests: write` permission +- Check API rate limits aren't exceeded + +**Duplicate comments:** +- The automation checks for existing comments +- If duplicates occur, check the comment detection logic + +## Future Improvements + +Potential enhancements: +1. Add validation to check if changes are actually in the correct section +2. Automatically detect the current version from RELEASENOTES.md +3. Add metrics/telemetry for tracking compliance +4. Create a pre-commit hook for local development + +## Testing + +To test the automation: + +1. **Test Workflow**: Create a test PR that modifies `RELEASENOTES.md` +2. **Test Script**: Run the script with a test token in a fork +3. **Verify**: Check that comments are added correctly and duplicates are avoided + +## References + +- [GitHub Actions - actions/github-script](https://github.com/actions/github-script) +- [GitHub REST API - Issues Comments](https://docs.github.com/en/rest/issues/comments) +- [AL-Go Release Notes](../RELEASENOTES.md) From 72ddc4e4c5b0011dbd66e932ca8a448245c7631e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:53:07 +0000 Subject: [PATCH 04/25] Add manual workflow to comment on existing release notes PRs Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/README.md | 14 ++- .../comment-on-existing-release-notes-prs.yml | 95 +++++++++++++++++++ docs/release-notes-pr-automation.md | 19 +++- 3 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/comment-on-existing-release-notes-prs.yml diff --git a/.github/scripts/README.md b/.github/scripts/README.md index 15e8f4f8be..6b948d7d78 100644 --- a/.github/scripts/README.md +++ b/.github/scripts/README.md @@ -8,6 +8,18 @@ This PowerShell script adds a reminder comment to all open PRs that modify the ` ### 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" @@ -37,4 +49,4 @@ pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 ### Note -For new PRs, the automated workflow `.github/workflows/check-release-notes-prs.yml` will automatically add the comment. This script is only needed to handle existing open PRs at the time of deployment. +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. diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml new file mode 100644 index 0000000000..27d17be456 --- /dev/null +++ b/.github/workflows/comment-on-existing-release-notes-prs.yml @@ -0,0 +1,95 @@ +name: Comment on Existing Release Notes PRs + +on: + workflow_dispatch: + 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: Add Comments to Existing PRs + uses: actions/github-script@v7 + with: + script: | + 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]; + + 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 \`## v8.1\`) 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}`); diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index aec96497e1..44bd8747b7 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -32,18 +32,27 @@ This workflow automatically triggers when a PR is opened, updated, or reopened i ### 2. One-Time Script for Existing PRs -**File**: `.github/scripts/comment-on-existing-release-notes-prs.ps1` +**Files**: +- `.github/scripts/comment-on-existing-release-notes-prs.ps1` (PowerShell script) +- `.github/workflows/comment-on-existing-release-notes-prs.yml` (Manual workflow) -This PowerShell script is designed to be run once to add comments to all currently open PRs that modify `RELEASENOTES.md`. After the initial run, the automated workflow handles new PRs. +These are designed to be run once to add comments to all currently open PRs that modify `RELEASENOTES.md`. After the initial run, the automated workflow handles new PRs. -**Usage:** +**Usage (Recommended - 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 (preview only) +5. Click "Run workflow" to execute + +**Usage (Alternative - PowerShell Script):** ```powershell $env:GITHUB_TOKEN = "your-token-here" pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 ``` -The script: -1. Fetches all open PRs +What it does: +1. Fetches all open PRs (or uses a predefined list) 2. Checks which ones modify `RELEASENOTES.md` 3. Adds the reminder comment (if not already present) From e43f26b76a10b00a97bf0fcffe7a85b2a6d9b492 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:04:44 +0000 Subject: [PATCH 05/25] Auto-detect version from RELEASENOTES.md instead of hardcoding Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 15 +++++++++++++- .github/workflows/check-release-notes-prs.yml | 18 ++++++++++++++++- .../comment-on-existing-release-notes-prs.yml | 18 ++++++++++++++++- docs/release-notes-pr-automation.md | 20 ++++++++++--------- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index e7c162d676..8781446f04 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -34,12 +34,25 @@ if (-not $GitHubToken) { 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+)') { + $currentVersion = $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 ``## v8.1``) in the RELEASENOTES.md file. +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. "@ diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml index c13c43b822..614a9371c2 100644 --- a/.github/workflows/check-release-notes-prs.yml +++ b/.github/workflows/check-release-notes-prs.yml @@ -14,19 +14,35 @@ 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+)/m); + if (versionMatch) { + currentVersion = 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 \`## v8.1\`) in the RELEASENOTES.md file. +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.`; diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml index 27d17be456..ac2d49528d 100644 --- a/.github/workflows/comment-on-existing-release-notes-prs.yml +++ b/.github/workflows/comment-on-existing-release-notes-prs.yml @@ -21,20 +21,36 @@ 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+)/m); + if (versionMatch) { + currentVersion = 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 \`## v8.1\`) in the RELEASENOTES.md file. +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.`; diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index 44bd8747b7..572b1835cd 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -70,12 +70,14 @@ Please ensure that your changes are placed **above the new version section** (cu This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version. ``` -## Customization +## Automatic Version Detection -To update the comment for a new version: +The workflows and script automatically detect the current version from `RELEASENOTES.md` by: +- Reading the file and finding the first line matching the pattern `## vX.Y` +- Using the detected version in the comment message +- Falling back to `v8.1` if the file cannot be read or the pattern is not found -1. **Workflow**: Edit `.github/workflows/check-release-notes-prs.yml` and update the version number in the comment -2. **Script**: Edit `.github/scripts/comment-on-existing-release-notes-prs.ps1` and update the version number in the `$comment` variable +This means no manual updates are needed when a new version is released - the comment will automatically reference the correct version. ## Implementation Details @@ -84,10 +86,11 @@ To update the comment for a new version: The workflow uses `actions/github-script@v7` which provides: - GitHub API access via `github` object - Context information via `context` object -- No need for checkout or separate authentication +- Checkout step to read `RELEASENOTES.md` for version detection **Key Features:** - Only triggers on `RELEASENOTES.md` changes (path filter) +- Automatically detects current version from RELEASENOTES.md - Checks for existing comments to avoid duplicates - Uses Bot user type to identify its own comments - Minimal permissions (read content, write comments) @@ -97,17 +100,16 @@ The workflow uses `actions/github-script@v7` which provides: The PowerShell script: - Uses GitHub REST API directly - Requires a GitHub token with PR comment permissions +- Automatically detects current version from RELEASENOTES.md - Implements duplicate detection - Provides detailed progress output - Handles errors gracefully ## Maintenance -### When to Update +### Automatic Updates -Update the version number in both files when: -- A new major/minor version is released -- The current version section in `RELEASENOTES.md` changes +The version number is automatically detected from `RELEASENOTES.md`, so no manual updates are needed when a new version is released. The workflows and script will automatically use the current version found in the file. ### Monitoring From 307c1d1054ab1e2431f6abc30168124d1e273917 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:07:17 +0000 Subject: [PATCH 06/25] Use more flexible regex pattern for version detection Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/comment-on-existing-release-notes-prs.ps1 | 4 ++-- .github/workflows/check-release-notes-prs.yml | 4 ++-- .github/workflows/comment-on-existing-release-notes-prs.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 8781446f04..0e8ad7960e 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -39,8 +39,8 @@ $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+)') { - $currentVersion = $matches[1] + if ($releaseNotesContent -match '^##\s*v(\d+\.\d+)') { + $currentVersion = "v$($matches[1])" Write-Host "Detected current version: $currentVersion" } } else { diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml index 614a9371c2..0f35de4c22 100644 --- a/.github/workflows/check-release-notes-prs.yml +++ b/.github/workflows/check-release-notes-prs.yml @@ -29,9 +29,9 @@ jobs: let currentVersion = 'v8.1'; // fallback try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s+(v\d+\.\d+)/m); + const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+)/m); if (versionMatch) { - currentVersion = versionMatch[1]; + currentVersion = 'v' + versionMatch[1]; } } catch (error) { console.log('Could not read RELEASENOTES.md, using fallback version'); diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml index ac2d49528d..b5a7787119 100644 --- a/.github/workflows/comment-on-existing-release-notes-prs.yml +++ b/.github/workflows/comment-on-existing-release-notes-prs.yml @@ -38,9 +38,9 @@ jobs: let currentVersion = 'v8.1'; // fallback try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s+(v\d+\.\d+)/m); + const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+)/m); if (versionMatch) { - currentVersion = versionMatch[1]; + currentVersion = 'v' + versionMatch[1]; } } catch (error) { console.log('Could not read RELEASENOTES.md, using fallback version'); From 46506c283fe35df805f367caee8f06f4e9fb3db6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:09:07 +0000 Subject: [PATCH 07/25] Support optional patch version in regex pattern Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/comment-on-existing-release-notes-prs.ps1 | 2 +- .github/workflows/check-release-notes-prs.yml | 2 +- .github/workflows/comment-on-existing-release-notes-prs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 0e8ad7960e..d9646a6db8 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -39,7 +39,7 @@ $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+)') { + if ($releaseNotesContent -match '^##\s*v(\d+\.\d+(?:\.\d+)?)') { $currentVersion = "v$($matches[1])" Write-Host "Detected current version: $currentVersion" } diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml index 0f35de4c22..d15cd79edb 100644 --- a/.github/workflows/check-release-notes-prs.yml +++ b/.github/workflows/check-release-notes-prs.yml @@ -29,7 +29,7 @@ jobs: let currentVersion = 'v8.1'; // fallback try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+)/m); + const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); if (versionMatch) { currentVersion = 'v' + versionMatch[1]; } diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml index b5a7787119..4d3f3147f9 100644 --- a/.github/workflows/comment-on-existing-release-notes-prs.yml +++ b/.github/workflows/comment-on-existing-release-notes-prs.yml @@ -38,7 +38,7 @@ jobs: let currentVersion = 'v8.1'; // fallback try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+)/m); + const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); if (versionMatch) { currentVersion = 'v' + versionMatch[1]; } From 52fd30ec011d11d86cf197a7dd92c89ef0d0bcff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:16:17 +0000 Subject: [PATCH 08/25] Improve PowerShell script logic and fix syntax errors Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../scripts/comment-on-existing-release-notes-prs.ps1 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index d9646a6db8..87439d809e 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -92,27 +92,26 @@ foreach ($pr in $prs) { } } -Write-Host "`nFound $($prsWithReleaseNotes.Count) PRs that modify RELEASENOTES.md" - if ($prsWithReleaseNotes.Count -eq 0) { - Write-Host "No PRs found that modify RELEASENOTES.md. Exiting." + 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" + 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 { - $_.user.type -eq "Bot" -and $_.body -like "*Release Notes Update Reminder*" + $_.body -like "*Release Notes Update Reminder*" } if ($alreadyCommented) { @@ -130,7 +129,7 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host " ✓ Comment added to PR #$prNumber" } catch { - Write-Error " ✗ Failed to add comment to PR #$prNumber: $_" + Write-Error " ✗ Failed to add comment to PR #${prNumber}: $_" } } From 2f26fb1ba23daa7357f9cc5fca17d2d52ba14ba3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:17:26 +0000 Subject: [PATCH 09/25] Error out if version cannot be detected from RELEASENOTES.md Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 19 +++++++++++-------- .github/workflows/check-release-notes-prs.yml | 8 ++++++-- .../comment-on-existing-release-notes-prs.yml | 8 ++++++-- docs/release-notes-pr-automation.md | 6 +++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 87439d809e..49e575cba0 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -35,16 +35,19 @@ if (-not $GitHubToken) { } # 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" - } +if (-not (Test-Path $releaseNotesPath)) { + Write-Error "RELEASENOTES.md not found at $releaseNotesPath" + exit 1 +} + +$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" + Write-Error "Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'" + exit 1 } $comment = @" diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml index d15cd79edb..841abfe1bf 100644 --- a/.github/workflows/check-release-notes-prs.yml +++ b/.github/workflows/check-release-notes-prs.yml @@ -26,15 +26,19 @@ jobs: const repo = context.repo; // Read RELEASENOTES.md to detect current version - let currentVersion = 'v8.1'; // fallback + let currentVersion; try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); if (versionMatch) { currentVersion = 'v' + versionMatch[1]; + console.log('Detected current version: ' + currentVersion); + } else { + throw new Error("Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'"); } } catch (error) { - console.log('Could not read RELEASENOTES.md, using fallback version'); + console.error('Error reading version from RELEASENOTES.md: ' + error.message); + throw error; } // Comment to add diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml index 4d3f3147f9..04966534e8 100644 --- a/.github/workflows/comment-on-existing-release-notes-prs.yml +++ b/.github/workflows/comment-on-existing-release-notes-prs.yml @@ -35,15 +35,19 @@ jobs: 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 + let currentVersion; try { const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); if (versionMatch) { currentVersion = 'v' + versionMatch[1]; + console.log('Detected current version: ' + currentVersion); + } else { + throw new Error("Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'"); } } catch (error) { - console.log('Could not read RELEASENOTES.md, using fallback version'); + console.error('Error reading version from RELEASENOTES.md: ' + error.message); + throw error; } const comment = `### ⚠️ Release Notes Update Reminder diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index 572b1835cd..8c43d8e98c 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -73,11 +73,11 @@ This helps maintain a clear changelog structure where new changes are grouped un ## Automatic Version Detection The workflows and script automatically detect the current version from `RELEASENOTES.md` by: -- Reading the file and finding the first line matching the pattern `## vX.Y` +- Reading the file and finding the first line matching the pattern `## vX.Y` or `## vX.Y.Z` - Using the detected version in the comment message -- Falling back to `v8.1` if the file cannot be read or the pattern is not found +- **Failing with an error if the version cannot be detected** (ensures the automation is working correctly) -This means no manual updates are needed when a new version is released - the comment will automatically reference the correct version. +This means no manual updates are needed when a new version is released - the comment will automatically reference the correct version. If version detection fails, it indicates an issue that needs to be addressed. ## Implementation Details From 3bb21cda69d412bcb1cbc7a67345c91e276fea2d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:25:38 +0000 Subject: [PATCH 10/25] Refactor to use GitHub CLI and remove workflows per feedback Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/README.md | 40 +++--- .../comment-on-existing-release-notes-prs.ps1 | 122 ++++++++++++------ .github/workflows/check-release-notes-prs.yml | 75 ----------- .../comment-on-existing-release-notes-prs.yml | 115 ----------------- docs/release-notes-pr-automation.md | 106 ++++++--------- 5 files changed, 138 insertions(+), 320 deletions(-) delete mode 100644 .github/workflows/check-release-notes-prs.yml delete mode 100644 .github/workflows/comment-on-existing-release-notes-prs.yml diff --git a/.github/scripts/README.md b/.github/scripts/README.md index 6b948d7d78..a697d3c0ca 100644 --- a/.github/scripts/README.md +++ b/.github/scripts/README.md @@ -4,24 +4,14 @@ 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. +This PowerShell script adds a reminder comment to all open PRs that modify the `RELEASENOTES.md` file. It uses GitHub CLI (gh) for better readability and maintainability. ### 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:GH_TOKEN = "your-github-token-here" +# or $env:GITHUB_TOKEN = "your-github-token-here" # Run the script @@ -32,21 +22,29 @@ pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 - `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 +1. Verifies GitHub CLI is installed and authenticated +2. Automatically detects the current version from `RELEASENOTES.md` +3. Fetches all open pull requests in the repository using `gh pr list` +4. Checks each PR to see if it modifies `RELEASENOTES.md` +5. For PRs that do modify the release notes: + - Checks if an active reminder comment already exists - If not, adds a comment reminding contributors to place their changes above the new version section +6. Provides a detailed summary with success/skip/fail counts +7. Lists any PRs where comment addition failed ### Requirements -- GitHub token with `pull-requests: write` permission +- GitHub CLI (`gh`) installed: https://cli.github.com/ +- GitHub token with PR comment permissions (set via `GH_TOKEN` or `GITHUB_TOKEN`) - PowerShell 7 or later -### Note +### Error Handling -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. +- Errors out if GitHub CLI is not installed +- Errors out if not authenticated +- Errors out if version cannot be detected from `RELEASENOTES.md` +- Tracks and reports failed comment additions +- Exit code 1 if any comments fail, 0 if all successful diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 49e575cba0..ed3a4ebada 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -7,30 +7,40 @@ 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. + Uses GitHub CLI (gh) for better readability and maintainability. .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" + # Set GH_TOKEN or GITHUB_TOKEN environment variable + $env:GH_TOKEN = "your-token-here" ./comment-on-existing-release-notes-prs.ps1 #> param( [string]$Owner = "microsoft", - [string]$Repo = "AL-Go", - [string]$GitHubToken = $env:GITHUB_TOKEN + [string]$Repo = "AL-Go" ) $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." +# Check if gh CLI is available +if (-not (Get-Command gh -ErrorAction SilentlyContinue)) { + Write-Error "GitHub CLI (gh) is not installed. Please install it from https://cli.github.com/" + exit 1 +} + +# Verify authentication +try { + $null = gh auth status 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Error "GitHub CLI is not authenticated. Run 'gh auth login' or set GH_TOKEN/GITHUB_TOKEN environment variable." + exit 1 + } +} catch { + Write-Error "Failed to verify GitHub CLI authentication: $_" exit 1 } @@ -60,32 +70,21 @@ Please ensure that your changes are placed **above the new version section** (cu 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" -$prs = Invoke-RestMethod -Uri $prsUrl -Headers $headers -Method Get +# Get all open PRs using gh CLI +$prsJson = gh pr list --repo "$Owner/$Repo" --state open --limit 100 --json number,title,files | ConvertFrom-Json -Write-Host "Found $($prs.Count) open PRs. Checking which ones modify RELEASENOTES.md..." +Write-Host "Found $($prsJson.Count) open PRs. Checking which ones modify RELEASENOTES.md..." $prsWithReleaseNotes = @() -foreach ($pr in $prs) { +foreach ($pr in $prsJson) { $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" } + $releaseNotesModified = $pr.files | Where-Object { $_.path -eq "RELEASENOTES.md" } if ($releaseNotesModified) { Write-Host " ✓ PR #$prNumber modifies RELEASENOTES.md" @@ -103,37 +102,74 @@ if ($prsWithReleaseNotes.Count -eq 0) { Write-Host "`nFound $($prsWithReleaseNotes.Count) PRs that modify RELEASENOTES.md" Write-Host "`nAdding comments to PRs..." +$successCount = 0 +$skipCount = 0 +$failCount = 0 +$failedPRs = @() + 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*" - } + # Check if we've already commented (check for active/open comments) + $existingCommentsJson = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '.[] | select(.body | contains("Release Notes Update Reminder")) | {id: .id, body: .body}' | ConvertFrom-Json -ErrorAction SilentlyContinue - if ($alreadyCommented) { - Write-Host " ℹ️ Comment already exists on PR #$prNumber, skipping..." - continue + # Check if there's an existing active comment + if ($existingCommentsJson) { + # Convert to array if single object + $existingComments = @($existingCommentsJson) + + if ($existingComments.Count -gt 0) { + Write-Host " ℹ️ Comment already exists on PR #$prNumber, skipping..." + $skipCount++ + continue + } } - # Add comment + # Add comment using gh CLI try { - $body = @{ - body = $comment - } | ConvertTo-Json + # Save comment to temp file to avoid escaping issues + $tempFile = [System.IO.Path]::GetTempFileName() + Set-Content -Path $tempFile -Value $comment -NoNewline + + gh pr comment $prNumber --repo "$Owner/$Repo" --body-file $tempFile - $response = Invoke-RestMethod -Uri $commentsUrl -Headers $headers -Method Post -Body $body -ContentType "application/json" - Write-Host " ✓ Comment added to PR #$prNumber" + Remove-Item -Path $tempFile -Force + + if ($LASTEXITCODE -eq 0) { + Write-Host " ✓ Comment added to PR #$prNumber" + $successCount++ + } else { + Write-Warning " ✗ Failed to add comment to PR #${prNumber}" + $failCount++ + $failedPRs += $prNumber + } } catch { - Write-Error " ✗ Failed to add comment to PR #${prNumber}: $_" + Write-Warning " ✗ Failed to add comment to PR #${prNumber}: $_" + $failCount++ + $failedPRs += $prNumber } } -Write-Host "`n✓ Done! Comments have been added to $($prsWithReleaseNotes.Count) PRs." +# Final summary +Write-Host "`n=========================================" +Write-Host "Summary:" +Write-Host " Total PRs with RELEASENOTES.md changes: $($prsWithReleaseNotes.Count)" +Write-Host " Comments added: $successCount" +Write-Host " Skipped (already commented): $skipCount" +Write-Host " Failed: $failCount" + +if ($failCount -gt 0) { + Write-Host "`n⚠️ Failed to add comments to the following PRs:" + foreach ($prNum in $failedPRs) { + Write-Host " - PR #$prNum" + } + Write-Host "`nPlease review these PRs manually." + exit 1 +} else { + Write-Host "`n✓ Done! All comments have been processed successfully." + exit 0 +} diff --git a/.github/workflows/check-release-notes-prs.yml b/.github/workflows/check-release-notes-prs.yml deleted file mode 100644 index 841abfe1bf..0000000000 --- a/.github/workflows/check-release-notes-prs.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Check Release Notes PRs - -on: - pull_request: - 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; - try { - const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); - if (versionMatch) { - currentVersion = 'v' + versionMatch[1]; - console.log('Detected current version: ' + currentVersion); - } else { - throw new Error("Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'"); - } - } catch (error) { - console.error('Error reading version from RELEASENOTES.md: ' + error.message); - throw error; - } - - // 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); - } diff --git a/.github/workflows/comment-on-existing-release-notes-prs.yml b/.github/workflows/comment-on-existing-release-notes-prs.yml deleted file mode 100644 index 04966534e8..0000000000 --- a/.github/workflows/comment-on-existing-release-notes-prs.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: Comment on Existing Release Notes PRs - -on: - workflow_dispatch: - 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; - try { - const releaseNotes = fs.readFileSync('RELEASENOTES.md', 'utf8'); - const versionMatch = releaseNotes.match(/^##\s*v(\d+\.\d+(?:\.\d+)?)/m); - if (versionMatch) { - currentVersion = 'v' + versionMatch[1]; - console.log('Detected current version: ' + currentVersion); - } else { - throw new Error("Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'"); - } - } catch (error) { - console.error('Error reading version from RELEASENOTES.md: ' + error.message); - throw error; - } - - 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}`); diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index 8c43d8e98c..a8c94cfef7 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -10,51 +10,40 @@ When multiple contributors update the release notes, there's a risk that changes ## Solution -The solution consists of two components: +### PowerShell Script for Adding Comments -### 1. Automated Workflow for New PRs +**File**: `.github/scripts/comment-on-existing-release-notes-prs.ps1` -**File**: `.github/workflows/check-release-notes-prs.yml` +This PowerShell script can be run manually to add reminder comments to all currently open PRs that modify `RELEASENOTES.md`. -This workflow automatically triggers when a PR is opened, updated, or reopened if it modifies the `RELEASENOTES.md` file. It: - -- Detects when `RELEASENOTES.md` has been changed in a PR -- Checks if a reminder comment already exists -- If not, adds a friendly comment reminding the contributor to place changes above the new version section - -**Trigger Conditions:** -- `pull_request` events: `opened`, `synchronize`, `reopened` -- Only when `RELEASENOTES.md` is modified - -**Permissions Required:** -- `pull-requests: write` - to add comments -- `contents: read` - to read the repository content - -### 2. One-Time Script for Existing PRs - -**Files**: -- `.github/scripts/comment-on-existing-release-notes-prs.ps1` (PowerShell script) -- `.github/workflows/comment-on-existing-release-notes-prs.yml` (Manual workflow) - -These are designed to be run once to add comments to all currently open PRs that modify `RELEASENOTES.md`. After the initial run, the automated workflow handles new PRs. - -**Usage (Recommended - 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 (preview only) -5. Click "Run workflow" to execute - -**Usage (Alternative - PowerShell Script):** +**Usage:** ```powershell +# Set GitHub token +$env:GH_TOKEN = "your-token-here" +# or $env:GITHUB_TOKEN = "your-token-here" + +# Run the script pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 ``` -What it does: -1. Fetches all open PRs (or uses a predefined list) -2. Checks which ones modify `RELEASENOTES.md` -3. Adds the reminder comment (if not already present) +**Key Features:** +- Uses GitHub CLI (`gh`) for better readability and maintainability +- Automatically detects current version from `RELEASENOTES.md` +- Checks for existing active comments to avoid duplicates +- Provides detailed summary with success/skip/fail counts +- Exits with error if any comments fail to add +- Lists failed PRs for manual review + +**What it does:** +1. Verifies GitHub CLI is installed and authenticated +2. Automatically detects the current version from `RELEASENOTES.md` +3. Fetches all open pull requests using `gh pr list` +4. Checks each PR to see if it modifies `RELEASENOTES.md` +5. For PRs that modify release notes: + - Checks if an active reminder comment already exists + - If not, adds the reminder comment +6. Provides a detailed summary report ## Comment Content @@ -81,29 +70,16 @@ This means no manual updates are needed when a new version is released - the com ## Implementation Details -### Workflow Implementation - -The workflow uses `actions/github-script@v7` which provides: -- GitHub API access via `github` object -- Context information via `context` object -- Checkout step to read `RELEASENOTES.md` for version detection - -**Key Features:** -- Only triggers on `RELEASENOTES.md` changes (path filter) -- Automatically detects current version from RELEASENOTES.md -- Checks for existing comments to avoid duplicates -- Uses Bot user type to identify its own comments -- Minimal permissions (read content, write comments) - ### Script Implementation The PowerShell script: -- Uses GitHub REST API directly -- Requires a GitHub token with PR comment permissions +- Uses GitHub CLI (`gh`) for better readability and maintainability +- Requires GitHub CLI to be installed and authenticated - Automatically detects current version from RELEASENOTES.md - Implements duplicate detection -- Provides detailed progress output -- Handles errors gracefully +- Tracks success, skip, and fail counts +- Provides detailed progress output and summary +- Handles errors gracefully and reports failures ## Maintenance @@ -120,15 +96,13 @@ You can monitor the automation by: ### Troubleshooting -**Workflow doesn't trigger:** -- Verify the PR modifies `RELEASENOTES.md` -- Check workflow permissions are correct -- Review the workflow run logs in Actions tab - **Script fails:** -- Ensure `GITHUB_TOKEN` is set and valid +- Ensure GitHub CLI (`gh`) is installed: https://cli.github.com/ +- Verify authentication: run `gh auth status` +- Set `GH_TOKEN` or `GITHUB_TOKEN` environment variable - Verify token has `pull-requests: write` permission - Check API rate limits aren't exceeded +- Ensure `RELEASENOTES.md` exists and contains a version header **Duplicate comments:** - The automation checks for existing comments @@ -144,14 +118,14 @@ Potential enhancements: ## Testing -To test the automation: +To test the script: -1. **Test Workflow**: Create a test PR that modifies `RELEASENOTES.md` -2. **Test Script**: Run the script with a test token in a fork -3. **Verify**: Check that comments are added correctly and duplicates are avoided +1. **Test Script**: Run the script with authentication in a fork or test repository +2. **Verify**: Check that comments are added correctly and duplicates are avoided +3. **Review**: Check the summary report for success/skip/fail counts ## References -- [GitHub Actions - actions/github-script](https://github.com/actions/github-script) +- [GitHub CLI Documentation](https://cli.github.com/manual/) - [GitHub REST API - Issues Comments](https://docs.github.com/en/rest/issues/comments) - [AL-Go Release Notes](../RELEASENOTES.md) From 64e0e5644d9616185f381459dd651ec75416e451 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:28:27 +0000 Subject: [PATCH 11/25] Fix error handling and add security notes per code review Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/README.md | 8 +++++++- .../comment-on-existing-release-notes-prs.ps1 | 18 +++++++++++------- docs/release-notes-pr-automation.md | 8 +++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/scripts/README.md b/.github/scripts/README.md index a697d3c0ca..8f5473dd58 100644 --- a/.github/scripts/README.md +++ b/.github/scripts/README.md @@ -9,7 +9,11 @@ This PowerShell script adds a reminder comment to all open PRs that modify the ` ### Usage ```powershell -# Set your GitHub token as an environment variable +# Option 1: Use gh auth login (recommended - more secure) +gh auth login + +# Option 2: Set GitHub token as environment variable +# Note: Tokens may be visible in shell history $env:GH_TOKEN = "your-github-token-here" # or $env:GITHUB_TOKEN = "your-github-token-here" @@ -18,6 +22,8 @@ $env:GITHUB_TOKEN = "your-github-token-here" pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 ``` +**Security Note:** When setting tokens directly, they may be visible in your shell history. Use `gh auth login` for better security. + ### Parameters - `Owner` (optional): Repository owner (default: "microsoft") diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index ed3a4ebada..072f05c84f 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -73,7 +73,13 @@ This helps maintain a clear changelog structure where new changes are grouped un Write-Host "Fetching open pull requests for $Owner/$Repo..." # Get all open PRs using gh CLI -$prsJson = gh pr list --repo "$Owner/$Repo" --state open --limit 100 --json number,title,files | ConvertFrom-Json +$prsJsonOutput = gh pr list --repo "$Owner/$Repo" --state open --limit 100 --json number,title,files +if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to fetch pull requests from GitHub" + exit 1 +} + +$prsJson = if ($prsJsonOutput) { $prsJsonOutput | ConvertFrom-Json } else { @() } Write-Host "Found $($prsJson.Count) open PRs. Checking which ones modify RELEASENOTES.md..." @@ -114,14 +120,12 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host "`nProcessing PR #${prNumber}: $prTitle" # Check if we've already commented (check for active/open comments) - $existingCommentsJson = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '.[] | select(.body | contains("Release Notes Update Reminder")) | {id: .id, body: .body}' | ConvertFrom-Json -ErrorAction SilentlyContinue + $existingCommentsOutput = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '[.[] | select(.body | contains("Release Notes Update Reminder")) | {id: .id}]' - # Check if there's an existing active comment - if ($existingCommentsJson) { - # Convert to array if single object - $existingComments = @($existingCommentsJson) + if ($LASTEXITCODE -eq 0 -and $existingCommentsOutput) { + $existingComments = $existingCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue - if ($existingComments.Count -gt 0) { + if ($existingComments -and $existingComments.Count -gt 0) { Write-Host " ℹ️ Comment already exists on PR #$prNumber, skipping..." $skipCount++ continue diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index a8c94cfef7..018d3cc9e4 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -18,7 +18,11 @@ This PowerShell script can be run manually to add reminder comments to all curre **Usage:** ```powershell -# Set GitHub token +# Option 1: Use gh auth login (recommended - more secure) +gh auth login + +# Option 2: Set GitHub token as environment variable +# Note: Tokens set this way may be visible in shell history $env:GH_TOKEN = "your-token-here" # or $env:GITHUB_TOKEN = "your-token-here" @@ -27,6 +31,8 @@ $env:GITHUB_TOKEN = "your-token-here" pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 ``` +**Security Note:** When setting tokens directly in the shell, they may be visible in your shell history. Consider using `gh auth login` or a secure credential manager for production use. + **Key Features:** - Uses GitHub CLI (`gh`) for better readability and maintainability - Automatically detects current version from `RELEASENOTES.md` From 10e3d2bda200d2e8d08d50559fb38d2393611a12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:30:11 +0000 Subject: [PATCH 12/25] Add finally block for temp file cleanup and simplify jq filter Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../scripts/comment-on-existing-release-notes-prs.ps1 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 072f05c84f..e72ce53315 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -120,7 +120,7 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host "`nProcessing PR #${prNumber}: $prTitle" # Check if we've already commented (check for active/open comments) - $existingCommentsOutput = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '[.[] | select(.body | contains("Release Notes Update Reminder")) | {id: .id}]' + $existingCommentsOutput = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '[.[] | select(.body | contains("Release Notes Update Reminder"))]' if ($LASTEXITCODE -eq 0 -and $existingCommentsOutput) { $existingComments = $existingCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue @@ -133,6 +133,7 @@ foreach ($pr in $prsWithReleaseNotes) { } # Add comment using gh CLI + $tempFile = $null try { # Save comment to temp file to avoid escaping issues $tempFile = [System.IO.Path]::GetTempFileName() @@ -140,8 +141,6 @@ foreach ($pr in $prsWithReleaseNotes) { gh pr comment $prNumber --repo "$Owner/$Repo" --body-file $tempFile - Remove-Item -Path $tempFile -Force - if ($LASTEXITCODE -eq 0) { Write-Host " ✓ Comment added to PR #$prNumber" $successCount++ @@ -156,6 +155,12 @@ foreach ($pr in $prsWithReleaseNotes) { $failCount++ $failedPRs += $prNumber } + finally { + # Always clean up temp file + if ($tempFile -and (Test-Path $tempFile)) { + Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue + } + } } # Final summary From c762f5b9a74d5fba497a5a1604dc212072c01cb4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:32:13 +0000 Subject: [PATCH 13/25] Fix regex to use multiline modifier for version detection Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/comment-on-existing-release-notes-prs.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index e72ce53315..974b6802ef 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -52,7 +52,7 @@ if (-not (Test-Path $releaseNotesPath)) { } $releaseNotesContent = Get-Content -Path $releaseNotesPath -Raw -if ($releaseNotesContent -match '^##\s*v(\d+\.\d+(?:\.\d+)?)') { +if ($releaseNotesContent -match '(?m)^##\s*v(\d+\.\d+(?:\.\d+)?)') { $currentVersion = "v$($matches[1])" Write-Host "Detected current version: $currentVersion" } else { From f608059500e5493950a8832e43e9544cf0436dcb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:34:11 +0000 Subject: [PATCH 14/25] Handle null result from ConvertFrom-Json on empty arrays Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../scripts/comment-on-existing-release-notes-prs.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index 974b6802ef..c76a3b6fbd 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -79,9 +79,14 @@ if ($LASTEXITCODE -ne 0) { exit 1 } -$prsJson = if ($prsJsonOutput) { $prsJsonOutput | ConvertFrom-Json } else { @() } +$prsJson = if ($prsJsonOutput) { + $result = $prsJsonOutput | ConvertFrom-Json + if ($null -eq $result) { @() } else { $result } +} else { + @() +} -Write-Host "Found $($prsJson.Count) open PRs. Checking which ones modify RELEASENOTES.md..." +Write-Host "Found $(@($prsJson).Count) open PRs. Checking which ones modify RELEASENOTES.md..." $prsWithReleaseNotes = @() From 7f92ee2bfb7eb842ffbc10eaf8c7bad5fc9b5e65 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:07:41 +0000 Subject: [PATCH 15/25] Remove support for vX.Y.Z format, only support vX.Y Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .github/scripts/comment-on-existing-release-notes-prs.ps1 | 4 ++-- docs/release-notes-pr-automation.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index c76a3b6fbd..cbda36a80b 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -52,11 +52,11 @@ if (-not (Test-Path $releaseNotesPath)) { } $releaseNotesContent = Get-Content -Path $releaseNotesPath -Raw -if ($releaseNotesContent -match '(?m)^##\s*v(\d+\.\d+(?:\.\d+)?)') { +if ($releaseNotesContent -match '(?m)^##\s*v(\d+\.\d+)') { $currentVersion = "v$($matches[1])" Write-Host "Detected current version: $currentVersion" } else { - Write-Error "Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y' or '## vX.Y.Z'" + Write-Error "Could not detect version from RELEASENOTES.md. Expected to find a line matching '## vX.Y'" exit 1 } diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md index 018d3cc9e4..560fd87e5e 100644 --- a/docs/release-notes-pr-automation.md +++ b/docs/release-notes-pr-automation.md @@ -68,7 +68,7 @@ This helps maintain a clear changelog structure where new changes are grouped un ## Automatic Version Detection The workflows and script automatically detect the current version from `RELEASENOTES.md` by: -- Reading the file and finding the first line matching the pattern `## vX.Y` or `## vX.Y.Z` +- Reading the file and finding the first line matching the pattern `## vX.Y` - Using the detected version in the comment message - **Failing with an error if the version cannot be detected** (ensures the automation is working correctly) From 7a54d948b8ca7d222664be13615c0aed63bf0430 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:12:14 +0000 Subject: [PATCH 16/25] Simplify array handling with @() operator Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../scripts/comment-on-existing-release-notes-prs.ps1 | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/scripts/comment-on-existing-release-notes-prs.ps1 index cbda36a80b..38081e42a5 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/scripts/comment-on-existing-release-notes-prs.ps1 @@ -79,14 +79,9 @@ if ($LASTEXITCODE -ne 0) { exit 1 } -$prsJson = if ($prsJsonOutput) { - $result = $prsJsonOutput | ConvertFrom-Json - if ($null -eq $result) { @() } else { $result } -} else { - @() -} +$prsJson = @($prsJsonOutput | ConvertFrom-Json) -Write-Host "Found $(@($prsJson).Count) open PRs. Checking which ones modify RELEASENOTES.md..." +Write-Host "Found $($prsJson.Count) open PRs. Checking which ones modify RELEASENOTES.md..." $prsWithReleaseNotes = @() From 0cd998e1f6d6ffad3fc140c5ce99ebb4aefca6e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:18:16 +0000 Subject: [PATCH 17/25] Move script to _Internal folder and remove separate documentation files Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 30 +++- .github/scripts/README.md | 56 ------- docs/release-notes-pr-automation.md | 137 ------------------ 3 files changed, 29 insertions(+), 194 deletions(-) rename .github/{scripts => _Internal}/comment-on-existing-release-notes-prs.ps1 (81%) delete mode 100644 .github/scripts/README.md delete mode 100644 docs/release-notes-pr-automation.md diff --git a/.github/scripts/comment-on-existing-release-notes-prs.ps1 b/.github/_Internal/comment-on-existing-release-notes-prs.ps1 similarity index 81% rename from .github/scripts/comment-on-existing-release-notes-prs.ps1 rename to .github/_Internal/comment-on-existing-release-notes-prs.ps1 index 38081e42a5..0ef214eb76 100644 --- a/.github/scripts/comment-on-existing-release-notes-prs.ps1 +++ b/.github/_Internal/comment-on-existing-release-notes-prs.ps1 @@ -8,14 +8,42 @@ and adds a reminder comment about placing changes above the new version section. Uses GitHub CLI (gh) for better readability and maintainability. + + The script will: + 1. Verify GitHub CLI is installed and authenticated + 2. Automatically detect the current version from RELEASENOTES.md + 3. Fetch all open pull requests using 'gh pr list' + 4. Check each PR to see if it modifies RELEASENOTES.md + 5. For PRs that modify the release notes: + - Check if an active reminder comment already exists + - If not, add a comment reminding contributors to place changes above the new version section + 6. Provide a detailed summary with success/skip/fail counts + 7. List any PRs where comment addition failed .PARAMETER Owner The repository owner (default: microsoft) .PARAMETER Repo The repository name (default: AL-Go) .EXAMPLE - # Set GH_TOKEN or GITHUB_TOKEN environment variable + # Recommended: Use gh auth login (more secure) + gh auth login + ./comment-on-existing-release-notes-prs.ps1 +.EXAMPLE + # Alternative: Set GH_TOKEN or GITHUB_TOKEN environment variable + # Note: Tokens may be visible in shell history $env:GH_TOKEN = "your-token-here" ./comment-on-existing-release-notes-prs.ps1 +.NOTES + Requirements: + - GitHub CLI (gh) installed: https://cli.github.com/ + - GitHub authentication (via 'gh auth login' or GH_TOKEN/GITHUB_TOKEN environment variable) + - PowerShell 7 or later + + Error Handling: + - Errors out if GitHub CLI is not installed + - Errors out if not authenticated + - Errors out if version cannot be detected from RELEASENOTES.md + - Tracks and reports failed comment additions + - Exit code 1 if any comments fail, 0 if all successful #> param( diff --git a/.github/scripts/README.md b/.github/scripts/README.md deleted file mode 100644 index 8f5473dd58..0000000000 --- a/.github/scripts/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# 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 uses GitHub CLI (gh) for better readability and maintainability. - -### Usage - -```powershell -# Option 1: Use gh auth login (recommended - more secure) -gh auth login - -# Option 2: Set GitHub token as environment variable -# Note: Tokens may be visible in shell history -$env:GH_TOKEN = "your-github-token-here" -# or -$env:GITHUB_TOKEN = "your-github-token-here" - -# Run the script -pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 -``` - -**Security Note:** When setting tokens directly, they may be visible in your shell history. Use `gh auth login` for better security. - -### Parameters - -- `Owner` (optional): Repository owner (default: "microsoft") -- `Repo` (optional): Repository name (default: "AL-Go") - -### What it does - -1. Verifies GitHub CLI is installed and authenticated -2. Automatically detects the current version from `RELEASENOTES.md` -3. Fetches all open pull requests in the repository using `gh pr list` -4. Checks each PR to see if it modifies `RELEASENOTES.md` -5. For PRs that do modify the release notes: - - Checks if an active reminder comment already exists - - If not, adds a comment reminding contributors to place their changes above the new version section -6. Provides a detailed summary with success/skip/fail counts -7. Lists any PRs where comment addition failed - -### Requirements - -- GitHub CLI (`gh`) installed: https://cli.github.com/ -- GitHub token with PR comment permissions (set via `GH_TOKEN` or `GITHUB_TOKEN`) -- PowerShell 7 or later - -### Error Handling - -- Errors out if GitHub CLI is not installed -- Errors out if not authenticated -- Errors out if version cannot be detected from `RELEASENOTES.md` -- Tracks and reports failed comment additions -- Exit code 1 if any comments fail, 0 if all successful diff --git a/docs/release-notes-pr-automation.md b/docs/release-notes-pr-automation.md deleted file mode 100644 index 560fd87e5e..0000000000 --- a/docs/release-notes-pr-automation.md +++ /dev/null @@ -1,137 +0,0 @@ -# Release Notes PR Automation - -## Overview - -This automation ensures that contributors are reminded to place their release note changes in the correct location within the `RELEASENOTES.md` file. - -## Problem - -When multiple contributors update the release notes, there's a risk that changes might be added to different version sections or in the wrong location. To maintain a clear and organized changelog, all new changes should be added under the latest/upcoming version section. - -## Solution - -### PowerShell Script for Adding Comments - -**File**: `.github/scripts/comment-on-existing-release-notes-prs.ps1` - -This PowerShell script can be run manually to add reminder comments to all currently open PRs that modify `RELEASENOTES.md`. - -**Usage:** -```powershell -# Option 1: Use gh auth login (recommended - more secure) -gh auth login - -# Option 2: Set GitHub token as environment variable -# Note: Tokens set this way may be visible in shell history -$env:GH_TOKEN = "your-token-here" -# or -$env:GITHUB_TOKEN = "your-token-here" - -# Run the script -pwsh .github/scripts/comment-on-existing-release-notes-prs.ps1 -``` - -**Security Note:** When setting tokens directly in the shell, they may be visible in your shell history. Consider using `gh auth login` or a secure credential manager for production use. - -**Key Features:** -- Uses GitHub CLI (`gh`) for better readability and maintainability -- Automatically detects current version from `RELEASENOTES.md` -- Checks for existing active comments to avoid duplicates -- Provides detailed summary with success/skip/fail counts -- Exits with error if any comments fail to add -- Lists failed PRs for manual review - -**What it does:** -1. Verifies GitHub CLI is installed and authenticated -2. Automatically detects the current version from `RELEASENOTES.md` -3. Fetches all open pull requests using `gh pr list` -4. Checks each PR to see if it modifies `RELEASENOTES.md` -5. For PRs that modify release notes: - - Checks if an active reminder comment already exists - - If not, adds the reminder comment -6. Provides a detailed summary report - -## Comment Content - -The comment added to PRs is: - -```markdown -### ⚠️ Release Notes Update Reminder - -Thank you for updating the release notes! - -Please ensure that your changes are placed **above the new version section** (currently `## v8.1`) in the RELEASENOTES.md file. - -This helps maintain a clear changelog structure where new changes are grouped under the latest unreleased version. -``` - -## Automatic Version Detection - -The workflows and script automatically detect the current version from `RELEASENOTES.md` by: -- Reading the file and finding the first line matching the pattern `## vX.Y` -- Using the detected version in the comment message -- **Failing with an error if the version cannot be detected** (ensures the automation is working correctly) - -This means no manual updates are needed when a new version is released - the comment will automatically reference the correct version. If version detection fails, it indicates an issue that needs to be addressed. - -## Implementation Details - -### Script Implementation - -The PowerShell script: -- Uses GitHub CLI (`gh`) for better readability and maintainability -- Requires GitHub CLI to be installed and authenticated -- Automatically detects current version from RELEASENOTES.md -- Implements duplicate detection -- Tracks success, skip, and fail counts -- Provides detailed progress output and summary -- Handles errors gracefully and reports failures - -## Maintenance - -### Automatic Updates - -The version number is automatically detected from `RELEASENOTES.md`, so no manual updates are needed when a new version is released. The workflows and script will automatically use the current version found in the file. - -### Monitoring - -You can monitor the automation by: -1. Checking PR comments for the reminder message -2. Reviewing workflow runs in the Actions tab -3. Checking for any workflow failures - -### Troubleshooting - -**Script fails:** -- Ensure GitHub CLI (`gh`) is installed: https://cli.github.com/ -- Verify authentication: run `gh auth status` -- Set `GH_TOKEN` or `GITHUB_TOKEN` environment variable -- Verify token has `pull-requests: write` permission -- Check API rate limits aren't exceeded -- Ensure `RELEASENOTES.md` exists and contains a version header - -**Duplicate comments:** -- The automation checks for existing comments -- If duplicates occur, check the comment detection logic - -## Future Improvements - -Potential enhancements: -1. Add validation to check if changes are actually in the correct section -2. Automatically detect the current version from RELEASENOTES.md -3. Add metrics/telemetry for tracking compliance -4. Create a pre-commit hook for local development - -## Testing - -To test the script: - -1. **Test Script**: Run the script with authentication in a fork or test repository -2. **Verify**: Check that comments are added correctly and duplicates are avoided -3. **Review**: Check the summary report for success/skip/fail counts - -## References - -- [GitHub CLI Documentation](https://cli.github.com/manual/) -- [GitHub REST API - Issues Comments](https://docs.github.com/en/rest/issues/comments) -- [AL-Go Release Notes](../RELEASENOTES.md) From 434f9afb48b6d9e3ca89c75a5cdf5e0c8e9d9729 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:23:47 +0000 Subject: [PATCH 18/25] Change to review comments on RELEASENOTES.md and rephrase message Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/.github/_Internal/comment-on-existing-release-notes-prs.ps1 b/.github/_Internal/comment-on-existing-release-notes-prs.ps1 index 0ef214eb76..499693be47 100644 --- a/.github/_Internal/comment-on-existing-release-notes-prs.ps1 +++ b/.github/_Internal/comment-on-existing-release-notes-prs.ps1 @@ -89,13 +89,11 @@ if ($releaseNotesContent -match '(?m)^##\s*v(\d+\.\d+)') { } $comment = @" -### ⚠️ Release Notes Update Reminder +A new version of AL-Go ($currentVersion) has been released. -Thank you for updating the release notes! +Please move your release notes changes to above the ``## $currentVersion`` section in the RELEASENOTES.md file. -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. +This ensures your changes are included in the next release rather than being listed under an already-released version. "@ Write-Host "Fetching open pull requests for $Owner/$Repo..." @@ -147,39 +145,51 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host "`nProcessing PR #${prNumber}: $prTitle" - # Check if we've already commented (check for active/open comments) - $existingCommentsOutput = gh api "/repos/$Owner/$Repo/issues/$prNumber/comments" --jq '[.[] | select(.body | contains("Release Notes Update Reminder"))]' + # Check if we've already commented (check for review comments on RELEASENOTES.md) + $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq '[.[] | select(.path == "RELEASENOTES.md" and (.body | contains("new version of AL-Go")))]' - if ($LASTEXITCODE -eq 0 -and $existingCommentsOutput) { - $existingComments = $existingCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue + if ($LASTEXITCODE -eq 0 -and $existingReviewCommentsOutput) { + $existingReviewComments = $existingReviewCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue - if ($existingComments -and $existingComments.Count -gt 0) { - Write-Host " ℹ️ Comment already exists on PR #$prNumber, skipping..." + if ($existingReviewComments -and $existingReviewComments.Count -gt 0) { + Write-Host " ℹ️ Review comment already exists on RELEASENOTES.md in PR #$prNumber, skipping..." $skipCount++ continue } } - # Add comment using gh CLI + # Add review comment on RELEASENOTES.md file $tempFile = $null try { - # Save comment to temp file to avoid escaping issues + # Get the commit SHA for the PR + $prDetails = gh api "/repos/$Owner/$Repo/pulls/$prNumber" | ConvertFrom-Json + $commitSha = $prDetails.head.sha + + # Create review comment payload + $reviewCommentBody = @{ + body = $comment + path = "RELEASENOTES.md" + commit_id = $commitSha + } | ConvertTo-Json -Compress + + # Save to temp file $tempFile = [System.IO.Path]::GetTempFileName() - Set-Content -Path $tempFile -Value $comment -NoNewline + Set-Content -Path $tempFile -Value $reviewCommentBody -NoNewline - gh pr comment $prNumber --repo "$Owner/$Repo" --body-file $tempFile + # Post the review comment + $response = gh api -X POST "/repos/$Owner/$Repo/pulls/$prNumber/comments" --input $tempFile if ($LASTEXITCODE -eq 0) { - Write-Host " ✓ Comment added to PR #$prNumber" + Write-Host " ✓ Review comment added to RELEASENOTES.md in PR #$prNumber" $successCount++ } else { - Write-Warning " ✗ Failed to add comment to PR #${prNumber}" + Write-Warning " ✗ Failed to add review comment to PR #${prNumber}" $failCount++ $failedPRs += $prNumber } } catch { - Write-Warning " ✗ Failed to add comment to PR #${prNumber}: $_" + Write-Warning " ✗ Failed to add review comment to PR #${prNumber}: $_" $failCount++ $failedPRs += $prNumber } From cb95a1dec268e7c81c5b98e578e3f9d49d69e256 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 10:20:51 +0000 Subject: [PATCH 19/25] Move script to Internal/Scripts folder at repository root Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../Scripts}/comment-on-existing-release-notes-prs.ps1 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {.github/_Internal => Internal/Scripts}/comment-on-existing-release-notes-prs.ps1 (100%) diff --git a/.github/_Internal/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 similarity index 100% rename from .github/_Internal/comment-on-existing-release-notes-prs.ps1 rename to Internal/Scripts/comment-on-existing-release-notes-prs.ps1 From 26de9921717cf822d0f2506dbacfe52bb524c481 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 14:34:07 +0000 Subject: [PATCH 20/25] Include current version in existing comment check Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- Internal/Scripts/comment-on-existing-release-notes-prs.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 index 499693be47..7cb6b9d584 100644 --- a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 +++ b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 @@ -146,7 +146,8 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host "`nProcessing PR #${prNumber}: $prTitle" # Check if we've already commented (check for review comments on RELEASENOTES.md) - $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq '[.[] | select(.path == "RELEASENOTES.md" and (.body | contains("new version of AL-Go")))]' + $searchText = "A new version of AL-Go ($currentVersion) has been released." + $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq "[.[] | select(.path == `"RELEASENOTES.md`" and (.body | contains(`"$searchText`")))]" if ($LASTEXITCODE -eq 0 -and $existingReviewCommentsOutput) { $existingReviewComments = $existingReviewCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue From a063f9d60d19603707e2252254a3749bc1399fcb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 14:38:13 +0000 Subject: [PATCH 21/25] Fix trailing whitespace in script Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 index 7cb6b9d584..cbf7528e02 100644 --- a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 +++ b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 @@ -6,9 +6,9 @@ .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. - + Uses GitHub CLI (gh) for better readability and maintainability. - + The script will: 1. Verify GitHub CLI is installed and authenticated 2. Automatically detect the current version from RELEASENOTES.md @@ -37,7 +37,7 @@ - GitHub CLI (gh) installed: https://cli.github.com/ - GitHub authentication (via 'gh auth login' or GH_TOKEN/GITHUB_TOKEN environment variable) - PowerShell 7 or later - + Error Handling: - Errors out if GitHub CLI is not installed - Errors out if not authenticated @@ -114,10 +114,10 @@ $prsWithReleaseNotes = @() foreach ($pr in $prsJson) { $prNumber = $pr.number Write-Host "Checking PR #$prNumber..." - + # Check if RELEASENOTES.md was modified $releaseNotesModified = $pr.files | Where-Object { $_.path -eq "RELEASENOTES.md" } - + if ($releaseNotesModified) { Write-Host " ✓ PR #$prNumber modifies RELEASENOTES.md" $prsWithReleaseNotes += $pr @@ -142,44 +142,44 @@ $failedPRs = @() foreach ($pr in $prsWithReleaseNotes) { $prNumber = $pr.number $prTitle = $pr.title - + Write-Host "`nProcessing PR #${prNumber}: $prTitle" - + # Check if we've already commented (check for review comments on RELEASENOTES.md) $searchText = "A new version of AL-Go ($currentVersion) has been released." $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq "[.[] | select(.path == `"RELEASENOTES.md`" and (.body | contains(`"$searchText`")))]" - + if ($LASTEXITCODE -eq 0 -and $existingReviewCommentsOutput) { $existingReviewComments = $existingReviewCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue - + if ($existingReviewComments -and $existingReviewComments.Count -gt 0) { Write-Host " ℹ️ Review comment already exists on RELEASENOTES.md in PR #$prNumber, skipping..." $skipCount++ continue } } - + # Add review comment on RELEASENOTES.md file $tempFile = $null try { # Get the commit SHA for the PR $prDetails = gh api "/repos/$Owner/$Repo/pulls/$prNumber" | ConvertFrom-Json $commitSha = $prDetails.head.sha - + # Create review comment payload $reviewCommentBody = @{ body = $comment path = "RELEASENOTES.md" commit_id = $commitSha } | ConvertTo-Json -Compress - + # Save to temp file $tempFile = [System.IO.Path]::GetTempFileName() Set-Content -Path $tempFile -Value $reviewCommentBody -NoNewline - + # Post the review comment $response = gh api -X POST "/repos/$Owner/$Repo/pulls/$prNumber/comments" --input $tempFile - + if ($LASTEXITCODE -eq 0) { Write-Host " ✓ Review comment added to RELEASENOTES.md in PR #$prNumber" $successCount++ From 0f405e73953f4e8398fdd4de11881da1e0ea1732 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:06:40 +0000 Subject: [PATCH 22/25] Fix file encoding to UTF-8 with BOM for PSScriptAnalyzer Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- Internal/Scripts/comment-on-existing-release-notes-prs.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 index cbf7528e02..e3ab5221dc 100644 --- a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 +++ b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 @@ -1,4 +1,4 @@ -#!/usr/bin/env pwsh +#!/usr/bin/env pwsh <# .SYNOPSIS From e26d8d6dc5d49a441ae3972de26510a616d469ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 23:02:57 +0000 Subject: [PATCH 23/25] Address PR review comments - fix API payload, error handling, and limits Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- .../comment-on-existing-release-notes-prs.ps1 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 index e3ab5221dc..a06b00591b 100644 --- a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 +++ b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 @@ -51,8 +51,7 @@ param( [string]$Repo = "AL-Go" ) -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 # Check if gh CLI is available if (-not (Get-Command gh -ErrorAction SilentlyContinue)) { @@ -99,7 +98,8 @@ This ensures your changes are included in the next release rather than being lis Write-Host "Fetching open pull requests for $Owner/$Repo..." # Get all open PRs using gh CLI -$prsJsonOutput = gh pr list --repo "$Owner/$Repo" --state open --limit 100 --json number,title,files +# NOTE: The maximum limit for 'gh pr list' is 1000. If the repository has more than 1000 open PRs, some may be missed. +$prsJsonOutput = gh pr list --repo "$Owner/$Repo" --state open --limit 1000 --json number,title,files if ($LASTEXITCODE -ne 0) { Write-Error "Failed to fetch pull requests from GitHub" exit 1 @@ -147,12 +147,13 @@ foreach ($pr in $prsWithReleaseNotes) { # Check if we've already commented (check for review comments on RELEASENOTES.md) $searchText = "A new version of AL-Go ($currentVersion) has been released." - $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq "[.[] | select(.path == `"RELEASENOTES.md`" and (.body | contains(`"$searchText`")))]" + $escapedSearchText = $searchText -replace '\\', '\\\\' -replace '"', '\"' + $existingReviewCommentsOutput = gh api "/repos/$Owner/$Repo/pulls/$prNumber/comments" --jq "[.[] | select(.path == `"RELEASENOTES.md`" and (.body | contains(`"$escapedSearchText`")))]" - if ($LASTEXITCODE -eq 0 -and $existingReviewCommentsOutput) { + if ($LASTEXITCODE -eq 0) { $existingReviewComments = $existingReviewCommentsOutput | ConvertFrom-Json -ErrorAction SilentlyContinue - if ($existingReviewComments -and $existingReviewComments.Count -gt 0) { + if ($existingReviewComments -and @($existingReviewComments).Count -gt 0) { Write-Host " ℹ️ Review comment already exists on RELEASENOTES.md in PR #$prNumber, skipping..." $skipCount++ continue @@ -171,6 +172,7 @@ foreach ($pr in $prsWithReleaseNotes) { body = $comment path = "RELEASENOTES.md" commit_id = $commitSha + line = 1 } | ConvertTo-Json -Compress # Save to temp file @@ -184,13 +186,13 @@ foreach ($pr in $prsWithReleaseNotes) { Write-Host " ✓ Review comment added to RELEASENOTES.md in PR #$prNumber" $successCount++ } else { - Write-Warning " ✗ Failed to add review comment to PR #${prNumber}" + Write-Host " ✗ Failed to add review comment to PR #${prNumber}" $failCount++ $failedPRs += $prNumber } } catch { - Write-Warning " ✗ Failed to add review comment to PR #${prNumber}: $_" + Write-Host " ✗ Failed to add review comment to PR #${prNumber}: $_" $failCount++ $failedPRs += $prNumber } From f508d16500bc73eca058f141c90890ed9b1c0bd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:01:52 +0000 Subject: [PATCH 24/25] Remove unused response variable to fix PSScriptAnalyzer alert Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- Internal/Scripts/comment-on-existing-release-notes-prs.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 index a06b00591b..69cd5ce627 100644 --- a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 +++ b/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 @@ -180,7 +180,7 @@ foreach ($pr in $prsWithReleaseNotes) { Set-Content -Path $tempFile -Value $reviewCommentBody -NoNewline # Post the review comment - $response = gh api -X POST "/repos/$Owner/$Repo/pulls/$prNumber/comments" --input $tempFile + gh api -X POST "/repos/$Owner/$Repo/pulls/$prNumber/comments" --input $tempFile | Out-Null if ($LASTEXITCODE -eq 0) { Write-Host " ✓ Review comment added to RELEASENOTES.md in PR #$prNumber" From 5c9b83163be2d035abd2f5e464fc0877f840b987 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:12:11 +0000 Subject: [PATCH 25/25] Rename script to PascalCase to match repository convention Co-authored-by: mazhelez <43066499+mazhelez@users.noreply.github.com> --- ...release-notes-prs.ps1 => CommentOnExistingReleaseNotesPrs.ps1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Internal/Scripts/{comment-on-existing-release-notes-prs.ps1 => CommentOnExistingReleaseNotesPrs.ps1} (100%) diff --git a/Internal/Scripts/comment-on-existing-release-notes-prs.ps1 b/Internal/Scripts/CommentOnExistingReleaseNotesPrs.ps1 similarity index 100% rename from Internal/Scripts/comment-on-existing-release-notes-prs.ps1 rename to Internal/Scripts/CommentOnExistingReleaseNotesPrs.ps1