Skip to content

fix(plugin,release,ci): CLI targets for non-cli plugins, catalog cache pairing, bump fixture TMPDIR, golden-path step 10 budget (D-0669, D-0875, D-0831, D-0307) - #955

Merged
acamarata merged 6 commits into
mainfrom
dw2-cli-10
Oct 26, 2026

Conversation

@acamarata

Copy link
Copy Markdown
Collaborator

Four open debt rows; one was already fixed.

D-0669 (fixed)

CLITargetsOf read cliCommands from the v2 projection, which cannot carry a v1 non-cli pluginType, so a service plugin with cliCommands yielded nself-<command> targets that the installer's v1 path never publishes. CLITargetsOf now returns nothing for a manifest without a commands block. Test TestCLITargetsOfNonCLIType (service + cliCommands yields no target, cli plugin still yields both); it failed before the change with got [{nself-server server}].

D-0875 (fixed)

catalog.json and catalog.etag were written as two files with no lock, so racing writers could leave one response's body with another's ETag. Reads and writes of the pair now hold one lock: a process mutex plus an flock on catalog.lock (no-op without flock, as in internal/invoke). A write without the lock is skipped (the cache is optional). Tests: TestWriteCacheConcurrentKeepsPair (8 writers x 60 rounds with readers checking the pair; 307 bad reads before, 0 after) and TestWriteCacheWaitsForOtherProcessLock (unix: a write waits for a lock held on another descriptor).

D-1109 (already fixed, no change)

The binary-package refusal now runs before the dev bypass: verifyReleaseSignature sends a pinned-tier binary package to verifyPlatformSignature first (f256710, #913, in main). The bypass only skips an absent platform entry, never a present or malformed one; covered by installer_platform_test.go (bypass and non-bypass E121 cases, including TestPlatformSignatureMalformedE121).

D-0307 (fixed, baseline raised from data)

The row's step number is stale: step 10 is plugin install claw, which installs six licensed dependencies (notify, google, mux, cron, voice, browser) before itself, so seven downloads from ping.nself.org. From the e2e-golden-path logs: warm ping gives ~1s per download (step 10 = 4-6s on 2026-10-10/11), slow ping ~20s per download (step 9, one download, = 23-26s). Slow-mode step 10 took 110s, 108s and 128s (runs 38087589999, 38202476017, 39192880837), so the fail limit of 90s was unreachable. Baseline 30 -> 60 (warn 90s, fail 180s); the warn line is the latency-regression signal. A retry inside plugin install was not added: the downloads are slow, not failing, so a retry would not help. The slow ping.nself.org itself is outside this repo. No unit test exists for a timing constant; checked with bash -n and shellcheck (only a pre-existing SC2034).

D-0831 (fixed)

mk_bump_env now does mkdir -p "$BASE/tmp"; export TMPDIR=$BASE/tmp. Added the check "bump runs with a TMPDIR that exists", which failed before (210 passed, 1 failed) and passes after (211 passed, 0 failed) on macOS, where BSD mktemp used to hide the problem. Not wired into nself ci: that is a decision about release gating, left to the owner.

Commands run

  • go build ./..., go vet ./internal/plugin/... ./tools/manifestv2migrate/
  • go test ./internal/plugin/... ./tools/manifestv2migrate/ (all ok); go test -race -count=3 ./internal/plugin/catalog/; GOOS=windows go vet ./internal/plugin/catalog/
  • bash scripts/release/test.sh: 211 passed, 0 failed

@acamarata

Copy link
Copy Markdown
Collaborator Author

Review fix: the m.Commands == nil early return in CLITargetsOf dropped the binaries of a manifest with cliCommands and no pluginType, which the installer publishes. CLITargetsOf now takes the plugin.json bytes and reads pluginType, binaryName and cliCommands as the installer does, so a v1 service plugin still gets none and a no-pluginType plugin gets one per command. Added TestCLITargetsOf and TestTargetsPluginTypeParity; the latter fails on the previous code (empty output) and passes now. Plugin and tools tests pass with -mod=vendor.

@acamarata

Copy link
Copy Markdown
Collaborator Author

Review fix: readCache now discards the ETag when the cache lock cannot be taken (timeout or open failure), so a body is never paired with an ETag read outside the lock; the next fetch is unconditional. Added TestReadCacheDropsETagWhenLockTimesOut (holds the flock through a second descriptor with a short lockWait). It fails on the previous code (etag returned) and passes now; internal/plugin/... tests pass.

@acamarata
acamarata merged commit b830114 into main Oct 26, 2026
35 checks passed
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