Series Navigation:
- Automating DevOps with Bitbucket Pipelines: Setting Up Repositories and CICD in BitBucket
- Automating DevOps with Bitbucket Pipelines: Configuring Triggers and Branch Protection Rules (This Article)
Introduction
This article is part of a series on setting up CI/CD in BitBucket. In this article, you’ll learn about pipeline triggers and branch protection rules – two essential concepts for efficient & secure pipelines.
Triggers in a CI/CD pipeline are the actions or conditions that initiate a pipeline run. They ensure pipelines run automatically, saving time and reducing errors. Pushes to a branch, pull request creation, or manually started pipeline runs are examples of triggers.
Branch protection rules are a set of permissions and checks that control the actions that can be performed on key branches and the users who can make those changes.
Pipeline Triggers
Triggers are the start conditions for your pipelines. They are defined in a pipelines
property in the bitbucket-pipelines.yml
file. This property includes the pipeline trigger and steps that should be run when the pipeline is started.
[!tip]
Restricting your pipelines to start certain conditions e.g only when a pull request is created or updated can reduce the number of build minutes used by your team
Pipelines can be triggered by any of the following:
- a commit to any branch — This is the Default start condition.
- a commit to a specific branch — This is the Branches start condition
- when a pull request is made or updated — Known as the Pull Request start condition
- when a git tag is created — The Tags start condition.
- Run when manually started by the user. — The Custom start condition.
Let’s cover examples of start conditions in the next section.
Push to any branch
This is the default start condition that matches pushes to any branch that does not match a pipeline definition in other sections of the bitbucket-pipelines.yml
file.
pipelines: default: - step: name: All pushes script: - echo "Hello, World"
This pipeline runs on every push to the repository unless a branch-specific pipeline is defined.
Push To A Specific Branch
To trigger pipelines for pushes to a specific branch, use the branches
property. Pushes to a branch specified under branches
do not trigger the default pipeline.
pipelines: branches: develop: - step: name: All pushes to develop branch script: - echo "Hello, Develop!" staging: - step: name: All pushes to staging branch script: - echo "Hello, Staging!"
The example below shows a pipeline definition for steps run when code is pushed to the develop
and staging
branches.
Pull Request
To run pipelines when Pull Requests are created, use the pull-requests
property:
pipelines: pull-requests: staging: - step: name: Unit tests for staging branch pull request script: - echo: "Hello, staging branch pull request" hotfix/*: - step: name: Lint checks for hotfix branch pull request script: - echo: "Hello, hotfix PR" '**': - step: name: Build for all other pull requests script: - echo: "Hello, non staging or hotfix pull request."
The example above shows triggers for pull requests made against the staging
and hostfix
branches. hotfix/*
will match any PR to a branch that starts with hotfix/
. The last pull request pipeline ('**'
) runs for pull requests to any other branch that doesn’t match the first two, similar to how a default
branch pipeline works.
Git Tags
Git Tags are used to mark specific versions of your code. To run pipelines against tags in BitBucket, use the tags
property:
pipelines: tags: '**': - step: script: - echo "This will run the pipeline for all tags" '*-release*': - step: script: - echo "This will run the pipeline for all tags containing 'release' in them."
The first example will run the first pipeline whenever a git tag is encountered that doesn’t match any other tags defined under the tags
property in the bitbucket-pipelines.yml
file. The next pipeline runs whenever there’s a [[Git Tags|git tag]] that contains the word release
in it. This can be useful for tagging
Manual (Custom) Pipelines
This is used to define pipelines that are only run manually or scheduled through the BitBucket UI. These types of pipelines are useful for deployments to production environments where you need signoff before deployments.****
pipelines: custom: run-migrations: - step: name: Run Database Migrations script: - echo "Applying database migrations" deploy-to-staging: - step: name: Deploy to Staging script: - echo "Deploying to staging environment" release-build: - step: name: Create Release Build script: - echo "Building release version"
Scheduled Pipeline Runs
Custom pipelines can be used to create scheduled pipeline runs. In the examples below, I’ll create scheduled pipelines to deploy to staging
and main
(production) branches.
![[Bitbucket CICD Pipeline Documentation#Create Scheduled Pipeline Runs]]
Create Scheduled Pipeline Runs
- Navigate to your repository and click “Pipelines” in the left navigation menu.
- Select Schedules and “New Schedule” to create a new scheduled Pipeline”
![[scheduled_pipeline.png]] - Set the branch, pipeline to run and frequency
![[Pasted image 20241205160407.png]]
To create a scheduled pipeline for both staging and production, do the following:
For staging pipelines:
- select the
staging
branch under “Branch”, - select “custom: staging” under Pipeline and
- under “Schedule” select your preferred Schedule. The custom pipelines must be defined in the
bitbucket-pipelines.yml
file in your repository.
For production pipelines:
- Select the
main
branch under “Branch“ - Select “custom: production” under “Pipeline”
- Set the desired schedule under “Schedule“
Tips
- To push code and skip CI triggering runs, add
[skip ci] or [ci skip]
anywhere in your commit message. - If Pull request and branch specific pipeline definitions overlap, you’ll get two pipelines running at the same time. An example of this is when you have a lint pipeline defined in a
default
pipeline trigger and a similar lint step defined in apull-requests
trigger. Whenever a push is made to the branch with an open PR, the same pipeline would run twice. To avoid this, consider replacing the pipeline defined inbranches
withpull-request
so you only have the pipeline running when PRs are created and not on every push to the branch.
Branch Protection Rules
Branch protection rules or “branch restrictions” as they are called in BitBucket are a set of rules and permissions that govern what actions can be performed on specific project branches. These rules control who can push or merge code to a branch and what conditions have to be met before a push can be made.
Having branch protection rules in place is an important aspect of CI that does the following for you:
- Ensures quality: Requiring merges to occur only when code has been fully tested and certain conditions such as passing tests, builds, and lint checks are met helps to enforce high code quality.
- Prevent accidental changes: Protection rules protect branches from accidental deletion and restrict who can push directly to critical branches like
main
orproduction
, ensuring that only authorised changes from the CICD pipeline are introduced. - Encourage Code Reviews: Using branch protection rules, you can require Pull Requests for changes, enabling code reviews to maintain code standards and reduce errors.
Add Branch Restrictions
To add branch restrictions in BitBucket, navigate to the Projects menu.
Select a project to create rules for and click “Project settings” on the left panel and then select “Branch restrictions” under the “Workflow” section:
Click the “Add a branch restriction” button to add a new restriction rule.:
A dialog window appears. This window allows you to set branch permissions and merge settings.
Branch permissions
In the Branch permissions tab, you specify settings such as the branch or branch type you’re creating the rule for, the users with write access to the branch and whether or not users can create Pull Requests for the branch.
Merge Settings
The Merge settings tab has a list of conditions you can check before allowing a merge to a branch to occur
Here, you can check for conditions such as a minimum number of approvals, pull request status, ensure only changes with passing builds get merged or tie merges to code reviews.
Benefits of using branch protection rules
Using rules such as merge checks has the following benefits:
- ensures users submit changes with passing builds
- tie merges to code review
- get your team to work collaboratively through Pull Requests
- Keep your workflow consistent so your developers always know what they have to do to merge.
- create tasks in pull requests to mark changes that need to be made and ensure all tasks in the pull request are complete before a merge.
- minimise the risk of errors and bugs reaching production
Best Practices for Pipeline triggers and Protection rules
- Use pipeline triggers to automate repetitive tasks but avoid unnecessary pipeline runs to conserve build minutes.
- Protect critical branches with strict rules. Consider disallowing direct commits or enforcing build success before code is merged into the branch.
- Collaborate with your team to create branch rules that match your workflow. For example, instead of having pipeline runs whenever a push is made to a branch, you can configure them to run only when certain files in a branch are changed, e.g run pipelines only for changes to
src/
ortests/
. - Use event-specific triggers: trigger pipelines only for specific events that require action. For example, run test and lint pipelines on pull request creation to minimise resource usage.
- implement manual triggers for running specific stages such as deployments to production, this helps avoid unintended deployments.
Branch protection rules best practices
- Require pull requests for important branches like
main
. - Limit write access to key branches.
- Restrict or block force pushes to critical branches.
Conclusion
In this article, you’ve seen how to set up BitBucket pipeline triggers and branch protection rules. Pipeline triggers or start conditions allow you to ensure pipelines run only when needed. Branch protection rules safeguard critical branches and enforce high-quality code standards.
In the next article, I’ll cover setting up deployment servers with BitBucket pipelines.