Refactor MSBuild project files to get PowerShell version from git tag#4182
Refactor MSBuild project files to get PowerShell version from git tag#4182daxian-dbw merged 11 commits intoPowerShell:masterfrom
Conversation
|
@daxian-dbw Could you please review? |
|
@iSazonov Sure, next item on my list :) |
|
@daxian-dbw 4 weeks pass by quickly :) , hence I wonder if this PR getting any closer to the top of your list? |
cab3688 to
f27883d
Compare
|
Sorry for leaving this PR unattended for such a long time ... The conflicts were resolved. The changes in
|
|
f27883d to
e4afa43
Compare
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
why include the git-dir if you are just getting it from running git in the current directory anyway?
There was a problem hiding this comment.
During the release process, we manually specify the version. How do you pick that up?
There was a problem hiding this comment.
It is seems a best practice for csproj to use variables everywhere. Currently we can assign the dir externally dotnet build /v:GitInfoBaseDir=....
We can use the same method to assign a version during the release process - @daxian-dbw ask the same and I'll check this and fix if need.
There was a problem hiding this comment.
I would suggest assigning the git directory externally. The reason I've added it to all the git commands I've touch is that sometimes git cannot find the directory, which the current solution will not solve.
There was a problem hiding this comment.
Anybody can assign GitInfoBaseDir externally - it is supported in the target.
e4afa43 to
b74c493
Compare
PowerShell.Common.props
Outdated
|
|
||
| <PropertyGroup> | ||
| <GitExe>git</GitExe> | ||
| </PropertyGroup> |
There was a problem hiding this comment.
Is this property necessary? dotnet/cli use 'git' directly -- see https://github.com/dotnet/cli/blob/45a1e9e56cc47e3973a49f164e98d41442cedebd/build/GitCommitInfo.targets#L3
There was a problem hiding this comment.
It seems a best practice for csproj is to use variables everywhere.
Here we can implement the idea - use another git version that is out off PATH. To get this we should do:
<GitExe Condition = " GitExe =='' ">git</GitExe>
What is your thoughts? Should we make our csproj-s power?
There was a problem hiding this comment.
I think using git directly makes the xml file a little simpler. I don't think we need to support using a different git that is not in PATH.
PowerShell.Common.props
Outdated
| <GitExe>git</GitExe> | ||
| </PropertyGroup> | ||
|
|
||
| <Exec Command='$(GitExe) rev-parse --show-cdup' ConsoleToMSBuild="true"> |
There was a problem hiding this comment.
Add StandardOutputImportance="Low", and it seems to suppress the log of the output.
PowerShell.Common.props
Outdated
|
|
||
| <Exec Command='$(GitExe) --git-dir="$(GitInfoBaseDir)" describe --abbrev=60 --long' | ||
| ConsoleToMSBuild="true" | ||
| EchoOff="true"> |
There was a problem hiding this comment.
Is EchoOff necessary? I don't see a difference when building with or without it ...
There was a problem hiding this comment.
Replaced with StandardOutputImportance="Low"
| </PropertyGroup> | ||
|
|
||
| <Exec Command='$(GitExe) --git-dir="$(GitInfoBaseDir)" describe --abbrev=60 --long' | ||
| ConsoleToMSBuild="true" |
There was a problem hiding this comment.
Add StandardOutputImportance="Low", and it seems to suppress the log of the output.
PowerShell.Common.props
Outdated
|
|
||
| <Exec Command='$(GitExe) rev-parse --show-cdup' ConsoleToMSBuild="true"> | ||
| <Output TaskParameter="ConsoleOutput" PropertyName="GitCDUP" /> | ||
| </Exec> |
There was a problem hiding this comment.
I think we don't need this step. When running git describe below, just set the WorkingDirectory=$(MSBuildProjectDirectory), then it's guaranteed that the git command executes from the directory where .csproj locates, so --git-dir would be unnecessary.
There was a problem hiding this comment.
It seems we can remove WorkingDirectory too because MSBuild make cd to project directory.
There was a problem hiding this comment.
so even I'm running dotnet build <path-to-s.m.a.csproj> from a totally different location, it still guarantees that the git command will run in the src\s.m.a folder?
There was a problem hiding this comment.
I run Publish-NuGetFeed (it don't change the current directory) from non repo directory and it works. (I can not find link to MSDN docs although I read about this. It seems it was an article about MSBuild targets).
Also we may have an issue here when later we'll implement the building from Visual Studio.
There was a problem hiding this comment.
There was a problem hiding this comment.
Also we may have an issue here when later we'll implement the building from Visual Studio.
What is the issue? Is it that the VS may use a different default working directory?
I feel this 'default working directory' is too implicit and most of us wouldn't know this. I think we should use WorkingDirectory=$(MSBuildProjectDirectory) to make it explicit.
There was a problem hiding this comment.
Yes, VS can. Mentioned CLI Issue imply about this.
Will fix.
PowerShell.Common.props
Outdated
|
|
||
| <PropertyGroup Condition = "'$(ReleaseTag)' != ''"> | ||
| <PSCoreBuildVersion>$(ReleaseTag)</PSCoreBuildVersion> | ||
| <PSCoreAdditionalCommits>$([System.Text.RegularExpressions.Regex]::Match($(PowerShellVersion), $(RegexGitVersion)).Groups[2].Value)</PSCoreAdditionalCommits> |
There was a problem hiding this comment.
This seems wrong -- so the PSCoreAdditionalCommits will be set only if ReleaseTag is specified, however, it's used only if ReleaseTag is not specified.
| </PropertyGroup> | ||
|
|
||
| <PropertyGroup> | ||
| <PSCoreBuildVersion Condition = "'$(PSCoreBuildVersion)' == ''">$([System.Text.RegularExpressions.Regex]::Match($(PowerShellVersion), $(RegexGitVersion)).Groups[1].Value)</PSCoreBuildVersion> |
There was a problem hiding this comment.
It seems to me RegexGitVersion can be moved to this PropertyGroup.
There was a problem hiding this comment.
Yes, I tried minimize Condition-s.
Fixed.
| [Parameter(ParameterSetName = "ReleaseTag")] | ||
| [ValidatePattern("^v\d+\.\d+\.\d+(-\w+\.\d+)?$")] | ||
| [ValidateNotNullOrEmpty()] | ||
| [string]$ReleaseTag |
There was a problem hiding this comment.
Let's make this parameter mandatory. -VersionSuffix was mandatory.
There was a problem hiding this comment.
Are we going to do daily builds? If so we shouldn't make it mandatory.
There was a problem hiding this comment.
yes we generate nuget packages from daily build, and you need to change the related code in appveyor.psm1: https://github.com/PowerShell/PowerShell/blob/master/tools/appveyor.psm1#L452
The existing code has predefined suffix for daily build, you need to think how to make it continue to work, or how to alter it according to this PR. /cc @TravisEz13 for input.
There was a problem hiding this comment.
I see there we call Start-PSPackage - we need fix it too. And in Start-PSPackage we have another code path for nuget packages - I wonder why we have two code path to generate nuget packages? Because Publish-NuGetFeed was not moved in Packaging.psm1 I thought it is not used on CI but it is used. Please explain the package build process. It seems we need (1) release (2) daily and (3) manual builds - the last only work in the PR. Should we fix all in the PR or can cut off?
There was a problem hiding this comment.
The nuget package created in Start-PSPackage is not individual assembly package to be used for development, but a package that contains all powershell core bits -- it's similar to the .zip packages we generated for release and can be installed directly by using PackageManagement module.
| ## Workaround: | ||
| ## dotnet restore /p:VersionSuffix=<suffix> # Bake the suffix into project.assets.json | ||
| ## dotnet pack --version-suffix <suffix> | ||
| ## We update 'project.assets.json' files with new version tag value by 'GetPSCoreVersionFromGit' target. |
There was a problem hiding this comment.
The comments is outdated now, as we don't use --version-suffix anymore.
There was a problem hiding this comment.
Left only my last comment.
| ## dotnet pack --version-suffix <suffix> | ||
| ## We update 'project.assets.json' files with new version tag value by 'GetPSCoreVersionFromGit' target. | ||
| $TopProject = (New-PSOptions).Top | ||
| if ($ReleaseTag) { |
There was a problem hiding this comment.
Let's make -ReleaseTag mandatory. So the if/else is unnecessary now.
build.psm1
Outdated
| [string]$OutputPath = "$PSScriptRoot/nuget-artifacts", | ||
| [Parameter(Mandatory=$true)] | ||
| [string]$VersionSuffix | ||
| [Parameter(ParameterSetName = "ReleaseTag")] |
There was a problem hiding this comment.
This parameter attribute seems not necessary.
There was a problem hiding this comment.
I added this because we could return [string]$VersionSuffix to temporary fix daily builds.
Fix appveyor.psm1 Add WorkingDirectory=$(MSBuildProjectDirectory)
Dismiss my previous review because of new commits
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
It's still using the default working directory. I think we agreed to explicitly use WorkingDirectory=$(MSBuildProjectDirectory)
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
The prefixversion, majorversion, minorversion and labelversion are not used anywhere, so maybe we should remove them here.
There was a problem hiding this comment.
Yes, currently we don't use but can in future. I added its because we do "strange" 😄 manipulations with version strings in build scripts
There was a problem hiding this comment.
I think we only used the individual major, minor and patch numbers when generating MSI package, so it's hard for me to see we will somehow use them in .csproj files. I tend to make our build faster, but probably it won't make much difference. So I will leave this decision up to you. #Closed
There was a problem hiding this comment.
We can comment this so that we don't waste time on creating this code if we'll need it in future.
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
The <ProductVersion> tag seems unnecessary -- the ProductVersion of the generated assembly uses the same as InformationalVersion. I found this when playing with the tag. You can double check, and if you see the same, we should remove this tag here.
There was a problem hiding this comment.
InformationalVersion is explicitly defined in Microsoft.NET.GenerateAssemblyInfo.targets from Version. ProductVersion is seems hard coded in AL task. So I explicitly set it here to exclude unpredictable behavior if AL task logic will be changed in any next dotnet update.
There was a problem hiding this comment.
I guess it's better to be explicit, so let's keep the <ProductVersion>. But can we move this tag next to <InformationalVersion> instead of having them separated by the comments?
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
Maybe also mention that Version is used as the default value for many other version properties, like AssemblyVersion.
There was a problem hiding this comment.
It seems it will be obvious comment. Or you meant we should explicitly enumerate such properties which we use?
There was a problem hiding this comment.
I mean if you mention FileVersion in the comment here, then better mention that version properties that use <Version> as the default value. Otherwise, the comment means more like FileVersion is the only reason we explicitly define <version> here.
There was a problem hiding this comment.
I thought there is many properties that depended on <Version> but it's not.
Added AssemblyVersion in the comment.
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
I think they can be removed now.
build.psm1
Outdated
There was a problem hiding this comment.
Shall we merge the two /p? Like --output $OutputPath "/p:IncludeSymbols=true;ReleaseTag=$ReleaseTag1"
There was a problem hiding this comment.
Fixed. (I can not test this.)
There was a problem hiding this comment.
Why can't this be tested? IncludeSymbols=true means symbol packages is demanded as well, so if you use Publish-NuGetFeed -ReleaseTag1 v6.0.0-beta.10, the expected result is both beta.10.nupkg and beta.10.symbols.nupkg are generated.
PowerShell.Common.props
Outdated
There was a problem hiding this comment.
Once we removed some of the unnecessary properties, this debug section need to be cleaned up to remove them as well.
There was a problem hiding this comment.
This debug section still needs to be cleaned up, for example, GitCDUP is gone now.
build.psm1
Outdated
There was a problem hiding this comment.
Do we need to explicitly run dotnet restore when the release tag is not specified? It's not necessary as we don't need to bake any customized version strings into the build.
There was a problem hiding this comment.
If we set new version git tag we should explicitly run dotnet restore before locally build nuget packages.
There was a problem hiding this comment.
I see your point. You mean dotnet pack may use the existing artifacts produced from previous dotnet restore run and thus use stale version info. It makes sense. #Closed
tools/appveyor.psm1
Outdated
There was a problem hiding this comment.
Isn't the tag name already has 'v' prefixed?
There was a problem hiding this comment.
I don't know - I can not test. I am only trying to follow previous logic.
There was a problem hiding this comment.
@TravisEz13 can you comment on this one? What would $env:APPVEYOR_REPO_TAG_NAME be like?
@iSazonov I think the next commit you submit should be marked with '[Feature]', so that we can see how the nupkg generation works in full build.
There was a problem hiding this comment.
[Feature] - done.
There was a problem hiding this comment.
contains tag name for builds started by tag; otherwise this variable is undefined
I don't think we ever do this, unless AppVeyor counts a push with a tag.
There was a problem hiding this comment.
I see. So if an AppVeyor build is triggered by pushing a tag, then this environment variable will be set to be the tag.
So we don't need to prefix with a 'v' here,
tools/appveyor.psm1
Outdated
There was a problem hiding this comment.
-ReleaseTag "/property:ReleaseTag=$preReleaseVersion"
This seems wrong ...
06e2998 to
39e04f1
Compare
0835d32 to
92b1ec4
Compare
92b1ec4 to
76a7e6f
Compare
|
The changes to I did find that the full build run in CI doesn't generate the powershell packages (msi, nupkg and zip) like our daily build (look in the |
|
Packaging is broken: See the very end of https://ci.appveyor.com/project/PowerShell/powershell/build/6.0.0-beta.6-4928#L9098 |
|
@TravisEz13 Now that |
|
No concerns with that change |
|
Windows artifacts look good. |
|
Thanks @TravisEz13. Then I will consider this PR to be almost ready. I will update some of the comments, and then it would be good to go. |
PowerShell.Common.props
Outdated
| because: | ||
| 1. By default the version properties are defined in global 'PropertyGroup' (not target!) in 'Microsoft.NET.DefaultAssemblyInfo.targets' | ||
| 2. Properties in global 'PropertyGroups' are assigned before any targets | ||
| 3. and cannot be conditionally excecuted as targets (after this target). |
There was a problem hiding this comment.
and cannot be conditionally excecuted as targets (after this target).
First, a typo I didn't notice in my last change: excecuted -> executed.
Second, I have trouble understanding this sentence accurately. Can you please reword this sentence a bit to make it easier to understand?
And one more thing, what does global PropertyGroup mean? Is it different from the PropertyGroup we used in this file?
There was a problem hiding this comment.
Typo fixed.
Under "global" I meant that they affect the entire project. Removed.
I tryed to reword but ... - feel free to rewrite.
|
@iSazonov Can you please take a look and see if my re-write reflects what you think? |
|
Yes, thanks! Look very good. |
|
Get-ComputerInfo test failed in AppVeyor CI. |
|
The test failure is not related to this change. Comparing with the last successful full build CI, the only changes we have are comment changes. So it's OK to merge this PR. |
|
@daxian-dbw @TravisEz13 Thanks for review and approvement! Should we continue to improve csproj files? I think it's worth moving a stable logic into them. |
|
@daxian-dbw My question was more about #3690 - I'll continue. |
|
@daxian-dbw What is your thoughts - should we set up the CommitId and PSVersion based on assembly version attributes or generate strong typed constant? |
|
I vote for getting the needed info from the attributes 😄 |

Related #3400
Continue #3690 and #4106.
Extract information about the release tag, number of commits since the tag and the hash of the latest commit within a MSBuild target, and bake that information into version properties of the assemblies appropriately.
GetPSCoreVersionFromGitdepends on (BeforeTargets) Restore and Nuget steps so now we get packages with the right version.