Git - Create Pull Request

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

Create a Pull or Merge Request for the repository

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.

Source Branch

Template.Git.Source.Branch =

The source branch name to compare the repository with.

Destination Branch

Template.Git.Destination.Branch =

The destination branch to create the pull/merge request against.

Source Control Technology

Template.Git.Repository.Technology =

Select which source control technology to create the request on.

Script body

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

# 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")
}

# Fix ANSI Color on PWSH Core issues when displaying objects
if ($PSEdition -eq "Core") {
    $PSStyle.OutputRendering = "PlainText"
}

# Get variables
$gitUrl = $OctopusParameters['Template.Git.Repo.Url']
$gitUser = $OctopusParameters['Template.Git.User.Name']
$gitPassword = $OctopusParameters['Template.Git.User.Password']
$gitSourceBranch = $OctopusParameters['Template.Git.Source.Branch']
$gitDestinationBranch = $OctopusParameters['Template.Git.Destination.Branch']
$gitTech = $OctopusParameters['Template.Git.Repository.Technology']

# Convert url into uri object
$gitUri = [System.Uri]$gitUrl

switch ($gitTech)
{
    "ado"
    {

		# Parse url
        $gitOrganization = $gitUri.AbsolutePath
        $gitOrganization = $gitOrganization.Substring(1)
		$gitOrganization = $gitOrganization.Substring(0, $gitOrganization.IndexOf("/"))
        
        # Encode personal access token
        $encodedPAT = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$gitPassword"))
        
        # Construct Headers
        $header = @{
        	Authorization = "Basic $encodedPAT"
        }
                
        $gitProject = $gitUri.AbsolutePath.Replace($gitOrganization, "").Replace("//", "")
        $gitProject = $gitProject.Substring(0, $gitProject.IndexOf("/"))
        
		# Create pull request
        $jsonBody = @{
        	sourceRefName = "refs/heads/" + $gitSourceBranch
            targetRefName = "refs/heads/" + $gitDestinationBranch
            title = "PR from Octopus Deploy"
            description = "PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}"
        }
        
        # Construct API call
        $adoApiUrl = "{0}://{1}:{2}/{3}/{4}/_apis/git/repositories/{4}/pullrequests" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitOrganization, $gitProject
        Invoke-RestMethod -Method Post -Uri ($adoApiUrl + "?api-version=7.0") -Body ($jsonBody | ConvertTo-Json -Depth 10) -Headers $header -ContentType "application/json"
    }
    "bitbucket"
    {
		# Parse url
        $gitOrganization = $gitUri.AbsolutePath
        $gitOrganization = $gitOrganization.Substring(1)
		$gitOrganization = $gitOrganization.Substring(0, $gitOrganization.IndexOf("/"))
        $gitProject = $gitUri.AbsolutePath.Replace($gitOrganization, "").Replace("//", "")
        
        # Check to see if Repo Name ends with .git
        if ($gitProject.EndsWith(".git"))
        {
        	# Strip off the last part
            $gitProject = $gitProject.Replace(".git", "")
        }

        # Construct Headers
        $header = @{
        	Authorization = "Bearer $gitPassword"
        }
        
        # Construct API url
        $bitbucketApiUrl = "{0}://api.{1}:{2}/2.0/repositories/{3}/{4}/pullrequests" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitOrganization, $gitProject
        
		# Construct json body
        $jsonBody = @{
        	title = "PR from Octopus Deploy"
            source = @{
            	branch = @{
                	name = $gitSourceBranch
                }
            }
            destination = @{
            	branch = @{
                	name = $gitDestinationBranch
                }
            }
        }
        
        # Create PR
        Invoke-RestMethod -Method Post -Uri $bitbucketApiUrl -Headers $header -Body ($jsonBody | ConvertTo-Json -Depth 10) -ContentType "application/json"
    }
    "github"
    {
        # Parse URL
        $gitRepoOwner = $gitUri.AbsolutePath.Substring(1, $gitUri.AbsolutePath.LastIndexOf("/") - 1)
        $gitRepoName = $gitUri.AbsolutePath.Substring($gitUri.AbsolutePath.LastIndexOf("/") + 1 )
        
        # Check to see if Repo Name ends with .git
        if ($gitRepoName.EndsWith(".git"))
        {
        	# Strip off the last part
            $gitRepoName = $gitRepoName.Replace(".git", "")
        }
        
        # Construct API endpoint
        $githubApiUrl = "{0}://api.{1}:{2}/repos/{3}/{4}/pulls" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitRepoOwner, $gitRepoName
        
        # Construct Headers
        $header = @{
        	Authorization = "Bearer $gitPassword"
            Accept = "application/vnd.github+json"
            "X-Github-Api-Version" = "2022-11-28"
        }
        
        # Construct body
        $jsonBody = @{
        	title = "PR from Octopus Deploy"
            body = "PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}"
            head = $gitSourceBranch
            base = $gitDestinationBranch
        }
        
        # Create the pull request
        Invoke-RestMethod -Method Post -Uri $gitHubApiUrl -Headers $header -Body ($jsonBody | ConvertTo-Json -Depth 10)
    }
    "gitlab"
    {
		# Get project name
        $gitlabProjectName = $gitUrl.SubString($gitUrl.LastIndexOf("/") + 1)
        
        # Parse uri
        $gitlabApiUrl = "{0}://{1}:{2}/api/v4/users/{3}/projects" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitUser
        
        # Check to see if it ends in .git
        if ($gitlabProjectName.EndsWith(".git"))
        {
        	# Strip that part off
            $gitlabProjectName = $gitlabProjectName.Replace(".git", "")
        }
        
        # Create header
        $header = @{ "PRIVATE-TOKEN" = $gitPassword }
        
        # Get the project
        $gitlabProject = (Invoke-RestMethod -Method Get -Uri $gitlabApiUrl -Headers $header) | Where-Object {$_.Name -eq $gitlabProjectName}
        
        # Create the merge request
         $gitlabApiUrl = "{0}://{1}:{2}/api/v4/projects/{3}/merge_requests?source_branch={4}&target_branch={5}&target_project_id={3}&title={6}" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitlabProject.id, $gitSourceBranch, $gitDestinationBranch, "PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}"
        Invoke-RestMethod -Method Post -Uri $gitlabApiUrl -Headers $header
    }
}

<#
# 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)"


# Push the new tag
Invoke-Git -Gitcommand "request-pull" -AdditionalArguments @("$gitSourceBranch", $gitUrl, "$gitDestinationBranch") -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": "a24c6354-5612-4e2c-a0ff-9b5a329fc0e9",
  "Name": "Git - Create Pull Request",
  "Description": "Create a Pull or Merge Request for the repository",
  "Version": 1,
  "ExportedAt": "2023-09-12T15:32:53.416Z",
  "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.Source.Branch",
      "Label": "Source Branch",
      "HelpText": "The source branch name to compare the repository with.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "2b0ee0d3-8542-4db2-87fc-52ee41e63cc6",
      "Name": "Template.Git.Destination.Branch",
      "Label": "Destination Branch",
      "HelpText": "The destination branch to create the pull/merge request against.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "74d8fc6d-2a4c-49ad-b7f8-248dcf44fc0f",
      "Name": "Template.Git.Repository.Technology",
      "Label": "Source Control Technology",
      "HelpText": "Select which source control technology to create the request on.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "ado|Azure DevOps\nbitbucket|BitBucket\ngithub|GitHub\ngitlab|GitLab"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "# 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\n# Fix ANSI Color on PWSH Core issues when displaying objects\nif ($PSEdition -eq \"Core\") {\n    $PSStyle.OutputRendering = \"PlainText\"\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$gitSourceBranch = $OctopusParameters['Template.Git.Source.Branch']\n$gitDestinationBranch = $OctopusParameters['Template.Git.Destination.Branch']\n$gitTech = $OctopusParameters['Template.Git.Repository.Technology']\n\n# Convert url into uri object\n$gitUri = [System.Uri]$gitUrl\n\nswitch ($gitTech)\n{\n    \"ado\"\n    {\n\n\t\t# Parse url\n        $gitOrganization = $gitUri.AbsolutePath\n        $gitOrganization = $gitOrganization.Substring(1)\n\t\t$gitOrganization = $gitOrganization.Substring(0, $gitOrganization.IndexOf(\"/\"))\n        \n        # Encode personal access token\n        $encodedPAT = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(\"`:$gitPassword\"))\n        \n        # Construct Headers\n        $header = @{\n        \tAuthorization = \"Basic $encodedPAT\"\n        }\n                \n        $gitProject = $gitUri.AbsolutePath.Replace($gitOrganization, \"\").Replace(\"//\", \"\")\n        $gitProject = $gitProject.Substring(0, $gitProject.IndexOf(\"/\"))\n        \n\t\t# Create pull request\n        $jsonBody = @{\n        \tsourceRefName = \"refs/heads/\" + $gitSourceBranch\n            targetRefName = \"refs/heads/\" + $gitDestinationBranch\n            title = \"PR from Octopus Deploy\"\n            description = \"PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}\"\n        }\n        \n        # Construct API call\n        $adoApiUrl = \"{0}://{1}:{2}/{3}/{4}/_apis/git/repositories/{4}/pullrequests\" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitOrganization, $gitProject\n        Invoke-RestMethod -Method Post -Uri ($adoApiUrl + \"?api-version=7.0\") -Body ($jsonBody | ConvertTo-Json -Depth 10) -Headers $header -ContentType \"application/json\"\n    }\n    \"bitbucket\"\n    {\n\t\t# Parse url\n        $gitOrganization = $gitUri.AbsolutePath\n        $gitOrganization = $gitOrganization.Substring(1)\n\t\t$gitOrganization = $gitOrganization.Substring(0, $gitOrganization.IndexOf(\"/\"))\n        $gitProject = $gitUri.AbsolutePath.Replace($gitOrganization, \"\").Replace(\"//\", \"\")\n        \n        # Check to see if Repo Name ends with .git\n        if ($gitProject.EndsWith(\".git\"))\n        {\n        \t# Strip off the last part\n            $gitProject = $gitProject.Replace(\".git\", \"\")\n        }\n\n        # Construct Headers\n        $header = @{\n        \tAuthorization = \"Bearer $gitPassword\"\n        }\n        \n        # Construct API url\n        $bitbucketApiUrl = \"{0}://api.{1}:{2}/2.0/repositories/{3}/{4}/pullrequests\" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitOrganization, $gitProject\n        \n\t\t# Construct json body\n        $jsonBody = @{\n        \ttitle = \"PR from Octopus Deploy\"\n            source = @{\n            \tbranch = @{\n                \tname = $gitSourceBranch\n                }\n            }\n            destination = @{\n            \tbranch = @{\n                \tname = $gitDestinationBranch\n                }\n            }\n        }\n        \n        # Create PR\n        Invoke-RestMethod -Method Post -Uri $bitbucketApiUrl -Headers $header -Body ($jsonBody | ConvertTo-Json -Depth 10) -ContentType \"application/json\"\n    }\n    \"github\"\n    {\n        # Parse URL\n        $gitRepoOwner = $gitUri.AbsolutePath.Substring(1, $gitUri.AbsolutePath.LastIndexOf(\"/\") - 1)\n        $gitRepoName = $gitUri.AbsolutePath.Substring($gitUri.AbsolutePath.LastIndexOf(\"/\") + 1 )\n        \n        # Check to see if Repo Name ends with .git\n        if ($gitRepoName.EndsWith(\".git\"))\n        {\n        \t# Strip off the last part\n            $gitRepoName = $gitRepoName.Replace(\".git\", \"\")\n        }\n        \n        # Construct API endpoint\n        $githubApiUrl = \"{0}://api.{1}:{2}/repos/{3}/{4}/pulls\" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitRepoOwner, $gitRepoName\n        \n        # Construct Headers\n        $header = @{\n        \tAuthorization = \"Bearer $gitPassword\"\n            Accept = \"application/vnd.github+json\"\n            \"X-Github-Api-Version\" = \"2022-11-28\"\n        }\n        \n        # Construct body\n        $jsonBody = @{\n        \ttitle = \"PR from Octopus Deploy\"\n            body = \"PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}\"\n            head = $gitSourceBranch\n            base = $gitDestinationBranch\n        }\n        \n        # Create the pull request\n        Invoke-RestMethod -Method Post -Uri $gitHubApiUrl -Headers $header -Body ($jsonBody | ConvertTo-Json -Depth 10)\n    }\n    \"gitlab\"\n    {\n\t\t# Get project name\n        $gitlabProjectName = $gitUrl.SubString($gitUrl.LastIndexOf(\"/\") + 1)\n        \n        # Parse uri\n        $gitlabApiUrl = \"{0}://{1}:{2}/api/v4/users/{3}/projects\" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitUser\n        \n        # Check to see if it ends in .git\n        if ($gitlabProjectName.EndsWith(\".git\"))\n        {\n        \t# Strip that part off\n            $gitlabProjectName = $gitlabProjectName.Replace(\".git\", \"\")\n        }\n        \n        # Create header\n        $header = @{ \"PRIVATE-TOKEN\" = $gitPassword }\n        \n        # Get the project\n        $gitlabProject = (Invoke-RestMethod -Method Get -Uri $gitlabApiUrl -Headers $header) | Where-Object {$_.Name -eq $gitlabProjectName}\n        \n        # Create the merge request\n         $gitlabApiUrl = \"{0}://{1}:{2}/api/v4/projects/{3}/merge_requests?source_branch={4}&target_branch={5}&target_project_id={3}&title={6}\" -f $gitUri.Scheme, $gitUri.Host, $gitUri.Port, $gitlabProject.id, $gitSourceBranch, $gitDestinationBranch, \"PR from #{Octopus.Project.Name} release version #{Octopus.Release.Number}\"\n        Invoke-RestMethod -Method Post -Uri $gitlabApiUrl -Headers $header\n    }\n}\n\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\n# Push the new tag\nInvoke-Git -Gitcommand \"request-pull\" -AdditionalArguments @(\"$gitSourceBranch\", $gitUrl, \"$gitDestinationBranch\") -GitFolder \"$($PWD)/$($folderName)\"    \n#>"
  },
  "Category": "Git",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/git-create-pull-request.json",
  "Website": "/step-templates/a24c6354-5612-4e2c-a0ff-9b5a329fc0e9",
  "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