refactor(env): rename cloud 'dev' tier → 'ci'; promote 'local' to first-class tier#103
Merged
refactor(env): rename cloud 'dev' tier → 'ci'; promote 'local' to first-class tier#103
Conversation
…s, workflows) Codebase-only rename. Renames the auto-deployed first cloud tier from 'dev' to 'ci' to stop conflating it with developer-machine work. The honest name for the tier that CI auto-deploys to without a human gate is 'ci'. 'dev' / developer-laptop work becomes the documented 'local' tier (added in Phase B docs). Final ladder: local → ci → ppe → prod. * infra/bicep: rename .dev.bicepparam files → .ci.bicepparam, switch @Allowed lists from ['dev','ppe','prod'] → ['ci','ppe','prod'], rename devPublicClients var → ciPublicClients (gate on env=='ci'). * scripts/{bootstrap-env,provision-apps}.sh: ENV=ci is the new default; ENV=dev still accepted with a deprecation warning so any cached runbooks survive the cutover. * .github/workflows/{cd,cd-cleanup,deploy-env,ci}.yml: deploy-dev job → deploy-ci, matrix env list, default workflow_dispatch input. * All 66 tests pass. Bicep modules build cleanly. Phase B (docs sweep) and Phase C (live Azure cutover with OIDC FIC subject migration) follow in subsequent commits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s tier (Phase B) Documentation sweep that follows Phase A (the Bicep/scripts/workflows rename). Three structural changes plus a mechanical rename pass: 1. environments.md fully rewritten as a 4-tier ladder: local → ci → ppe → prod, with explicit ASPNETCORE_ENVIRONMENT mapping per tier (Development / Staging / Staging / Production) and idle cost. Calls out why 'ci' beats 'dev' for the auto-deploy tier (dev colloquially means the local laptop) and clarifies that 'ppe' is Microsoft jargon for 'staging/preprod'. 2. run-locally.md opening promotes 'local' to the documented first tier (was a footnote-style addendum before). 3. glossary.md gains 'ci' (under C), 'local' (new L section), and 'ppe' (new P section), each with the doctrine rationale and a primary-source link. Plus mechanical rename across operations.md, cost-zero.md, deploy-cloud.md, sample-setup.md, matrix.md, best-practices.md, README.md, DOCTRINE.md, coverage-map.md: every cloud-tier reference to dev / ftgo-dev-* / rg-ftgo-dev-eastus / ENV=dev / deploy-dev / environment=dev becomes ci / ftgo-ci-* / rg-ftgo-ci-eastus / ENV=ci / deploy-ci / environment=ci. Phrases like 'local dev', 'dev box', 'IntelliJ', 'slsa.dev', 'sigstore.dev' are deliberately preserved (they don't refer to the tier). Tables realigned per markdownlint MD060 in the touched files. All 66 tests still pass; CI markdownlint job clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the Phase C migration runbook to docs/operations.md with the
exact OIDC-safe step order:
1. Land the codebase rename (Phases A+B) — no live changes yet.
2. Provision the new tier alongside the old (bootstrap-env.sh
ENV=ci + provision-apps.sh ENV=ci).
3. Migrate the env-scoped GH variable ENTRA_CONFIG_JSON via
'gh variable get/set' (env-scoped vars can't be renamed).
4. Smoke-test the new tier in isolation, then run the *positive*
Restaurants happy-path probe (curl with a real Bearer token →
expect 200), not just the rejection path.
5. Tear down the old RG and GH environment.
Includes the rollback story (old tier intact through step 4) and
explains the AADSTS70021 trap (FIC subject is matched verbatim
against the GH OIDC token's 'sub' claim, so the order of step 3 vs
step 5 matters).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ce → orders-api/restaurants-api)
The README still mentioned the old monolith-decomposition app reg
names ('orderservice', 'restaurantservice') from the deleted
credential-patterns demo. The actual live app regs are
'orders-api' / 'restaurants-api' (and the BFF is 'apigateway',
not 'bff'). Reflect reality.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The auto-deployed first cloud tier was named
dev, which conflatedtwo things:
Azure resources,
dotnet run).human gate (an Azure RG, real cloud APIs, public ingress).
Calling them both "dev" hid what was actually running where. The honest
name for #2 is `ci` (built and deployed by CI, no human gate),
and #1 is its own first-class tier called `local` (no Azure, no
GH Environment, configured via `appsettings.Development.json` +
`dotnet user-secrets`).
Final ladder: `local → ci → ppe → prod`. `ppe` (Microsoft jargon
for "pre-production environment", analogous to "staging" elsewhere)
is unchanged.
What this PR does
Phase A — codebase rename (commit `dbd6537`):
Phase B — docs sweep (commit `cb6021e`):
Phase C — live cutover runbook (commit `6b39dfe`):
Plus (commit `f35c5d2`): README's stale references to the deleted
credential-patterns demo (`orderservice` / `restaurantservice`) are
updated to the live app reg names (`orders-api` / `restaurants-api`).
Live cutover not yet executed
The PR is codebase-only. Live Azure / GitHub changes (provisioning
`rg-ftgo-ci-eastus`, migrating `ENTRA_CONFIG_JSON` to a new `ci` GH
env, updating FIC subjects, tearing down `rg-ftgo-dev-eastus`) are
deferred to a one-shot operation following the runbook in this PR
(`docs/operations.md` → "Renaming a deployment tier" section). Until
that happens, the `dev` tier still works because:
deprecated alias and translate it to `ENV=ci` (with a stderr warning).
push trigger will fail to find the `ci` env after this PR merges
until the cutover runs — that's intentional, so the cutover is
done deliberately, not as a side-effect of merge.
Verification
Out of scope (deliberate)