Skip to content

Commit 3c69a12

Browse files
authored
Add release preparation script (#14680)
1 parent 258a303 commit 3c69a12

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

eng/scripts/Prepare-Release.ps1

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
[CmdletBinding()]
2+
param(
3+
[Parameter(Mandatory=$true)]
4+
$package
5+
)
6+
7+
function Get-LevenshteinDistance {
8+
<#
9+
.SYNOPSIS
10+
Get the Levenshtein distance between two strings.
11+
.DESCRIPTION
12+
The Levenshtein Distance is a way of quantifying how dissimilar two strings (e.g., words) are to one another by counting the minimum number of operations required to transform one string into the other.
13+
.EXAMPLE
14+
Get-LevenshteinDistance 'kitten' 'sitting'
15+
.LINK
16+
http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.23
17+
http://en.wikipedia.org/wiki/Edit_distance
18+
https://communary.wordpress.com/
19+
https://github.com/gravejester/Communary.PASM
20+
.NOTES
21+
Author: Øyvind Kallstad
22+
Date: 07.11.2014
23+
Version: 1.0
24+
#>
25+
[CmdletBinding()]
26+
param(
27+
[Parameter(Position = 0)]
28+
[string]$String1,
29+
30+
[Parameter(Position = 1)]
31+
[string]$String2,
32+
33+
# Makes matches case-sensitive. By default, matches are not case-sensitive.
34+
[Parameter()]
35+
[switch] $CaseSensitive,
36+
37+
# A normalized output will fall in the range 0 (perfect match) to 1 (no match).
38+
[Parameter()]
39+
[switch] $NormalizeOutput
40+
)
41+
42+
if (-not($CaseSensitive)) {
43+
$String1 = $String1.ToLowerInvariant()
44+
$String2 = $String2.ToLowerInvariant()
45+
}
46+
47+
$d = New-Object 'Int[,]' ($String1.Length + 1), ($String2.Length + 1)
48+
for ($i = 0; $i -le $d.GetUpperBound(0); $i++) {
49+
$d[$i,0] = $i
50+
}
51+
52+
for ($i = 0; $i -le $d.GetUpperBound(1); $i++) {
53+
$d[0,$i] = $i
54+
}
55+
56+
for ($i = 1; $i -le $d.GetUpperBound(0); $i++) {
57+
for ($j = 1; $j -le $d.GetUpperBound(1); $j++) {
58+
$cost = [Convert]::ToInt32((-not($String1[$i1] -ceq $String2[$j1])))
59+
$min1 = $d[($i1),$j] + 1
60+
$min2 = $d[$i,($j1)] + 1
61+
$min3 = $d[($i1),($j1)] + $cost
62+
$d[$i,$j] = [Math]::Min([Math]::Min($min1,$min2),$min3)
63+
}
64+
}
65+
66+
$distance = ($d[$d.GetUpperBound(0),$d.GetUpperBound(1)])
67+
68+
if ($NormalizeOutput) {
69+
return (1 – ($distance) / ([Math]::Max($String1.Length,$String2.Length)))
70+
}
71+
72+
else {
73+
return $distance
74+
}
75+
}
76+
77+
$ErrorPreference = 'Stop'
78+
$repoRoot = Resolve-Path "$PSScriptRoot/../..";
79+
80+
if (!(Get-Command az)) {
81+
throw 'You must have the Azure CLI installed: https://aka.ms/azure-cli'
82+
}
83+
84+
. ${repoRoot}\eng\common\scripts\SemVer.ps1
85+
. ${repoRoot}\eng\common\scripts\ChangeLog-Operations.ps1
86+
87+
$packageDirectory = Get-ChildItem "$repoRoot/sdk" -Directory -Recurse -Depth 2 -Filter $package
88+
$serviceDirectory = $packageDirectory.Parent.Name
89+
90+
Write-Host "Source directory $serviceDirectory"
91+
92+
$existing = Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/$($package.ToLower())/index.json" | ConvertFrom-Json;
93+
94+
$libraryType = "Preview";
95+
$latestVersion = "unknown";
96+
foreach ($existingVersion in $existing.versions)
97+
{
98+
$parsedVersion = [AzureEngSemanticVersion]::new($existingVersion)
99+
if (!$parsedVersion.IsPrerelease)
100+
{
101+
$libraryType = "GA"
102+
}
103+
104+
$latestVersion = $existingVersion;
105+
}
106+
107+
$currentProjectVersion = ([xml](Get-Content "$packageDirectory/src/*.csproj")).Project.PropertyGroup.Version
108+
109+
Write-Host
110+
Write-Host "Latest released version $latestVersion, library type $libraryType" -ForegroundColor Green
111+
112+
$newVersion = Read-Host -Prompt "Input the new version or press Enter to use use current project version '$currentProjectVersion'"
113+
114+
if (!$newVersion)
115+
{
116+
$newVersion = $currentProjectVersion;
117+
}
118+
119+
$releaseType = "None";
120+
$parsedNewVersion = [AzureEngSemanticVersion]::new($newVersion)
121+
if ($parsedNewVersion.Major -ne $parsedVersion.Major)
122+
{
123+
$releaseType = "Major"
124+
}
125+
elseif ($parsedNewVersion.Minor -ne $parsedVersion.Minor)
126+
{
127+
$releaseType = "Minor"
128+
}
129+
elseif ($parsedNewVersion.Patch -ne $parsedVersion.Patch)
130+
{
131+
$releaseType = "Bugfix"
132+
}
133+
elseif ($parsedNewVersion.IsPrerelease)
134+
{
135+
$releaseType = "Bugfix"
136+
}
137+
138+
Write-Host
139+
Write-Host "Detected released type $releaseType" -ForegroundColor Green
140+
141+
Write-Host
142+
Write-Host "Updating versions" -ForegroundColor Green
143+
144+
& "$repoRoot\eng\scripts\Update-PkgVersion.ps1" -ServiceDirectory $serviceDirectory -PackageName $package -NewVersionString $newVersion
145+
146+
$date = Get-Date
147+
$month = $date.ToString("MMMM")
148+
if ($date.Day -gt 15)
149+
{
150+
$month = $date.AddMonths(1).ToString("MMMM")
151+
}
152+
Write-Host
153+
Write-Host "Assuming release is in $month" -ForegroundColor Green
154+
155+
$commonParameter = @("--organization", "https://dev.azure.com/azure-sdk", "-o", "json", "--only-show-errors")
156+
157+
$workItems = az boards query @commonParameter --project Release --wiql "SELECT [ID], [State], [Iteration Path], [Title] FROM WorkItems WHERE [State] <> 'Closed' AND [Iteration Path] under 'Release\2020\$month' AND [Title] contains '.NET'" | ConvertFrom-Json;
158+
159+
Write-Host
160+
Write-Host "The following work items exist:"
161+
foreach ($item in $workItems)
162+
{
163+
$id = $item.fields."System.ID";
164+
$title = $item.fields."System.Title";
165+
$path = $item.fields."System.IterationPath";
166+
Write-Host "$id - $path - $title"
167+
}
168+
169+
# Sort using fuzzy match
170+
$workItems = $workItems | Sort-Object -property @{Expression = { Get-LevenshteinDistance $_.fields."System.Title" $package -NormalizeOutput }}
171+
$mostProbable = $workItems | Select-Object -Last 1
172+
173+
$issueId = Read-Host -Prompt "Input the work item ID or press Enter to use '$($mostProbable.fields."System.ID") - $($mostProbable.fields."System.Title")'"
174+
175+
if (!$issueId)
176+
{
177+
$issueId = $mostProbable.fields."System.ID"
178+
}
179+
180+
$fields = @{
181+
"Permalink usetag"="https://github.com/Azure/azure-sdk-for-net/sdk/$serviceDirectory/$package/README.md"
182+
"Package Registry Permalink"="https://nuget.org/packages/$package/$newVersion"
183+
"Library Type"=$libraryType
184+
"Release Type"=$releaseType
185+
"Version Number"=$newVersion
186+
}
187+
188+
Write-Host
189+
Write-Host "Going to set the following fields:" -ForegroundColor Green
190+
191+
foreach ($field in $fields.Keys)
192+
{
193+
Write-Host " $field = $($fields[$field])"
194+
}
195+
196+
$decision = $Host.UI.PromptForChoice("Updating work item https://dev.azure.com/azure-sdk/Release/_workitems/edit/$issueId", 'Are you sure you want to proceed?', @('&Yes'; '&No'), 0)
197+
198+
if ($decision -eq 0)
199+
{
200+
az boards work-item update @commonParameter --id $issueId --state Active > $null
201+
foreach ($field in $fields.Keys)
202+
{
203+
az boards work-item update @commonParameter --id $issueId -f "$field=$($fields[$field])" > $null
204+
}
205+
}
206+
207+
$changeLogEntry = Get-ChangeLogEntry -ChangeLogLocation "$packageDirectory/CHANGELOG.md" -VersionString $newVersion
208+
209+
$githubAnchor = $changeLogEntry.ReleaseTitle.Replace("## ", "").Replace(".", "").Replace("(", "").Replace(")", "").Replace(" ", "-")
210+
Write-Host
211+
Write-Host "Snippet for the centralized CHANGELOG:" -ForegroundColor Green
212+
Write-Host "dotnet add package $package --version $newVersion"
213+
Write-Host "### $package [Changelog](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/$serviceDirectory/$package/CHANGELOG.md#$githubAnchor)"
214+
$changeLogEntry.ReleaseContent | Write-Host
215+

0 commit comments

Comments
 (0)