ci: path-scoped deployments gated on the full test suite - #63
Merged
Conversation
Adds deploy-api.yml and deploy-web.yml, each triggered by an allowlist of paths rather than paths-ignore, so scope is explicit: src/tests/solution files deploy the API, web/** deploys the SPA, and a docs or markdown change matches neither and deploys nothing. Both call a new reusable test-suite.yml and declare needs: tests, so nothing reaches Azure unless backend units, frontend units and the end-to-end smoke test all pass for that exact commit. The suite lives in one file so the two deploys cannot drift on what 'tests passed' means. The web deploy is gated on the smoke test too — a SPA is useless against a broken API. The API job publishes Release to a directory outside the workspace and audits it before deploying: any .cs, .csproj, .sln, .env, compose file, or .git/node_modules/src/web/tests/docs directory fails the run, and the app dll and appsettings.json must be present. It then polls /health and stops the web app on a 503, because a crash-looping F1 app silently consumes the 60 CPU-minutes/day allowance. Azure auth is OIDC — id-token: write and no stored credential. Every action is pinned to a full commit SHA, each verified to exist against the GitHub API; one I had written from memory was wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Everyone now lands on a guide at / and the store moves to /store. A working storefront is confusing without knowing it is a demo, that nothing can charge you, and which account to use, so the guide answers those first and links into the store from several places. The guide leads with the payments question because it is the one that decides whether a visitor trusts the site: checkout runs a mock gateway, no card details are collected, no processor is contacted, and a Stripe configuration is restricted to test mode. Three roles existed but only two were seeded, so nothing demonstrated what ManageCatalog actually buys you. DbSeeder now creates a Manager as well, and the guide spells out for each role what it can and cannot do — the interesting line being that a Manager may restock and hide a widget but not retire one. Staff could not find an order at all: admin had only lookup-by-GUID, and nobody has a GUID to hand. Adds GET /admin/orders with a recent-orders list, and rebuilds the admin page around selecting from it. The item rows are loaded rather than skipped — OrderSummary derives its item count from them, and an initial optimisation reported every order as empty. Receipts work on the free tier without a mail server: the hosted demo writes email to the log, so the order detail page carries the same line items, totals, payment and tracking, and now prints as a receipt. The print stylesheet drops the chrome and collapses the columns. Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.
Adds the two deployment workflows and the reusable test gate.
Scope is explicit, not inferred
Both deploy workflows trigger on a
pathsallowlist rather thanpaths-ignore:src/**,tests/**, solution files,Dockerfile.apiweb/**docs/**, any*.mdNothing deploys unless every test passes
Both call the new reusable
test-suite.ymland declareneeds: tests, so a deployment cannotstart unless backend units, frontend units and the end-to-end smoke test all pass for that
exact commit. Keeping the suite in one file stops the two deploys drifting on what "tests passed"
means. The web deploy is gated on the smoke test too — a SPA is useless against a broken API.
Deployment safety
.cs,.csproj,.sln,.env, compose file, or.git/node_modules/src/web/tests/docsdirectory fails the run. Deploying the repo would serve source and git history from
wwwroot.appsettings.jsonare present before shipping./healthafter deploying and stops the web app on a 503 — a crash-looping F1 appsilently consumes the 60 CPU-minutes/day allowance.
Credentials
Azure auth is OIDC (
id-token: write), so no Azure credential is stored in GitHub. Everyaction is pinned to a full commit SHA, each verified to exist against the GitHub API — one I had
written from memory turned out to be wrong.
Requires these repo settings before the first run: secrets
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_SUBSCRIPTION_ID,AZURE_STATIC_WEB_APPS_API_TOKEN; variablesVITE_API_BASE_URL,VITE_GOOGLE_CLIENT_ID.🤖 Generated with Claude Code