Skip to content
Latchkey

How to Set Up a Monorepo Pipeline in Bitbucket Pipelines

Bitbucket runs a step only when relevant files change using the condition.changesets.includePaths key.

Add a condition: to a step with changesets.includePaths globs. The step is skipped unless the push changed a file matching one of those paths - the core monorepo lever.

Per-component change condition

Each component step runs only when files under its path changed.

bitbucket-pipelines.yml
pipelines:
  default:
    - parallel:
        - step:
            name: API
            image: node:20
            condition:
              changesets:
                includePaths:
                  - 'packages/api/**'
            script:
              - cd packages/api && npm ci && npm test
        - step:
            name: Web
            image: node:20
            condition:
              changesets:
                includePaths:
                  - 'packages/web/**'
            script:
              - cd packages/web && npm ci && npm run build

Gotchas

  • includePaths globs are evaluated against the commits in the push; the first build of a branch may run everything.
  • A step skipped by condition is shown as skipped - it does not fail, but downstream steps that need its artifacts will miss them.
  • Use for recursive matches (packages/api/); a single * does not match nested files.

Verify it actually works

Bitbucket validates bitbucket-pipelines.yml on push, and a schema error disables the pipeline rather than failing a build, which can look like nothing happened at all.

Terminal
# validate before pushing
curl -X POST -H "Content-Type: application/x-yaml" \
  --data-binary @bitbucket-pipelines.yml \
  https://api.bitbucket.org/2.0/repositories/<workspace>/<repo>/pipelines/validate

# confirm which pipeline definition matched
# Pipelines -> the run -> "Configuration" tab

Constraints that catch people out

  • Each step runs in a fresh container. Nothing persists between steps unless it is declared as an artifact or a cache.
  • The default memory allocation per step is limited, and service containers share that budget, so adding a database service can push a previously passing build into an out-of-memory failure.
  • Only branches with a matching branches: definition run; a push to an unmatched branch silently runs nothing.
  • Artifacts are passed forward only to later steps in the same pipeline, not between pipelines.

Frequently asked questions

How do I set Up a Monorepo Pipeline in Bitbucket Pipelines?
Add a condition: to a step with changesets.includePaths globs. The step is skipped unless the push changed a file matching one of those paths - the core monorepo lever.
Per-component change condition?
Each component step runs only when files under its path changed.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card