11<#
22. SYNOPSIS
33 Tags a branch (default: main) with a version computed by GitVersion, optionally
4- bumping major/minor/patch by 1 or by an arbitrary amount.
4+ bumping major/minor/patch by 1 or by an arbitrary amount, and optionally
5+ re-applying a prerelease label after a bump.
56
67. DESCRIPTION
78 - If -Directory is omitted, the script runs in its own folder and only requires
1213 - Supports bump switches (-BumpMajor/-BumpMinor/-BumpPatch) to bump by 1.
1314 - Supports increment integers (-IncrementMajor/-IncrementMinor/-IncrementPatch) to bump
1415 by an arbitrary amount; these override the switches if > 0.
16+ - If a bump occurs and -PreReleaseLabel is supplied, the tag becomes X.Y.Z-<label>.1.
1517 - Restores the original working directory AND the originally checked-out branch
1618 (if the script switched branches), even on error.
1719
4648 Integer (default 0). If > 0, bumps PATCH by that amount.
4749 Overrides -BumpPatch.
4850
49- . EXAMPLE
50- .\TagVersion.ps1
51- # Tags the current repo’s 'main' with GitVersion’s FullSemVer.
52-
53- . EXAMPLE
54- .\TagVersion.ps1 -Pull
55- # Same as above, but fetches and pulls first.
56-
57- . EXAMPLE
58- .\TagVersion.ps1 -Directory ..\..\my-repo -Branch release
59- # Runs in the specified repo root, tagging the 'release' branch.
51+ . PARAMETER PreReleaseLabel
52+ Optional prerelease label to apply **after** a bump (e.g., 'beta', 'rc', 'dev', 'feature.x').
53+ Resulting tag is `X.Y.Z-<label>.1`. Must match `[0-9A-Za-z\-\.]+`.
54+ Ignored if no bump occurs (in that case we tag with GitVersion's FullSemVer as-is).
6055
6156. EXAMPLE
6257 .\TagVersion.ps1 -BumpPatch
63- # Uses GitVersion’s SemVer base, bumps PATCH by 1, and tags a stable X.Y.Z.
58+ # From 2.0.44[-something], tags v2.0.45 (stable)
6459
6560. EXAMPLE
66- .\TagVersion.ps1 -IncrementMinor 2
67- # Bumps MINOR by 2 (resets patch to 0) and tags a stable X.(Y+2).0.
61+ .\TagVersion.ps1 -BumpMinor -PreReleaseLabel rc
62+ # From 2.0.44[-something], tags v2.1.0-rc.1
6863
69- . NOTES
70- Requires Git, .NET SDK, and GitVersion.Tool. If GitVersion.Tool is not present
71- in the repo, the script will create a local tool manifest and install it.
64+ . EXAMPLE
65+ .\TagVersion.ps1 -IncrementMinor 2 -PreReleaseLabel feature.widgets
66+ # From 2.0.44[-something], tags v2.2.0-feature.widgets.1
7267#>
7368
7469[CmdletBinding ()]
8176 [switch ] $BumpPatch ,
8277 [int ] $IncrementMajor = 0 ,
8378 [int ] $IncrementMinor = 0 ,
84- [int ] $IncrementPatch = 0
79+ [int ] $IncrementPatch = 0 ,
80+ [string ] $PreReleaseLabel
8581)
8682
8783$ErrorActionPreference = ' Stop'
@@ -128,8 +124,7 @@ function Assert-GitRepository {
128124 if (-not $repoRoot ) { throw " Could not determine repository toplevel for '$Path '." }
129125 $normPath = Normalize- PathCanonical $Path
130126 if (-not [String ]::Equals($repoRoot , $normPath , [System.StringComparison ]::OrdinalIgnoreCase)) {
131- throw " Path mismatch: repo toplevel is '$repoRoot ' but script targeted '$normPath '."
132- }
127+ throw " Path mismatch: repo toplevel is '$repoRoot ' but script targeted '$normPath '." }
133128 }
134129}
135130
@@ -236,7 +231,6 @@ try {
236231 $effMaj = $IncrementMajor
237232 $effMin = $IncrementMinor
238233 $effPat = $IncrementPatch
239-
240234 if ($BumpMajor.IsPresent -and $effMaj -le 0 ) { $effMaj = 1 }
241235 if ($BumpMinor.IsPresent -and $effMin -le 0 ) { $effMin = 1 }
242236 if ($BumpPatch.IsPresent -and $effPat -le 0 ) { $effPat = 1 }
@@ -245,14 +239,29 @@ try {
245239 $bumped = Compute- BumpedVersion - SemVerBase $gv.SemVer `
246240 - IncrementMajor $effMaj - IncrementMinor $effMin - IncrementPatch $effPat
247241
242+ # Validate prerelease label (if provided)
243+ if (-not [string ]::IsNullOrWhiteSpace($PreReleaseLabel )) {
244+ if ($PreReleaseLabel -notmatch ' ^[0-9A-Za-z\-.]+$' ) {
245+ throw " Invalid -PreReleaseLabel '$PreReleaseLabel '. Allowed: letters, digits, '-' and '.'"
246+ }
247+ }
248+
248249 if ($bumped ) {
249- $versionToTag = $bumped
250- $tagMessage = " Release $versionToTag (bumped from $ ( $gv.FullSemVer ) )"
250+ # If we bumped, optionally apply -PreReleaseLabel
251+ if (-not [string ]::IsNullOrWhiteSpace($PreReleaseLabel )) {
252+ $versionToTag = " $bumped -$PreReleaseLabel .1"
253+ $tagMessage = " Release $versionToTag (bumped from $ ( $gv.FullSemVer ) )"
254+ } else {
255+ $versionToTag = $bumped
256+ $tagMessage = " Release $versionToTag (bumped from $ ( $gv.FullSemVer ) )"
257+ }
251258 } else {
259+ # No bump requested → tag FullSemVer exactly
252260 $versionToTag = $gv.FullSemVer
253261 $tagMessage = " Release $versionToTag "
254262 }
255263
264+ # Normalize tag with 'v' prefix
256265 $tagName = if ($versionToTag -match ' ^[vV]\d' ) { $versionToTag } else { " v$versionToTag " }
257266
258267 if (Test-TagExistsLocal $tagName ) { throw " Tag '$tagName ' already exists locally. Aborting." }
@@ -280,7 +289,7 @@ finally {
280289 git checkout " $initialBranch " | Out-Null
281290 }
282291 }
283- } catch { } # best-effort; don't hide earlier exceptions
292+ } catch { } # best-effort
284293
285294 # Restore caller's directory
286295 Set-Location $orig
0 commit comments