CI/CD

Monorepo deployments

6 min readUpdated April 2026

Deploy multiple services from a single repository. StackBlaze detects changes per service using root directory filters: only the affected service rebuilds when you push. If you touch apps/api, only the API service kicks off a new Tekton PipelineRun; the web frontend is untouched.

This means your monorepo stays as a single source of truth in GitHub while each service gets its own independent deploy history, rollback capability, scaling policy, and environment variables.

Recommended monorepo layout

acme/platform (monorepo)

acme/platform/

├── apps/

│ ├── web/ # Next.js frontend

│ │ ├── package.json

│ │ └── src/

│ ├── api/ # Express REST API

│ │ ├── package.json

│ │ └── src/

│ └── worker/ # Background job processor

│ └── src/

├── packages/

│ ├── shared/ # Shared types & utilities

│ └── ui/ # Component library

├── turbo.json

└── package.json

Build filter configuration

Service settings, Build filter (one glob per line)

Service: web (Root Dir: apps/web)

apps/web/**

packages/shared/**

packages/ui/**

Service: api (Root Dir: apps/api)

apps/api/**

packages/shared/**

Service: worker (Root Dir: apps/worker)

apps/worker/**

packages/shared/**

Change detection, only affected services rebuild

webhookMATCHskip
Git Push

apps/web/src/

packages/ui/

Change Detection

diff path globs

per service

web, rebuild

PipelineRun started

apps/web matched

api, skipped

no matching paths

unchanged

Under the hood

When a push webhook arrives, StackBlaze runs the following logic for every service attached to that repository:

  • Path diffing: the commit’s changed file list is matched against each service’s build filter globs using standard glob minimatch semantics. A single match is enough to trigger.
  • Tekton PipelineRun: for matched services, StackBlaze creates a Tekton PipelineRun in the build namespace. The PipelineRun clones the repo, changes to the root directory, runs your build command, pushes the image, and triggers a rolling update.
  • Shared packages as watch paths: list packages/shared/** in the build filter for every service that imports it. A change to a shared type will rebuild all consumers.
  • Independent deploy history: each service records its own sequence of deploys. Rolling back apps/api to a previous image does not affect apps/web.

Step by step

01

Structure your monorepo

Organise your repository so each deployable application lives in its own sub-directory under apps/. Shared code goes in packages/. StackBlaze does not mandate a specific monorepo tool, it works equally well with Turborepo, Nx, pnpm workspaces, or a plain directory layout.

02

Create a service per app and set the root directory

When adding a service, expand "Advanced settings" and set the Root Directory field to the app's path, for example "apps/web" or "apps/api". StackBlaze changes into that directory before running your build and start commands, so your package.json scripts work exactly as they do locally.

03

Configure build filters

Set the "Build filter" for each service to the glob paths that should trigger a rebuild. For apps/web, add "apps/web/**" and "packages/shared/**". When a push arrives, StackBlaze diffs the changed file paths against these globs, if no files match, the service is skipped entirely.

04

Each service is fully independent

Each service in your monorepo has its own deploy pipeline, environment variables, scaling configuration, and deploy history. You can roll back apps/api without touching apps/web. Teams can own different services within the same repository with separate access controls.