Repository navigation
feat(ci): extract the global.json SDK resolution into actions/dotnet-sdk - #48
Merged
Merged
Conversation
actions/setup-dotnet's global-json-file input resolves the version itself and, when it cannot install it, falls back to the LTS channel and reports success. The job then fails at its first dotnet command with "A compatible .NET SDK was not found", several steps after the message that named the version. purview-build.yml already resolved the pin from global.json and installed an explicit version, but ci.yml and release.yml duplicated that script, and a consuming repository's own jobs had no way to get it at all: telemetry-sourcegenerator's four pr.yml jobs hand-rolled setup-dotnet with global-json-file and failed for exactly that reason. This is the one implementation, following the nuget-sources precedent: the reusable workflow calls it, ci.yml and release.yml dogfood it from ./actions, and a consuming job calls purview-dev/build/actions/dotnet-sdk@main.
kieronlanning
added a commit
to purview-dev/telemetry-sourcegenerator
that referenced
this pull request
Nov 11, 2026
Four jobs failed on PR #157 before running a single dotnet command: dependency-floor, samples, pack-validation and packed-consumers each installed the SDK with actions/setup-dotnet's global-json-file input, which resolved and installed LTS 10.0.404, reported success, and left the pinned 11.0.100 unmet. rollForward: latestMajor cannot help - it only rolls forward. purview-dev/build#48 extracted the resolution the reusable build workflow already did into actions/dotnet-sdk, so the same one line replaces the broken input in all four jobs. The build job was green throughout because it calls that workflow.
kieronlanning
added a commit
to purview-dev/telemetry-sourcegenerator
that referenced
this pull request
Nov 11, 2026
* feat: updated net 11 as the new base * feat: updated union support with tests * perf(benchmarks): consume both sides of a comparison through the interface MetricsBenchmarks and LoggerBenchmarks held the generated implementation as its interface and the hand-written baseline as its concrete type. At nanosecond scale that is not a fair pair: a concrete call is inlined into the measurement loop and an interface call is not, so the delta was dispatch reported as generator overhead. Every generated metrics row came out at a flat 1.3 ns whatever the instrument or tag count, and every disabled logging row at 1.13 ns against a 0.77 ns baseline. ManualMetricsTelemetry and ManualLoggerMessageTelemetry now implement the benchmark interfaces, the benchmark classes hold them as the interface, and the factories return them that way. The generated and hand-written rows then track each other: 1.29-1.31 ns against 1.28-1.34 ns for instruments on .NET 10.0, 1.11-1.13 ns for a disabled log call, within 3% on .NET Framework. The developer skill records the rule, so a new family does not reintroduce the asymmetry. * docs: refresh the performance tables from a fresh three-runtime run A full Release run of all seven benchmark classes on .NET 10, .NET 11 and .NET Framework 4.8 (198 benchmarks, no NA rows), plus a like-for-like re-run of MetricsBenchmarks and LoggerBenchmarks after their baselines were moved to the interface. docs/wiki/Performance.md carries the new environment header, a row per runtime and parameter in every family, a new "Generator model overhead" section for GeneratorModelBenchmarks, and rewritten interpretations. The stale caveats are gone: .NET 11 is measured, no .NET 8/9 rows are missing, and .NET Framework produced results. The raw-results link went with them, because BenchmarkDotNet.Artifacts is gitignored and the link to it never resolved. README.md keeps its .NET 10.0 digest and says the ratios compare against the hand-written implementation of the same scenario. The logging claims are the ones that moved: v1 is at parity rather than faster, and v2 is the fastest of the three on every runtime. The metrics table no longer implies generated code is 1.7x slower, because it was not. Platform-Support.md now cites the measured model comparison instead of saying the tables predate it. AGENTS.md records the three benchmark target frameworks. * ci: install the SDK from the shared actions/dotnet-sdk action Four jobs failed on PR #157 before running a single dotnet command: dependency-floor, samples, pack-validation and packed-consumers each installed the SDK with actions/setup-dotnet's global-json-file input, which resolved and installed LTS 10.0.404, reported success, and left the pinned 11.0.100 unmet. rollForward: latestMajor cannot help - it only rolls forward. purview-dev/build#48 extracted the resolution the reusable build workflow already did into actions/dotnet-sdk, so the same one line replaces the broken input in all four jobs. The build job was green throughout because it calls that workflow. * fix(build): drop dotnet-inspect from the tool manifest again The pack-validation job fails at `dotnet tool restore` with The command "purview-build" specified in the tool manifest file is not contained in the package with Package Id purview.build. The commands contained in the package are dotnet-inspect. That is 7427652's failure returning: 2f1c731 re-added the dotnet-inspect entry. The package is still a DotNetCliTool Version="2" with RuntimeIdentifierPackages, laid out under tools/any/any, and beside another tool NuGet validates the wrong package's commands on the Linux runner. It restores on Windows, which is why the local loop never saw it. Nothing in the repository runs the tool. Removed again, and ToolManifestTests now rejects it by name so it cannot come back a third time. AGENTS.md records the manifest rule: csharpier and purview.build, nothing RID-specific. Verified with an empty NUGET_PACKAGES folder and --no-cache: csharpier and purview.build restore, and the guard fails when the entry is put back. * ci: make the Native AOT prerequisite install survive a missing mirror The packed-consumers job failed twice in one afternoon at E: Failed to fetch https://security.ubuntu.com/.../clang_18.0-59~exp2_amd64.deb Temporary failure resolving 'azure.archive.ubuntu.com' Every other job in both runs was green, so this was the last red on PR #157. The mirror is the one the runner's /etc/apt/apt-mirrors.txt points at, and the failure is DNS, not a package problem: the apt call is the first thing the job does after the preflight, so nothing downstream of it had a chance to run. The step now probes with dpkg first - the ubuntu-latest image usually carries clang and zlib1g-dev, in which case no network is touched at all - and retries the install with backoff three times when it does not. * ci: stop the Native AOT prerequisites step hanging on a dead mirror The retry loop added in fadb8d2 made the failure worse: each apt call blocked on DNS for azure.archive.ubuntu.com for minutes, three attempts in a row, so the step ran 24 minutes and still failed. It is the only step in the job that needs the network, and the first after the preflight, so nothing downstream ran at all. The step now prefers what the image already has - a versioned clang-18 linked as clang when the unversioned name is missing, and /usr/include/zlib.h - and only touches apt when a package really is absent, with -o Acquire::Retries=0, 15s fetch timeouts, timeout(1) around each call and a 5 minute step timeout. A dead mirror now costs seconds instead of half an hour. If the image has neither a clang nor the headers, the next suspect is the runner label: the run warns that ubuntu-latest migrated to Ubuntu 26 on 2026-10-19, and the mirror this job fails to reach is the one that image's apt-mirrors.txt points at.
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
actions/setup-dotnet'sglobal-json-fileinput resolves the version itself, and when it cannot install that version it falls back to the LTS channel, reports success, and leaves the job to fail at its firstdotnetcommand:purview-build.ymlalready avoided that by resolving.sdk.versionfromglobal.jsonand installing an explicit version — butci.ymlandrelease.ymlcarried their own copies of the script, and a consuming repository's own jobs had no way to reach it at all.purview-dev/telemetry-sourcegeneratorPR #157 is the proof: its reusable-workflowbuildjob is green, and its four hand-rolledpr.ymljobs all fail with the message above.What
actions/dotnet-sdkis now the one implementation, following thenuget-sourcesprecedent:sdk.versionfrom the caller'sglobal.jsonand installs exactly thatdotnet-versioninput (default10.0.x) only whenglobal.jsonpins nothingdotnet-versionoutputpermissions:block, novars/secretscontext, soWorkflowParityTestsstill passesCallers:
.github/workflows/purview-build.ymlpurview-dev/build/actions/dotnet-sdk@main, passing the workflow'sdotnet-versioninputci.yml(×2),release.yml./actions/dotnet-sdk— dogfooded from the working tree, asnuget-sourcesalready isThe three duplicated resolve scripts are gone: −107/+31 lines across the workflows.
Validation
just lint-check(CSharpier + actionlint) — cleanjust test— 1100 passed, 0 failed (184 + 898 + 18 across the three suites)Follow-up
purview-dev/telemetry-sourcegeneratorpr.ymlwill switch its four jobs (dependency-floor,samples,pack-validation,packed-consumers) topurview-dev/build/actions/dotnet-sdk@mainonce this is onmain.