/icons/ci-cd.png
/icons/bitbucket.png

Building and Using a Custom Bitbucket Pipe (Plugin)

@red_sh4d0w / March 16, 2025
4 min read

Building a Custom Bitbucket Pipe for Automated Tasks

Github Repo Link

Bitbucket Pipes make CI/CD automation easy—deploy code, run security scans, and notify your team effortlessly. But what if the already made pipes don’t quite fit what you need? That's where custom pipes come in, giving you total control.

This guide shows you how to create custom Bitbucket Pipes. It lets you make your CI/CD processes just right. You'll see how to set up your pipe and pack it as a Docker container. Plus, learn to easily add it to your Bitbucket pipelines.

Understanding Bitbucket Pipes and Their Power

Bitbucket Pipes streamline complex CI/CD workflows, making automation simple and reusable. But sometimes, the built-in options don’t cover all requirements. That’s when building a custom Pipe becomes essential.

What is a Bitbucket Pipe?

A Bitbucket Pipe is a reusable script packaged inside a Docker container that executes specific tasks in a pipeline. It helps simplify complex configurations and improves reusability across projects.

Why Build a Custom Bitbucket Pipe?

  • Reuse common functionality across multiple repositories.
  • Standardize workflows and ensure consistency.
  • Reduce duplication of CI/CD configuration.
  • Provide an easier way to integrate third-party services.

Key Components of a Bitbucket Pipe

A Bitbucket Pipe contains the following required files:

  • Metadata (pipe.yml): The pipe.yml file is a metadata file that defines a Bitbucket Pipe. It provides essential details about the Pipe, such as its name, description, Docker image, maintainer information, etc. This file helps Bitbucket understand how to use and display the Pipe in the pipeline configuration.
  • Script/Binary: This is the core of the Pipe, containing the logic for the task you want to automate. It can be a Bash script, Python script, or compiled binary that executes the desired operations when the Pipe runs.
  • Dockerfile: Defines how the Pipe is built and executed.
  • README.md: Documentation for using the Pipe.

Creating a Custom Bitbucket Pipe

1. Setting Up the Repository

Start by creating a new repository on Bitbucket to store the Pipe files. Inside the repository, maintain the following folder structure:

├── Dockerfile
├── LICENSE.txt
├── pipe
│   ├── main.py
│   └── requirements.txt
├── pipe.yml
└── README.md

2. Writing the Pipe Script

For our example, we’ll build a Pipe (pipe/main.py) that prints a personalized greeting.

from bitbucket_pipes_toolkit import Pipe, get_logger
import os

logger = get_logger()
PIPE_METADATA_FILE=f'{os.environ["WORKDIR"]}/pipe.yml'

schema = {
    'NAME': {'type': 'string', 'required': True},
    'MESSAGE': {'type': 'string', 'required': True},
}

class Greet(Pipe):
    def run(self):
        super().run()
        logger.info('Starting Greet...')
        name = self.get_variable('NAME').strip('"')
        message = self.get_variable('MESSAGE').strip('"')
        print(f"Hello, {name}! {message}")

if __name__ == '__main__':
    pipe = Greet(pipe_metadata=PIPE_METADATA_FILE, schema=schema)
    pipe.run()

2. Installing Dependencies

Create a pipe/requirements.txt file with the required dependencies:

bitbucket-pipes-toolkit==4.*

3. Creating the Dockerfile

The Dockerfile initializes the Bitbucket Pipe environment from a minimal Python image. It defines a working directory, copies required files (the script and metadata), installs requirements, and specifies the entry point to run the main script when the container starts.

FROM python:3.10-slim
ENV WORKDIR /PIPE
WORKDIR $WORKDIR

COPY pipe ./
RUN pip install --no-cache-dir -r ./requirements.txt
COPY LICENSE.txt README.md pipe.yml ./

ENTRYPOINT ["python3", "/PIPE/main.py"]

4. Defining Pipe Metadata

The pipe.yml file is the metadata descriptor for the Bitbucket Pipe. Bitbucket uses this file when the Pipe is invoked in a Bitbucket pipeline to determine how to run the Pipe. It specifies the image of the container that should be utilized. After triggering the Pipe in the pipeline, Bitbucket will pull the image specified and execute it, sending inputs and environment variables as necessary for running.

name: Greet Pipe
image: r3dshadow/demo:bitbucket-pipe-1.0
description: This Bitbucket Pipe prints a personalized greeting message
category: Testing
repository: https://bitbucket.org/safeervs789/bitbucket-pipe/
vendor:
  name: Safeer
  website: https://red-shadow.live/
maintainer:
  name: Safeer
  website: https://red-shadow.live/
tags:
    - greet

5. Running and Testing the Pipe

To build and run the Pipe locally:

docker build -t my-bitbucket-pipe .
docker run --rm -e NAME="John" -e MESSAGE="Welcome to Bitbucket Pipes" my-bitbucket-pipe

6. Publishing the Pipe

Push your Docker image to a container registry like Docker Hub:

docker tag my-bitbucket-pipe <your-dockerhub-username>/bitbucket-pipe:1.0
docker push <your-dockerhub-username>/bitbucket-pipe:1.0

8. Using the Pipe in Bitbucket Pipelines

After publishing, utilize the Pipe in your Bitbucket pipeline:

pipelines:
  branches:
    main:
    - step:
        name: Greet Pipe
        script:
          - pipe: safeervs789/bitbucket-pipe:main
            variables:
              NAME: "Safeer"
              MESSAGE: "Testing"

The pipe field indicates the repository where Pipe is located (safeervs789/bitbucket-pipe:main). main can be replaced with a versioned tag such as 1.0 for stability

Constructing a custom Bitbucket Pipe eases repetitive CI/CD procedures, enhances consistency, and offers increased reusability. Automated deployments, tests, or notification - whatever, custom Pipes deliver an organized manner of extending Bitbucket Pipelines.

GithubLinkedInTwitter