Git - Tag repository

Octopus.Script exported 2023-09-12 by twerthi belongs to ‘Git’ category.

Tags a git repository with the specified tag

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Git Repository URL

Template.Git.Repo.Url =

The URL used for the git clone operation.

Git Username

Template.Git.User.Name =

Username of the credentials to use to log into git.

Git User Password

Template.Git.User.Password =

Password for the git credential.

Tag

Template.Git.Tag =

The tag name to tag the repository with.

Action if tag already exists

Template.Git.Action =

Select the action if the tag already exsists.

Script body

Steps based on this template will execute the following PowerShell script.

Function Invoke-Git
{
	# Define parameters
    param (
    	$GitRepositoryUrl,
        $GitFolder,
        $GitUsername,
        $GitPassword,
        $GitCommand,
        $AdditionalArguments,
        $SupressOutput = $false
    )
    
    # Get current work folder
    $workDirectory = Get-Location
    
    # Create arguments array
    $gitArguments = @()
    $gitArguments += $GitCommand
    
    # Check for url
    if (![string]::IsNullOrWhitespace($GitRepositoryUrl))
    {
      # Convert url to URI object
      $gitUri = [System.Uri]$GitRepositoryUrl
      $gitUrl = "{0}://{1}:{2}@{3}:{4}{5}" -f $gitUri.Scheme, $GitUsername, $GitPassword, $gitUri.Host, $gitUri.Port, $gitUri.PathAndQuery
      $gitArguments += $gitUrl

      # Get the newly created folder name
      $gitFolderName = $GitRepositoryUrl.SubString($GitRepositoryUrl.LastIndexOf("/") + 1)
      if ($gitFolderName.Contains(".git"))
      {
          $gitFolderName = $gitFolderName.SubString(0, $gitFolderName.IndexOf("."))
      }
    }
   
    
    # Check for additional arguments
    if ($null -ne $AdditionalArguments)
    {
 		# Add the additional arguments
        $gitArguments += $AdditionalArguments
    }
    
    # Execute git command
    $results = Execute-Command "git" $gitArguments $GitFolder
    
    # Check to see if output is supposed to be suppressed
    if ($SupressOutput -ne $true)
    {
    	Write-Host $results.stdout
    }

	# Always display error messages
    Write-Host $results.stderr
    
    # Store results into file
    Add-Content -Path "$PWD/$($GitCommand).txt" -Value $results.stdout
    
    # Return the foldername
   	return $gitFolderName
}

# Check to see if $IsWindows is available
if ($null -eq $IsWindows) {
    Write-Host "Determining Operating System..."
    $IsWindows = ([System.Environment]::OSVersion.Platform -eq "Win32NT")
    $IsLinux = ([System.Environment]::OSVersion.Platform -eq "Unix")
}

Function Execute-Command
{
	param (
    	$commandPath,
        $commandArguments,
        $workingDir
    )

	$gitExitCode = 0
    $executionResults = $null

  Try {
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $commandPath
    $pinfo.WorkingDirectory = $workingDir
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $commandArguments
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $executionResults = [pscustomobject]@{
        stdout = $p.StandardOutput.ReadToEnd()
        stderr = $p.StandardError.ReadToEnd()
        ExitCode = $null
    }
    $p.WaitForExit()
    $gitExitCode = [int]$p.ExitCode
    $executionResults.ExitCode = $gitExitCode
    
    if ($gitExitCode -ge 2) 
    {
		# Fail the step
        throw
    }
    
    return $executionResults
  }
  Catch {
    # Check exit code
    Write-Error -Message "$($executionResults.stderr)" -ErrorId $gitExitCode
    exit $gitExitCode
  }

}


# Get variables
$gitUrl = $OctopusParameters['Template.Git.Repo.Url']
$gitUser = $OctopusParameters['Template.Git.User.Name']
$gitPassword = $OctopusParameters['Template.Git.User.Password']
$gitTag = $OctopusParameters['Template.Git.Tag']
$gitAction = $OctopusParameters['Template.Git.Action']

# Clone repository
$folderName = Invoke-Git -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword -GitCommand "clone"

# Set user
$gitAuthorName = $OctopusParameters['Octopus.Deployment.CreatedBy.DisplayName']
$gitAuthorEmail = $OctopusParameters['Octopus.Deployment.CreatedBy.EmailAddress']

# Check to see if user is system
if ([string]::IsNullOrWhitespace($gitAuthorEmail) -and $gitAuthorName -eq "System")
{
	# Initiated by the Octopus server via automated process, put something in for the email address
    $gitAuthorEmail = "system@octopus.local"
}

# Configure user information
Invoke-Git -GitCommand "config" -AdditionalArguments @("user.name", $gitAuthorName) -GitFolder "$($PWD)/$($folderName)"
Invoke-Git -GitCommand "config" -AdditionalArguments @("user.email", $gitAuthorEmail) -GitFolder "$($PWD)/$($folderName)"

# Record existing tags, if any
Invoke-Git -GitCommand "tag" -GitFolder "$($PWD)/$($folderName)" -SupressOutput $true

# Check the file
$existingTags = Get-Content "$PWD/tag.txt"

if (![String]::IsNullOrWhitespace($existingTags))
{
	# Parse
    $existingTags = $existingTags.Split("`n",[System.StringSplitOptions]::RemoveEmptyEntries)
    
    # Check to see if tag already exists
    if ($null -ne ($existingTags | Where-Object {$_ -eq $gitTag}))
    {
		# Check the selected action
        switch ($gitAction)
        {
        	"delete"
            {
                # Delete the tag locally
                Write-Host "Deleting tag $gitTag from cloned repository ..."
                Invoke-Git -GitCommand "tag" -AdditionalArguments @("--delete", "$gitTag") -GitFolder "$($PWD)/$($folderName)"
                
                # Delete the tag on remote
                Write-Host "Deleting tag from remote repository ..."
                Invoke-Git -GitCommand "push" -AdditionalArguments @(":refs/tags/$gitTag") -GitFolder "$($PWD)/$($folderName)" -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword
                
                break
            }
            "ignore"
            {
            	# Ignore and continue
                Write-Host "$gitTag already exists on $gitUrl.  Selected action is Ignore, exiting."
                
                exit 0
            }
            "fail"
            {
				# Error, tag already exists
        		Write-Error "Error: $gitTag already exists on $gitUrl!"
            }
        }
    }
}

# Tag the repo
Invoke-Git -GitCommand "tag" -AdditionalArguments @("-a", $gitTag, "-m", "`"Tag from #{Octopus.Project.Name} release version #{Octopus.Release.Number}`"") -GitFolder "$($PWD)/$($folderName)"

# Push the new tag
Invoke-Git -Gitcommand "push" -AdditionalArguments @("--tags") -GitFolder "$($PWD)/$($folderName)"

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "dd76dee1-f5b1-4974-a5ae-bde643cf67af",
  "Name": "Git - Tag repository",
  "Description": "Tags a git repository with the specified tag",
  "Version": 2,
  "ExportedAt": "2023-09-12T15:33:15.238Z",
  "ActionType": "Octopus.Script",
  "Author": "twerthi",
  "Packages": [],
  "Parameters": [
    {
      "Id": "674d5325-aa93-4779-a734-cee8e5690f17",
      "Name": "Template.Git.Repo.Url",
      "Label": "Git Repository URL",
      "HelpText": "The URL used for the `git clone` operation.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "f2d07c9c-85fc-485e-8057-5577efd9a26d",
      "Name": "Template.Git.User.Name",
      "Label": "Git Username",
      "HelpText": "Username of the credentials to use to log into git.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "597ae9a5-1ef4-4062-a435-2d9bb1fb16a2",
      "Name": "Template.Git.User.Password",
      "Label": "Git User Password",
      "HelpText": "Password for the git credential.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "7cfa6ba5-76c6-4b15-a30c-593e2cd8f914",
      "Name": "Template.Git.Tag",
      "Label": "Tag",
      "HelpText": "The tag name to tag the repository with.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "b7ae407f-f926-4478-af72-74397025e4b6",
      "Name": "Template.Git.Action",
      "Label": "Action if tag already exists",
      "HelpText": "Select the action if the tag already exsists.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "delete|Delete and recreate\nfail|Fail\nignore|Ignore"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "Function Invoke-Git\n{\n\t# Define parameters\n    param (\n    \t$GitRepositoryUrl,\n        $GitFolder,\n        $GitUsername,\n        $GitPassword,\n        $GitCommand,\n        $AdditionalArguments,\n        $SupressOutput = $false\n    )\n    \n    # Get current work folder\n    $workDirectory = Get-Location\n    \n    # Create arguments array\n    $gitArguments = @()\n    $gitArguments += $GitCommand\n    \n    # Check for url\n    if (![string]::IsNullOrWhitespace($GitRepositoryUrl))\n    {\n      # Convert url to URI object\n      $gitUri = [System.Uri]$GitRepositoryUrl\n      $gitUrl = \"{0}://{1}:{2}@{3}:{4}{5}\" -f $gitUri.Scheme, $GitUsername, $GitPassword, $gitUri.Host, $gitUri.Port, $gitUri.PathAndQuery\n      $gitArguments += $gitUrl\n\n      # Get the newly created folder name\n      $gitFolderName = $GitRepositoryUrl.SubString($GitRepositoryUrl.LastIndexOf(\"/\") + 1)\n      if ($gitFolderName.Contains(\".git\"))\n      {\n          $gitFolderName = $gitFolderName.SubString(0, $gitFolderName.IndexOf(\".\"))\n      }\n    }\n   \n    \n    # Check for additional arguments\n    if ($null -ne $AdditionalArguments)\n    {\n \t\t# Add the additional arguments\n        $gitArguments += $AdditionalArguments\n    }\n    \n    # Execute git command\n    $results = Execute-Command \"git\" $gitArguments $GitFolder\n    \n    # Check to see if output is supposed to be suppressed\n    if ($SupressOutput -ne $true)\n    {\n    \tWrite-Host $results.stdout\n    }\n\n\t# Always display error messages\n    Write-Host $results.stderr\n    \n    # Store results into file\n    Add-Content -Path \"$PWD/$($GitCommand).txt\" -Value $results.stdout\n    \n    # Return the foldername\n   \treturn $gitFolderName\n}\n\n# Check to see if $IsWindows is available\nif ($null -eq $IsWindows) {\n    Write-Host \"Determining Operating System...\"\n    $IsWindows = ([System.Environment]::OSVersion.Platform -eq \"Win32NT\")\n    $IsLinux = ([System.Environment]::OSVersion.Platform -eq \"Unix\")\n}\n\nFunction Execute-Command\n{\n\tparam (\n    \t$commandPath,\n        $commandArguments,\n        $workingDir\n    )\n\n\t$gitExitCode = 0\n    $executionResults = $null\n\n  Try {\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\n    $pinfo.FileName = $commandPath\n    $pinfo.WorkingDirectory = $workingDir\n    $pinfo.RedirectStandardError = $true\n    $pinfo.RedirectStandardOutput = $true\n    $pinfo.UseShellExecute = $false\n    $pinfo.Arguments = $commandArguments\n    $p = New-Object System.Diagnostics.Process\n    $p.StartInfo = $pinfo\n    $p.Start() | Out-Null\n    $executionResults = [pscustomobject]@{\n        stdout = $p.StandardOutput.ReadToEnd()\n        stderr = $p.StandardError.ReadToEnd()\n        ExitCode = $null\n    }\n    $p.WaitForExit()\n    $gitExitCode = [int]$p.ExitCode\n    $executionResults.ExitCode = $gitExitCode\n    \n    if ($gitExitCode -ge 2) \n    {\n\t\t# Fail the step\n        throw\n    }\n    \n    return $executionResults\n  }\n  Catch {\n    # Check exit code\n    Write-Error -Message \"$($executionResults.stderr)\" -ErrorId $gitExitCode\n    exit $gitExitCode\n  }\n\n}\n\n\n# Get variables\n$gitUrl = $OctopusParameters['Template.Git.Repo.Url']\n$gitUser = $OctopusParameters['Template.Git.User.Name']\n$gitPassword = $OctopusParameters['Template.Git.User.Password']\n$gitTag = $OctopusParameters['Template.Git.Tag']\n$gitAction = $OctopusParameters['Template.Git.Action']\n\n# Clone repository\n$folderName = Invoke-Git -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword -GitCommand \"clone\"\n\n# Set user\n$gitAuthorName = $OctopusParameters['Octopus.Deployment.CreatedBy.DisplayName']\n$gitAuthorEmail = $OctopusParameters['Octopus.Deployment.CreatedBy.EmailAddress']\n\n# Check to see if user is system\nif ([string]::IsNullOrWhitespace($gitAuthorEmail) -and $gitAuthorName -eq \"System\")\n{\n\t# Initiated by the Octopus server via automated process, put something in for the email address\n    $gitAuthorEmail = \"system@octopus.local\"\n}\n\n# Configure user information\nInvoke-Git -GitCommand \"config\" -AdditionalArguments @(\"user.name\", $gitAuthorName) -GitFolder \"$($PWD)/$($folderName)\"\nInvoke-Git -GitCommand \"config\" -AdditionalArguments @(\"user.email\", $gitAuthorEmail) -GitFolder \"$($PWD)/$($folderName)\"\n\n# Record existing tags, if any\nInvoke-Git -GitCommand \"tag\" -GitFolder \"$($PWD)/$($folderName)\" -SupressOutput $true\n\n# Check the file\n$existingTags = Get-Content \"$PWD/tag.txt\"\n\nif (![String]::IsNullOrWhitespace($existingTags))\n{\n\t# Parse\n    $existingTags = $existingTags.Split(\"`n\",[System.StringSplitOptions]::RemoveEmptyEntries)\n    \n    # Check to see if tag already exists\n    if ($null -ne ($existingTags | Where-Object {$_ -eq $gitTag}))\n    {\n\t\t# Check the selected action\n        switch ($gitAction)\n        {\n        \t\"delete\"\n            {\n                # Delete the tag locally\n                Write-Host \"Deleting tag $gitTag from cloned repository ...\"\n                Invoke-Git -GitCommand \"tag\" -AdditionalArguments @(\"--delete\", \"$gitTag\") -GitFolder \"$($PWD)/$($folderName)\"\n                \n                # Delete the tag on remote\n                Write-Host \"Deleting tag from remote repository ...\"\n                Invoke-Git -GitCommand \"push\" -AdditionalArguments @(\":refs/tags/$gitTag\") -GitFolder \"$($PWD)/$($folderName)\" -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword\n                \n                break\n            }\n            \"ignore\"\n            {\n            \t# Ignore and continue\n                Write-Host \"$gitTag already exists on $gitUrl.  Selected action is Ignore, exiting.\"\n                \n                exit 0\n            }\n            \"fail\"\n            {\n\t\t\t\t# Error, tag already exists\n        \t\tWrite-Error \"Error: $gitTag already exists on $gitUrl!\"\n            }\n        }\n    }\n}\n\n# Tag the repo\nInvoke-Git -GitCommand \"tag\" -AdditionalArguments @(\"-a\", $gitTag, \"-m\", \"`\"Tag from #{Octopus.Project.Name} release version #{Octopus.Release.Number}`\"\") -GitFolder \"$($PWD)/$($folderName)\"\n\n# Push the new tag\nInvoke-Git -Gitcommand \"push\" -AdditionalArguments @(\"--tags\") -GitFolder \"$($PWD)/$($folderName)\""
  },
  "Category": "Git",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/git-tag-repository.json",
  "Website": "/step-templates/dd76dee1-f5b1-4974-a5ae-bde643cf67af",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////9CQ09TJB/dbZ9k1a/vHy+ZGZ/MjM+HaA92l0+62z91tn/uTm+YSN9T9N/Lq/+p+mxWmzxwAAA/5JREFUeNrs3dlyqzAMBmAWs0Po+z9t007OaUJskCXZljL6r3pDqi94w6bTqrJYLBaLxWKxWCwWi8VisVgYsw736GfMrv7NpNvSPhi/lE6xo6mf4rrPcOiVHB1aJe8OnRKfQ6PE79AnCTm0ScIOXZIzhybJuUOP5MqhRXLt0CGBODRIYA4Fkltdf4YEekdMYhKTmKRw7S+bJHol98rdJ0h+6/4AyaNq9ZL/NSuXPFWsWvJSr2LJoVq1krdalUo8laqUeOs8SG5T3/dLI1oS+L5fSvr3877IlQTbjb+kvREqOWn//pJWJ1Jy2o/9JXU3gZKL8chfUiuvn7S4Br9JkwDmh9HbTYSNwpB5bvZeOYmSgObr1Xvpl6Q5HuRo/NcOglYrsPXT4r94lbPuAq4DA5BOzAoSup4lNK0sEvi63F/KLGRVD3cEht9RxvNJhCPQSWQ8acU46noQK4lz1E7qDnekI7DaKi+JdgiVIBzBFzJLSlCO+7TYC5MgHff8fYQECd7xB+nH8hKC4wlSF5dQHM+Q0hKS4wVSVkJzvEJKSoiOA6SchOo4QkpJyI43SBkJ3fEOOUjcNg/D3rukEgaHBxLYgxzTSTgcPkhgVTykOj9hcXghAUmX5vyEx+GHhCRJ7omrE0JCrevyASfeMddJIQHJ5Wb9UOqGBCH1nueWrHVqiL+538CfB8yQGhLY5B6521ZySGCHpVcH8e9KVPunQGb2YSs1ZEI2rTUWMiWG3HC/1lWlhq3gd92iFilz/NQ+JYaMmC7iEGutzqWF+Fr71Vs3TVsVk4QhS/SrKjgHk+RkPBojGxbWwSM5G1jHTA4WyekMsTz1k25K5+CQXEx142OmbrcmpYNBcj1nL/dcPlZTHXQJfPGR1kGWsEA4HFQJB4THQZQwQLgcNAkdwucgScgQTgdFQoXwOggSIoTbgZfQIPwOpGRcn450ZDgwkmaPedrI5YiXvNUxy3BES4bYJ8BcjkjJRtvjT+mIkjQdaZMprSNGsuGODTI5IiT+TdpNigMuoWxg5nBAJaG3fuU4gJIFv8ufywGT4O9IPgdMgu0jOR0gSYs7yMnrgEg21PF9bgdAgprZ8zsAkj7+hpRwACRtbA8p47iWxD6PlHJES76kOiD95K/Hr4tcB2TsGvcfyzpPtWQH29lvcQeXpLyDRyLBwSGR4aBLpDioEjkOmkSSgyKR5cBLpDmwEnkOnESiA3V+ItLBcH6iVCLXESeR7IiRyHbAJdIdUIl8B0yiwQGR6HAg9ruUSvQ4ziWaHGcSXY6wRJsjJNHn8Es0OnwSnY53iVbHUaLX8fo3IU6x457hQXFzpT4//yB4rSwWi8VisVgsFovFYrFYLBbGfAswAOAaON62iVbvAAAAAElFTkSuQmCC",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, September 12, 2023