Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eng/pipelines/templates/jobs/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ jobs:
displayName: "Install Node.js 22"
inputs:
versionSpec: '22.x'

- ${{ if endsWith(variables['Build.Repository.Name'], '-pr') }}:
- template: /eng/common/pipelines/templates/steps/login-to-github.yml
parameters:
TokenOwners: ['Microsoft']

- task: Powershell@2
displayName: "Run source analysis"
Expand Down
10 changes: 10 additions & 0 deletions eng/scripts/Analyze-Code.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ try {
Write-Host "✅ Tool id validation passed."
}

# Run changelog entry validation
& "$PSScriptRoot/Test-ChangelogEntry.ps1"

if ($LASTEXITCODE -ne 0) {
Write-Host "❌ Changelog entry validation failed"
$hasErrors = $true
} else {
Write-Host "✅ Changelog entry validation passed."
}

if($hasErrors) {
exit 1
}
Expand Down
63 changes: 63 additions & 0 deletions eng/scripts/Test-ChangelogEntry.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env pwsh
#Requires -Version 7

# Validates that a PR includes a changelog entry or has the 'skip-changelog' label.

. "$PSScriptRoot/../common/scripts/common.ps1"

# Fetch PR labels once at the start via GitHub REST API
$prNumber = $env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER
$prLabels = @()
if ($prNumber) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking for changelog files before fetching labels. Most PRs that include a changelog entry don't need the label check at all, and this way the build won't break if the API call fails for any reason (auth issue, rate limit, wrong repo name):

# Check changed files first
Push-Location $RepoRoot
$changedFiles = git diff --name-only --diff-filter=AM origin/main...HEAD
$hasChangelog = $changedFiles | Where-Object { $_ -match 'changelog-entries/.*\.ya?ml$' -or $_ -match 'CHANGELOG\.md' }
if ($hasChangelog) {
    Write-Host "Found changelog entry"
    exit 0
}
Pop-Location

# Only fetch labels if no changelog files found
if ($prNumber) {
    # ... label fetch logic
}

$repo = $env:BUILD_REPOSITORY_NAME
if (-not $repo) {
$repo = "microsoft/mcp"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Build.Repository.Name is microsoft/mcp-pr in PR validation pipelines (which the endsWith(..., '-pr') condition in analyze.yml is designed to detect), this variable would be microsoft/mcp-pr and the API call on line 17 would hit a non-existent GitHub repo.

Consider stripping the suffix:

Suggested change
$repo = "microsoft/mcp"
$repo = $env:BUILD_REPOSITORY_NAME
if (-not $repo) {
$repo = "microsoft/mcp"
}
$repo = $repo -replace '-pr$', ''

}
$apiUrl = "https://api.github.com/repos/$repo/pulls/$prNumber"
$headers = @{ "Accept" = "application/vnd.github+json"; "User-Agent" = "mcp-changelog-check" }
if ($env:GH_TOKEN) {
$headers["Authorization"] = "Bearer $($env:GH_TOKEN)"
}
try {
$response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Get -ErrorAction Stop
$prLabels = @($response.labels | ForEach-Object { $_.name })
Write-Host "PR #$prNumber labels: $($prLabels -join ', ')"
}
catch {
Write-Error "Failed to fetch PR labels from GitHub API for PR #$prNumber. Unable to validate whether the 'skip-changelog' label is present. Ensure the GitHub authentication step ran and GH_TOKEN is available, then retry. Underlying error: $_"
exit 1
}
}

Push-Location $RepoRoot
try {
$diffRange = "origin/main...HEAD"
$changedFiles = git diff --name-only --diff-filter=AM $diffRange 2>&1
if ($LASTEXITCODE -ne 0) {
$gitError = ($changedFiles | Out-String).Trim()
Write-Error "Failed to determine changed files with 'git diff --name-only --diff-filter=AM $diffRange'. $gitError"
exit 1
}
$hasChangelog = $changedFiles | Where-Object { $_ -match 'changelog-entries/.*\.ya?ml$' -or $_ -match 'CHANGELOG\.md'}

if ($hasChangelog) {
Write-Host "Found changelog entry: $($hasChangelog -join ', ')"
exit 0
}

if (-not $prNumber) {
Write-Host "Not a PR build - skipping skip-changelog label check."
exit 0
}

if ($prLabels -contains 'skip-changelog') {
Write-Host "'skip-changelog' label found — skipping."
exit 0
}

Write-Error "Add a changelog entry to the PR or apply the 'skip-changelog' label."
exit 1
}
finally {
Pop-Location
}