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.