Creating pull requests from Azure Pipelines
Since there isn't a built-in function for creating a PR from inside a pipeline, let's create it ourselves using az repos pr create.
Here's the template, which is nothing more than a wrapper around the command to support different use cases:
# /internal/shared/steps/create-pull-request.yml
# Create a pull request from the specified source branch to the target branch
# Requires that the System.AccessToken variable is populated with a token for a user with permissions to contribute to the branch
# This is done by using persistCredentials: true in a checkout task
parameters:
# The source branch for the pull request
- name: sourceBranch
type: string
# The target branch for the pull request. Optional - if empty, will use the default branch of the repo
- name: targetBranch
type: string
default: ''
# Whether to auto-complete the pull request.
- name: autoComplete
type: boolean
default: true
# Whether to delete the source branch after the pull request is completed.
- name: deleteSourceBranch
type: boolean
default: true
# Whether to squash the commits in the branch during merge.
- name: squashMerge
type: boolean
default: true
# The description for the pull request. If left empty, the description will be taken from the commit message
- name: pullRequestDescription
type: string
default: ''
# The title of the pull request. If left empty, the title will be taken from the commit message
- name: pullRequestTitle
type: string
default: ''
# If you're creating the PR to another project than the one the pipeline is running in, you need to specify the project name or ID
- name: project
type: string
default: ''
# If you're creating the PR to another repository than the one the pipeline is running in, you need to specify the repository name or ID
- name: repository
type: string
default: ''
# If there is a condition to satisfy before creating the pull request, define it here
- name: condition
type: string
default: ''
steps:
- bash: |
params=(
--auto-complete ${{ parameters.autoComplete }}
--delete-source-branch ${{ parameters.deleteSourceBranch }}
-s refs/heads/${{ parameters.sourceBranch }}
--squash ${{ parameters.squashMerge }}
)
[[ -n "${{ parameters.targetBranch }}" ]] && params+=(-t refs/heads/${{ parameters.targetBranch }})
[[ -n "${{ parameters.pullRequestTitle }}" ]] && params+=(--title "${{ parameters.pullRequestTitle }}")
[[ -n "${{ parameters.pullRequestDescription }}" ]] && params+=(-d "${{ parameters.pullRequestDescription }}")
[[ -n "${{ parameters.project }}" ]] && params+=(-p ${{ parameters.project }})
[[ -n "${{ parameters.repository }}" ]] && params+=(-r ${{ parameters.repository }})
az repos pr create "${params[@]}"
displayName: Create a pull request
env:
AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
${{ if parameters.condition }}:
condition: ${{parameters.condition}}
NOTE: for this to work, the build account needs the following permissions in the repository security settings:
- contribute
- create branches
- contribute to pull requests
The easiest way to find out which user the pipeline is running with is to let this step fail, then copying the user id from the output and giving that account the required permissions.
To use this template, the pipeline needs to first create a branch and push some changes to it. Here's a simple sample:
jobs:
- job:
steps:
- checkout: self
persistCredentials: true # this is important
- bash: |
touch $(Build.Repository.LocalPath)\newfile.md
git config user.email "some@email.com"
git config user.name "Rewiring"
git switch -c newbranch
git commit -a -m "add new file" || echo "##vso[task.setvariable variable=NO_CHANGES]true"
- bash: git push --set-upstream origin newbranch
displayName: publish branch
condition: ne(variables['NO_CHANGES'], 'true')
- template: /internal/shared/steps/create-pull-request.yml
parameters:
sourceBranch: newbranch
pullRequestTitle: 'This is the title'
condition: ne(variables['NO_CHANGES'], 'true')
And that's it - a simple template for creating all sorts of pull requests. Very useful for e.g. automating package updates.
Thoughts, comments? Send me an email!