How to Execute pre-receive hook after upgrading Bitbucket Server from 7.x to 8.x version
Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.
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:
- Upload the script(s)
- 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}}
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.
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.
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
{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.
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..