Skip to content

Commit b2d05c1

Browse files
authored
feat: Automate promotion of analyzer release documentation (#479)
Introduces a GitHub Actions workflow to automatically move new analyzer rule entries from `AnalyzerReleases.Unshipped.md` to `AnalyzerReleases.Shipped.md` when a new version tag is pushed. This streamlines the release process and ensures accurate publication of analyzer release notes.
1 parent 9b43cd5 commit b2d05c1

2 files changed

Lines changed: 117 additions & 3 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
[CmdletBinding()]
2+
param(
3+
[Parameter(Mandatory = $true)]
4+
[string]$PackageVersion,
5+
6+
[Parameter()]
7+
[string]$UnshippedPath = ".\Moq.AutoMocker.Generators\AnalyzerReleases.Unshipped.md",
8+
9+
[Parameter()]
10+
[string]$ShippedPath = ".\Moq.AutoMocker.Generators\AnalyzerReleases.Shipped.md"
11+
)
12+
13+
Set-StrictMode -Version Latest
14+
$ErrorActionPreference = "Stop"
15+
16+
function Normalize-LineEndings {
17+
param([string]$Content)
18+
19+
return $Content -replace "`r`n?", "`n"
20+
}
21+
22+
function Has-RuleEntries {
23+
param([string[]]$Lines)
24+
25+
foreach ($line in $Lines) {
26+
$trimmed = $line.Trim()
27+
28+
if ([string]::IsNullOrWhiteSpace($trimmed)) {
29+
continue
30+
}
31+
32+
if ($trimmed.StartsWith("### ", [System.StringComparison]::Ordinal)) {
33+
continue
34+
}
35+
36+
if ($trimmed -eq "Rule ID | Category | Severity | Notes") {
37+
continue
38+
}
39+
40+
if ($trimmed -match '^-+\|-+\|-+\|-+$') {
41+
continue
42+
}
43+
44+
if ($trimmed.StartsWith("## Release ", [System.StringComparison]::Ordinal)) {
45+
continue
46+
}
47+
48+
return $true
49+
}
50+
51+
return $false
52+
}
53+
54+
if ($PackageVersion.Contains("-", [System.StringComparison]::Ordinal)) {
55+
Write-Host "Package version '$PackageVersion' is a prerelease. Skipping analyzer release promotion."
56+
exit 0
57+
}
58+
59+
$unshippedContent = [System.IO.File]::ReadAllText($UnshippedPath)
60+
$shippedContent = [System.IO.File]::ReadAllText($ShippedPath)
61+
62+
$normalizedUnshipped = Normalize-LineEndings -Content $unshippedContent
63+
$normalizedShipped = Normalize-LineEndings -Content $shippedContent
64+
$unshippedLines = $normalizedUnshipped.Split("`n")
65+
66+
if (-not (Has-RuleEntries -Lines $unshippedLines)) {
67+
Write-Host "No unshipped analyzer entries found. Skipping analyzer release promotion."
68+
exit 0
69+
}
70+
71+
$releaseHeading = "## Release $PackageVersion"
72+
if ($normalizedShipped -match "(?m)^$([regex]::Escape($releaseHeading))\s*$") {
73+
Write-Host "Release heading '$releaseHeading' already exists. Skipping analyzer release promotion."
74+
exit 0
75+
}
76+
77+
$releaseBlock = "{0}`n`n{1}" -f $releaseHeading, $normalizedUnshipped.Trim()
78+
$newShipped = if ([string]::IsNullOrWhiteSpace($normalizedShipped)) {
79+
"$releaseBlock`n"
80+
}
81+
else {
82+
"{0}`n`n{1}`n" -f $normalizedShipped.TrimEnd(), $releaseBlock
83+
}
84+
85+
$cleanUnshippedLines = foreach ($line in $unshippedLines) {
86+
if ($line.Trim() -match '^[A-Za-z]{2,}\d{4}\s*\|') {
87+
continue
88+
}
89+
90+
$line.TrimEnd()
91+
}
92+
93+
$newUnshipped = ($cleanUnshippedLines -join "`n").TrimEnd()
94+
if ([string]::IsNullOrWhiteSpace($newUnshipped)) {
95+
$newUnshipped = @(
96+
"### New Rules",
97+
"",
98+
"Rule ID | Category | Severity | Notes",
99+
"--------|----------|----------|-------"
100+
) -join "`n"
101+
}
102+
103+
$utf8Bom = [System.Text.UTF8Encoding]::new($true)
104+
[System.IO.File]::WriteAllText($ShippedPath, ($newShipped -replace "`n", "`r`n"), $utf8Bom)
105+
[System.IO.File]::WriteAllText($UnshippedPath, (($newUnshipped -replace "`n", "`r`n") + "`r`n"), $utf8Bom)
106+
107+
Write-Host "Promoted analyzer release entries for version '$PackageVersion'."

.github/workflows/dotnetcore.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ jobs:
8282
--configuration Release `
8383
--verbosity normal `
8484
/p:LocalNuGetSource=true
85+
86+
# Move analyzer rules to shipped docs for tag releases
87+
- name: Promote Analyzer Release Docs
88+
if: startsWith(github.ref, 'refs/tags/v')
89+
run: |
90+
$packageVersion = '${{ github.ref_name }}'.Substring(1)
91+
.\.github\scripts\Promote-AnalyzerReleaseDocs.ps1 -PackageVersion $packageVersion
8592
8693
# Update the docs
8794
- name: Update Docs
@@ -101,14 +108,14 @@ jobs:
101108
if: github.event_name == 'push'
102109
with:
103110
commit-message: |
104-
[Docs update detected by Github Action].
111+
[Generated updates detected by GitHub Action].
105112
Auto generated pull request.
106113
branch: docs/automated-update
107114
delete-branch: true
108115
base: master
109-
title: Update Docs [GitHub Action]
116+
title: Update generated docs [GitHub Action]
110117
body: |
111-
[Docs update detected by Github Action].
118+
[Generated updates detected by GitHub Action].
112119
Auto generated pull request.
113120
114121
# Publish to NuGet and GitHub Packages

0 commit comments

Comments
 (0)