Skip to content

Commit

Permalink
Merge pull request #486 from ap0llo/prepare-release-json-output
Browse files Browse the repository at this point in the history
Add JSON output option to 'prepare-release' command
  • Loading branch information
AArnott authored May 29, 2020
2 parents c7a3395 + 12c81cc commit 3e4e1f8
Show file tree
Hide file tree
Showing 4 changed files with 351 additions and 13 deletions.
43 changes: 43 additions & 0 deletions doc/nbgv-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,49 @@ The behaviour of the `prepare-release` command can be customized in
| versionIncrement | `minor` | Specifies which part of the version on the current branch is incremented when preparing a release. Allowed values are `major`, `minor` and `build`. |
| firstUnstableTag | `alpha` | Specified the unstable tag to use for the main branch. |

### Customizing the `prepare-release` output format

By default, the `prepare-release` command writes information about created and updated branches to the console as text.
Alternatively the information can be written to the output as `json`.
The output format to use can be set using the `--format` command line parameter.

For example, running the follwoing command on `master`

```
nbgv prepare-release --format json
```

will generate output similar to this:

```json
{
"CurrentBranch": {
"Name": "master",
"Commit": "5a7487098ac1be1ceb4dbf72d862539cf0b0c27a",
"Version": "1.7-alpha"
},
"NewBranch": {
"Name": "v1.7",
"Commit": "b2f164675ffe891b66b601c00efc4343581fc8a5",
"Version": "1.7"
}
}
```

The JSON object has to properties:

- `CurrentBranch` provides information about the branch `prepare-release` was started on (typically `master`)
- `NewBranch` provides information about the new branch created by the command.

For each branch, the following proprties are provided:

- `Name`: The name of the branch
- `Commit`: The id of the latest commit on that branch
- `Version`: The version configured in that branch's `version.json`

**Note:** When the current branch is already the release branch for the current version, no new branch will be created.
In that case, the `NewBranch` property will be `null`.

## Learn more

There are several more sub-commands and switches to each to help you build and maintain your projects, find a commit that built a particular version later on, create tags, etc.
Expand Down
152 changes: 152 additions & 0 deletions src/NerdBank.GitVersioning.Tests/ReleaseManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Linq;
using LibGit2Sharp;
using Nerdbank.GitVersioning;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -401,6 +403,156 @@ public void PrepareRelease_InvalidVersionIncrement()
this.AssertError(() => new ReleaseManager().PrepareRelease(this.RepoPath), ReleasePreparationError.InvalidVersionIncrementSetting);
}

[Fact]
public void PrepareRelease_TextOutput()
{
// create and configure repository
this.InitializeSourceControl();

// create version.json
var versionOptions = new VersionOptions() { Version = SemanticVersion.Parse("1.0") };
this.WriteVersionFile(versionOptions);

var stdout = new StringWriter();
var releaseManager = new ReleaseManager(stdout);
releaseManager.PrepareRelease(this.RepoPath);

// by default, text output mode should be used => trying to parse it as JSON should fail
Assert.ThrowsAny<JsonException>(() => JsonConvert.DeserializeObject(stdout.ToString()));
}

[Fact]
public void PrepareRelease_JsonOutput()
{
// create and configure repository
this.InitializeSourceControl();

// create version.json
var versionOptions = new VersionOptions()
{
Version = SemanticVersion.Parse("1.0"),
Release = new ReleaseOptions()
{
BranchName = "v{version}",
VersionIncrement = ReleaseVersionIncrement.Minor
}
};
this.WriteVersionFile(versionOptions);

var currentBranchName = this.Repo.Head.FriendlyName;
var releaseBranchName = "v1.0";

// run release preparation
var stdout = new StringWriter();
var releaseManager = new ReleaseManager(stdout);
releaseManager.PrepareRelease(this.RepoPath, outputMode: ReleaseManager.ReleaseManagerOutputMode.Json);


// Expected output:
// {
// "CurrentBranch" : {
// "Name" : "<NAME-OF-CURRENT-BRANCH>",
// "Commit" : "<HEAD-COMMIT-OF-CURRENT-BRANCH>",
// "Version" : "<UPDATED-VERSION-ON-CURRENT-BRANCH>",
// },
// "NewBranch" : {
// "Name" : "<NAME-OF-CREATED-BRANCH>",
// "Commit" : "<HEAD-COMMIT-OF-CREATED-BRANCH>",
// "Version" : "<VERSION-ON-CREATED-BRANCH>",
// }
// }

var jsonOutput = JObject.Parse(stdout.ToString());

// check "CurrentBranch" output
{
var expectedCommitId = this.Repo.Branches[currentBranchName].Tip.Sha;
var expectedVersion = VersionFile.GetVersion(this.Repo.Branches[currentBranchName].Tip).Version.ToString();

var currentBranchOutput = jsonOutput.Property("CurrentBranch")?.Value as JObject;
Assert.NotNull(currentBranchOutput);

Assert.Equal(currentBranchName, currentBranchOutput.GetValue("Name")?.ToString());
Assert.Equal(expectedCommitId, currentBranchOutput.GetValue("Commit")?.ToString());
Assert.Equal(expectedVersion, currentBranchOutput.GetValue("Version")?.ToString());

}

// Check "NewBranch" output
{
var expectedCommitId = this.Repo.Branches[releaseBranchName].Tip.Sha;
var expectedVersion = VersionFile.GetVersion(this.Repo.Branches[releaseBranchName].Tip).Version.ToString();

var newBranchOutput = jsonOutput.Property("NewBranch")?.Value as JObject;
Assert.NotNull(newBranchOutput);

Assert.Equal(releaseBranchName, newBranchOutput.GetValue("Name")?.ToString());
Assert.Equal(expectedCommitId, newBranchOutput.GetValue("Commit")?.ToString());
Assert.Equal(expectedVersion, newBranchOutput.GetValue("Version")?.ToString());
}
}

[Fact]
public void PrepareRelease_JsonOutputWhenUpdatingReleaseBranch()
{
// create and configure repository
this.InitializeSourceControl();

// create version.json
var versionOptions = new VersionOptions()
{
Version = SemanticVersion.Parse("1.0"),
Release = new ReleaseOptions()
{
BranchName = "v{version}",
VersionIncrement = ReleaseVersionIncrement.Minor
}
};
this.WriteVersionFile(versionOptions);
var branchName = "v1.0";

// switch to release branch
Commands.Checkout(this.Repo, this.Repo.CreateBranch(branchName));

// run release preparation
var stdout = new StringWriter();
var releaseManager = new ReleaseManager(stdout);
releaseManager.PrepareRelease(this.RepoPath, outputMode: ReleaseManager.ReleaseManagerOutputMode.Json);


// Expected output:
// {
// "CurrentBranch" : {
// "Name" : "<NAME>",
// "Commit" : "<COMMIT>",
// "Version" : "<VERSION>",
// },
// "NewBranch" : null
// }

var jsonOutput = JObject.Parse(stdout.ToString());

// check "CurrentBranch" output
{
var expectedCommitId = this.Repo.Branches[branchName].Tip.Sha;
var expectedVersion = VersionFile.GetVersion(this.Repo.Branches[branchName].Tip).Version.ToString();

var currentBranchOutput = jsonOutput.Property("CurrentBranch")?.Value as JObject;
Assert.NotNull(currentBranchOutput);

Assert.Equal(branchName, currentBranchOutput.GetValue("Name")?.ToString());
Assert.Equal(expectedCommitId, currentBranchOutput.GetValue("Commit")?.ToString());
Assert.Equal(expectedVersion, currentBranchOutput.GetValue("Version")?.ToString());

}
// Check "NewBranch" output
{
// no new branch was created, so "NewBranch" should be null
var newBranchOutput = jsonOutput.Property("NewBranch")?.Value as JObject;
Assert.Null(newBranchOutput);
}
}

private void AssertError(Action testCode, ReleasePreparationError expectedError)
{
var ex = Assert.Throws<ReleasePreparationException>(testCode);
Expand Down
Loading

0 comments on commit 3e4e1f8

Please sign in to comment.