Skip to content

fix(gonx): include dependency source in inferred target inputs#218

Merged
NachoVazquez merged 4 commits into
mainfrom
claude/test-net-e2e-tests-55isuc
Jul 24, 2026
Merged

fix(gonx): include dependency source in inferred target inputs#218
NachoVazquez merged 4 commits into
mainfrom
claude/test-net-e2e-tests-55isuc

Conversation

@NachoVazquez

@NachoVazquez NachoVazquez commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our guidelines: CONTRIBUTING.md#commit
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

[x] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

gonx's inferred targets (build, test, lint, tidy, generate) hash only project-local inputs (go.mod, go.sum, own *.go), with no ^-prefixed dependency inputs. In a go.work or replace-directive monorepo an app compiles a local library's source, but that source is not part of the app's input hash — so after editing the library, nx build app / nx test app return stale cache hits (a binary compiled against the old library, a test pass that never re-ran).

Issue Number: #217

What is the new behavior?

  • Every inferred Go project defines a goSource named input: {projectRoot}/go.mod, {projectRoot}/go.sum, {projectRoot}/**/*.go, plus {workspaceRoot}/go.work and {workspaceRoot}/go.work.sum (go.work changes module resolution for every Go project; the patterns match nothing when it doesn't exist).
  • build, test, lint, and tidy now hash ["goSource", "^goSource"], so dependency source participates in the cache key — transitively (app → lib1 → lib2). generate intentionally stays project-local (["goSource"]): go:generate directives only read the local module, and ordering is already handled by dependsOn: ["^generate"].
  • Because Nx errors when a ^goSource input is expanded for a dependency that doesn't define it, init (and nx add @naxodev/gonx) also writes a workspace-level goSource fallback into nx.json namedInputs — covering user-added edges from Go projects to non-Go projects (e.g. via implicitDependencies). A user-defined goSource is never overwritten.
  • New e2e regression net (packages/gonx-e2e/src/caching.spec.ts) covering the two most common local-dependency setups: a go.work workspace (apps//libs/ layout with a transitive lib chain) and replace-directive modules without go.work. It asserts the inferred inputs structurally, proves build/test cache invalidation on library-only edits (including executing the rebuilt binary and asserting its output), transitive invalidation, and that an unrelated app's cache survives (guard against over-broad inputs). Library edits deliberately touch nothing outside the library, since rewriting any app file would invalidate the app's own inputs and mask the exact regression the suite exists to catch.
  • e2e harness hardening: the local Verdaccio registry is now spawned under node pinned to 127.0.0.1 (the bun-test preload previously propagated bun as the child runtime, whose detect-port probe binds the IPv6 wildcard and fails on IPv6-less hosts), and a failed registry start rejects with the captured output instead of surfacing later as a ConnectionRefused.

Verification: unit tests, lint, build, and format all green. The e2e suite was run in both directions — green with the fix (7/7 pass), and red against a build of the unfixed plugin (6/7 fail; the only pass is the unrelated-project guard, which must pass either way). Docs updated across the five executor pages plus a new "Caching and inputs" section.

Does this PR introduce a breaking change?

[ ] Yes
[x] No

Existing consumer caches are invalidated once on upgrade (the input set changed — that is the fix working as intended); no migration is required.

Other information

The version-bump commit subject for release purposes is the squash-merge title (fix(gonx): ... → patch release for gonx).

claude added 3 commits July 24, 2026 09:37
Inferred targets hashed only project-local files (go.mod, go.sum, own
*.go), so in a go.work or replace-directive monorepo, editing a shared
Go library never invalidated a dependent's build/test cache — nx build
returned a binary compiled against the old library from cache.

Every inferred Go project now defines a goSource named input (go.mod,
go.sum, **/*.go, plus the workspace-level go.work/go.work.sum, which
change module resolution for every project), and build/test/lint/tidy
hash ['goSource', '^goSource'] so dependency source participates in the
cache key, transitively. generate stays project-local: its go:generate
directives only read the local module and ordering is already handled
by dependsOn ^generate.

Because ^goSource resolves against each dependency's own namedInputs
and Nx errors when a dependency doesn't define it, init also writes a
workspace-level goSource fallback into nx.json (never overwriting a
user-defined one) to cover user-added edges from Go projects to non-Go
projects.

Existing caches are invalidated once on upgrade (the input set changed);
no migration is required.

Closes #217
…oopback

The bun-test preload forked the registry via @nx/js's startLocalRegistry,
which propagates bun as the child runtime for nx run and, transitively,
the verdaccio executor. That executor's detect-port probe binds the IPv6
wildcard under bun and fails outright ('Failed to listen at ::') on
hosts without IPv6. nx and verdaccio are node programs, so the preload
now spawns them under node explicitly, and the registry is pinned to
127.0.0.1 (project.json listenAddress + the non-owner fallback URL) so
it binds deterministically everywhere.

The local replacement also rejects with the captured output when the
registry child exits before the address is seen, instead of resolving
with a no-op stop function — a failed start now surfaces at startup
rather than as a ConnectionRefused during publish/install much later.
Regression net for #217 covering the two most common local-dependency
layouts: a go.work workspace (libs/apps layout, transitive lib1 -> lib2
chain) and replace-directive modules without go.work. Verifies that the
inferred targets declare goSource/^goSource inputs, that editing only a
library invalidates a dependent app's build and test caches (directly
and transitively, with the rebuilt binary's output asserted against the
new value), and that an unrelated app's cache survives — guarding
against over-broad inputs.

Library edits deliberately touch nothing outside the library: the app's
test asserts a stable prefix and is written once, since rewriting any
app file would invalidate the app's own inputs and mask the exact
regression the suite exists to catch. Verified red against the unfixed
plugin (6 of 7 fail; only the unrelated-project guard passes) and green
with the fix (7 of 7).
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
nx-cloudflare 58570c8 Commit Preview URL

Branch Preview URL
Jul 24 2026, 01:42 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gonx-docs 58570c8 Commit Preview URL

Branch Preview URL
Jul 24 2026, 01:42 PM

@nx-cloud

nx-cloud Bot commented Jul 24, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit b44ad79

Command Status Duration Result
nx affected -t e2e --parallel=1 ✅ Succeeded 5m 26s View ↗
nx affected -t build --yes ✅ Succeeded <1s View ↗
nx affected -t lint test typecheck ✅ Succeeded 1s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 2s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-07-24 13:47:55 UTC

Comment thread packages/gonx-e2e/src/caching.spec.ts Fixed
@NachoVazquez
NachoVazquez force-pushed the claude/test-net-e2e-tests-55isuc branch from 2b32da8 to a767f68 Compare July 24, 2026 13:05
@NachoVazquez
NachoVazquez marked this pull request as ready for review July 24, 2026 13:38
Signed-off-by: Nacho Vazquez <nacho@naxo.dev>
@NachoVazquez
NachoVazquez force-pushed the claude/test-net-e2e-tests-55isuc branch from b44ad79 to 58570c8 Compare July 24, 2026 13:41
@NachoVazquez
NachoVazquez merged commit f848eae into main Jul 24, 2026
10 checks passed
@NachoVazquez
NachoVazquez deleted the claude/test-net-e2e-tests-55isuc branch July 24, 2026 13:48
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.

3 participants