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
- 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, changecatladder.tsand regenerate. - Regenerate after every
catladder.tschange by runningyarn catenv. With direnv set up, re-entering the project directory does this automatically. - 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),stageandprod(deployed on tagged releases),local(only for local development via catenv). Per-env overrides live underenv.<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 oftrueallow per-pipeline settings (e.g.runnerVariables). - Package manager: yarn and pnpm are supported and autodetected
(from the
packageManagerfield 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 aspnpm catenv/pnpm catladder.
Common tasks
- Add a component: add an entry under
components, runyarn 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-levelhooks) —transformFileBeforeWrite/transformYamlBeforeWriterewrite 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.
Related skills
catladder-builds— the componentbuildconfig (build types, Docker)catladder-deploys— the componentdeployconfig (k8s, Cloud Run, …)catladder-secrets— env vars and secret managementcatladder-releases— releasing (semantic-release / changesets)catladder-pipelines— how the generated pipelines work, debugging CIcatladder-cli— non-interactive CLI usage and command referencecatladder-migrate-ci-backend— moving a project between GitLab CI and GitHub Actionscatladder-migrate-release-method— switching between semantic-release and changesetscatladder-migrate-package-manager— switching a project between yarn and pnpm