Skip to content

ci: land the SHA pins, Dependabot and the consumer smoke test on main (recovers #5, #9) - #13

Merged
CaffeinatedCoder merged 5 commits into
mainfrom
recover/pins-dependabot-smoke-test
Aug 16, 2026
Merged

CaffeinatedCoder merged 5 commits into
mainfrom
recover/pins-dependabot-smoke-test

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Why

#5 (SHA-pinned actions + Dependabot) and #9 (consumer smoke test) were stacked PRs. They were merged into their base branches seconds after those bases had already been merged to main, so their content never reached main — main today has no .github/dependabot.yml, no test/consumer-smoke-test.sh, and the actions are still tag-pinned. My stacking set that trap; this lands the content.

What

origin/main + the orphaned ci/pin-actions-dependabot branch (which contains #5 and #9), one conflict resolved in CLAUDE.md (the conventions-project bullet #6 reworded, with the smoke-test bullet #9 added after it). Everything else merged cleanly. Nothing new beyond what #5 and #9 already described and verified:

  • every uses: SHA-pinned with the exact tag in a trailing comment; .github/dependabot.yml (actions weekly, nuget monthly on test/*, EF/Npgsql ignored);
  • test/consumer-smoke-test.sh + the Consumer smoke test job on PRs and the pre-built-feed step in Pack and in the release gate.

actionlint clean; conventions suite green. Once merged, Consumer smoke test is a candidate required check.

🤖 Generated with Claude Code

CaffeinatedCoder and others added 5 commits August 16, 2026 13:20
Every action in both workflows was referenced by major tag. A tag can be
moved to a different commit — that is how the tj-actions/changed-files
compromise (March 2025) reached every workflow that trusted `@v45` — and
NuGet/login runs in the one job that can mint a publishing token. Each
reference is now the commit SHA of the current release, with the exact tag
in a trailing comment (checkout v6.1.0, setup-dotnet v5.4.0, upload-artifact
v6.0.0, download-artifact v7.0.0, NuGet/login v1.2.0), which is what
Dependabot reads to propose an update.

.github/dependabot.yml keeps the pins current: github-actions weekly, one
grouped PR. It also covers the test projects' NuGet references monthly, and
deliberately not src/ — the provider and NodaTime references there are the
floors consumers restore against, and raising one is a release decision.
The test projects' EF Core and Npgsql references track those floors and are
ignored for the same reason. Security advisories still surface for
everything through Dependabot security updates and NuGetAudit.

Verified: SHAs resolved from each repository's peeled tag refs; actionlint
clean on both workflows; dependabot.yml parses; the conventions suite passes.

Co-Authored-By: Claude Fable 5 <[email protected]>
Every layer of the suite references the projects directly. A
ProjectReference hides exactly what breaks for a consumer of the package:
a satellite whose nuspec fails to declare the core package, a version
range that lets NuGet resolve a different core than the one built here, a
type public in the project and missing from the package, a plugin that
registers through a project reference and not through the assembly a
consumer restores. Each packs cleanly and restores cleanly, and the first
person to notice is a consumer.

test/consumer-smoke-test.sh packs the four packages, restores them into
throwaway projects created outside the repository — inside it,
Directory.Build.props would apply and they would stop resembling anything
a consumer builds — compiles real code against them, runs it, and asserts
on what it prints and on the SQL the EF plugins translate. Never on the
exit code alone. Two consumers: core only (parse, algebra, JSON round
trip, value set canonical form), and the NodaTime EF satellite, which
pulls all four through the nuspec chain — the chain itself is asserted
from `dotnet list package --include-transitive`, each id at this version —
and translates a BCL range, a NodaTime range and a value set predicate to
SQL through ToQueryString, which never connects.

Two things carried over from the sibling repository because they were
learned the hard way there: NUGET_PACKAGES redirected to a private folder,
since NuGet resolves id+version from the global cache before any source
and a locally built package is otherwise shadowed by whatever build of
that version was restored before; and package source mapping in the
generated nuget.config, so this repository's ids come from the local feed
only and everything else from nuget.org — restricting the whole restore
to the local feed fails with NU1101 on the transitive dependencies.

Wired into both workflows in both invocation modes: a `consumer` job on
every PR that packs its own feed, and a step in the pack job and in the
release gate that is handed the pre-built dist — the artifacts published
are the artifacts tested. The script builds before it packs, so it works
whether or not GeneratePackageOnBuild is set.

Verified: passes in both modes locally. Sabotaging the mechanism — the
NodaTime satellite no longer calling UseValueRanges() — fails the run.
actionlint clean.

Co-Authored-By: Claude Fable 5 <[email protected]>
test: add a consumer smoke test that exercises delivery, not code
…recover/pins-dependabot-smoke-test

# Conflicts:
#	CLAUDE.md
@CaffeinatedCoder
CaffeinatedCoder merged commit d1340cc into main Aug 16, 2026
8 checks passed
@CaffeinatedCoder

Copy link
Copy Markdown
Owner Author

Added one commit: Dependabot ignores semver-major action bumps (same rule as EFCore.ComplexIndexes #25 — Dependabot's first PR there proposed download-artifact v8, which stops auto-unzipping and would break the publish job's dist/*.nupkg glob), and release.yml now carries the note explaining why the artifact actions stay on v6/v7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant