Types/OpenPackage.Publisher/GitTag.ps1

<#
.SYNOPSIS
    Publishes Git Tags
.DESCRIPTION
    Publishes Git Tags if the version has changed.

    This is required to create releases on github.
.NOTES
    Must provide a single package to publish.

    Must be run from the repository in question.
#>

[CmdletBinding(SupportsShouldProcess,ConfirmImpact='High')]
param(
[Parameter(Mandatory,ValueFromPipeline)]
[IO.Packaging.Package]
$Package
)

# Throw if there is no version
if (-not $package.Version) { throw "No Package Version" }

# Throw if there is no repository relationship
if (-not $package.RelationshipExists('repository')) {
    throw "Package not related to repository"    
}

# Get the gip application (no to be confused with any functions named git)
$gitApp = $ExecutionContext.SessionState.InvokeCommand.GetCommand('git', 'application')

# Find our repository url.
$repositoryUrl = @(& $gitApp remote)[0] |
    ForEach-Object {
        & $gitApp remote get-url $_
    }

# If we could not, throw.
if (-not $repositoryUrl) {
    throw "No Repository"
}

# Make sure this package is related to our repository.
$packageGitRepo = $package.GetRelationship('repository').TargetUri
if ($packageGitRepo -ne $repositoryUrl) {
    throw "Package unrelated to '$repositoryUrl'"
    return
}

# Try to get a github event.
$gitHubEvent = if ($env:GITHUB_EVENT_PATH) {
    [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json
} else { $null }

# If there was no event, we are going to prompt.
if (-not $gitHubEvent) {
    Write-Warning "No github event found, prompting for confirmation"    
} else {
    # If there was an event, and it is not merging a pull request, we do not want to potentially tag.
    if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?<PRNumber>\d+)") -and 
        (-not $gitHubEvent.psobject.properties['inputs'])) {
        "::warning::Pull Request has not merged, skipping Tagging" | Out-Host
        return
    }    
}

# Find the existing tags
$existingTags = & $gitApp tag --list
if (-not $existingTags) {
    # warn if none exist.
    Write-Warning "No tags found"
}

# Get the target version
$targetVersion = "v$($package.Version)"

# And find out if it already exists
$versionTagExists = $existingTags -contains $targetVersion 

# If it does
if ($versionTagExists) { 
    # warn them
    "::warning::Version $($versionTagExists)"
    return 
}

# If we have an ACTOR and GITHUB_ACTOR_ID
if ($env:GITHUB_ACTOR -AND $env:GITHUB_ACTOR_ID) {
    # config git
    & $gitApp config --global user.email "$env:GITHUB_ACTOR_ID+$env:GITHUB_ACTOR@users.noreply.github.com"
    & $gitApp config --global user.name  $env:GITHUB_ACTOR
}

# Prepare our git tag
$gitTagArgs = @(
    'tag'
    '-a'
    "v$($package.Version)"
    '-m'
    "$($package.Identifier) $($package.Version)"
)

# If -WhatIf was passed,
if ($WhatIfPreference) {
    $gitTagArgs # output the arguments to git.
    return
}

# If there was no github event
if (-not $githubEvent) {
    # prompt before we create tags
    if ($PSCmdlet.ShouldProcess("git tag $gitTagArgs")) {
        git @gitTagArgs        
    }
    # and prompt before we push them.
    if ($PSCmdlet.ShouldProcess("git push origin --tags")) {
        git push origin --tags
    }
} else {
    # If there was a GitHubEvent
    git @gitTagArgs # tag,
    git push origin --tags # push tags,
    $LASTEXITCODE = 0 # and set the last exit code.
}