Skip to content

ci: read the provider's drift paths from its build graph - #306

Merged
rldyourmnd merged 3 commits into
mainfrom
fix/provider-drift-follows-the-dependency-graph
Aug 31, 2026
Merged

ci: read the provider's drift paths from its build graph#306
rldyourmnd merged 3 commits into
mainfrom
fix/provider-drift-follows-the-dependency-graph

Conversation

@rldyourmnd

Copy link
Copy Markdown
Contributor

config/provider-derivative.yaml promises that binary_sha256 is what this tree builds, and two jobs enforce it — one decides whether the provider changed at all, the other refuses a release whose source commit no longer matches HEAD. Both asked a hand-written list of directories.

That list named eight packages. go list -deps ./cmd/garm-provider-incus-nddev reports eighteen. Missing, among others:

internal/cachebroker      internal/queueintent
internal/telemetryattrs   internal/fleettrace
internal/admission        internal/tenant
internal/pressuregate     internal/hostprobe
internal/incuspolicy      internal/workerdiagnostics

Both cachebroker and queueintent are real provider dependencies, so a change to either skipped the reproducible-build job entirely and shipped under a manifest digest that no longer described main. That is how v0.1.5-nddev.95 came to be stamped against a commit whose provider bytes main no longer produces — building the released source gives f7a76eaf…, building main gives ba2df150…, and nothing said so. I found it by building the release locally before deploying it.

The fix. scripts/provider-package-directories.sh reads the set from the same graph the compiler walks, so it cannot fall behind a new import. Both jobs consume it. A _test.go file is still ignored; go.mod/go.sum still count.

The contract test was part of the problem. It asserted that five path strings appeared somewhere in ci.yml — which stayed green the whole time the list was missing ten packages. It now runs the same script and asserts the boundary itself: every package the binary links, never the observer-only internal/providerretry. A second test holds the workflow to actually consulting it, since a boundary nothing reads classifies every change as provider=false.

v0.1.5-nddev.96 stamps main, so the deployed provider matches a manifest again.

config/provider-derivative.yaml promises that binary_sha256 is what this
tree builds, and two jobs enforce it: one decides whether the provider
changed at all, the other refuses a release whose source commit no longer
matches HEAD. Both asked a hand-written list of directories.

That list named eight packages. `go list -deps ./cmd/garm-provider-incus-nddev`
reports eighteen. internal/cachebroker and internal/queueintent are both
real provider dependencies and both absent, so a change to either skipped
the reproducible-build job entirely and shipped under a manifest digest
that no longer described main. It is how v0.1.5-nddev.95 came to be
stamped against a commit whose provider bytes main no longer produces:
building the released source gives f7a76eaf, building main gives ba2df150.

scripts/provider-package-directories.sh reads the set from the same graph
the compiler walks, so it cannot fall behind a new import. Both jobs use
it. A test file is still ignored; go.mod and go.sum still count.
v0.1.5-nddev.95 is stamped against 541be59, whose provider bytes main no
longer produces: the log-injection fix that followed it changed
internal/cachebroker, a real provider dependency that the old drift list
did not name. Building the released source gives f7a76eaf; building main
gives ba2df150, and no gate said so.

This release stamps main. The drift gate in the preceding commit now reads
its path set from `go list -deps`, so the next one cannot slip the same way.
TestProviderDerivativeExcludesObserverOnlyRetryReader checked that five
path strings appeared somewhere in ci.yml. That passed for as long as the
list named eight of the provider's eighteen packages, which is how a
change to internal/cachebroker reached a release unnoticed.

It now runs the same script CI runs and asserts what the boundary must
contain and must not: every package the binary links, including
cachebroker and queueintent, and never the observer-only providerretry.
A second test holds the workflow to actually consulting it, because a
boundary nothing reads classifies every change as provider=false.
@rldyourmnd
rldyourmnd merged commit aeadfd5 into main Aug 31, 2026
10 checks passed
@rldyourmnd
rldyourmnd deleted the fix/provider-drift-follows-the-dependency-graph branch August 31, 2026 03:43
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