Skip to content

Commit 4674c27

Browse files
authored
Merge pull request #303 from ap0llo/master
Improved commandline options for prepare-release command
2 parents d69d232 + 6675320 commit 4674c27

File tree

4 files changed

+118
-63
lines changed

4 files changed

+118
-63
lines changed

doc/nbgv-cli.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,28 @@ nbgv prepare-release rc
7777
no new branch will be created. Instead the tool will just update the version
7878
in the current branch by replacing or removing the prerelease tag.
7979

80-
### Explicitly setting the next version
80+
### Customizing the next version
8181

82-
If you want to explicitly set the next version of the main branch instead of
83-
automatically determining it by incrementing the current version, you
84-
can set the version as commandline parameter:
82+
By default, the next version of the main branch is determined from the current
83+
version and the `versionIncrement` setting in `version.json`.
84+
To customize this behaviour, you can either explicitly set the next version
85+
or override the version increment setting.
86+
87+
To explicitly set the next version, run:
88+
89+
```ps1
90+
nbgv prepare-release --nextVersion 2.0
91+
```
92+
93+
To override the `versionIncrement` setting from `version.json`, run:
8594

8695
```ps1
87-
nbgv prepare-release --nextVersion 2.0-beta
96+
nbgv prepare-release --versionIncrement Major
8897
```
8998

99+
**Note:** The parameters `nextVersion` and `versionIncrement` cannot
100+
be combined.
101+
90102
### Customizing the behaviour of `prepare-release`
91103

92104
The behaviour of the `prepare-release` command can be customized in

src/NerdBank.GitVersioning.Tests/ReleaseManagerTests.cs

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using ReleasePreparationError = Nerdbank.GitVersioning.ReleaseManager.ReleasePreparationError;
1212
using ReleasePreparationException = Nerdbank.GitVersioning.ReleaseManager.ReleasePreparationException;
1313
using ReleaseVersionIncrement = Nerdbank.GitVersioning.VersionOptions.ReleaseVersionIncrement;
14+
using Version = System.Version;
1415

1516
public class ReleaseManagerTests : RepoTestBase
1617
{
@@ -200,42 +201,45 @@ public void PrepeareRelease_ReleaseBranchWithVersionDecrement(string initialVers
200201

201202
[Theory]
202203
// base test cases
203-
[InlineData("1.2-beta", null, null, null, null, null, "v1.2", "1.2", "1.3-alpha")]
204-
[InlineData("1.2-beta", null, null, null, "rc", null, "v1.2", "1.2-rc", "1.3-alpha")]
205-
[InlineData("1.2-beta.{height}", null, null, null, null, null, "v1.2", "1.2", "1.3-alpha.{height}")]
206-
[InlineData("1.2-beta.{height}", null, null, null, "rc", null, "v1.2", "1.2-rc.{height}", "1.3-alpha.{height}")]
204+
[InlineData("1.2-beta", null, null, null, null, null, null, "v1.2", "1.2", "1.3-alpha")]
205+
[InlineData("1.2-beta", null, null, null, "rc", null, null, "v1.2", "1.2-rc", "1.3-alpha")]
206+
[InlineData("1.2-beta.{height}", null, null, null, null, null, null, "v1.2", "1.2", "1.3-alpha.{height}")]
207+
[InlineData("1.2-beta.{height}", null, null, null, "rc", null, null, "v1.2", "1.2-rc.{height}", "1.3-alpha.{height}")]
207208
// modify release.branchName
208-
[InlineData("1.2-beta", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", null, null, "v1.2release", "1.2", "1.3-alpha")]
209-
[InlineData("1.2-beta", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", "rc", null, "v1.2release", "1.2-rc", "1.3-alpha")]
210-
[InlineData("1.2-beta.{height}", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", null, null, "v1.2release", "1.2", "1.3-alpha.{height}")]
211-
[InlineData("1.2-beta.{height}", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", "rc", null, "v1.2release", "1.2-rc.{height}", "1.3-alpha.{height}")]
209+
[InlineData("1.2-beta", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", null, null, null, "v1.2release", "1.2", "1.3-alpha")]
210+
[InlineData("1.2-beta", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", "rc", null, null, "v1.2release", "1.2-rc", "1.3-alpha")]
211+
[InlineData("1.2-beta.{height}", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", null, null, null, "v1.2release", "1.2", "1.3-alpha.{height}")]
212+
[InlineData("1.2-beta.{height}", "v{version}release", ReleaseVersionIncrement.Minor, "alpha", "rc", null, null, "v1.2release", "1.2-rc.{height}", "1.3-alpha.{height}")]
212213
// modify release.versionIncrement: "Major"
213-
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Major, "alpha", null, null, "v1.2", "1.2", "2.0-alpha")]
214-
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Major, "alpha", "rc", null, "v1.2", "1.2-rc", "2.0-alpha")]
215-
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Major, "alpha", null, null, "v1.2", "1.2", "2.0-alpha.{height}")]
216-
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Major, "alpha", "rc", null, "v1.2", "1.2-rc.{height}", "2.0-alpha.{height}")]
214+
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Major, "alpha", null, null, null, "v1.2", "1.2", "2.0-alpha")]
215+
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Major, "alpha", "rc", null, null, "v1.2", "1.2-rc", "2.0-alpha")]
216+
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Major, "alpha", null, null, null, "v1.2", "1.2", "2.0-alpha.{height}")]
217+
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Major, "alpha", "rc", null, null, "v1.2", "1.2-rc.{height}", "2.0-alpha.{height}")]
217218
// modify release.versionIncrement: "Build"
218-
[InlineData("1.2.3-beta", null, ReleaseVersionIncrement.Build, "alpha", null, null, "v1.2.3", "1.2.3", "1.2.4-alpha")]
219-
[InlineData("1.2.3-beta", null, ReleaseVersionIncrement.Build, "alpha", "rc", null, "v1.2.3", "1.2.3-rc", "1.2.4-alpha")]
220-
[InlineData("1.2.3-beta.{height}", null, ReleaseVersionIncrement.Build, "alpha", null, null, "v1.2.3", "1.2.3", "1.2.4-alpha.{height}")]
221-
[InlineData("1.2.3-beta.{height}", null, ReleaseVersionIncrement.Build, "alpha", "rc", null, "v1.2.3", "1.2.3-rc.{height}", "1.2.4-alpha.{height}")]
219+
[InlineData("1.2.3-beta", null, ReleaseVersionIncrement.Build, "alpha", null, null, null, "v1.2.3", "1.2.3", "1.2.4-alpha")]
220+
[InlineData("1.2.3-beta", null, ReleaseVersionIncrement.Build, "alpha", "rc", null, null, "v1.2.3", "1.2.3-rc", "1.2.4-alpha")]
221+
[InlineData("1.2.3-beta.{height}", null, ReleaseVersionIncrement.Build, "alpha", null, null, null, "v1.2.3", "1.2.3", "1.2.4-alpha.{height}")]
222+
[InlineData("1.2.3-beta.{height}", null, ReleaseVersionIncrement.Build, "alpha", "rc", null, null, "v1.2.3", "1.2.3-rc.{height}", "1.2.4-alpha.{height}")]
222223
// modify release.firstUnstableTag
223-
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Minor, "preview", null, null, "v1.2", "1.2", "1.3-preview")]
224-
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Minor, "preview", "rc", null, "v1.2", "1.2-rc", "1.3-preview")]
225-
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Minor, "preview", null, null, "v1.2", "1.2", "1.3-preview.{height}")]
226-
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Minor, "preview", "rc", null, "v1.2", "1.2-rc.{height}", "1.3-preview.{height}")]
224+
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Minor, "preview", null, null, null, "v1.2", "1.2", "1.3-preview")]
225+
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Minor, "preview", "rc", null, null, "v1.2", "1.2-rc", "1.3-preview")]
226+
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Minor, "preview", null, null, null, "v1.2", "1.2", "1.3-preview.{height}")]
227+
[InlineData("1.2-beta.{height}", null, ReleaseVersionIncrement.Minor, "preview", "rc", null, null, "v1.2", "1.2-rc.{height}", "1.3-preview.{height}")]
227228
// include build metadata in version
228-
[InlineData("1.2-beta+metadata", null, ReleaseVersionIncrement.Minor, "alpha", null, null, "v1.2", "1.2+metadata", "1.3-alpha+metadata")]
229-
[InlineData("1.2-beta+metadata", null, ReleaseVersionIncrement.Minor, "alpha", "rc", null, "v1.2", "1.2-rc+metadata", "1.3-alpha+metadata")]
230-
[InlineData("1.2-beta.{height}+metadata", null, ReleaseVersionIncrement.Minor, "alpha", null, null, "v1.2", "1.2+metadata", "1.3-alpha.{height}+metadata")]
231-
[InlineData("1.2-beta.{height}+metadata", null, ReleaseVersionIncrement.Minor, "alpha", "rc", null, "v1.2", "1.2-rc.{height}+metadata", "1.3-alpha.{height}+metadata")]
229+
[InlineData("1.2-beta+metadata", null, ReleaseVersionIncrement.Minor, "alpha", null, null, null, "v1.2", "1.2+metadata", "1.3-alpha+metadata")]
230+
[InlineData("1.2-beta+metadata", null, ReleaseVersionIncrement.Minor, "alpha", "rc", null, null, "v1.2", "1.2-rc+metadata", "1.3-alpha+metadata")]
231+
[InlineData("1.2-beta.{height}+metadata", null, ReleaseVersionIncrement.Minor, "alpha", null, null, null, "v1.2", "1.2+metadata", "1.3-alpha.{height}+metadata")]
232+
[InlineData("1.2-beta.{height}+metadata", null, ReleaseVersionIncrement.Minor, "alpha", "rc", null, null, "v1.2", "1.2-rc.{height}+metadata", "1.3-alpha.{height}+metadata")]
232233
// versions without prerelease tags
233-
[InlineData("1.2", null, ReleaseVersionIncrement.Minor, "alpha", null, null, "v1.2", "1.2", "1.3-alpha")]
234-
[InlineData("1.2", null, ReleaseVersionIncrement.Major, "alpha", null, null, "v1.2", "1.2", "2.0-alpha")]
235-
// explicitly set next version (firstUnstableTag setting will be ignored)
236-
[InlineData("1.2-beta", null, null, null, null, "4.5", "v1.2", "1.2", "4.5")]
237-
[InlineData("1.2-beta", null, null, null, null, "4.5-pre", "v1.2", "1.2", "4.5-pre")]
238-
[InlineData("1.2-beta.{height}", null, null, null, null, "4.5-pre.{height}", "v1.2", "1.2", "4.5-pre.{height}")]
234+
[InlineData("1.2", null, ReleaseVersionIncrement.Minor, "alpha", null, null, null, "v1.2", "1.2", "1.3-alpha")]
235+
[InlineData("1.2", null, ReleaseVersionIncrement.Major, "alpha", null, null, null, "v1.2", "1.2", "2.0-alpha")]
236+
// explicitly set next version
237+
[InlineData("1.2-beta", null, null, null, null, "4.5", null, "v1.2", "1.2", "4.5-alpha")]
238+
[InlineData("1.2-beta.{height}", null, null, null, null, "4.5", null, "v1.2", "1.2", "4.5-alpha.{height}")]
239+
[InlineData("1.2-beta.{height}", null, null, "pre", null, "4.5.6", null, "v1.2", "1.2", "4.5.6-pre.{height}")]
240+
// explicitly set version increment overriding the setting from ReleaseOptions
241+
[InlineData("1.2-beta", null, ReleaseVersionIncrement.Minor, null, null, null, ReleaseVersionIncrement.Major, "v1.2", "1.2", "2.0-alpha")]
242+
[InlineData("1.2.3-beta", null, ReleaseVersionIncrement.Minor, null, null, null, ReleaseVersionIncrement.Build, "v1.2.3", "1.2.3", "1.2.4-alpha")]
239243
public void PrepareRelease_Master(
240244
// data for initial setup (version and release options configured in version.json)
241245
string initialVersion,
@@ -245,6 +249,7 @@ public void PrepareRelease_Master(
245249
// arguments passed to PrepareRelease()
246250
string releaseUnstableTag,
247251
string nextVersion,
252+
ReleaseVersionIncrement? parameterVersionIncrement,
248253
// expected versions and branch name after running PrepareRelease()
249254
string expectedBranchName,
250255
string resultingReleaseVersion,
@@ -295,7 +300,7 @@ public void PrepareRelease_Master(
295300

296301
// prepare release
297302
var releaseManager = new ReleaseManager();
298-
releaseManager.PrepareRelease(this.RepoPath, releaseUnstableTag, (nextVersion == null ? null : SemanticVersion.Parse(nextVersion)));
303+
releaseManager.PrepareRelease(this.RepoPath, releaseUnstableTag, (nextVersion == null ? null : Version.Parse(nextVersion)), parameterVersionIncrement);
299304

300305
// check if a branch was created
301306
Assert.Contains(this.Repo.Branches, branch => branch.FriendlyName == expectedBranchName);
@@ -371,7 +376,7 @@ public void PrepareRelease_MasterWithVersionDecrement(string initialVersion, str
371376
// running PrepareRelease should result in an error
372377
// because we're trying to add a prerelease tag to a version without prerelease tag
373378
this.AssertError(
374-
() => new ReleaseManager().PrepareRelease(this.RepoPath, releaseUnstableTag, (nextVersion == null ? null : SemanticVersion.Parse(nextVersion))),
379+
() => new ReleaseManager().PrepareRelease(this.RepoPath, releaseUnstableTag, (nextVersion == null ? null : Version.Parse(nextVersion))),
375380
ReleasePreparationError.VersionDecrement);
376381
}
377382

src/NerdBank.GitVersioning/ReleaseManager.cs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
using System;
44
using System.Collections.Generic;
55
using System.IO;
6-
using System.Linq;
76
using LibGit2Sharp;
87
using Validation;
8+
using Version = System.Version;
99

1010
/// <summary>
1111
/// Methods for creating releases
@@ -110,7 +110,12 @@ public ReleaseManager(TextWriter outputWriter = null, TextWriter errorWriter = n
110110
/// version based on the current version and the <c>versionIncrement</c> setting in <c>version.json</c>.
111111
/// Parameter will be ignored if the current branch is a release branch.
112112
/// </param>
113-
public void PrepareRelease(string projectDirectory, string releaseUnstableTag = null, SemanticVersion nextVersion = null)
113+
/// <param name="versionIncrement">
114+
/// The increment to apply in order to determine the next version on the current branch.
115+
/// If specified, value will be used instead of the increment specified in <c>version.json</c>.
116+
/// Parameter will be ignored if the current branch is a release branch.
117+
/// </param>
118+
public void PrepareRelease(string projectDirectory, string releaseUnstableTag = null, Version nextVersion = null, VersionOptions.ReleaseVersionIncrement? versionIncrement = null)
114119
{
115120
Requires.NotNull(projectDirectory, nameof(projectDirectory));
116121

@@ -136,7 +141,6 @@ public void PrepareRelease(string projectDirectory, string releaseUnstableTag =
136141
var releaseVersion = string.IsNullOrEmpty(releaseUnstableTag)
137142
? versionOptions.Version.WithoutPrepreleaseTags()
138143
: versionOptions.Version.SetFirstPrereleaseTag(releaseUnstableTag);
139-
var nextDevVersion = this.GetNextDevVersion(versionOptions, nextVersion);
140144

141145
// check if the current branch is the release branch
142146
if (string.Equals(originalBranchName, releaseBranchName, StringComparison.OrdinalIgnoreCase))
@@ -146,6 +150,8 @@ public void PrepareRelease(string projectDirectory, string releaseUnstableTag =
146150
return;
147151
}
148152

153+
var nextDevVersion = this.GetNextDevVersion(versionOptions, nextVersion, versionIncrement);
154+
149155
// check if the release branch already exists
150156
if (repository.Branches[releaseBranchName] != null)
151157
{
@@ -273,29 +279,38 @@ private static bool IsVersionDecrement(SemanticVersion oldVersion, SemanticVersi
273279
}
274280
}
275281

276-
private SemanticVersion GetNextDevVersion(VersionOptions versionOptions, SemanticVersion nextVersion)
282+
private SemanticVersion GetNextDevVersion(VersionOptions versionOptions, Version nextVersionOverride, VersionOptions.ReleaseVersionIncrement? versionIncrementOverride)
277283
{
278-
if (nextVersion != null)
279-
return nextVersion;
284+
var currentVersion = versionOptions.Version;
280285

281-
var releaseOptions = versionOptions.ReleaseOrDefault;
286+
SemanticVersion nextDevVersion;
287+
if(nextVersionOverride != null)
288+
{
289+
nextDevVersion = new SemanticVersion(nextVersionOverride, currentVersion.Prerelease, currentVersion.BuildMetadata);
290+
}
291+
else
292+
{
293+
// Determine the increment to use:
294+
// Use parameter versionIncrementOverride if it has a value, otherwise use setting from version.json.
295+
var versionIncrement = versionIncrementOverride ?? versionOptions.ReleaseOrDefault.VersionIncrementOrDefault;
282296

283-
// the increment is only valid if the current version has the required precision
284-
// increment settings "Major" and "Minor" are always valid
285-
// increment setting "Build" is only valid if the version has at lease three segments
286-
var isValidIncrement = releaseOptions.VersionIncrementOrDefault != VersionOptions.ReleaseVersionIncrement.Build ||
287-
versionOptions.Version.Version.Build >= 0;
297+
// The increment is only valid if the current version has the required precision:
298+
// - increment settings "Major" and "Minor" are always valid.
299+
// - increment setting "Build" is only valid if the version has at lease three segments.
300+
var isValidIncrement = versionIncrement != VersionOptions.ReleaseVersionIncrement.Build ||
301+
versionOptions.Version.Version.Build >= 0;
288302

289-
// increment is ignored when the next version was specified explicitly
290-
if (!isValidIncrement)
291-
{
292-
this.stderr.WriteLine($"Cannot apply version increment 'build' to version '{versionOptions.Version}' because it only has major and minor segments");
293-
throw new ReleasePreparationException(ReleasePreparationError.InvalidVersionIncrementSetting);
303+
if (!isValidIncrement)
304+
{
305+
this.stderr.WriteLine($"Cannot apply version increment 'build' to version '{versionOptions.Version}' because it only has major and minor segments.");
306+
throw new ReleasePreparationException(ReleasePreparationError.InvalidVersionIncrementSetting);
307+
}
308+
309+
nextDevVersion = currentVersion.Increment(versionIncrement);
294310
}
295311

296-
return versionOptions.Version
297-
.Increment(releaseOptions.VersionIncrementOrDefault)
298-
.SetFirstPrereleaseTag(releaseOptions.FirstUnstableTagOrDefault);
312+
// return next version with prerelease tag specified in version.json
313+
return nextDevVersion.SetFirstPrereleaseTag(versionOptions.ReleaseOrDefault.FirstUnstableTagOrDefault);
299314
}
300315
}
301316
}

0 commit comments

Comments
 (0)