Skip to content

fix(release): build the CLI against this tree, not the last published root - #48

Merged
juicycleff merged 2 commits into
mainfrom
fix/release-cli-module-resolution
Aug 7, 2026
Merged

fix(release): build the CLI against this tree, not the last published root#48
juicycleff merged 2 commits into
mainfrom
fix/release-cli-module-resolution

Conversation

@juicycleff

Copy link
Copy Markdown
Contributor

The failure

The release job died in goreleaser after 5m53s:

plugins/client_diff.go:71:19: undefined: client.DiffSpecs
plugins/client.go:401:23:     undefined: client.PathFilter
plugins/client.go:438:3:      unknown field ReactQuery in struct literal of type client.GeneratorConfig

Why

Nothing had regressed. builds.dir is ./cmd/forge, a separate module pinning github.com/xraph/forge v1.8.2 — its go.mod must stay free of replace directives for go install ...@latest to accept it. With no workspace, goreleaser compiled the CLI against the published root module rather than the tag being released, so every root API added since v1.8.2 came back undefined.

go.yml's "Build CLI" job already solved this with a throwaway workspace. That is exactly why CI stayed green while the release broke — the two jobs built the CLI differently.

Pinning forward doesn't help: internal/client/filter.go (82cdebcc, Aug 3) and internal/client/diff.go (8bc90574, Aug 4) both postdate v1.9.2, the newest published root tag. Measured — against v1.9.2 the PathFilter errors clear and client_diff.go still doesn't build.

The change

The real release job is a reusable workflow in xraph/workflows, so a step can't be added to it. .goreleaser.yml is in this repo and already had a before: hooks: block, so the workspace goes there as the first hook — the existing go mod tidy hooks resolve modules too. That covers the real release and the dry run alike, with no cross-repo change and no new tag.

GOWORK is pinned to $PWD because a bare go work init searches upward and refuses when the checkout sits inside another workspace.

The dry-run job's Validate module builds step had the identical hole (for a CLI release module_path is cmd/forge) and would have reported a break the release no longer has. Same treatment, scoped by module path: the workfile stays outside the repo, and everything other than cmd/forge and extensions/database still builds with GOWORK=off so each module is checked standalone — following the rationale already documented in go.yml.

Verification

Run locally with real goreleaser:

  • Before: goreleaser build --snapshot reproduces the failure exactly — same symbols, same targets.
  • After: all five targets build, including the three from the failed run (linux_amd64_v1, windows_amd64_v1, darwin_arm64_v8.0). Binary runs.
  • Hooks leave no tracked file modified; go.work stays gitignored.
  • All three case branches exercised with real builds: cmd/forge, extensions/database, root, and an extension.
  • Both YAML files parse. Three Go modules build and test clean, 0 failures. gofmt -l internal/client internal/router internal/shared cmd *.go prints nothing.

Out of scope

This does not fix go install github.com/xraph/forge/cmd/forge@latest for users, who have no workspace and still resolve the published root module. That needs a root tag cut at or after 8bc90574, then cmd/forge/go.mod pinned to it — a release-ordering change rather than a build one.

🤖 Generated with Claude Code

… root

goreleaser builds `dir: ./cmd/forge`, which is a separate module pinning
github.com/xraph/forge v1.8.2 -- its go.mod must stay free of replace
directives for `go install ...@latest` to accept it. With no workspace it
therefore compiled the CLI against the *released* root module rather than the
tag being released, so every root API added since v1.8.2 failed as "undefined":

    plugins/client_diff.go:71:19: undefined: client.DiffSpecs
    plugins/client.go:401:23:     undefined: client.PathFilter
    plugins/client.go:438:3:      unknown field ReactQuery in GeneratorConfig

Nothing had regressed. internal/client/filter.go (82cdebc, Aug 3) and
internal/client/diff.go (8bc9057, Aug 4) both postdate v1.9.2, the newest
published root tag, so no released version carries them -- pinning forward does
not help either, and was measured: against v1.9.2 the PathFilter errors clear
and client_diff.go still does not build.

go.yml's "Build CLI" job already solved this with a throwaway workspace, which
is exactly why CI stayed green while the release broke -- the two jobs built the
CLI differently. This moves the same workspace to where the release can see it,
as .goreleaser.yml's first before-hook, so it applies to the real release and
the dry run alike without touching the reusable workflow in xraph/workflows.

GOWORK is pinned to $PWD because a bare `go work init` searches upward and
refuses when the checkout sits inside another workspace.

The dry-run job's "Validate module builds" step had the identical hole and would
have reported a break the release no longer has, so it gets the same treatment,
scoped by module path: the workfile stays outside the repo and everything other
than cmd/forge and extensions/database still builds with GOWORK=off, so each
module is checked standalone.

Verified with goreleaser locally: the failure reproduces exactly before the
change, and after it all five targets build -- including the three from the
failed run (linux_amd64_v1, windows_amd64_v1, darwin_arm64_v8.0). The hooks
leave no tracked file modified and go.work stays gitignored.

Does NOT fix `go install github.com/xraph/forge/cmd/forge@latest` for users,
who have no workspace. That needs a root tag cut at or after 8bc9057 and
cmd/forge/go.mod pinned to it -- a release-ordering change, not a build one.
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
forge Ready Ready Preview Aug 7, 2026 4:11am

Request Review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Conventional Commits Validation

PR Title: valid
Commits: all 1 follow conventional format

A release run failed before it built anything:

    git tag extensions/ai/v1.9.3 was not made against commit d07b870

This repository tags far more than the CLI -- every extension carries
`extensions/<name>/vX.Y.Z` and the editor plugin carries `vscode-forge/vX.Y.Z`.
GoReleaser takes the newest tag in the repo as "the release", so it picked up
whichever extension was tagged last and then refused, because that tag belongs
to a different commit than the one being released.

`git.ignore_tags` restricts the search to the CLI's own `vX.Y.Z` tags. Verified:
before, tag selection resolved to `current=extensions/ai/v1.9.3`; after, to
`current=v1.9.3`, and the snapshot version stamps as `1.9.3-SNAPSHOT-...`
instead of `extensions/ai/v1.9.3-SNAPSHOT-...`.

Worth noting why this survived review: snapshot builds disable tag validation,
so `goreleaser build --snapshot` reports the wrong tag as a skipped-pipe notice
and carries on. Only a real release treats it as fatal.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Conventional Commits Validation

PR Title: valid
Commits: all 2 follow conventional format

@github-actions github-actions Bot added fix and removed fix labels Aug 7, 2026
@juicycleff
juicycleff merged commit b72ad0c into main Aug 7, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant