-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added task
Create_Release_Git_Tag
(#380)
- Loading branch information
Showing
6 changed files
with
559 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
<# | ||
.SYNOPSIS | ||
This build task creates and pushes a preview release tag to the default | ||
branch. | ||
.DESCRIPTION | ||
This build task creates and pushes a preview release tag to the default | ||
branch. | ||
This task is primarily meant to be used for SCM's that does not have | ||
releases that connects to tags like GitHub does with GitHub Releases, but | ||
this task can also be used as an alternative when using GitHub as SCM. | ||
.PARAMETER ProjectPath | ||
The root path to the project. Defaults to $BuildRoot. | ||
.PARAMETER OutputDirectory | ||
The base directory of all output. Defaults to folder 'output' relative to | ||
the $BuildRoot. | ||
.PARAMETER BuiltModuleSubdirectory | ||
The parent path of the module to be built. | ||
.PARAMETER VersionedOutputDirectory | ||
If the module should be built using a version folder, e.g. ./MyModule/1.0.0. | ||
Defaults to $true. | ||
.PARAMETER ProjectName | ||
The project name. | ||
.PARAMETER SourcePath | ||
The path to the source folder. | ||
.PARAMETER SkipPublish | ||
If publishing should be skipped. Defaults to $false. | ||
.PARAMETER MainGitBranch | ||
The name of the default branch. Defaults to 'main'. | ||
.PARAMETER RepositoryPAT | ||
The personal access token used for accessing hte Git repository. | ||
.PARAMETER BuildInfo | ||
The build info object from ModuleBuilder. Defaults to an empty hashtable. | ||
.NOTES | ||
This is a build task that is primarily meant to be run by Invoke-Build but | ||
wrapped by the Sampler project's build.ps1 (https://github.com/gaelcolas/Sampler). | ||
#> | ||
param | ||
( | ||
[Parameter()] | ||
[System.String] | ||
$ProjectPath = (property ProjectPath $BuildRoot), | ||
|
||
[Parameter()] | ||
[System.String] | ||
$OutputDirectory = (property OutputDirectory (Join-Path $BuildRoot 'output')), | ||
|
||
[Parameter()] | ||
[System.String] | ||
$BuiltModuleSubdirectory = (property BuiltModuleSubdirectory ''), | ||
|
||
[Parameter()] | ||
[System.Management.Automation.SwitchParameter] | ||
$VersionedOutputDirectory = (property VersionedOutputDirectory $true), | ||
|
||
[Parameter()] | ||
[System.String] | ||
$ProjectName = (property ProjectName ''), | ||
|
||
[Parameter()] | ||
[System.String] | ||
$SourcePath = (property SourcePath ''), | ||
|
||
[Parameter()] | ||
$SkipPublish = (property SkipPublish ''), | ||
|
||
[Parameter()] | ||
$MainGitBranch = (property MainGitBranch 'main'), | ||
|
||
[Parameter()] | ||
$RepositoryPAT = (property RepositoryPAT ''), | ||
|
||
[Parameter()] | ||
[string] | ||
$GitConfigUserEmail = (property GitConfigUserEmail ''), | ||
|
||
[Parameter()] | ||
[string] | ||
$GitConfigUserName = (property GitConfigUserName ''), | ||
|
||
[Parameter()] | ||
$BuildInfo = (property BuildInfo @{ }) | ||
) | ||
|
||
# Synopsis: Creates a git tag for the release that is published to a Gallery | ||
task Create_Release_Git_Tag { | ||
if ($SkipPublish) | ||
{ | ||
Write-Build Yellow ('Skipping the creating of a tag for module version ''{0}'' since ''$SkipPublish'' was set to ''$true''.' -f $ModuleVersion) | ||
|
||
return | ||
} | ||
|
||
. Set-SamplerTaskVariable | ||
|
||
<# | ||
This will return the tag on the HEAD commit, or blank if it | ||
fails (the error that is catched to $null). | ||
This call should not use Invoke-SamplerGit since it should not throw | ||
on error, but return $null if failing. | ||
#> | ||
$isCurrentTag = git describe --contains 2> $null | ||
|
||
if ($isCurrentTag) | ||
{ | ||
Write-Build Green ('Found a tag. Assuming a full release has been pushed for module version ''{0}''. Exiting.' -f $ModuleVersion) | ||
} | ||
else | ||
{ | ||
Write-Build DarkGray ('About to create the tag ''{0}'' for module version ''{1}''.' -f $releaseTag, $ModuleVersion) | ||
|
||
foreach ($gitConfigKey in @('UserName', 'UserEmail')) | ||
{ | ||
$gitConfigVariableName = 'GitConfig{0}' -f $gitConfigKey | ||
|
||
if (-not (Get-Variable -Name $gitConfigVariableName -ValueOnly -ErrorAction 'SilentlyContinue')) | ||
{ | ||
# Variable is not set in context, use $BuildInfo.ChangelogConfig.<varName> | ||
$configurationValue = $BuildInfo.GitConfig.($gitConfigKey) | ||
|
||
Set-Variable -Name $gitConfigVariableName -Value $configurationValue | ||
|
||
Write-Build DarkGray "`t...Set property $gitConfigVariableName to the value $configurationValue" | ||
} | ||
} | ||
|
||
Write-Build DarkGray "`tSetting git configuration." | ||
|
||
Sampler\Invoke-SamplerGit -Argument @('config', 'user.name', $GitConfigUserName) | ||
Sampler\Invoke-SamplerGit -Argument @('config', 'user.email', $GitConfigUserEmail) | ||
|
||
# Make empty line in output | ||
"" | ||
|
||
$releaseTag = 'v{0}' -f $ModuleVersion | ||
|
||
Write-Build DarkGray ("`tGetting HEAD commit for the default branch '{0}." -f $MainGitBranch) | ||
|
||
$defaultBranchHeadCommit = Sampler\Invoke-SamplerGit -Argument @('rev-parse', "origin/$MainGitBranch") | ||
|
||
Write-Build DarkGray ("`tCreating tag '{0}' on the commit '{1}'." -f $releaseTag, $defaultBranchHeadCommit) | ||
|
||
Sampler\Invoke-SamplerGit -Argument @('tag', $releaseTag, $defaultBranchHeadCommit) | ||
|
||
Write-Build DarkGray ("`tPushing created tag '{0}' to the default branch '{1}'." -f $releaseTag, $MainGitBranch) | ||
|
||
$pushArguments = @() | ||
|
||
if ($RepositoryPAT) | ||
{ | ||
Write-Build DarkGray "`t`tUsing personal access token to push the tag." | ||
|
||
$patBase64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(('{0}:{1}' -f 'PAT', $RepositoryPAT))) | ||
|
||
$pushArguments += @('-c', ('http.extraheader="AUTHORIZATION: basic {0}"' -f $patBase64)) | ||
} | ||
|
||
$pushArguments += @('-c', 'http.sslbackend="schannel"', 'push', 'origin', '--tags') | ||
|
||
Sampler\Invoke-SamplerGit -Argument $pushArguments | ||
|
||
<# | ||
Wait for a few seconds so the tag have time to propegate. | ||
This way next task have chance to find the tag. | ||
#> | ||
Start-Sleep -Seconds 5 | ||
|
||
Write-Build Green 'Tag created and pushed.' | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -585,6 +585,31 @@ Add-Sample -Sample PublicFunction -PublicFunctionName Get-MyStuff | |
This example adds a public function to the module (in the current folder), | ||
with a sample unit test that test the public function. | ||
|
||
### `Invoke-SamplerGit` | ||
|
||
This command executes git with the provided arguments and throws an error | ||
if the call failed. | ||
|
||
#### Syntax | ||
|
||
<!-- markdownlint-disable MD013 - Line length --> | ||
```plaintext | ||
Invoke-SamplerGit [-Argument] <string[]> [<CommonParameters>] | ||
``` | ||
<!-- markdownlint-enable MD013 - Line length --> | ||
|
||
#### Outputs | ||
|
||
[System.String] | ||
|
||
#### Example | ||
|
||
```powershell | ||
Invoke-SamplerGit -Argument @('config', 'user.name', 'MyName') | ||
``` | ||
|
||
Calls git to set user name in the git config. | ||
|
||
### `New-SampleModule` | ||
|
||
This command helps you scaffold your PowerShell module project by creating | ||
|
@@ -1423,3 +1448,53 @@ THe path to the release notes markdown file. Defaults to the path for | |
The path to the source folder. Defaults to the same path where the module | ||
manifest is found in either the folder 'source', 'src', or a folder with | ||
the same name as the module. | ||
|
||
## Tasks | ||
|
||
### `Create_Release_Git_Tag` | ||
|
||
This build task creates and pushes a preview release tag to the default branch. | ||
|
||
>Note: This task is primarily meant to be used for SCM's that does not have | ||
>releases that connects to tags like GitHub does with GitHub Releases, but | ||
>this task can also be used as an alternative when using GitHub as SCM. | ||
This is an example of how to use the task in the _build.yaml_ file: | ||
|
||
```yaml | ||
publish: | ||
- Create_Release_Git_Tag | ||
``` | ||
#### Task parameters | ||
Some task parameters are vital for the resource to work. See comment based | ||
help for the description for each available parameter. Below is the most | ||
important. | ||
#### Task configuration | ||
The build configuration (_build.yaml_) can be used to control the behavior | ||
of the build task. | ||
```yaml | ||
#################################################### | ||
# Git Configuration # | ||
#################################################### | ||
GitConfig: | ||
UserName: bot | ||
UserEmail: [email protected] | ||
``` | ||
#### Section GitConfig | ||
This configures git. user name and e-mail address of the user before task pushes the | ||
tag. | ||
##### Property UserName | ||
User name of the user that should push the tag. | ||
##### Property UserEmail | ||
E-mail address of the user that should push the tag. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<# | ||
.SYNOPSIS | ||
Executes git with the provided arguments. | ||
.DESCRIPTION | ||
This command executes git with the provided arguments and throws an error | ||
if the call failed. | ||
.PARAMETER Argument | ||
Specifies the arguments to call git with. It is passes as an array of strings, | ||
e.g. @('tag', 'v2.0.0'). | ||
.EXAMPLE | ||
Invoke-SamplerGit -Argument @('config', 'user.name', 'MyName') | ||
Calls git to set user name in the git config. | ||
.NOTES | ||
Git does not throw an error that can be caught by the pipeline. For example | ||
this git command error but does not throw 'hello' as one would expect. | ||
``` | ||
PS> try { git describe --contains } catch { throw 'hello' } | ||
fatal: cannot describe '144e0422398e89cc8451ebba738c0a410b628302' | ||
``` | ||
So we have to determine if git worked or not by checking the last exit code | ||
and then throw an error to stop the pipeline. | ||
#> | ||
function Invoke-SamplerGit | ||
{ | ||
param | ||
( | ||
[Parameter(Mandatory = $true)] | ||
[System.String[]] | ||
$Argument | ||
) | ||
|
||
# The catch is triggered only if 'git' can't be found. | ||
try | ||
{ | ||
& git $Argument | ||
} | ||
catch | ||
{ | ||
throw $_ | ||
} | ||
|
||
<# | ||
This will trigger an error if git returned an error code from the above | ||
execution. Git will also have outputted an error message to the console | ||
so we just need to throw a generic error. | ||
#> | ||
if ($LASTEXITCODE) | ||
{ | ||
throw "git returned exit code $LASTEXITCODE indicated failure." | ||
} | ||
} |
Oops, something went wrong.