Run Bitbucket Pipelines locally
Project description
bb-run
Run Bitbucket Pipelines locally. bb-run reads bitbucket-pipelines.yml and runs it in Docker (default) or on the host, including parallel steps, fail-fast, and artifacts.
Why bb-run?
- Test before pushing - Catch CI failures locally before committing
- Fast iteration - No waiting for Bitbucket's pipeline queue
- Debug easily - Run in verbose mode and inspect output directly
- Two modes - Docker for an environment closer to Bitbucket; host mode needs no Docker
- Parallel steps -
parallel:groups run concurrently; group and per-stepfail-faststop sibling processes when a failing step demands it - Artifacts - Shared / scoped uploads,
capture-on, and selectivedownload(see below) - Small install - One runtime dependency: PyYAML (see
pyproject.toml). Docker is only required for--mode docker
Installation
via pip
pip install bb-run
via pipx (isolated CLI)
If you prefer not to use a project virtualenv:
pipx install bb-run
Recommended for most CLI users: pipx keeps bb-run out of system Python and usually puts bb-run on your PATH without extra setup.
If bb-run is not on your PATH
After pip install --user or some IDE setups, the script directory may be missing from PATH. Run the same CLI via Python:
python3 -m bbrun --version
python3 -m bbrun --validate
Homebrew
There is no official Homebrew formula in this repository yet. Use pip or pipx above for the supported install path.
To package for Homebrew later: submit a formula to homebrew-core (tagged releases + tests that do not require Docker are typical expectations), or maintain a third-party tap and document it in your fork; see Homebrew docs.
from source
git clone https://github.com/karlhillx/bb-run.git
cd bb-run
pip install -e .
To run tests or Ruff locally, use the dev extra (includes pytest, pytest-cov, and ruff):
pip install -e ".[dev]"
Using bb-run reliably
- Run commands from the repository root (the directory that contains
bitbucket-pipelines.yml), or pass--repo /path/to/that/root. - Prefer
bb-run --validatefirst; it checks the file without Docker. If you do not have Docker, use--mode hostfor runs (see Modes). - On macOS/Linux where
pip installis restricted (PEP 668), use a venv,pipx, or:
python3 -m pip install --user bb-run
(then ensure that user script directory is on yourPATH).
Quick Start
Validate a pipeline (instant)
cd /path/to/your/repo # where bitbucket-pipelines.yml lives
bb-run --validate
Run the default pipeline
bb-run
Run a specific branch
bb-run --target branches.main
bb-run -t branches.main
Simulate a feature branch
bb-run --branch feature/my-work
Run on your host (no Docker)
bb-run --mode host
Pass variables
bb-run -v ENVIRONMENT=staging -v API_KEY=secret
List available targets
bb-run --list-targets
List targets as JSON
bb-run --list-targets --json
Preview a run without executing commands
bb-run --dry-run
bb-run --target branches.feature/my-work --branch feature/my-work --dry-run
bb-run --dry-run --json
Target Syntax
bb-run uses the same target naming as Bitbucket Pipelines:
defaultbranches.<branch-name>tags.<tag-name>custom.<name>for pipelines underpipelines: custom:pull-requests.<pattern>for pipelines underpipelines: pull-requests:
For branches.*, tags.*, and pull-requests.*, bb-run first tries an exact key match and then falls back to Bitbucket-style wildcard keys like feature/*, release/**, v*, or **.
Modes
Docker Mode (default)
Runs steps in Docker containers matching Bitbucket's build environment.
bb-run --mode docker
Pros: Faithful reproduction of Bitbucket's environment
Cons: Requires Docker, images may take time to download
Host Mode
Runs steps directly on your local machine.
bb-run --mode host
Pros: Fast, no image downloads
Cons: May differ from Bitbucket's environment (Python vs Python3, etc.)
Parallel steps
Bitbucket-style parallel blocks are supported in Docker and host mode. Child steps run at the same time. While a parallel group runs, each container / shell receives BITBUCKET_PARALLEL_STEP (0-based index) and BITBUCKET_PARALLEL_STEP_COUNT, matching Bitbucket’s parallel variables.
pipelines:
default:
- parallel:
fail-fast: true
steps:
- step:
name: Integration A
script:
- ./integration.sh --batch 1
- step:
name: Integration B
script:
- ./integration.sh --batch 2
You can set fail-fast: false on an individual step inside the group so its failure does not stop the others (when the group uses fail-fast).
Artifacts
bb-run models Bitbucket pipeline artifacts so later steps can rely on captured files even if you delete them mid-pipeline:
- List form —
artifacts: [dist/**, reports/*.txt] - Object form —
artifacts: { paths: [...], download: false }plus optionalupload:entries withname,type(shared/scoped/test-reports),paths,ignore-paths, andcapture-on(success/failed/always) download— default is to restore all prior shared layers before a step;download: falseskips that restore; a list of names restores only those shared artifacts (plus unnamed list-style captures as a fallback when nothing matches)
Captured trees are stored under .bb-run/artifacts/ in the repo (ignored by git). Shared layers are replayed onto the clone directory before each step that downloads them. Scoped and test-reports uploads are saved for inspection but are not injected into later steps.
Caveats: With --mode host or a bind-mounted Docker workspace, files left on disk by an earlier step are still visible even when download: false; bb-run only controls replay from its cache, not deleting your working tree. Parallel groups capture each child after the whole group finishes, reading the final workspace (Bitbucket isolates children more strictly).
Examples
Python project
cd my-python-project
bb-run
Node.js project
cd my-node-project
bb-run --target branches.main
Run with verbose output
bb-run --verbose
--verbose currently prints -v / --variables values before the run; more detail may be added later.
Configuration
bb-run automatically looks for bitbucket-pipelines.yml in your current directory. Use --repo to specify a different path:
bb-run --repo /path/to/repo
Supported vs Unsupported Bitbucket Features
Supported (today):
default,branches.<name>,tags.<name>,custom.<name>, andpull-requests.<pattern>targets- Step
scriptexecution (sequential) - Basic environment variables (Bitbucket-style values)
- Docker images per step (Docker mode)
Not yet supported / simplified:
- Pipes (listed but not executed)
- Parallel steps or step conditions
- Services, caches, and artifacts
- Deployment environments, manual triggers, or step size
Requirements
- Python 3.12+ (
requires-pythoninpyproject.toml) - PyYAML 6.x (installed automatically with
bb-run) - Docker CLI (optional; only for
--mode docker, the default)
Local development (virtualenv)
Use Python 3.12 for the project venv so python --version matches requires-python in pyproject.toml:
# macOS (Homebrew)
brew install python@3.12
"$(brew --prefix python@3.12)/bin/python3.12" -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# or tests + coverage only: pip install -e ".[test]"
python -m pytest
python -m pytest --cov=bbrun --cov-report=xml tests/
ruff check bbrun
Environment Variables
bb-run sets these Bitbucket-specific environment variables:
| Variable | Description |
|---|---|
BITBUCKET_BUILD_NUMBER |
Build number (set to "1") |
BITBUCKET_CLONE_DIR |
Repo root on the host; in Docker mode the path inside the container (/opt/atlassian/pipelines/agent/build) |
BITBUCKET_COMMIT |
Git commit SHA (or local if unavailable) |
BITBUCKET_BRANCH |
Branch name (from --branch or default) |
BITBUCKET_REPO_SLUG |
Repository directory name |
BITBUCKET_REPO_UUID |
Unique run ID for this process |
BITBUCKET_WORKSPACE |
Set to "local" |
BITBUCKET_PARALLEL_STEP |
Zero-based index inside a parallel: group (parallel steps only) |
BITBUCKET_PARALLEL_STEP_COUNT |
Number of steps in that parallel group (parallel steps only) |
Troubleshooting
"bitbucket-pipelines.yml not found"
You are not in the repo root, or the file name does not match exactly. cd into the project that contains the YAML, or use --repo.
"No steps found for target"
The --target name does not match your file. List names with:
bb-run --list-targets
"Docker is not available"
Use --mode host to run on your local machine instead of in Docker:
bb-run --mode host
"pip: command not found"
bb-run automatically translates pip to pip3 and adds --break-system-packages for PEP 668 environments.
pytest: error: unrecognized arguments: --cov=...
Coverage flags come from the pytest-cov plugin. Install the test or dev extra, then use the same interpreter for pytest:
pip install -e ".[dev]"
# or: pip install -e ".[test]"
python -m pytest --cov=bbrun --cov-report=xml tests/
Image pull failures
Docker Hub rate limits may cause image downloads to fail. Try:
- Waiting and retrying later
- Using
--mode hosttemporarily - Configuring a Docker mirror
License
MIT License - see LICENSE for details.
Contributing
See CONTRIBUTING.md. User-facing changes should be noted in CHANGELOG.md. Security reports: SECURITY.md.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bb_run-1.1.0.tar.gz.
File metadata
- Download URL: bb_run-1.1.0.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6886160a10029d95676a181cc05b75e468f034ea9f754b4c8755169a82e7655
|
|
| MD5 |
c9db4c60accfb72575659fc97d18a0d2
|
|
| BLAKE2b-256 |
c2e484b8f0fe3b8104286d6215774747557b86c7433db915a0c2ae942647df29
|
Provenance
The following attestation bundles were made for bb_run-1.1.0.tar.gz:
Publisher:
publish.yml on karlhillx/bb-run
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bb_run-1.1.0.tar.gz -
Subject digest:
a6886160a10029d95676a181cc05b75e468f034ea9f754b4c8755169a82e7655 - Sigstore transparency entry: 1399067267
- Sigstore integration time:
-
Permalink:
karlhillx/bb-run@bc5aac2c96c4bd6a5818bb9e11701884654086cc -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/karlhillx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bc5aac2c96c4bd6a5818bb9e11701884654086cc -
Trigger Event:
release
-
Statement type:
File details
Details for the file bb_run-1.1.0-py3-none-any.whl.
File metadata
- Download URL: bb_run-1.1.0-py3-none-any.whl
- Upload date:
- Size: 25.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d133d460290115f6f7b20365d40d21ccd5b0b68a02df98e7c0f5d5925067a2c
|
|
| MD5 |
380335a72c559c7eedf08d437043b10c
|
|
| BLAKE2b-256 |
93586cfcfc20a48dd6f954bd464110b885d039443341f154bed095661e54fa52
|
Provenance
The following attestation bundles were made for bb_run-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on karlhillx/bb-run
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bb_run-1.1.0-py3-none-any.whl -
Subject digest:
5d133d460290115f6f7b20365d40d21ccd5b0b68a02df98e7c0f5d5925067a2c - Sigstore transparency entry: 1399067276
- Sigstore integration time:
-
Permalink:
karlhillx/bb-run@bc5aac2c96c4bd6a5818bb9e11701884654086cc -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/karlhillx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bc5aac2c96c4bd6a5818bb9e11701884654086cc -
Trigger Event:
release
-
Statement type: