Skip to content

Conversation

@tmat
Copy link
Member

@tmat tmat commented Mar 8, 2018

When a source control provider is available in the project append the value of SourceRevisionId set by the provider to InformationalVersion string.

See https://github.com/tmat/repository-info/blob/master/docs/Readme.md and dotnet/msbuild#3063 for details.

@tmat tmat changed the title Include SourceRevisionId to InformationalVersion WIP: Include SourceRevisionId to InformationalVersion Mar 8, 2018
@tmat
Copy link
Member Author

tmat commented Mar 8, 2018

@jaredpar @nguerrera @AArnott PTAL

DependsOnTargets="InitializeSourceControlInformation"
Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true'">
<PropertyGroup>
<InformationalVersion>$(InformationalVersion) (revision $(SourceRevisionId))</InformationalVersion>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better syntax to use for the revision? I believe Nerdbank.GitVersioning uses g+ and assume g stands for git. SourceRevisionId could be commit hash, TFVC changeset number, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost. NB.GV uses this syntax: 1.2.3+gabc123. Yes, g stands for git.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we haven't any precedent for $(SourceRevisionId) values yet, perhaps we can indicate they should assume that they are appending some + value to the version, semver 2 style. Just because technically there can be multiple build metadata identifiers specified, they should probably not specify + themselves (we should do that, or add . if there is already a + in the $(InformationalVersion) property).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the g an official/standard thing? I've gotten tripped up by it, pasting it as part of the hash. After a minute, I realized g isn't valid hex but I'd rather the Sha appear with better punctuation around it. I'll back away if there's an industry effort to write versions that way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, i would not include the g in the version. Just x.y.z+sha seems good enough.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't my idea, but I can't remember exactly where I'd seen the precedent for it. At the time I figured I'd follow the pattern others had established. It is a little inconvenient, I agree.

DependsOnTargets="InitializeSourceControlInformation"
Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true'">
<PropertyGroup>
<InformationalVersion>$(InformationalVersion) (revision $(SourceRevisionId))</InformationalVersion>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does $(SourceRevisionId) get set? And if it's empty, shouldn't you avoid appending to $(InformationalVersion) to avoid leaving an obvious hole in the added string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, forgot to add SourceRevisionId != '' to the condition.
It's set by InitializeSourceControlInformation target that is provided by a source control package.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider doing nothing if informational version already contains revision id. This allows custom formatting and will play better with pre existing techniques like nb.gv, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we detect that though? Look for + in InformationalVersion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking $(InformationalVersion.Contains($(SourceRevisionId))

But that isn't foolproof due to ordering and possible SHA abbreviation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that isn't foolproof due to ordering and possible SHA abbreviation.

Yup, that's the problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about nb.gv interop as well (thanks, @nguerrera). It won't be a problem because nb.gv already turns generation of this attribute off completely to avoid conflicts with the one it generates itself.

DependsOnTargets="InitializeSourceControlInformation"
Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true'">
<PropertyGroup>
<InformationalVersion>$(InformationalVersion) (revision $(SourceRevisionId))</InformationalVersion>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we haven't any precedent for $(SourceRevisionId) values yet, perhaps we can indicate they should assume that they are appending some + value to the version, semver 2 style. Just because technically there can be multiple build metadata identifiers specified, they should probably not specify + themselves (we should do that, or add . if there is already a + in the $(InformationalVersion) property).

@nguerrera
Copy link
Contributor

We should add a test with mock provider targets. Shouldn't be too hard to base it on existing assembly info tests.

@tmat
Copy link
Member Author

tmat commented Mar 8, 2018

@nguerrera Yes, I'll definitely add a test

@livarcocc livarcocc added this to the 2.1.3xx milestone Mar 9, 2018

<Target Name="AddSourceRevisionToInformationalVersion"
DependsOnTargets="InitializeSourceControlInformation"
Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true' and '$(SourceRevisionId)' != ''">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe build will break here if msbuild version used does not include your change and SourceRevisionId is set. I'm not sure we want such a hard break. We may need to stub InitializeSourceControlInformation in props.

I think we are saying that 15.7+ is required for 2.1.300, though, so maybe it's fine. We need to think about it carefully and be deliberate. cc @livarcocc

Copy link
Contributor

@AArnott AArnott Mar 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way to have a 'soft dependency' is change DependsOnTargets to AfterTargets. That doesn't fail if the target is missing. But it also doesn't guarantee that the antecedent runs first -- it just will in the common case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AArnott We need the guarantee that InitializeSourceControlInformation runs.

@nguerrera Yes, I agree we need to be careful about the dependency. Let's discuss it next week.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nguerrera I have an idea how to avoid the break. Let me check with msbuild team.

@tmat tmat force-pushed the RevisionNumberInAIVA branch from 61fc0cb to 8c0efeb Compare March 14, 2018 19:57
@tmat tmat force-pushed the RevisionNumberInAIVA branch from 8c0efeb to aee0d72 Compare March 15, 2018 01:16
@tmat tmat changed the title WIP: Include SourceRevisionId to InformationalVersion Include SourceRevisionId to InformationalVersion Mar 15, 2018
@tmat tmat changed the title Include SourceRevisionId to InformationalVersion Include SourceRevisionId in InformationalVersion Mar 15, 2018
@tmat
Copy link
Member Author

tmat commented Mar 15, 2018

@dsplaisted @nguerrera PTAL

Condition="'$(GenerateAssemblyInfo)' == 'true'" />

<Target Name="AddSourceRevisionToInformationalVersion"
DependsOnTargets="InitializeSourceControlInformation"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably also depend on the GetAssemblyVersion, which is where InformationalVersion is set by default. It currently works because of the ordering of DependsOnTargets for GetAssemblyAttributes, but it's probably better to be more explicit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

project.Root.Add(
new XElement(ns + "PropertyGroup",
new XElement("SourceControlInformationFeatureSupported", "true"),
new XElement("IncludeSourceRevisionInInformationalVersion", "true")));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: You can add these properties to the AdditionalProperties of the TestProject instead of creating the XML nodes yourself here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the IncludeSourceRevisionInInformationalVersion property is set to true by default in the SDK, is there a reason to set it in this test?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

}

[Fact]
public void It_does_not_include_source_revision_id_if_not_available2()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tests where the name only differs by a number appended to it, I'd like to see comments summarizing what the tests cover / how they are different.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the names.

}

[Fact]
public void It_includes_source_revision_id_if_available__version_without_plus()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Looks like there's an extra underscore between "available" and "version" in the name here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, perhaps this was intentional to separate the different parts of the test name.

You might consider changing these tests to a Theory.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests define different XML elements. I'd rather leave them separate.


project.Root.Add(
new XElement(ns + "PropertyGroup",
new XElement("SourceControlInformationFeatureSupported", "true")));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please file a follow-up bug for us to remove the SourceControlInformationFeatureSupported property and InitializeSourceControlInformation target from all of these tests once we are using a version of MSBuild that includes them in all places where these tests run (the last one will probably be the full Framework version of MSBuild that we use on CI machines).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting point. Can we run tests against older msbuild common targets? Ideally we would test against the current and a fixed previous version that doesn't have these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to. Generally for customers to be using an SDK with this feature, they will be using an updated version of MSBuild. The only way they wouldn't have an updated version of MSBuild is if they were using full Framework MSBuild and installed the 2.1.300 SDK, but hadn't updated VS/MSBuild to 15.7. That combination might be blocked otherwise anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's the case wouldn't we want to remove the condition on SourceControlInformationFeatureSupported from the product as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it there for now, as the updated version of MSBuild hasn't made its way into the SDK. I would leave it there in general, in order to follow the recommended pattern for hooking into the extension point (since others who use it can't depend on shipping together with MSBuild), and in order to not block the 2.1.300 SDK / MSBuild 15.6 combination just because of this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #2051


testAsset.Restore(Log, testProject.Name);

var command = new GetValuesCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name), "netcoreapp2.0", valueName: "InformationalVersion");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use testProject.TargetFrameworks instead of hardcoding netcoreapp2.0 as the target framework to pass to the GetValuesCommand method (here and elsewhere).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

@dsplaisted
Copy link
Member

@tmat I've reviewed this. Thanks!

@tmat
Copy link
Member Author

tmat commented Mar 16, 2018

@dsplaisted Good to merge?

@dsplaisted dsplaisted merged commit 2e6c593 into dotnet:master Mar 16, 2018
JL03-Yue pushed a commit that referenced this pull request Mar 19, 2024
@tmat tmat deleted the RevisionNumberInAIVA branch November 20, 2025 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants