CatLadder
Your whole CI/CD pipeline, generated from one TypeScript file
Catladder turns a single typed config into complete, committed pipelines for GitLab CI and GitHub Actions: build, test, review apps per merge request, cloud deployments, post-deploy verification and releases. Change the config, regenerate, commit. Never hand-edit CI YAML again.
// catladder.ts
import type { Config } from "@catladder/cli";
const config = {
appName: "my-app",
customerName: "acme",
pipelines: { github: true }, // and/or gitlab — both at once during a migration
releases: { when: "auto", method: "changesets" },
components: {
www: {
dir: "apps/www",
build: { type: "node" },
deploy: { type: "google-cloudrun", projectId: "my-project", region: "europe-west6" },
env: { review: {}, dev: {}, prod: {} },
},
},
} satisfies Config;
export default config;
yarn catenv generates everything from it — and the generated files are checked in, so every pipeline change is a reviewable diff.
Two CI backends, one config
GitLab CI and GitHub Actions are generated from the same catladder.ts. Run both in parallel to migrate between them step by step.
Environments built in
A review app per merge request (stopped when it closes), a dev deployment on the main branch, stage and prod on tagged releases — and .env files for local development.
Deploy types, not deploy scripts
Google Cloud Run (services, jobs, worker pools, Cloud SQL, schedules), Kubernetes, npm packages, GitLab/GitHub pages — or your own script.
Releases as a feature
semantic-release or changesets, both gated on a security audit, with release queueing, a force-release escape hatch and a changeset check on every merge request.
Secrets with a source of truth
A vault holds the values, CI backends only get mirrored copies, and the same declarations produce your local .env files.
A doctor for drift
catladder project doctor compares the config against the infrastructure that actually exists — IAM, secrets, tokens, merge gating — and prints the command that heals each finding.