Speed up CI and format and lint CLI commands#895
Open
tjementum wants to merge 10 commits into
Open
Conversation
0440bae to
1da4403
Compare
0440bae to
acacc4b
Compare
acacc4b to
69d9c50
Compare
131e4f6 to
0592515
Compare
0592515 to
719edf2
Compare
e9be7c9 to
eeda671
Compare
…w with scope detection
5633dc6 to
cb4a829
Compare
31d3be9 to
f80592d
Compare
f80592d to
9587ec5
Compare
|
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 & Motivation
Three coordinated changes that cut CI critical path roughly in half and speed up local format and lint runs.
Test infrastructure
BackOfficeEndpointBaseTestandEndpointBaseTest<TContext>each constructed a freshWebApplicationFactory<Program>per test instance. Combined withMeziantou.Xunit.ParallelTestFramework, every account-API test booted a complete ASP.NET Core host: full DI container, all singletons, test server. With 27 BackOffice classes and ~60 Account API classes, every CI run paid hundreds of cold-starts, and the cost grew with every test added.Both test bases now share one host per test class via xUnit's
IClassFixture<...>:BackOfficeWebApplicationFactory+BackOfficeTestContextroute per-test state (SqliteConnection, telemetry collector, MockStripeState) through anAsyncLocal. 26 derived test classes use the fixture via primary constructor +IClassFixture<BackOfficeWebApplicationFactory>.BackOfficeBlobProxyTestscarries a derived factory to keep itsIBlobStorageClientsubstitute.AccountWebApplicationFactory+AccountTestContextmirror the same pattern (adds per-testIEmailClientrouting). 60 derived test classes converted.CompleteEmailSignupTestscarries a derived factory for its logger override.MockStripeStateis re-registered as transient in the test host so per-request resolution reads the per-test instance from the accessor.TestServer.PreserveExecutionContextenabled so the AsyncLocal flows from the calling test into request handling.Single Code Style workflow
A new
code-style.ymlreplaces the per-SCS code-style work inaccount.yml,main.yml,app-gateway.yml. One workflow, four jobs:detect-scope— small first job that classifies the diff and outputs the backend scope and format mode for the downstream jobs (inlinegit diff, no third-party action).code-linting— backend inspectcode + frontend build + frontend lint (oxlint).code-formatting— backend cleanupcode + frontend format check (oxfmt).sonarcloud— runs once per push againstapplication/PlatformPlatform.slnx(was previously running three times per push, once per SCS).Backend lint and format are scoped to a single SCS via
--self-contained-system <name>when the diff touches only that SCS; cross-cutting changes (shared-kernel, AppGateway, multi-SCS) fall back to the full solution.Faster format and lint
formatcommand defaults to changed-only. Cleanupcode runs against.csfiles diffed vsorigin/main; explicit--all-filesfor full sweep. CI auto-flips to--all-fileswhenapplication/dotnet-tools.jsonchanges (JetBrains tool upgrades reset the format ruleset, so accumulated drift in untouched files needs a full pass).lint --changed-onlyflag is opt-in (default = full). Recommended for routine local runs; CI always lints the full solution because inspectcode has cross-file rules. The lint skill documents when to omit--changed-only(cross-cutting changes that affect untouched files)..slnffrom each.slnxto feedcleanupcode— JetBrains 2026.1 accepts.slnxdirectly.Database Plan reuses Build and Test artifacts
build-and-testuploadsapplication/**/binandapplication/**/objas a<scs>-buildartifact (only when staging is enabled)._migrate-database.ymldownloads it intoapplication/and runsdotnet restorefor the NuGet cache, skipping the redundant checkout + setup +dotnet buildchain.CI benchmark
Comparing real PR-sync workflow durations on a comparable sister branch (PR #888, n=8 per workflow) against this branch (n=3 per workflow, mean):
The AppGateway delta is large because
code-lintingandcode-formattingwere removed fromapp-gateway.ymlentirely — they live in the consolidatedcode-style.ymlnow. AppGateway PR runs are just build + test.Note for downstream projects
Downstream projects with a substantial Main SCS will see a bigger lift than this benchmark suggests. The slowest single CI step used to be backend
cleanupcode; it now only inspects changed.csfiles. Evidence: Main and Account workflows now sit at roughly the same wall-clock (5m47s vs 6m16s) even though Account has materially more code than Main. The fixed-cost setup (npm + dotnet restore + build) dominates once the format pass is changed-only, so SCS size matters less than it used to.Test-step benchmark (isolated)
To isolate the impact of the test-host refactor alone, I temporarily disabled the Code Style and Database Staging jobs and measured just
Run Tests with SonarScanner Analysis(5 samples per side):Δ −37% on the test step alone, and stddev more than halves — the runs are markedly more stable too.
Checklist