Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache version info to a file in quickbuild #668

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions doc/quickbuild.md
Expand Up @@ -4,8 +4,6 @@ Nerdbank.GitVersioning supports the Microsoft-internal quickbuild/cloudbuild too

It works out of the box, but each project will recompute the version, which may accumulate to a significant increase in overall build time.

🚧 A future version of Nerdbank.GitVersioning will cache version information as a file so that the following instructions will be effective. 🚧

To calculate the version just once for an entire build, a few manual steps are required.

1. Create this project in your repo. The suggested location is `VersionGeneration/VersionGeneration.msbuildproj`.
Expand Down
62 changes: 62 additions & 0 deletions src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LibGit2Sharp;
Expand Down Expand Up @@ -929,4 +930,65 @@ public void GetVersionHeight_VeryLongHistory()
this.GetVersionHeight();
}

[Fact]
public void Serialization()
{
// test with path filters, and two serialization rounds.
this.WriteVersionFile(new VersionOptions { Version = SemanticVersion.Parse("1.2"), GitCommitIdShortAutoMinimum = 4 });
this.InitializeSourceControl();
this.AddCommits(1);
var oracle = new VersionOracle(this.Context);
this.SerializationRoundTrip(oracle);
}

private VersionOracle SerializationRoundTrip(VersionOracle oracle)
{
using StringWriter sw = new();
oracle.Serialize(sw);
string json1 = sw.ToString();
this.Logger.WriteLine(json1);

using StringReader sr = new(json1);
VersionOracle deserialized = VersionOracle.Deserialize(sr, this.Context.RepoRelativeProjectDirectory);

// Serialize again to make sure all information carries.
sw.GetStringBuilder().Clear();
deserialized.Serialize(sw);
string json2 = sw.ToString();

// Make sure the same data was preserved from the original vs. the deserialized copy.
Assert.Equal(json1, json2);

// Compare all meaningful properties.
AssertEqual(oracle.CloudBuildAllVars, deserialized.CloudBuildAllVars);

return deserialized;

void AssertEqual(IDictionary<string, string> expected, IDictionary<string, string> actual)
{
SortedSet<string> expectedKeys = new(expected.Keys);
SortedSet<string> actualKeys = new(actual.Keys);

var missingKeys = expectedKeys.Except(actualKeys);
var extraKeys = actualKeys.Except(expectedKeys);
if (missingKeys.Any() || extraKeys.Any())
{
this.Logger.WriteLine("Missing keys: {0}", string.Join(", ", missingKeys));
this.Logger.WriteLine("Extra keys: {0}", string.Join(", ", extraKeys));
}

Assert.False(missingKeys.Any() || extraKeys.Any());

foreach (KeyValuePair<string, string> expectedPair in expected)
{
string expectedValue = expectedPair.Value;
string actualValue = actual[expectedPair.Key];
if (expectedValue != actualValue)
{
this.Logger.WriteLine($"Value for key {expectedPair.Key} was not as expected.");
Assert.Equal(expectedValue, actualValue);
}
}
}
}
}