This tutorial describes how to create a custom merge check app that can block a pull request merge when the title contains the word 'DRAFT'. You can view the complete app code in the Bitbucket pull request title validator repository.
This tutorial assumes you're already familiar with the basics of Forge development. If this is your first time using Forge, see Getting started first.
For Bitbucket apps you need to join or create a shared Bitbucket team workspace (as Forge apps are not supported on personal workspaces). If you don't have a Bitbucket workspace, see the references below for related instructions:
A free Bitbucket team space can have up to 5 users.
Create an app based on the Bitbucket merge check template.
Navigate to the directory where you want to create the app. A new directory with the app's name will be created there.
Create your app by running:
1 2forge create
Enter a name for the app. For example, pr-title-validator.
Select the Triggers and Validators category.
Select the Bitbucket product.
Select the bitbucket-merge-check template.
Change to the app subdirectory to see the app files
1 2cd pr-title-validator
In the app's top-level directory, open the manifest.yml
file.
Ensure the app has the read:pullrequest:bitbucket
permission. This scope is required for the bitbucket:mergeCheck
module.
Additionally, the app will call the Get a pull request API for which the read:pullrequest:bitbucket
permission is required.
1 2permissions: scopes: - read:pullrequest:bitbucket
Change the key
under bitbucket:mergeCheck
to check-pr-title.
Change the name
under bitbucket:mergeCheck
to Check pull request title.
Change the description
under bitbucket:mergeCheck
to Check pull request title does not contain 'DRAFT'.
Update the triggers
under bitbucket:MergeCheck
, replacing the on-code-pushed
trigger with on-merge
.
The check should be invoked when a user attempts to merge the pull request.
Your manifest.yml
should look like the following:
1 2permissions: scopes: - read:pullrequest:bitbucket modules: bitbucket:mergeCheck: - key: check-pr-title function: main name: Check pull request title description: Check pull request title does not contain 'DRAFT' triggers: - on-merge function: - key: main handler: index.run app: runtime: name: nodejs22.x id: '<your-app-id>'
See Manifest to learn more about the manifest file.
Your manifest.yml
defines that when an on-merge
event occurs, the main
entry under function
is invoked for the merge check.
The main
function references the run
function in your src/index.js
file. Update the run
function to implement the merge check.
In the app's top-level directory, install the @forge/api
package API by running the following command:
1 2npm install @forge/api
Open the src/index.js
file.
Import the @forge/api
package by adding the following to the top of the file:
1 2import api, { route } from "@forge/api";
In the run
function, before you return the check result, make a request to Get a pull request API.
Note, await
expressions are only allowed within async functions, so you will need to change the function definition of run
to be async.
1 2const workspaceUuid = event.workspace.uuid; const repoUuid = event.repository.uuid; const prId = event.pullrequest.id; const res = await api .asApp() .requestBitbucket( route`/2.0/repositories/${workspaceUuid}/${repoUuid}/pullrequests/${prId}` ); const pr = await res.json();
Copy the following code to check whether the pull request title contains the word 'DRAFT'.
1 2const success = !pr.title.includes("DRAFT"); const message = success ? "Pull request title does not contain 'DRAFT'" : "Pull request title contains 'DRAFT'";
Then, construct and return a check result object containing the outcome of the title checking logic, accompanied by a message. This check result object should be consistent with the response payload for a custom merge check.
1 2return { success, message };
Your src/index.js
file should look something like this:
1 2import api, { route } from "@forge/api"; export const run = async (event, context) => { const workspaceUuid = event.workspace.uuid; const repoUuid = event.repository.uuid; const prId = event.pullrequest.id; const res = await api .asApp() .requestBitbucket( route`/2.0/repositories/${workspaceUuid}/${repoUuid}/pullrequests/${prId}` ); const pr = await res.json(); const success = !pr.title.includes("DRAFT"); const message = success ? "Pull request title does not contain 'DRAFT'" : "Pull request title contains 'DRAFT'"; return { success, message }; };
Navigate to the app's top-level directory and deploy your app by running:
1 2forge deploy
Install your app by running:
1 2forge install
Select Bitbucket using the arrow keys and press the enter key.
Enter the URL for your workspace. For example, https://bitbucket.org/example-workspace/.
Forge apps are not supported on personal workspaces. If you install an app to a personal workspace, you will get an insufficient permissions error. See set up a shared team workspace.
Enable the custom merge check feature in Workspace settings → Workflow → Custom merge checks
Navigate to the repository within the workspace you want to enable the merge check for.
Navigate to the Repository settings → Workflow → Custom merge checks page.
Find your app in the list of merge check apps, and click the Add Check button.
Select the Check pull request title check from the Name dropdown.
Select the Branch you wish the check to be run against (for the sake of this tutorial, select All branches
).
If you're on a premium plan, tick the Required checkbox
Create a pull request in your repository with the word ‘DRAFT' in the title and attempt to merge the pull request. The merge check should fail. If you configured the check as
Required: The merge will fail and the check failure will be visible on the merge checks card on the right side bar.
Not required: The merge will succeed, but the check failure will be visible on the merge checks card on the right side bar.
Create another pull request in your repository without the word ‘DRAFT' and merge the pull request. This time the merge check should pass.
See Set up custom merge checks for more details.
Congratulations, you've built your first custom merge check. In this tutorial you covered:
In the next tutorial, you'll learn how to make your custom merge check configurable with UI Kit and Forge storage.
Rate this page: