Deploy after Pull Request merge to target branch

Dusan Schiffel October 14, 2021

First I have to point out that Atlassian has very bad technical support or. none, even for paying customers !!!! Very bad!

I don't think anyone here can help me, but I'll ask anyway.

I can't handle the bitbucket-pipeline.yaml configuration.

I need to deploy to my own VPS over SSH, but only after merging the pull request from into the develop or master branch.

Is it even possible? If not, can anyone advise an alternative solution? Unless If that's not possible, I'm afraid we'll have to move to CircleCI.

2 answers

1 vote
Theodora Boudale
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 19, 2021

Hi Dusan,

I can see that you have created a support ticket for this issue and our engineers have responded there. If you have any further questions, you can let us know in the support ticket and we can assist there.

I just wanted to leave a reply here as well for any other users who may come across your post:

There is no direct way to trigger Pipelines after a PR is merged, based on the destination branch. Pipelines defined for pull-requests run when a PR is created and are based on the source branch. We have a feature request for what you are asking in our issue tracker:

In the meantime, you can look into either of the following options to work around this issue:

1st Option - Use Branch Triggers and a script to check if the commit is a merge commit.

Firstly, you would have to use branch triggers and specify the branch. This can be configured in the "bitbucket-pipelines.yml" file.
As per the config below, the build will only run only when the commit is pushed to the master / develop branch.

Once that condition is met, you can add a step using a script to check if the commit the build is running on is a merge commit or not. A merge commit will always have two parent commits.

This is only on the condition that the commit is merged using the "Merge Commit" strategy. The reason is with Squash Merge, we can't identify if it's a merge commit as it does not have two parent commits. If you are using Squash merge, this option wouldn't be a solution.

The script checks if the commit is a "Merge Commit" by validating that it has two parent commits, then only it will proceed with the next steps, else it will exit the build.

pipelines:
  branches:
    master:
      - step:
          name: Branch Trigger to Master
          script:
            - echo "Checking Merge Commit"
            - chmod +x MergeCommitCheck.sh && ./MergeCommitCheck.sh
            - <deployment commands>
    develop:
      - step:
          name: Branch Trigger to Develop
          script:
            - echo "Checking Merge Commit"
            - chmod +x MergeCommitCheck.sh && ./MergeCommitCheck.sh
            - <deployment commands>

scirpt:

#!/bin/bash

parent_commit_count=$(git cat-file -p $BITBUCKET_COMMIT | grep -o -i parent | wc -l)
echo $parent_commit_count

if [ "${parent_commit_count}" = "2" ]
then
    echo "Commit $BITBUCKET_COMMIT has two parents. Hence this is a merge commit"
    echo "Proceeding with build"
else
    echo "Commit $BITBUCKET_COMMIT is not a merge commit, Exiting Build"
    exit 1 
fi

2nd Option - Implement Branch Permissions that only allows a Merge Via Pull Request.

This approach depends on how your workflow is designed. With this approach, the workflow should be to avoid direct pushes to "master" and "develop".

Here, you can implement branch permissions that allow only "Merge via Pull Request".
You will have to block users from writing directly to the branch.
This way, that each time a commit is written into the "master" OR "develop" branch, it's through a PR Merge. Hence we can be assured that only merge commits are allowed into this branch.

Then you can configure Bitbucket Pipelines to use branch triggers to run your deployment similar to the config above but excluding the need to use a script.

You can read more about Branch Permissions here:

https://support.atlassian.com/bitbucket-cloud/docs/use-branch-permissions/

Kind regards,
Theodora

Kerry Johnson December 14, 2021

Thank you for that.

In my situation I needed to deploy some files to a server after a pull request merges the pull request (source) branch into the target branch (master in my case); the directory on the server is based on the PR's source branch name.  As I understand it pull request pipelines do not currently support that strategy.  Since Bitbucket Pipelines follows a (pull request #n) comment pattern (see below), I was able to naively hook into it at the master pipeline level.

Merged in feature/someone/something (pull request #777)

PR_SOURCE=$(git log -1 --merges origin/master --format="%s" --grep '(pull request #.*)' | sed -e 's/Merged in //g' -e 's/(pull request #.*)//g' | xargs);

The above is what I used to retrieve the branch name of the last pull request.

Kelly Cliffe July 10, 2023

@Theodora Boudale That issue was created in 2017? And it's status is still a suggestion? Is there any timeline on fixing the workaround(s) above?

Theodora Boudale
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
July 11, 2023

Hi,

The feature request is still open, I'm afraid I don't have an ETA to share. Implementation of features is done as per our policy here:

Kind regards,
Theodora

0 votes
Upsmod Inc
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
January 14, 2024

i finded the true solution for that moment

- step:

name: "Find release from source branch name"

clone:

depth: full

script:

- export RELEASE=$(git cat-file -p $BITBUCKET_COMMIT | grep parent | awk '{print "git branch --remotes --contains " $2 }' | sh | grep release | grep --only-matching --extended-regexp '([0-9]+)\.([0-9]+)\.([0-9]+)')


need to add on step 

 

clone:
    depth: true

 then from the merge source branch release/1.0.0

export RELEASE=$(git cat-file -p $BITBUCKET_COMMIT | grep parent | awk '{print "git branch --remotes --contains " $2 }' | sh | grep release | grep --only-matching --extended-regexp '([0-9]+)\.([0-9]+)\.([0-9]+)')

RELEASE will contains 1.0.0


Upsmod Inc
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
January 16, 2024

*UPD* That script has profit only if you are using sample practice of git flow - like and checkouting new feature/SOME-123-migrating from dev. that will be nesting commits inside a tree and parents will have only one branch with dev (if you are merging in dev) 

else if you are checkouting feature/SOME-123-migrating from feature/SOME-122-nesting - parents will have several tags and several commits with origin and local branch 
And when you want to pick up with that script token SOME-123 you will picking up 
"SOME-122 SOME-123" - for evade this - you need to add END to awk script for analyze only last parent of merge commit - 

awk 'END{print "git branch --remotes --contains " $2 }'

AND SO VERY IMPORTANT - you dont need to check checkbox with "Close source branch" because this causes before the pipeline is run - you can't find tag if origin/remote doesnt exists.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events