build: decouple the Go modules with a workspace so Dependabot PRs stay green - #213
Merged
Merged
Conversation
…y green `remote-worker` consumes `gen/go` through a local `replace`, and the `proto` job builds both modules. Dependabot opens one PR per `go.mod`, so any bump to a `gen/go` dependency left `remote-worker/go.mod` pinning stale indirect versions and CI failed with `go: updates to go.mod needed`. Dependabot cannot fix that itself -- the tidy has to land in the same commit as the bump, and its branches are not maintainer-writable -- so rossoctl#210 had to be bundled by hand into rossoctl#211. Add a root `go.work` covering both modules. In workspace mode the go command resolves one MVS across them, so a stale consumer `go.mod` no longer breaks the build and the two modules can be bumped independently. Verified against the tree that failed in rossoctl#210 (`gen/go` bumped, `remote-worker` left at the pre-rossoctl#211 state): `go vet` and `go test -race` went from `updates to go.mod needed` to passing, with `gen/go` build and tests unaffected. `directories:` (plural) is a shorthand here, not the fix: Dependabot still opens one PR per directory. Bundling would need `group-by: dependency-name`, which is version-updates-only and splits one PR per dependency, so it would leave the security bumps this entry exists for unbundled. It collapses a duplicated `grpc-protobuf` group block, nothing more. `go mod tidy -diff` still reports drift in workspace mode, so it runs as an advisory step. Failing on it would put the coupled bumps back in the red, and neither module is consumed externally -- `gen/go` is reached only through the local `replace` -- so per-module tidiness is hygiene, not correctness. A module left out of the workspace would silently reintroduce the failure, so a blocking step checks every tracked `go.mod` is listed in `go.work`. `remote-worker/Dockerfile` builds from the repo root and now copies `go.work`; without it that build resolves each module alone and would still hit a stale `go.mod`. Closes rossoctl#212 Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
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
remote-workerconsumesgen/gothrough a localreplace, and theprotojob buildsboth modules. Dependabot opens one PR per
go.mod, so any bump to agen/godependencyleft
remote-worker/go.modpinning stale indirect versions and CI failed withgo: updates to go.mod needed. Dependabot cannot fix that itself — the tidy has to landin the same commit as the bump, and its branches are not maintainer-writable — so #210 had
to be bundled by hand into #211.
This adds a root
go.workcovering both modules. In workspace mode the go commandresolves one MVS across them, so a stale consumer
go.modno longer breaks the build andthe modules can be bumped independently, whatever layout Dependabot chooses.
Verification
Reconstructed the tree that failed in #210 —
gen/goat grpc 1.83.2 / protobuf 1.36.12,remote-worker/{go.mod,go.sum}restored to the pre-#211 commitb1af7bb— and ran theprotojob steps against it, before and after:remote-worker/go.mod)cd gen/go && go build ./... && go test ./...cd remote-worker && go vet ./...updates to go.mod neededcd remote-worker && go test -race ./...cd remote-worker && go mod tidy -diffAlso verified on a clean tree: every step green, both modules tidy. The workspace-coverage
guard was tested both ways — passes as-is, and fails when a
go.modis not ingo.work.Why not the
directories:fix from the issuePlural
directories:is a shorthand here, not the fix — Dependabot still opens one PR perdirectory. Bundling needs
groups.<name>.group-by: dependency-name, which per theoptions reference
"[a]pplies to version updates only" and creates "a single pull request for each
dependency". That would leave the security bumps this entry exists for (cf.
CVE-2026-84304 in #203) unbundled, and would split the deliberate
grpc-protobufcohort.Separately,
remote-workercarries protobuf as// indirect, which Dependabot's defaultallowskips entirely. The config change here only collapses a duplicated group block.A CI step that tidies and commits back to Dependabot's branch was also considered and
dropped:
GITHUB_TOKENis read-only on Dependabotpull_requestevents, so it needs a PATwith write access triggered by dependency-PR content — a poor trade for a repo that pins
every action by digest and runs Scorecard.
Changes
go.work— pinnedgo 1.25.0to match both modules and CI'sgo-version-file(
go work initwrites the local toolchain instead)..gitignore—go.work.sum; the checksum database still verifies downloads, so thisavoids a fourth sum file to keep in sync.
ci.yml— blocking check that every trackedgo.modis listed ingo.work(a moduleleft out would silently reintroduce the failure), plus an advisory
go mod tidy -diff.Failing on tidiness would put the coupled bumps back in the red, and neither module is
consumed externally, so it is hygiene rather than correctness.
remote-worker/Dockerfile— copiesgo.work; that build runs from the repo root andwould otherwise resolve each module alone and still hit a stale
go.mod. Not built in CI(
build.yamlcovers the rootDockerfile,sandbox.Dockerfile,echo-target), so thiswas latent rather than breaking.
No dependency versions change, so there is no new CVE surface.
Closes #212
Assisted-By: Claude Code