Environments
FetchCatch treats each deployment stage as its own workspace and lets a single
.fetchcatch/ project bind to several of them. That keeps dev, staging, and prod
configurations out of long-lived per-branch divergence — they live side by side as named
profiles in project.json, and you pick which one a command targets with --env <name>.
Why workspaces, not branches?
Mixing config and code on the same branch makes "what's actually deployed?" depend on history walks. Workspaces are isolated runtime resources (own API keys, own auth profiles, own runs), which means:
- A staging API key cannot evaluate flows in production — even by accident.
- Run history, audit events, and quotas are scoped per-stage.
- Governance modes can differ:
Hybridin dev for rapid iteration,CodeManagedin prod.
v2 `project.json`
{
"schemaVersion": 2,
"apiBaseUrl": "https://api.fetchcatch.com",
"tenantSlug": "acme",
"tenantId": "…",
"defaultEnvironment": "dev",
"environments": {
"dev": { "workspaceSlug": "billing-dev" },
"stg": { "workspaceSlug": "billing-stg" },
"prod": { "workspaceSlug": "billing-prod" }
},
"workspaceSlug": "billing-dev",
"workspaceId": "…"
}
environmentsis a map of short labels → workspace bindings.defaultEnvironmentis whatfcc apply(without--env) targets.- The legacy
workspaceSlug/workspaceIdfields at the top are kept in sync with the default for v1 compatibility (olderfccversions still work against the same project). - Per-env
apiBaseUrlis optional — useful when staging lives on a different region.
Usage
fcc plan # dry-run against defaultEnvironment (dev)
fcc apply # push to dev
fcc apply --env stg # push the same files to staging
fcc publish --env prod # ship to production
fcc drift --env prod # nightly drift check, CI exits 2 on divergence
--envis a per-command flag and never mutates the binding registry —fcc apply --env stgwill not silently makestgyour new default. To switch default, editdefaultEnvironmentinproject.json(or just re-init).
Bootstrap
The simplest way to populate environments is to create one workspace per stage in the console
(Sidebar → Workspaces → +), then hand-edit project.json. Tag each workspace with its
EnvironmentKind (Development / Staging / Production / Other) from
Settings → Workspaces → Settings so the console badge matches the CLI label.
Recommended governance + environment combos
| Environment | Suggested governance | Why |
|---|---|---|
dev |
Hybrid or DesignerOnly |
Iterate fast in the console; CLI is optional. |
stg |
Hybrid |
CLI seeds it from main; humans can still poke. |
prod |
CodeManaged |
Every change is a reviewed PR. |
This produces the classic four-step lifecycle:
- Edit and publish in
devfrom the console. fcc pull --env devto capture the change in git.- Open a PR; reviewer compares with
fcc difflocally. - CI runs
fcc publish --env prodafter merge.
Multi-environment CI snippet
jobs:
deploy:
strategy:
matrix:
env: [stg, prod]
steps:
- uses: actions/checkout@v4
- run: fcc apply --env ${{ matrix.env }}
- run: fcc publish --env ${{ matrix.env }}
env:
FETCHCATCH_TOKEN: ${{ secrets.FETCHCATCH_TOKEN }}
CI: "true"
The X-FCC-Git-Commit header is captured automatically by the CLI from GITHUB_SHA (or
git rev-parse HEAD locally) and stamped onto every FlowVersions row that lands, so the
console history panel can show "ci-bot · v17 · commit a1b2c3d4".