How to Execute pre-receive hook after upgrading Bitbucket Server from 7.x to 8.x version

Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.

Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Except Fisheye and Crucible

Summary

Starting Bitbucket 8.0, legacy hook scripts are deprecated, i.e. customer hook scripts stored in the hooks/pre-receive.d or hooks/post-receive.d directories inside the git repositories on the Bitbucket instance. This KB drafts the steps to configure and execute pre-receive hooks in Bitbucket 8.x.

Environment

Bitbucket Server 8.6.1

Is applicable to Bitbucket Server/Datacenter 8.x

Solution

The following steps will help to execute pre-receive hooks after upgrading Bitbucket Server from the 7.x version to the 8.x version:

There are two steps involved in this process:

  1. Upload the script(s)

  2. Enable the script(s) for the relevant repositories.

Note: The recommended way is to create a Plugin Using our Java plugin development framework instead of hook scripts.

Step-by-step guide:

The following steps need to be performed for each pre-receive hook script that needs to be migrated.

1. Locate the script. In the following example, a dummy script is included as a reference and saved in a file {{rejectAll.sh}}

1 2 echo "You didn't say the magic word" exit 1

2. Upload the script to Bitbucket using the below REST API call.

Note: You need SYS_ADMIN account to perform this step.

1 2 3 4 5 6 7 8 9 10 11 curl -F "content=@rejectAll.sh" -F "name=rejectAll" -F "description=Reject all" -F "type=PRE" -H 'X-Atlassian-Token:no-check'  -u <admin_user> '<Bitbucket_BASE_URL>/rest/api/latest/hook-scripts' Here Replace below parameters with the actual values. Capture the response and retrieve the ID needed for the next step. <Bitbucket_BASE_URL> - Bitbucket Base URL <admin_user> - Bitbucket system admin user description -> Description for the script (any details). name -> To name the script which you want to see in the database). The sample response or output from the above request looks like following {"id":1,"name":"rejectAll","pluginKey":"com.atlassian.bitbucket.server.bitbucket-hook-scripts","size":49,"type":"PRE","createdDate":1666746268255,"updatedDate":1666746268255,"version":0,"description":"Reject all"} {code}

3. Enable script for Repository using the REST API below where *1* is representing the ID -> received from step 2 for the script.

Follow the REST API document for reference.

1 2 3 4 5 6 7 curl -v -X PUT --header 'Content-Type: application/json' --data '{ "triggerIds": [ ] }' -u <admin_user> '<Bitbucket_URL>/rest/api/latest/projects/<Project_Key>/repos/<repository_slug>/hook-scripts/1' Here Replace <Project_Key>, <repository_slug>, script ID (from the previous step), and <admin_user> with the actual values. Sample response or output about REST API looks like following {"triggerIds":[],"scope":{"type":"REPOSITORY","resourceId":1},"script":{"id":1,"name":"rejectAll","pluginKey":"com.atlassian.bitbucket.server.bitbucket-hook-scripts","size":49,"type":"PRE","createdDate":1666746268255,"updatedDate":1666746268255,"version":0,"description":"Reject all"} {code}

ℹ️ Please note that triggerIDs field in the API call is to specify the action that trigger the hook. For example, BRANCH_CREATE, REPO_PUSH, TAG_CREATE etc., Please refer to this document for supported triggers.

4. Once done, Test pre-receive hook by pushing the changes in the GIT repository

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 {code:java} nshar@F243Y9XG49 test % cat >> first.txt  added script and doing checks now nshar@F243Y9XG49 test % git add . nshar2@F243Y9XG49 test %  nshar2@F243Y9XG49 test % git commit -m "added script, now checking push for pre-receive hook test" [master d889786] added script, now checking push for pre-receive hook test  1 file changed, 1 insertion(+) nshar@F243Y9XG49 test %  nshar@F243Y9XG49 test %  nshar@F243Y9XG49 test % git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 10 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 346 bytes | 346.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 remote: rejectAll declined remote: You didn't say the magic word To https://linux-hostname/bitbucket/scm/test/test.git  ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'https://linux-hostname/bitbucket/scm/test/test.git' nshar@F243Y9XG49 test %  {code}

5. The script should be available with the script IDs in <Bitbucket-Home>/shared/config/hooks-scripts on Bitbucket Server.

6. Similar way, this hook-script can be applied at Project level as well (instead of each repository). To do the same, instead of using Repository specific REST API, need to use Project level REST API.

1 2 3 curl -v -X PUT --header 'Content-Type: application/json' --data '{ "triggerIds": [ ] }' -u <admin_user> '<Bitbucket_BASE_URL>/rest/api/latest/projects/<Project_Key>/hook-scripts/1' Here Replace <Bitbucket_BASE_URL>, <Project_Key>, script ID (from the previous step - currently it is 1 in command), and <admin_user> with the actual values.

ℹ️ Please note that triggerIDs field in the API call is to specify the action that trigger the hook. For example, BRANCH_CREATE, REPO_PUSH, TAG_CREATE etc., Please refer to this document for supported triggers.

Please note: The difference between Normal Pre-receive hook (hooks present in Bitbucket UI) and hook-script which we are trying to use in 8.x is that - In general if we enable Pre-receive hook in Bitbucket UI, the behaviour is that pre-receive hook will get inherited from Project to its relevant repositories. But if user don't want pre-receive hook to be present on any specific repository of same project where hook was enabled, we do have an option to disable this pre-receive hook on any relevant repository in UI.

But while using hook-scripts if we enable it at Project level, this also gets inherited to repositories but we can not disable hook script at Repository level. It may show the curl command successful to delete the hook-script on repository but will not remove it from any repository of the project where hook-script is deployed or associated..

Updated on April 8, 2025

Still need help?

The Atlassian Community is here for you.