Include SourceRevisionId in InformationalVersion#2028
Include SourceRevisionId in InformationalVersion#2028dsplaisted merged 4 commits intodotnet:masterfrom
Conversation
|
@jaredpar @nguerrera @AArnott PTAL |
| DependsOnTargets="InitializeSourceControlInformation" | ||
| Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true'"> | ||
| <PropertyGroup> | ||
| <InformationalVersion>$(InformationalVersion) (revision $(SourceRevisionId))</InformationalVersion> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Almost. NB.GV uses this syntax: 1.2.3+gabc123. Yes, g stands for git.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Yeah, i would not include the g in the version. Just x.y.z+sha seems good enough.
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Ah, yes, forgot to add SourceRevisionId != '' to the condition.
It's set by InitializeSourceControlInformation target that is provided by a source control package.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
How do we detect that though? Look for + in InformationalVersion?
There was a problem hiding this comment.
I was thinking $(InformationalVersion.Contains($(SourceRevisionId))
But that isn't foolproof due to ordering and possible SHA abbreviation.
There was a problem hiding this comment.
But that isn't foolproof due to ordering and possible SHA abbreviation.
Yup, that's the problem.
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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).
|
We should add a test with mock provider targets. Shouldn't be too hard to base it on existing assembly info tests. |
|
@nguerrera Yes, I'll definitely add a test |
|
|
||
| <Target Name="AddSourceRevisionToInformationalVersion" | ||
| DependsOnTargets="InitializeSourceControlInformation" | ||
| Condition="'$(IncludeSourceRevisionInInformationalVersion)' == 'true' and '$(SourceRevisionId)' != ''"> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
@nguerrera I have an idea how to avoid the break. Let me check with msbuild team.
61fc0cb to
8c0efeb
Compare
8c0efeb to
aee0d72
Compare
|
@dsplaisted @nguerrera PTAL |
| Condition="'$(GenerateAssemblyInfo)' == 'true'" /> | ||
|
|
||
| <Target Name="AddSourceRevisionToInformationalVersion" | ||
| DependsOnTargets="InitializeSourceControlInformation" |
There was a problem hiding this comment.
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.
| project.Root.Add( | ||
| new XElement(ns + "PropertyGroup", | ||
| new XElement("SourceControlInformationFeatureSupported", "true"), | ||
| new XElement("IncludeSourceRevisionInInformationalVersion", "true"))); |
There was a problem hiding this comment.
Nit: You can add these properties to the AdditionalProperties of the TestProject instead of creating the XML nodes yourself here.
There was a problem hiding this comment.
Since the IncludeSourceRevisionInInformationalVersion property is set to true by default in the SDK, is there a reason to set it in this test?
| } | ||
|
|
||
| [Fact] | ||
| public void It_does_not_include_source_revision_id_if_not_available2() |
There was a problem hiding this comment.
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.
| } | ||
|
|
||
| [Fact] | ||
| public void It_includes_source_revision_id_if_available__version_without_plus() |
There was a problem hiding this comment.
Nit: Looks like there's an extra underscore between "available" and "version" in the name here.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
The tests define different XML elements. I'd rather leave them separate.
|
|
||
| project.Root.Add( | ||
| new XElement(ns + "PropertyGroup", | ||
| new XElement("SourceControlInformationFeatureSupported", "true"))); |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
If that's the case wouldn't we want to remove the condition on SourceControlInformationFeatureSupported from the product as well?
There was a problem hiding this comment.
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.
|
|
||
| testAsset.Restore(Log, testProject.Name); | ||
|
|
||
| var command = new GetValuesCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name), "netcoreapp2.0", valueName: "InformationalVersion"); |
There was a problem hiding this comment.
Use testProject.TargetFrameworks instead of hardcoding netcoreapp2.0 as the target framework to pass to the GetValuesCommand method (here and elsewhere).
|
@tmat I've reviewed this. Thanks! |
|
@dsplaisted Good to merge? |
…114.3 (#2028) [main] Update dependencies from dotnet/arcade
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.