Skip to content

Commit 04fa5c5

Browse files
authored
Cover all packages in version bump scripts (#1711)
## Motivation The version bump scripts only updated a subset of the packages they release. In particular, `UnitsNet.NumberExtensions.CS14` and `UnitsNet.Serialization.SystemTextJson` could be left on the previous version. UnitsNet.Modular also had no equivalent bump command for its MinVer tag stream. ## Changes - Update the UnitsNet script to version UnitsNet and both NumberExtensions packages. - Update the JSON script to version both serialization packages and preserve unrelated working changes. - Add a MinVer-aware UnitsNet.Modular script for minor, patch, and prerelease suffix tags. - Document the Modular release command and update the wrapper descriptions. ## Validation - Parsed the PowerShell scripts in Windows PowerShell and PowerShell 7. - Checked the shell wrappers with Git Bash. - Ran both explicit-version scripts in an isolated clone and verified all five project versions, commits, and annotated tags. - Verified the Modular tag flow and MinVer version resolution in an isolated clone. - Ran `git diff --check`.
1 parent 42205dc commit 04fa5c5

11 files changed

Lines changed: 185 additions & 78 deletions
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<# .SYNOPSIS
2+
Creates an annotated UnitsNet.Modular release tag with a bumped version.
3+
.DESCRIPTION
4+
Finds the nearest reachable UnitsNet.Modular/* tag, bumps its minor, patch, or prerelease suffix,
5+
and creates an annotated tag on HEAD. MinVer uses that tag to version both UnitsNet.Modular and
6+
UnitsNet.Core.
7+
8+
Minor and patch bumps remove any prerelease suffix, matching the existing UnitsNet version scripts.
9+
A suffix bump increments the final numeric prerelease identifier, for example alpha.1 to alpha.2.
10+
After a stable tag, a suffix bump starts the next patch prerelease at alpha.1, matching MinVer's
11+
post-release version range.
12+
.PARAMETER Bump
13+
The semantic version component to bump: minor, patch, or suffix.
14+
.EXAMPLE
15+
./Build/bump-version-UnitsNet.Modular.ps1 -Bump suffix
16+
.EXAMPLE
17+
./Build/bump-version-UnitsNet.Modular.ps1 -Bump minor -WhatIf
18+
#>
19+
[CmdletBinding(SupportsShouldProcess = $true)]
20+
Param(
21+
[Parameter(Mandatory = $true, Position = 0)]
22+
[ValidateSet("minor", "patch", "suffix")]
23+
[string] $Bump
24+
)
25+
26+
$ErrorActionPreference = "Stop"
27+
$tagPrefix = "UnitsNet.Modular/"
28+
$repositoryRoot = Resolve-Path "$PSScriptRoot\.."
29+
30+
Remove-Module set-version -ErrorAction Ignore
31+
Import-Module "$PSScriptRoot\set-version.psm1"
32+
33+
function Invoke-Git([string[]] $Arguments) {
34+
$output = & git -C $repositoryRoot @Arguments 2>&1
35+
if ($LASTEXITCODE -ne 0) {
36+
throw "git $([string]::Join(' ', $Arguments)) failed:`n$([string]::Join([Environment]::NewLine, $output))"
37+
}
38+
39+
return $output
40+
}
41+
42+
$status = Invoke-Git @("status", "--porcelain", "--untracked-files=normal")
43+
if ($status) {
44+
throw "The working tree must be clean before tagging a release."
45+
}
46+
47+
$latestTag = [string](Invoke-Git @(
48+
"describe",
49+
"--tags",
50+
"--abbrev=0",
51+
"--match",
52+
"$tagPrefix*",
53+
"HEAD"
54+
))
55+
$latestTag = $latestTag.Trim()
56+
57+
if (!$latestTag.StartsWith($tagPrefix, [StringComparison]::OrdinalIgnoreCase)) {
58+
throw "Latest tag '$latestTag' does not start with '$tagPrefix'."
59+
}
60+
61+
$currentVersion = $latestTag.Substring($tagPrefix.Length)
62+
if ($Bump -eq "suffix" -and !$currentVersion.Contains("-")) {
63+
$nextPatchVersion = Get-BumpedSemanticVersion $currentVersion "patch"
64+
$newVersion = Get-BumpedSemanticVersion "$nextPatchVersion-alpha.0" "suffix" "alpha.0"
65+
}
66+
else {
67+
$newVersion = Get-BumpedSemanticVersion $currentVersion $Bump "alpha.0"
68+
}
69+
$newTag = "$tagPrefix$newVersion"
70+
71+
& git -C $repositoryRoot rev-parse --verify --quiet "refs/tags/$newTag" *> $null
72+
if ($LASTEXITCODE -eq 0) {
73+
throw "Tag '$newTag' already exists."
74+
}
75+
76+
$message = "UnitsNet.Modular $newVersion"
77+
if ($PSCmdlet.ShouldProcess("HEAD", "Create annotated tag '$newTag'")) {
78+
Invoke-Git @("tag", "--annotate", $newTag, "--message", $message, "HEAD") | Out-Null
79+
Write-Host "Created annotated tag $newTag"
80+
Write-Host "Push it with: git push origin $newTag"
81+
}

Build/bump-version-json.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
@echo off
2-
rem This scripts increases the version of nugets: UnitsNet.Serialization.JsonNet.
2+
rem This script increases the version of both UnitsNet serialization packages.
33
rem The change is committed and tagged locally, but must be pushed to origin/master to take effect.
44
rem Only contributors with write access can perform this directly to master, others must perform via pull request.
55

66
SET scriptdir=%~dp0
7-
echo Bump version UnitsNet.Serialization.JsonNet nuget:
7+
echo Bump version UnitsNet serialization packages:
88
echo.
99
echo 1: minor 4.90.0 to 4.91.0
1010
echo 2: patch 4.90.0 to 4.90.1

Build/bump-version-json.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Increments version of nuget UnitNets.Serialization.JsonNet.
2+
# Increments the version of both UnitsNet serialization packages.
33
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
44
set_version_script="$script_dir/set-version-UnitsNet.Serialization.JsonNet.ps1"
55

Build/bump-version.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
@echo off
2-
rem This scripts increases the version of nugets: UnitsNet, UnitsNet.NumberExtensions.
2+
rem This script increases the version of UnitsNet and both UnitsNet.NumberExtensions packages.
33
rem The change is committed and tagged locally, but must be pushed to origin/master to take effect.
44
rem Only contributors with write access can perform this directly to master, others must perform via pull request.
55

66
SET scriptdir=%~dp0
7-
echo Bump version UnitsNet and UnitsNet.NumberExtensions:
7+
echo Bump version UnitsNet and both UnitsNet.NumberExtensions packages:
88
echo.
99
echo 1: minor 4.90.0 to 4.91.0
1010
echo 2: patch 4.90.0 to 4.90.1

Build/bump-version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Increments version of nugets UnitNets, UnitsNet.NumberExtensions.
2+
# Increments version of UnitsNet and both UnitsNet.NumberExtensions packages.
33
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
44
set_version_script="$script_dir/set-version-UnitsNet.ps1"
55

Build/set-version-UnitsNet.Serialization.JsonNet.ps1

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<# .SYNOPSIS
2-
Updates the version of all UnitsNet.Serialiation.JsonNet projects.
2+
Updates the version of all UnitsNet serialization projects.
33
.DESCRIPTION
44
Updates the <Version> property of the .csproj project files.
55
.PARAMETER set
@@ -48,11 +48,25 @@ Import-Module "$PSScriptRoot\set-version.psm1"
4848

4949
$root = Resolve-Path "$PSScriptRoot\.."
5050
$paramSet = $PsCmdlet.ParameterSetName
51-
$projFile = "$root\UnitsNet.Serialization.JsonNet\UnitsNet.Serialization.JsonNet.csproj"
51+
$projectFiles = @(
52+
"$root\UnitsNet.Serialization.JsonNet\UnitsNet.Serialization.JsonNet.csproj",
53+
"$root\UnitsNet.Serialization.SystemTextJson\UnitsNet.Serialization.SystemTextJson.csproj"
54+
)
5255

5356
# Use project version as base when bumping major/minor/patch
54-
$newVersion = Get-NewProjectVersion $projFile $paramSet $setVersion $bumpVersion
57+
$newVersion = Get-NewProjectVersion $projectFiles[0] $paramSet $setVersion $bumpVersion
58+
59+
# Reset and stash any other local changes.
60+
$didStash = Invoke-StashPush
61+
62+
foreach ($projectFile in $projectFiles) {
63+
Set-ProjectVersion $projectFile $newVersion
64+
}
5565

56-
Set-ProjectVersion $projFile $newVersion
5766
Invoke-CommitVersionBump "JsonNet" $newVersion
5867
Invoke-TagVersionBump "JsonNet" $newVersion
68+
69+
# Restore any local changes.
70+
if ($didStash) {
71+
Invoke-StashPop
72+
}

Build/set-version-UnitsNet.ps1

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,22 @@ Import-Module "$PSScriptRoot\set-version.psm1"
5151

5252
$root = Resolve-Path "$PSScriptRoot\.."
5353
$paramSet = $PsCmdlet.ParameterSetName
54-
$projFile = "$root\UnitsNet\UnitsNet.csproj"
55-
$numberExtensionsProjFile = "$root\UnitsNet.NumberExtensions\UnitsNet.NumberExtensions.csproj"
54+
$projectFiles = @(
55+
"$root\UnitsNet\UnitsNet.csproj",
56+
"$root\UnitsNet.NumberExtensions\UnitsNet.NumberExtensions.csproj",
57+
"$root\UnitsNet.NumberExtensions.CS14\UnitsNet.NumberExtensions.CS14.csproj"
58+
)
5659

57-
# Use UnitsNet.Common.props version as base if bumping major/minor/patch
58-
$newVersion = Get-NewProjectVersion $projFile $paramSet $setVersion $bumpVersion
60+
# Use UnitsNet version as base if bumping major/minor/patch
61+
$newVersion = Get-NewProjectVersion $projectFiles[0] $paramSet $setVersion $bumpVersion
5962

6063
# Reset and stash any other local changes.
6164
$didStash = Invoke-StashPush
6265

6366
# Update project files
64-
Set-ProjectVersion $projFile $newVersion
65-
Set-ProjectVersion $numberExtensionsProjFile $newVersion
67+
foreach ($projectFile in $projectFiles) {
68+
Set-ProjectVersion $projectFile $newVersion
69+
}
6670

6771
# Git commit and tag
6872
Invoke-CommitVersionBump @("UnitsNet") $newVersion

Build/set-version-json.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Sets version of nuget UnitNets.Serialization.JsonNet.
2+
# Sets the version of both UnitsNet serialization packages.
33
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
44
set_version_script="$script_dir/set-version-UnitsNet.Serialization.JsonNet.ps1"
55

Build/set-version.psm1

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -71,85 +71,86 @@ function Set-NuspecVersion([string] $file, [string] $version) {
7171
function Get-BumpedProjectVersion([string] $projectPath, [string] $bumpVersion) {
7272
[xml]$projectXml = Get-Content -Path $projectPath
7373

74-
$old = Get-ProjectVersionAndSuffix $projectXml
74+
$oldSemVer = [string]($projectXml.Project.PropertyGroup.Version)[0]
75+
76+
return Get-BumpedSemanticVersion $oldSemVer $bumpVersion
77+
}
78+
79+
function Get-BumpedSemanticVersion(
80+
[string] $semanticVersion,
81+
[string] $bumpVersion,
82+
[string] $defaultPreReleaseIdentifiers = "alpha000") {
83+
$match = [regex]::Match(
84+
$semanticVersion,
85+
'^(?<major>0|[1-9][0-9]*)\.(?<minor>0|[1-9][0-9]*)\.(?<patch>0|[1-9][0-9]*)(?:-(?<prerelease>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+(?<metadata>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$')
86+
87+
if (!$match.Success) {
88+
throw "Unable to parse semantic version '$semanticVersion'."
89+
}
90+
91+
$preRelease = $match.Groups["prerelease"].Value
92+
foreach ($identifier in $preRelease.Split(".", [StringSplitOptions]::RemoveEmptyEntries)) {
93+
if ($identifier -match '^[0-9]+$' -and $identifier.Length -gt 1 -and $identifier.StartsWith("0")) {
94+
throw "Numeric prerelease identifier '$identifier' in '$semanticVersion' must not contain leading zeroes."
95+
}
96+
}
97+
98+
$major = [long]$match.Groups["major"].Value
99+
$minor = [long]$match.Groups["minor"].Value
100+
$patch = [long]$match.Groups["patch"].Value
75101

76102
switch ($bumpVersion) {
77103
"major" {
78-
$newVersion = BumpMajor $old.Version
79-
$newSuffix = ""
104+
return "$($major + 1).0.0"
80105
}
81106
"minor" {
82-
$newVersion = BumpMinor $old.Version
83-
$newSuffix = ""
107+
return "$major.$($minor + 1).0"
84108
}
85109
"patch" {
86-
$newVersion = BumpPatch $old.Version
87-
$newSuffix = ""
110+
return "$major.$minor.$($patch + 1)"
88111
}
89112
"suffix" {
90-
$newVersion = $old.Version
91-
$newSuffix = BumpSuffix $old.Suffix
113+
$newSuffix = BumpSuffix $(if ($preRelease) { "-$preRelease" } else { "" }) $defaultPreReleaseIdentifiers
114+
return "$major.$minor.$patch$newSuffix"
92115
}
93116
default {
94117
throw "Unrecognized 'bumpVersion' argument: $bumpVersion"
95118
}
96119
}
97-
98-
$newSemVer = $newVersion.ToString() + $newSuffix
99-
return $newSemVer
100-
}
101-
102-
function BumpMajor ([Version] $oldVersion) {
103-
return New-Object System.Version -ArgumentList ($oldVersion.Major+1), 0, 0
104-
}
105-
106-
function BumpMinor([Version] $oldVersion) {
107-
return New-Object System.Version -ArgumentList $oldVersion.Major, ($oldVersion.Minor+1), 0
108-
}
109-
110-
function BumpPatch([Version] $oldVersion) {
111-
return New-Object System.Version -ArgumentList $oldVersion.Major, $oldVersion.Minor, ($oldVersion.Build+1);
112120
}
113121

114-
function BumpSuffix([string] $oldSuffix) {
122+
function BumpSuffix(
123+
[string] $oldSuffix,
124+
[string] $defaultPreReleaseIdentifiers = "alpha000") {
115125
$oldSuffix = $oldSuffix.Trim()
116126

117-
# A suffix is a dash '-', then a sequcence of word characters followed by an optional number
118-
# Example:
119-
# "" => "-alpha001"
120-
# "-beta" => "-beta001"
121-
# "-beta1"=> "-beta002"
122-
$match = [regex]::Match($oldSuffix, '^-([a-zA-Z]+)(\d+)?$');
123-
$oldSuffix = $match.Groups[1].Value
124-
if (!$oldSuffix) {
125-
$oldSuffix = "alpha"
127+
$preRelease = $oldSuffix.TrimStart("-")
128+
if (!$preRelease) {
129+
$preRelease = $defaultPreReleaseIdentifiers
126130
}
127131

128-
$numberGroup = $match.Groups[2]
129-
130-
$number = if ($numberGroup.Success) { 1+$match.Groups[2].Value } else { 1 }
131-
132-
# Use 3 digits for the number "-alpha003", for 999 releases lexically sorted.
133-
return [string]::Format("-{0}{1:D3}", $oldSuffix, $number)
134-
}
135-
136-
# Returns object with properties: Version, Suffix
137-
function Get-ProjectVersionAndSuffix([xml] $projectXml) {
132+
$identifiers = [Collections.Generic.List[string]]::new()
133+
$identifiers.AddRange([string[]]$preRelease.Split("."))
134+
$lastIdentifierIndex = $identifiers.Count - 1
135+
$lastIdentifier = $identifiers[$lastIdentifierIndex]
138136

139-
# Split "1.2.3-alpha" into ["1.2.3", "alpha"]
140-
# Split "1.2.3" into ["1.2.3"]
141-
$oldSemVer = $($projectXml.Project.PropertyGroup.Version)[0]
142-
143-
$oldSemVerParts = $oldSemVer.Split('-')
144-
$oldVersion = $null
145-
if (-not [Version]::TryParse($oldSemVerParts[0], [ref] $oldVersion)) { throw "Unable to parse old version." }
146-
147-
$oldSuffix = if ($oldSemVerParts.Length -eq 2) { "-" + $oldSemVerParts[1]} else { "" }
148-
return [PSCustomObject]@{
149-
PSTypeName = "VersionAndSuffix"
150-
Version = $oldVersion
151-
Suffix = $oldSuffix
137+
if ($lastIdentifier -match '^[0-9]+$') {
138+
$identifiers[$lastIdentifierIndex] = ([long]$lastIdentifier + 1).ToString()
139+
}
140+
elseif ($lastIdentifier -match '^(?<prefix>.*?)(?<number>[0-9]+)$') {
141+
$numberWidth = $Matches["number"].Length
142+
$number = [long]$Matches["number"] + 1
143+
$identifiers[$lastIdentifierIndex] = $Matches["prefix"] + $number.ToString("D$numberWidth")
152144
}
145+
elseif ($identifiers.Count -eq 1) {
146+
# Preserve the repository's existing alpha001/beta001 suffix convention.
147+
$identifiers[0] += "001"
148+
}
149+
else {
150+
$identifiers.Add("1")
151+
}
152+
153+
return "-" + [string]::Join(".", $identifiers)
153154
}
154155

155156
function Resolve-Error ($ErrorRecord=$Error[0])
@@ -169,6 +170,7 @@ function Resolve-Error ($ErrorRecord=$Error[0])
169170
}
170171

171172
export-modulemember -function Get-NewProjectVersion,
173+
Get-BumpedSemanticVersion,
172174
Invoke-CommitVersionBump,
173175
Invoke-TagVersionBump,
174176
Set-ProjectVersion,

Build/set-version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Increments version of nugets UnitNets, UnitsNet.NumberExtensions.
2+
# Sets the version of UnitsNet and both UnitsNet.NumberExtensions packages.
33
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
44
set_version_script="$script_dir/set-version-UnitsNet.ps1"
55

0 commit comments

Comments
 (0)