-
-
Save PlagueHO/40d80a7f3747c18594e63584f7745cbc to your computer and use it in GitHub Desktop.
<# | |
.SYNOPSIS | |
Convert Git tags to the format required by the DSC Resource module | |
CI Process. | |
.PARAMETER Remote | |
The name of the Git remote repository for your fork. | |
.PARAMETER Upstream | |
The name of the Git remote repository for the upstream fork. | |
.PARAMETER ModuleName | |
The name of the module that will be used in the tag comment. | |
.PARAMETER DeleteOldTags | |
Delete the old tags after they have been converted. | |
#> | |
[CmdletBinding(SupportsShouldProcess=$True)] | |
param ( | |
[Parameter()] | |
[System.String] | |
$Remote = 'origin', | |
[Parameter()] | |
[System.String] | |
$Upstream = 'upstream', | |
[Parameter()] | |
[System.String] | |
$ModuleName = (Get-Location | Split-Path -Leaf), | |
[Parameter()] | |
[Switch] | |
$DeleteOldTags | |
) | |
function Test-GitTag { | |
[CmdletBinding()] | |
[OutputType([System.Boolean])] | |
param ( | |
[Parameter()] | |
[System.String] | |
$Tag | |
) | |
$result = & git @('tag','-l',$Tag) | |
return -not ([System.String]::IsNullOrWhiteSpace($result)) | |
} | |
Write-Verbose -Message "Checking out master branch." | |
& git @('checkout','master') | |
Write-Verbose -Message "Pulling latest tags from '$Upstream'." | |
& git @('pull',$Upstream,'master','--tags') | |
if ($PSCmdlet.ShouldProcess($Remote, "Push tags to '$Remote' master")) | |
{ | |
Write-Verbose -Message "Pushing latest tags to '$Remote'." | |
& git @('push',$Remote,'master','--tags') | |
} | |
$tagRefs = & git @('show-ref','--tags') | |
$backupDatetime = Get-Date -Format FileDateTime | |
$backupGuid = [Guid]::NewGuid().Guid | |
$repoName = Split-Path -Path (Get-Location) -Leaf | |
$backupFile = Join-Path -Path $ENV:Temp -ChildPath "Convert-GitTagForDsc_$($repoName)_$($backupDatetime)_$($backupGuid).txt" | |
$tagRefs | Out-File -FilePath $backupFile | |
Write-Host -Object "A backup of the current tags has been written to '$backupFile'. Use this with the Restore-GitTagForDsc function to restore tags if something goes wrong." -ForegroundColor Yellow | |
foreach ($tagRef in $tagRefs) | |
{ | |
$hash, $ref = $tagRef -split ' ' | |
$tag = ($ref -split '/')[2] | |
Write-Verbose -Message "Begin processing tag '$tag'." | |
if ($tag -match '^v([0-9]+)\.([0-9]+)\.([0-9]+)(\.([0-9]+))?') | |
{ | |
Write-Warning -Message "Tag '$tag' already appears to be in the desired format. Tag will be skipped." | |
break | |
} | |
try { | |
$version = [Version] ($tag -split '-')[0] | |
} | |
catch | |
{ | |
Write-Warning -Message "Error converting tag '$tag' to version string. Tag will be skipped." | |
break | |
} | |
$newTag = 'v' + $version.Major + '.' + $version.Minor + '.' + $version.Build | |
if (Test-GitTag -Tag $newTag) | |
{ | |
Write-Verbose -Message "Tag '$newTag' already exists so skipping create." | |
} | |
else | |
{ | |
$message = "Release of version $version of $ModuleName" | |
if ($PSCmdlet.ShouldProcess($newTag, "Creating tag '$newTag' against '$hash' with message '$message'")) | |
{ | |
Write-Verbose -Message "Creating tag '$newTag' against '$hash' with message '$message'." | |
& git @('tag','-a',$newTag,$hash,'-m',$message) | |
} | |
} | |
if ($DeleteOldTags.IsPresent) | |
{ | |
if (Test-GitTag -Tag $tag) | |
{ | |
if ($PSCmdlet.ShouldProcess($tag, "Deleting tag '$tag' from local")) | |
{ | |
Write-Verbose -Message "Deleting tag '$tag' from local." | |
& git @('tag','-d',$tag) | |
} | |
if ($PSCmdlet.ShouldProcess($tag, "Deleting tag '$tag' from '$Remote'")) | |
{ | |
Write-Verbose -Message "Deleting tag '$tag' from '$Remote'." | |
& git @('push',$Remote,":$tag") | |
} | |
if ($PSCmdlet.ShouldProcess($tag, "Deleting tag '$tag' from '$Upstream'")) | |
{ | |
Write-Verbose -Message "Deleting tag '$tag' from '$Upstream'." | |
& git @('push',$Upstream,":$tag") | |
} | |
} | |
else | |
{ | |
Write-Verbose -Message "Tag '$tag' does not exist so skipping delete." | |
} | |
} | |
} | |
if ($PSCmdlet.ShouldProcess($Remote, "Pushing '$Remote' tags")) | |
{ | |
Write-Verbose -Message "Pushing '$Remote' tags." | |
& git @('push',$Remote,'--tag') | |
} | |
if ($PSCmdlet.ShouldProcess($Upstream, "Pushing '$Upstream' tags")) | |
{ | |
Write-Verbose -Message "Pushing '$Upstream' tags." | |
& git @('push',$Upstream,'--tag') | |
} |
@PlagueHO I have cloned the repos to several computers. If I push a new version tag from another computer I will also push any old tags that I already removed in origin resulting I get back all *PSGallery tags. Unless I remember to push just the one new tag. I suggest this script also supports a new parameter to only clear/remove tags locally that does not exist in upstream. 😄
Ah right! I'll have a think about how I might be able to detect if a tag only exists in the upstream. The git tag -l
command doesn't look like it supports specifying an upstream - it only works on local. Any ideas?
In my case you just need to delete any tags not having the correct format, no need to check if they exist in upstream.
git show
doesn’t seems to take a remote either.
Maybe this works? I haven’t tested, on the phone now https://stackoverflow.com/questions/6294224/check-if-pushed-tag-is-on-the-git-remote/6295385
I added a WhatIf as well. Have successfully run it against NetworkingDsc.