Skip to content

Project repo workflow

Synced from lytebase-infra/lytebase-cli/docs/PROJECT_REPO_WORKFLOW.md. Run pnpm sync:docs to refresh this snapshot.

Lytebase deploys from a project repo, not from the Lytebase tech repo directly.

The tech repo owns:

  • control-plane services
  • CLI code
  • reusable deployment catalog and schema assets

The project repo owns:

  • project.yaml
  • environment overlays under setup/environments/
  • secrets under setup/secrets/
  • pinned bundle metadata in lytebase.lock
  • project-specific catalog overrides such as the generated Terraform project directory

Application repos stay separate. They build and publish artifacts. The project repo decides when those artifact versions are rolled out.

  • lytebase-infra: source repo for controller, CLI, engine, schema, and reusable catalog assets
  • lytebase-dev2: deployable project repo for one independently managed cluster installation
  • app repos: build pipelines and release artifacts consumed by the project repo

Keep dev, staging, and prod in the same project repo by default. Split repos only when approval boundaries, customers, or compliance requirements need hard separation.

Use bootstrap-repo for new cluster repos. This is the preferred day-0 path.

Terminal window
lytebase project bootstrap-repo \
--repo ../lytebase-dev2 \
--project-id lytebase-dev2 \
--environment dev \
--runtime k3s \
--topology single-node \
--cluster-name lytebase-dev2 \
--domain dev2.example.com

The command creates a valid artifact repo with:

  • project.yaml
  • lytebase.lock
  • setup/schema/
  • setup/catalog/
  • setup/environments/dev/runtime/k3s/config.yaml
  • local .env.dev and .env.dev.example
  • setup/secrets/example.enc.yaml

It also validates the generated repo with the project contract validator and the active config loader.

Use sync-catalog for day-2 updates of vendored bundle content.

Terminal window
lytebase project sync-catalog \
--repo ../lytebase-dev2 \
--bundle-version 2026.03.1

sync-catalog replaces only bundle-owned roots from the current tech-repo bundle source:

  • setup/catalog/
  • setup/schema/

It preserves project-owned content:

  • project.yaml
  • README.md
  • lytebase.lock
  • setup/environments/
  • setup/secrets/
  • paths listed in ownership.project_owned_overrides

In the first supported path, that override list includes the generated Terraform project directory under setup/catalog/runtime/k3s/infra/terraform/<provider>/<project-id>.

lytebase.lock records:

  • bundle version
  • source repo and setup root
  • source commit
  • generated timestamp
  • project metadata used by sync validation
  • ownership boundaries between bundle-owned and project-owned paths

Treat the lock file as the contract between bootstrap, sync, and future audits of what a deployable repo actually contains.

The first disposable cluster deployment spec at spec/first_single_node_test_deployment_spec.md should consume a bootstrapped project repo, not the tech repo root.

The intended path is:

  1. bootstrap lytebase-dev2
  2. fill local env values and real encrypted secrets
  3. review setup/environments/dev/runtime/k3s/config.yaml
  4. validate the repo
  5. submit infra, runtime, and platform plans from that repo commit

That keeps the first live deployment aligned with the controller contract of repo_path + project.yaml.

lytebase project init-contract remains available as a low-level scaffold command for tests and edge cases.

For real clusters:

  • use bootstrap-repo to create new project repos
  • use sync-catalog to update vendored bundle content
  • use init-contract only when you explicitly need the bare minimum contract shell without deployable assets

The default operator guidance should now point to bootstrap-repo, not manual copying of setup/ or hand-written project.yaml.