ci: wire nself-ci gate into plugins (dogfood adoption) - #91
Merged
Merged
Conversation
Closes the ADOPTION gap found in the 2026-09-11 audit: nself-ci existed in free/ci but was wired into zero of the 13 nself-org repos, not even this one, which owns the source. Adds a workflow that builds and runs the gate via scripts/nself-ci.sh and posts a nself-ci commit status, plus a wiki guide documenting the pattern, real verified local output, and the gaps found (this repo's package.json has no lint/typecheck/test/build scripts and no pnpm-workspace.yaml, so the node gate currently runs nothing but the secret scan). Branch protection is proposed, not applied.
5 tasks
4 tasks
acamarata
added a commit
that referenced
this pull request
Sep 12, 2026
…sdk (#93) * fix(ci): green the node:typecheck gate for plugins-registry and feature-flags sdk nself-ci's new implicit-workspace-member discovery (gate_workspace.go, #91) found and ran node:typecheck against .workers/plugins-registry and free/feature-flags/sdk-ts for the first time, and both failed on main. .workers/plugins-registry already declared @cloudflare/workers-types correctly in package.json/tsconfig and had a valid committed lockfile — the TS2688 only happened because nself-ci.yml never installed this directory's dependencies before running its typecheck script, so tsc fell back to the runner's global toolchain with no project node_modules at all. Same root cause produced the sdk-ts TS2307 on 'react'. Added an install step for both nested packages (this repo has no pnpm-workspace.yaml, so pnpm never recurses into them on its own) and committed a lockfile for sdk-ts, which had none. Separately, sdk-ts's evaluate() typed its ctx parameter as the full EvaluateRequest even though flag_key is always supplied by the explicit key argument, never by ctx — evaluateFlag()/useFlag() correctly pass Omit<EvaluateRequest, 'flag_key'>, which the wider parameter type rejected (TS2345). Narrowed evaluate()'s ctx type to match what it actually needs, and swapped the request-body spread order so an explicit key can never be silently overridden by a flag_key on ctx. free/file-processing/ts, free/media-processing/ts, and the sdk-ts jest config remain red for unrelated pre-existing reasons and are out of scope here. * fix(ci): install+build deps for file-processing/media-processing, wire jest transform for feature-flags sdk (#94) nself-ci's node gate surfaced three more pre-existing reds beyond PR #93's scope (same root cause class: nothing installs a nested package's own dependencies before typecheck/test/build runs): - free/file-processing/ts and free/media-processing/ts both had every declared dependency (commander, fastify, @types/node, @nself/plugin-utils, etc.) present in package.json but never installed. Added the same `pnpm install --frozen-lockfile --dir <pkg>` pattern PR #93 introduced. Their @nself/plugin-utils dependency is a file: path to shared/, whose dist/ output pnpm never builds on link — added a build step for shared ahead of the gate so the type/JS output exists. - Installing file-processing surfaced a genuine bug once tsc could actually resolve @nself/plugin-utils: src/server.ts imports createMetrics, which was never implemented in the shared package. Added a minimal dependency-free Prometheus-text-format counter (shared/src/metrics.ts) matching the incrementRequest/incrementError/format surface the plugin already calls. - free/feature-flags/sdk-ts had ts-jest installed but no jest config at all, so jest ran with zero TypeScript transform. Added jest.config.js (ts-jest preset + a moduleNameMapper for the NodeNext-style `.js` import extensions). That surfaced two more real gaps: the tsconfig's Node16/NodeNext module kind needs isolatedModules for ts-jest's per-file transpile, and the test file's `global.fetch` mock needed @types/node (never a declared dependency here). scripts/nself-ci.sh --check --no-gitleaks -v . now reports PASS for every node:typecheck, node:test, and node:build entry across all 5 discovered workspace members. * fix(ci): build shared before installing its dependents The nself-ci gate still failed with 'Cannot find module @nself/plugin-utils' across every importing file in free/file-processing/ts and free/media-processing/ts, even though shared was installed and built. Cause: pnpm does not symlink a file: dependency back to the source tree. It takes a real directory COPY into its store at install time. Building shared afterwards populates shared/dist in the source tree but not in the copy the dependents resolve against, and @nself/plugin-utils' main/types point at ./dist/*, so tsc finds no module. Reordered so shared is built before file-processing and media-processing are installed, which means their copies already contain dist/. Verified from a clean state (dist and node_modules removed): both typechecks pass. No gate was weakened and no dependency changed - only step ordering.
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
nself ci(built infree/ci) was wired into 0 of 13 nself-org repos, not even this one, which owns the source..github/workflows/nself-ci.yml: builds the gate viascripts/nself-ci.shand posts anself-cicommit status usinggh api+GH_TOKEN: ${{ github.token }}..github/wiki/guides/Nself-CI-Adoption.md: the copy-paste pattern for the other 12 repos, the real verified local output, and an honest list of what this gate does NOT check on this repo today (see below).Verified locally (not just "should work")
Known gap (documented in the wiki guide, not hidden)
This repo's root
package.jsonhas nolint/typecheck/test/buildscripts (only a customci:localstub) and nopnpm-workspace.yaml, sonself-ci's node-gate detection currently runs only the secret scan here — same shape of issue as.claude/memory/lesson_hollow_ci_gates.md. This PR does not paper over that: the wiki guide calls it out explicitly and recommends requiringnself-ciin branch protection in addition to, not instead of,validate.yml/build-test.yml/gitleaks.ymluntil it's fixed.Branch protection is not changed by this PR — that's the owner's call (recipe already in
~/Sites/nself/.claude/docs/CI-LOCAL.md).Test plan
free/ci/nself-cilocally and ranscripts/nself-ci.sh --check -v .against this worktree — real output above.yaml.safe_load).nself-ci.ymlworkflow runs green on this PR and posts thenself-cistatus (GitHub Actions, free public-repo runner).