FC

Workspace environment kinds and isolation.

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: Hybrid in dev for rapid iteration, CodeManaged in 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":   "…"
}
  • environments is a map of short labels → workspace bindings.
  • defaultEnvironment is what fcc apply (without --env) targets.
  • The legacy workspaceSlug / workspaceId fields at the top are kept in sync with the default for v1 compatibility (older fcc versions still work against the same project).
  • Per-env apiBaseUrl is 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

--env is a per-command flag and never mutates the binding registry — fcc apply --env stg will not silently make stg your new default. To switch default, edit defaultEnvironment in project.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.

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:

  1. Edit and publish in dev from the console.
  2. fcc pull --env dev to capture the change in git.
  3. Open a PR; reviewer compares with fcc diff locally.
  4. CI runs fcc publish --env prod after 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".