Skip to main content

Working with catladder

catladder generates this repository's CI/CD pipelines, deployments and environment files from the TypeScript config catladder.ts at the repo root. It is installed per project (@catladder/cli) — always use the locally installed version (yarn catenv, yarn catladder).

Golden rules

  1. Never hand-edit generated files. Everything under .catladder-generated/, the generated parts of .gitlab-ci.yml, and catladder-generated workflows under .github/workflows/ are overwritten on every regeneration (they carry a "generated by catladder" header). To change them, change catladder.ts and regenerate.
  2. Regenerate after every catladder.ts change by running yarn catenv. With direnv set up, re-entering the project directory does this automatically.
  3. Commit the regenerated files together with the config change. Generated files are checked in; CI includes them directly.

Structure of catladder.ts

import type { Config } from "@catladder/cli";

const config = {
appName: "my-app",
customerName: "pan",
pipelines: { gitlab: true, github: true }, // which CI systems to generate
components: {
www: {
dir: "frontend", // working directory of this component
vars: { public: {}, secret: [] }, // env vars (see catladder-secrets skill)
build: { type: "node" }, // node | rails | meteor | custom — see catladder-builds
deploy: { type: "kubernetes" }, // kubernetes | google-cloudrun | dockerTag | custom — see catladder-deploys
env: { // enable/customize per environment
review: {},
dev: {},
stage: false, // false disables the env for this component
prod: {},
},
},
},
} satisfies Config;

export default config;

Key concepts:

  • Components are the sub-apps/services of the project (frontend, api, ...). Each has a build config and a deploy config.
  • Environments: dev (deployed on push to the main branch), review (per merge/pull request), stage and prod (deployed on tagged releases), local (only for local development via catenv). Per-env overrides live under env.<name> and can override vars, deploy settings, and more.
  • Pipelines: pipelines: { gitlab: true, github: true } selects which CI systems get generated files. Options objects instead of true allow per-pipeline settings (e.g. runnerVariables).
  • Package manager: yarn and pnpm are supported and autodetected (from the packageManager field in package.json or the lockfile; yarn is the fallback). packageManager: "pnpm" | "yarn" at the top level overrides the detection. In pnpm projects, run the CLIs as pnpm catenv / pnpm catladder.

Common tasks

  • Add a component: add an entry under components, run yarn catenv, commit config + generated files.
  • Change resources / deployment settings: edit the component's deploy (or per-env override), regenerate.
  • Inspect the resulting pipeline: read the generated files (e.g. .catladder-generated/gitlab/, .github/workflows/) — but never edit them.

Escape hatches — last resort, and a signal to file an issue

catladder has two escape hatches for things it doesn't (yet) support natively:

  • customJobs (per component) — hand-written CI job specs injected into the pipeline.
  • transform hooks (top-level hooks) — transformFileBeforeWrite / transformYamlBeforeWrite rewrite the generated files just before they're written to disk.

Both work, but they are fragile by design: they depend on the exact shape of catladder's generated output, so a catladder upgrade can break them silently, and they sit outside everything the rest of the config gives you (rules, caching, images, per-env logic, snapshots). Prefer a first-class config option whenever one exists — check the build, deploy, releases, and env/vars surfaces (and the sibling skills) first.

When you do reach for one, treat it as a missing-feature signal. If a dev needs customJobs or a transform hook, it almost always means catladder is missing a capability that other projects will need too. Open an issue at https://github.com/panter/catladder/issues describing the use case (what you're trying to achieve and why the existing config can't express it) so it can be generalized into a supported feature — and, where possible, offer to help the dev write that issue. The goal is for escape hatches to shrink over time, not accumulate.

  • catladder-builds — the component build config (build types, Docker)
  • catladder-deploys — the component deploy config (k8s, Cloud Run, …)
  • catladder-secrets — env vars and secret management
  • catladder-releases — releasing (semantic-release / changesets)
  • catladder-pipelines — how the generated pipelines work, debugging CI
  • catladder-cli — non-interactive CLI usage and command reference
  • catladder-migrate-ci-backend — moving a project between GitLab CI and GitHub Actions
  • catladder-migrate-release-method — switching between semantic-release and changesets
  • catladder-migrate-package-manager — switching a project between yarn and pnpm