feat(cli) add --ensure-cosmos-containers post-deploy smoke-test#57
Merged
Conversation
Adds a CLI flag that resolves CosmosBootstrapper from DI and runs EnsureCreatedAsync: creates the configured database + every container in CosmosOptions.Containers if missing, asserts existing partition-key paths match. Idempotent. Useful as the canonical post-deploy smoke-test that the configured Cosmos endpoint + Managed Identity / Aspire connection string actually work end-to-end. Before this flag, --status was the closest available smoke-test in the playbook, but --status reads only the local file catalog and does NOT exercise Cosmos at all — so a Cosmos misconfig would surface only at first --source opdb attempt (which requires an OPDB API token). Returns exit code 2 with a clear remediation message when Cosmos is not configured (CosmosBootstrapper is only DI-registered when AddCosmosPersistence was wired). Also: CosmosOptions.Containers default flips from [] to the canonical Phase 1 list per ADR 0011 — machines (PK /manufacturer) and ingestion_sources (PK /partitionKey). Matches the container names the existing MachineRepository and IngestionSourceRepository registrations already reference; previously the bootstrapper would no-op without an appsettings.json Cosmos:Containers entry. +5 tests in CosmosOptionsTests pinning the defaults so a future drift between the options list and the repository hardcoded names trips a test. Tests: 496 -> 501. Build clean, zero warnings. README + session-handoff Step 7 updated to use the new flag for the post-deploy smoke-test. Pre-push self-audit: 7-item mechanical (all pass). /local-review skipped — single-flag addition with the dispatch mirroring the existing --install-playwright early-exit pattern; the new CosmosOptions defaults are pinned by behavior tests.
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.
Summary
Adds a CLI flag that runs
CosmosBootstrapper.EnsureCreatedAsyncagainst the configured Cosmos account — creates thepinwizdatabase + the configured containers if missing, asserts existing partition-key paths match (drift throws). Idempotent. Returns exit code 2 with a clear remediation message when Cosmos isn't configured (the bootstrapper is only DI-registered whenAddCosmosPersistencewas wired).Why this exists: before this flag, the closest "is Cosmos working?" smoke-test was
--status, but--statusreads only the local file catalog and does NOT exercise Cosmos at all. A Cosmos misconfig would surface only on first--source opdbattempt (which requires an OPDB API token to even reach the Cosmos write path).Also:
CosmosOptions.Containersdefault flips from[]to the canonical Phase 1 list per ADR 0011 —machines(PK/manufacturer) andingestion_sources(PK/partitionKey). Matches the container names the existingMachineRepository/IngestionSourceRepositoryregistrations already reference; previously the bootstrapper would no-op without an explicitappsettings.jsonCosmos:Containersentry..gitignoregainsinfra/*.jsonto prevent future accidental commits ofaz bicep buildartifacts (caught one in this branch and removed it before push).Test Plan
dotnet build PinballWizard.slnx-> 7 / 7 projects, 0 warnings, 0 errorsdotnet test PinballWizard.slnx-> 501 / 501 passing (was 496 — +5 inCosmosOptionsTestspinning the canonical defaults)pwsh ./infra/scripts/Deploy-SharedResources.ps1 -Environment devthen$env:Cosmos__AccountEndpoint = "<endpoint>" ; dotnet run --project src/PinballWizard.Cli -- --ensure-cosmos-containers-> expects"Cosmos database + containers ensured."and thepinwizdatabase + 2 containers visible in the Azure portalOut of Scope
CosmosOptions.Containersdefaults and the hardcoded"machines"/"ingestion_sources"strings inPersistence/Cosmos/ServiceCollectionExtensions.cs. Future small PR — pull the names into constants onCosmosOptionsso the repository registrations reference them too.EnsureCreatedAsyncautomatically at startup. Considered; rejected in favor of an explicit flag so--scrape-only --source jjpdoesn't fail at startup if Cosmos is mis-configured (and so the smoke-test is a deliberate operator action, not a side effect of every CLI run).Checklist
README.mdis updated ->--ensure-cosmos-containersrow added to the CLI Flags table; the session-handoff playbook Step 7 updated to use the new flag instead of--statusfor the post-deploy smoke-testTODO/FIXME/ commented-out code committedPre-push self-audit
Step 0 —
/local-review(qualitative)--install-playwrightearly-exit pattern; the newCosmosOptionsdefaults are pinned by 5 behavior tests; no architectural surface added.Step 1 — Mechanical checklist
*Optionsproperty has at least one real getter call insrc/—CosmosOptions.Containersis read byCosmosBootstrapper.EnsureCreatedAsync(lines 52-55)--install-playwrightearly-exit pattern (Program.cs:103); error path matches--source opdbexit-code-2 pattern (Program.cs:130-134)catch { }— N/A (no catch added)ISourceScraper? — N/A (the flag is a host-resolved bootstrap call, not a scraper)CosmosOptionsagainst ADR 0011git log -1 --format='%an <%ae>'shows personal noreply, not work email