Skip to main content
Fleet releases promote a canary-proven Corgtex release through GitHub Actions. Operators trigger and monitor the workflow; GitHub Actions and the Ops control plane own provider credentials, target discovery, release metadata, and health proof. The release workflow must use the GitHub environment fleet-release-production. Do not wire fleet releases to the generic production environment. Fleet promotion reuses immutable GHCR images for the release SHA. It does not build Docker images. If the canonical web or worker image for sha-<gitSha> is missing, publish it with the Release Images workflow before running a real fleet promotion.

Required GitHub Environment Settings

Configure these values on the fleet-release-production environment. Store secret values only in GitHub environment secrets, never in docs, issues, PR bodies, logs, or committed files.
NameKindPurpose
CONTROL_PLANE_AGENT_API_KEYSecretLets GitHub Actions call the Ops control-plane MCP endpoint for discovery and verified inventory recording.
RAILWAY_API_TOKENSecretLets GitHub Actions promote Railway web and worker services.
AZURE_CLIENT_IDSecretAzure workload identity client used by azure/login.
AZURE_TENANT_IDSecretAzure tenant used by azure/login.
AZURE_SUBSCRIPTION_IDSecretAzure subscription used by azure/login.
GHCR_IMPORT_TOKENSecret, optionalUsed only when the workflow token cannot import GHCR images into Azure Container Registry.
CONTROL_PLANE_URLVariableOps control-plane origin. Defaults to https://ops.corgtex.com when unset.
RAILWAY_GRAPHQL_ENDPOINTVariable, optionalRailway GraphQL endpoint override. Leave unset unless Railway support directs otherwise.
FLEET_RELEASE_STABLE_GIT_SHAVariableLatest stable 40-character git SHA. Update only after canary proof.
FLEET_RELEASE_TARGETS_JSONVariableRailway customer targets, or leave unset only if control-plane discovery is intentionally used.
FLEET_RELEASE_OPS_TARGET_JSONVariableDedicated Ops target.
FLEET_RELEASE_BACKUP_APP_TARGET_JSONVariableBackup app target.
FLEET_RELEASE_AZURE_TARGET_JSONVariableAzure self-serve target.
FLEET_RELEASE_ACR_SERVERVariable, optionalAzure Container Registry server. Defaults to the production self-serve registry.
FLEET_RELEASE_PREFLIGHT_MAX_SECONDSVariable, optionalDry-run preflight timing gate. Defaults to 30.
GHCR_IMPORT_USERNAMEVariable, optionalGHCR username for Azure imports. Defaults to the GitHub Actions actor.

Target Inventory Checklist

Each target variable may contain one target object or an array of target objects. Keep target inventory operational and sanitized: IDs, URLs, provider IDs, and release metadata are acceptable; raw customer content, credentials, private uploads, and bearer tokens are not. Railway targets must include:
  • id
  • label
  • url
  • group, one of railway-customers, ops, or backup-app
  • provider: "railway"
  • railway.projectId
  • railway.environmentId
  • railway.webServiceId
  • railway.workerServiceId
Azure self-serve targets must include:
  • id
  • label
  • url
  • group: "azure-selfserve"
  • provider: "azure"
  • azure.resourceGroup
  • azure.acrName
  • azure.webAppName
  • azure.workerAppName

Operator Checklist

  1. Confirm fleet-release-production has the required secrets and variables for the selected target groups.
  2. Confirm FLEET_RELEASE_STABLE_GIT_SHA points to the canary-proven stable release, not an arbitrary main commit.
  3. Confirm the Release Images workflow has published both canonical GHCR images for sha-<FLEET_RELEASE_STABLE_GIT_SHA>.
  4. Run a dry-run:
npm run release:fleet -- --reason "Plan latest stable fleet release." --dry-run
Dry-runs use the lightweight preflight workflow by default. That path validates configuration, resolves latest-stable, and plans rings without npm ci, Prisma generation, Docker build, Azure login, or provider mutation.
  1. Confirm the dry-run dispatches fleet-release-preflight.yml, prints the manifest, selected targets, rings, blockers, and elapsed seconds before any provider mutation.
  2. If the dry-run fails on missing config, fix the named GitHub environment setting and rerun.
  3. If the preflight takes longer than 30 seconds or reports unclear blockers, stop and repair the preflight before expanding release orchestration.
  4. For a real promotion, use a specific support reason and monitor the GitHub Actions run until each target proves matching gitSha, imageTag, database=up, and schema=ready.
  5. If any target fails, stop at the failed ring unless an operator explicitly supplies a force reason.

Gate For Next Work

The immutable-image workflow is sufficient only if a canary promotion reuses existing images, skips Docker build work inside fleet promotion, and proves matching gitSha, imageTag, database=up, and schema=ready. Move to the next release PR only when this gate is not met.