Skip to content

feat(go)!: publish the wrapper as moq.dev/moq - #2957

Merged
kixelated merged 2 commits into
devfrom
claude/go-vanity-module-path
Aug 20, 2026
Merged

feat(go)!: publish the wrapper as moq.dev/moq#2957
kixelated merged 2 commits into
devfrom
claude/go-vanity-module-path

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

The Go modules were named after the mirror repos they happen to be published from, so the ergonomic wrapper imported as github.com/moq-dev/moq-go/moq and the raw bindings as github.com/moq-dev/moq-go-ffi/moq. Both now use vanity paths that moq.dev owns:

Import path Mirror
moq.dev/moq github.com/moq-dev/moq-go
moq.dev/moq-ffi github.com/moq-dev/moq-go-ffi

moq.dev serves the go-import meta tag the go command reads to find the repo (moq.dev#126, already deployed), so the import path is no longer hostage to a repo name. Renaming or relocating a mirror now costs a line in a table on the site instead of a breaking change for every consumer.

import "moq.dev/moq"   // was: "github.com/moq-dev/moq-go/moq"

The package moved to its module root

go/wrapper/moq/*.go is now go/wrapper/*.go. That is what makes the import path end in the package name: Go binds the identifier from the package clause, but tooling adds an explicit alias whenever it disagrees with the last path element, which moq-go did. At the module root, import "moq.dev/moq" binds moq with nothing added. package-wrapper.sh stages the sources flat to match.

The bindings keep their moq/ subdirectory (moq.dev/moq-ffi/moq). That path already ends in moq, the generator emits into that layout, and every caller aliases it to ffi regardless.

Breaking

Consumers must change their imports. go get github.com/moq-dev/moq-go@latest will fail with a module-path mismatch rather than a friendly deprecation, because both paths resolve to the same mirror repo and its newest tag now declares the new path. Versions already pinned to the old path keep resolving; only @latest and fresh installs break. There is no way to soften this while the two paths share one repo's tags, and per CLAUDE.md's deprecation rule the dead name stays out of /doc rather than being advertised there.

VERSION goes 0.5 -> 0.6, so the next release is v0.6.0 (publish-wrapper.sh derives the patch from existing v0.6.* tags, of which there are none).

Testing

just fix, just check, and just test all pass. just go check builds moq-ffi, regenerates the bindings with uniffi-bindgen-go, stages both modules, and reports ok moq.dev/moq from the staged tree, which confirms the package really is at the module root.

The interesting one is the live resolver. moq.dev is already serving the tags, so the real go command can be pointed at the vanity path today:

go: downloading moq.dev/moq v0.5.14
go: moq.dev/moq@latest (v0.5.14) requires moq.dev/moq@v0.5.14: parsing go.mod:
	module declares its path as: github.com/moq-dev/moq-go
	        but was required as: moq.dev/moq

That is the entire chain working: resolve moq.dev/moq, read the meta tag, clone the mirror, read its go.mod, and reject the tag for declaring the old path. This PR is what makes the next tag declare the right one.

Base

Targets dev per CLAUDE.md: a changed module path is a semver break in a published API.

(written by Opus 5)

The Go modules were named after the mirror repos they happen to be published
from, so the ergonomic wrapper imported as `github.com/moq-dev/moq-go/moq` and
the raw bindings as `github.com/moq-dev/moq-go-ffi/moq`. Both now use vanity
paths that moq.dev owns:

  moq.dev/moq      -> github.com/moq-dev/moq-go
  moq.dev/moq-ffi  -> github.com/moq-dev/moq-go-ffi

moq.dev serves the `go-import` meta tag the go command reads to find the repo,
so the import path is no longer hostage to a repo name. Renaming or relocating
a mirror costs a line in a table on the site instead of a breaking change for
every consumer.

The wrapper package moves from go/wrapper/moq/ to go/wrapper/, the module root.
That is what makes the import path end in the package name, so `import
"moq.dev/moq"` binds `moq` with no alias. package-wrapper.sh stages the sources
flat to match. The bindings keep their moq/ subdirectory, since the import path
already ends in `moq` and every caller aliases it to `ffi` anyway.

BREAKING CHANGE: consumers must change their imports. `go get
github.com/moq-dev/moq-go@latest` will fail with a module-path mismatch rather
than a friendly deprecation, because both paths resolve to the same mirror repo
and its newest tag now declares the new path. Versions already pinned to the old
path keep resolving; only @latest and fresh installs break. VERSION goes 0.5 ->
0.6, so the next release is v0.6.0.

Verified against the live resolver: with moq.dev already serving the tags,
`go get moq.dev/moq@latest` today follows the meta tag, clones the mirror, and
rejects v0.5.14 for declaring the old path. That is precisely what this commit
fixes. `just go check` builds moq-ffi, regenerates the bindings, and reports
`ok moq.dev/moq` from the staged module.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da406c8476

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

cd "$PKG_STAGE"
go mod edit -require="github.com/moq-dev/moq-go-ffi@v${FFI_VERSION}"
go mod edit -dropreplace="github.com/moq-dev/moq-go-ffi"
go mod edit -require="moq.dev/moq-ffi@v${FFI_VERSION}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Publish the renamed FFI module before pinning it

When this reaches main, release-go.yml resolves the current Rust FFI version (0.3.11) and accepts its already-existing mirror tag, but that tag's go.mod still declares github.com/moq-dev/moq-go-ffi. Consequently the go mod tidy below fails with a module-path mismatch when this new requirement fetches moq.dev/moq-ffi@v0.3.11, so no v0.6 wrapper can be packaged. The inspected .github/workflows/release-go-ffi.yml only republishes on a new moq-ffi-v* tag, and this change does not cause such a tag, so the renamed FFI module must be released first or the release orchestration must explicitly bootstrap it.

Useful? React with 👍 / 👎.

Review finding from Codex.

The gate checked that the ffi's mirror tag exists, which used to be the same
question as "can the wrapper require it". With the rename it isn't: every tag
published so far declares github.com/moq-dev/moq-go-ffi, so a main push would
sail through the gate, pin moq.dev/moq-ffi@v0.3.11, and then die in
package-wrapper.sh's `go mod tidy` on the path mismatch. Local `just go check`
can't catch that, since it stages with --skip-tidy.

So read the tagged go.mod and require the new path before packaging. A tag that
predates the rename now defers exactly like a missing one: the next moq-ffi
release republishes the mirror under the new path and the workflow_run chain
re-cuts the wrapper. Network failures still fail loudly rather than
masquerading as a deferral, since nothing retries a wrapper-only push.

Verified against the live mirror: v0.3.11 reads back as the old path and defers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5566a13fb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread go/wrapper/go.mod
@@ -1,9 +1,9 @@
module github.com/moq-dev/moq-go
module moq.dev/moq

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Land the module-path break on dev

This commit is based directly on the repository's main commit, but changing the published module from github.com/moq-dev/moq-go to moq.dev/moq invalidates every existing consumer import and is explicitly accompanied by a breaking 0.5 to 0.6 version-line bump. Retarget this change to dev; merging it directly into main bypasses the repository's required staging path for breaking changes to language wrappers. (Written by GPT-5.6 Sol)

AGENTS.md reference: AGENTS.md:L205-L207

Useful? React with 👍 / 👎.

@kixelated
kixelated enabled auto-merge (squash) August 20, 2026 18:41
@kixelated
kixelated merged commit 7fef960 into dev Aug 20, 2026
2 checks passed
@kixelated
kixelated deleted the claude/go-vanity-module-path branch August 20, 2026 18: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