Safeguarding Bitbucket’s default branch with branch permissions, merge checks, and Pipelines CI
Learn how to lock down your Bitbucket main branch so only reviewed, green builds can be merged, with a concrete Node.js pipeline example and practical verification steps.
31 Dec 2025, 18:00 UTC

The problem: unchecked pushes to main
When a team allows direct pushes or merge‑without‑checks to the default branch, a single faulty commit can break the build and hide the offending change behind a flood of later work. Debugging regressions becomes a time‑consuming hunt, and the risk of shipping broken code to production rises.
Solution overview: branch permissions + merge checks + Pipelines
Bitbucket lets you lock down a branch with two complementary mechanisms:
- Branch permissions – block direct pushes, set a minimum number of approving reviews, and restrict who can push or merge.
- Merge checks – require that specific Pipelines builds (or other statuses) succeed before the merge button becomes active.
Together they enforce that every change reaching main has been reviewed and has passed the CI pipeline.
Worked example: Node.js project with unit‑test pipeline
Assume a simple Node.js repository that already has npm test defined.
# bitbucket-pipelines.yml
image: node:18
pipelines:
pull-requests:
'**':
- step:
name: Test
script:
- npm ci
- npm test
branches:
main:
- step:
name: Build
script:
- npm ci
- npm run build
This file defines two pipelines:
- Every pull request runs the
Teststep (install dependencies and execute unit tests). - Pushes to
maintrigger aBuildstep that runs the same install followed by a build script.
To make the pipeline a required merge check:
- Go to Repository settings → Branch permissions.
- Add a rule for the branch pattern
main. - Under Permissions disable Allow pushes and set Minimum number of approving reviews to 1 (or more).
- Scroll to Merge checks and enable Successful build. Choose the
mainpipeline defined above (Bitbucket will list it aspipelines.branches.main). - Save the rule.
With the rule in place, the merge button on a pull request stays disabled until:
- At least one reviewer approves.
- The
Testpipeline for that pull request finishes with aSUCCESSresult.
Only then can the change be merged, guaranteeing that main receives only reviewed, green code.
Trade‑offs and limitations
- Latency – each merge waits for the CI pipeline to finish; a slow test suite can add minutes to the merge process.
- Build minutes – every PR and every push to
mainconsumes Pipelines minutes; monitor usage to stay within your plan. - Reviewer availability – if the team is distributed or understaffed, the required approval can become a bottleneck.
- Over‑restriction – a branch pattern that is too broad (e.g.,
*) would also protect release or hotfix branches; test patterns on a throw‑away branch first.
Practical verification: open a test pull request, leave it without approvals or with a failing test, and confirm the merge button remains disabled. Then approve and make the test pass; the button should become active.
Actionable closing
Start small: enable the Test pipeline as a required merge check and require a single approval. Once the team is comfortable with the added latency, layer on additional checks—linting, security scans, or coverage thresholds—adjusting the bitbucket-pipelines.yml and merge‑check settings accordingly. This incremental approach gives you confidence that main stays stable without overwhelming the team.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.