Deploy after Pull Request merge to target branch
Asked by Dusan Schiffel:

**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.


Answers:
author: Theodora Boudale
body: 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:

* <https://jira.atlassian.com/browse/BCLOUD-13867>

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/bashparent_commit_count=$(git cat-file -p $BITBUCKET_COMMIT | grep -o -i parent | wc -l)echo $parent_commit_countif [ "${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

comments: author: Kerry Johnson
body: 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.


author: Kelly Cliffe
body: [@Theodora Boudale](/t5/user/viewprofilepage/user-id/818086) That issue was created in 2017? And it's status is still a suggestion? Is there any timeline on fixing the workaround(s) above?


author: Theodora Boudale
body: 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:

* <https://confluence.atlassian.com/support/implementation-of-new-features-policy-201294576.html>

Kind regards,  
Theodora


author: Upsmod Inc
body: 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]+)')
```

<br />

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  

<br />

comments: author: Upsmod Inc
body: \*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.


Tags: bitbucket-pipelines

deployment

ssh