Skip to content

ADR-0005 — Monorepo with per-project plug-in to a shared CI/CD pipeline

  • Status: accepted
  • Date: 2026-06-30
  • Domain: repository structure · CI/CD

Context

The lab holds shared infrastructure (Traefik, monitoring, the compose that wires the web network) plus a growing set of independent data projects under projects/. A single CI/CD pipeline already takes any project from git push main to live in well under a minute: lint and compose validation gate the build, an image is pushed to public GHCR, and the VPS pulls and restarts. The question is how to organize the source: one repository for everything, or one per project. This is a solo project; there are no team-ownership boundaries to enforce across repositories.

Decision

A monorepo at ~/data-lab, with each project under projects/ plugging into the shared pipeline through small per-project config. For a solo developer, the coordination overhead of polyrepo (synchronized changes across repos, duplicated CI config, version pinning between repos) buys isolation that no one currently needs. The monorepo makes cross-cutting changes — touching the shared network and a project at once — atomic and reviewable in a single diff, and lets every project inherit one well-tested pipeline instead of maintaining its own.

Consequences

  • One clone holds the whole system; navigation and onboarding are trivial. Infrastructure and project changes can land atomically in a single commit. One CI/CD definition is shared by all projects; new projects inherit it cheaply.
  • CI can run more broadly than strictly necessary on a change; this is mitigated with path filters so a project change does not rebuild unrelated services. Discipline is required to keep project boundaries clean, since nothing physically prevents cross-coupling in a monorepo. The repository is public, so everything in it is exposed at once — secrets must never be committed, and anything sensitive stays out of the tree (env files, not in git).
  • A project that grows into an independent thing can be extracted to its own repository later; the monorepo is a default, not a cage. Revisit if a project needs an independent release cadence, separate access control, its own contributors, or if CI runtime/repo size grows enough that the monorepo's broad scope becomes a real drag despite path filtering.

Alternatives considered

  • Polyrepo (a repository per project plus one for infrastructure, each with its own pipeline) — rejected: duplicates CI config across repos and requires synchronized changes across repositories for anything cross-cutting, at a coordination cost this solo project doesn't need.
  • Hybrid (infrastructure in its own repo, projects sharing a second repo) — rejected: splits the single source of truth without buying real isolation, for the same reason as polyrepo.