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 @@ -8,6 +8,11 @@ jobs:
fetchDepth: 0

- template: /eng/pipelines/templates/steps/install-dotnet.yml

- ${{ if endsWith(parameters.Repository, '-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) {
$repo = $env:BUILD_REPOSITORY_NAME
if (-not $repo) {
$repo = "microsoft/mcp"
}
$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/.*\.yml$' -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
}