-
Notifications
You must be signed in to change notification settings - Fork 0
Nself CI Adoption
Status: wired into plugins (this repo) 2026-09-11 — the first of 13 nself-org repos to adopt it. Zero repos had it wired before this, including plugins itself, which owns the source at free/ci.
This guide is the copy-paste pattern for the other 12 repos. It also records, honestly, what the gate does and does not check today — read "Known gaps" before requiring it as a sole merge gate.
- It owns the
nself-cisource (free/ci/) and the wrapper (scripts/nself-ci.sh) — self-hosting the gate here is the purest dogfood: a regression in the gate breaks its own repo's checks first. - It is public, so the workflow runs on free GitHub-hosted Actions — no runner-fleet dependency to prove the pattern.
- Its own
.claude/docs/CI-LOCAL.md(project-level) already documents the branch-protection recipe; this guide is the repo-level companion showing the wiring actually in place.
-
Workflow —
.github/workflows/nself-ci.yml: checkout →setup-go(builds the binary) →setup-node/pnpm(for the Node gate path) → installgitleaks→ runscripts/nself-ci.sh .withpermissions: statuses: writeandGH_TOKEN: ${{ github.token }}sogh apican post the status without a PAT. -
Wrapper —
scripts/nself-ci.shbuildsfree/ci/nself-ciif missing/stale, thenexecs it. Same script works locally and in CI. -
Status — the binary posts a
nself-cicommit status viagh api repos/{owner}/{repo}/statuses/{sha}(OAuth, no token in a URL). -
Branch protection (NOT applied by this PR — owner's call) — add
nself-citorequired_status_checks.contextsper the exactgh apicommand in~/Sites/nself/.claude/docs/CI-LOCAL.md§ "Requiring nself-ci in branch protection". Do this as an additional required check alongside the repo's existing checks, not a replacement — see gaps below.
Copy .github/workflows/nself-ci.yml from this repo into each of the other 12 (cli, admin, web, nchat, nclaw, nsentry, ntask, nfamily, clawde, homebrew-nself, packages, plugins-pro), adjusting the toolchain setup steps to match that repo's stack (e.g. Flutter repos need subosito/flutter-action instead of setup-node).
$ scripts/nself-ci.sh --check -v .
[nself-ci] building gate binary...
[nself-ci] built .../free/ci/nself-ci
[nself-ci] running: gitleaks detect --source . --exit-code 1 --config .github/gitleaks.toml
nself-ci gate results — .
Stacks: node
────────────────────────────────────────────────────────────
secrets:gitleaks PASS (3.617s)
────────────────────────────────────────────────────────────
Overall: PASSED (4s)
That is the real, complete output — one gate ran (secrets:gitleaks), it passed, in under 4 seconds. Read that literally: no lint, typecheck, test, or build gate ran, for the reason below.
1. This repo's Node gate is a no-op. nself-ci detects Node stacks by checking the root package.json for lint / typecheck / test / build scripts (or workspace members' scripts, if pnpm-workspace.yaml exists). This repo's root package.json has neither: it has one custom script, ci:local (a stub — tsc --noEmit --allowJs || echo skip; echo passed), and no pnpm-workspace.yaml, even though shared/ has its own package.json. Result: the workspace-recursion path in free/ci/internal/gate_runners.go (runNodeGates) never triggers, the non-workspace path finds no matching scripts, and the gate silently runs nothing but the secret scan — while still printing Overall: PASSED. This is exactly the shape of failure flagged in .claude/memory/lesson_hollow_ci_gates.md: a gate that passes while checking nothing.
-
Fix options (not applied by this PR): (a) add real
lint/typecheck/test/buildscripts to rootpackage.json(or addpnpm-workspace.yamlso member scripts are picked up), or (b) extendgate_runners.goto also recognize this repo'sci:localconvention. Until one of these lands,nself-cion this repo is a secrets-only gate, not a lint/test/build gate.
-
No per-plugin checks. The real quality bar for this repo is per-plugin (schema validation, duplicate-port checks, registry consistency — see
validate.yml,registry-check.yml,hygiene.yml,license-gate.yml).nself-cionly inspects the repo root; it does not walkfree/*/plugin.jsonor run plugin-level TypeScript builds. It does not replace any of those workflows. -
No lint/typecheck/test/build for Go-only subpackages either.
free/ciitself (and other Go-based plugins) has ago.mod, but stack detection only looks at the repo root, which has no rootgo.mod. A regression insidefree/ci's own Go code would not be caught bynself-cirunning against repo root — only by its owngo test ./...if invoked directly in that subdirectory, or bybuild-test.yml. -
Per the plugin's own README ("What it explicitly does NOT do"):
nself ciis not a GitHub Actions emulator. E2E, Lighthouse, axe-a11y, CodeQL, Trivy, SBOM, license audit, coverage ratchet, bundle-size, commitlint, i18n-check, and deploy jobs all still need to run somewhere else — free-runner Actions for public repos (this repo), or a dedicated additional gate for private ones. -
Fork PRs:
GH_TOKEN: ${{ github.token }}on a fork PR is read-only for status writes; the binary treats a failed status post as a warning (non-fatal), so the job's pass/fail still reflects the real gate result, but thenself-cicheck may not appear on fork PRs.
Bottom line: this PR adds nself-ci as evidence the wiring works end-to-end (workflow → build → gates → status), not as proof the gate is a complete substitute for this repo's existing checks. Recommend requiring it in branch protection in addition to, not instead of, validate.yml / build-test.yml / gitleaks.yml / registry-check.yml until gap 1 is closed.
- Copy
.github/workflows/nself-ci.yml, adjust toolchain setup for the repo's stack. - Run
scripts/nself-ci.sh --check -v .(orplugins/free/ci/nself-cidirectly) locally first — confirm which stacks it detects and which gates actually execute. Do not assume; read the printed gate table. - If the repo's real lint/typecheck/test/build live under a non-standard script name (as
ci:localdoes here) or in workspace members withoutpnpm-workspace.yaml, fix that before treating a greennself-cias meaningful. - Open a PR, let Actions run it once, confirm the
nself-cicommit status appears on the PR. - Propose (do not silently apply) the branch-protection addition per
CI-LOCAL.md— owner approves it.
- Commands
- File Processing Commands
- GitHub Commands
- ID.me Commands
- Jobs Commands
- Notifications Commands
- Realtime Commands
- Shopify Commands
- Stripe Commands
View All: Home (or see the full alphabetical list below — 129/129 synced with registry.json)
- Access-Controls
- Admin-Api
- AI-CLI
- AI-Studio
- Alerts
- Analytics
- API
- Audit
- Audit-Analytics
- Audit-Log
- Auth-Enterprise
- Backup
- BYOK
- CDC
- CDN
- CI
- Claw-CLI
- Cloudflare
- Compliance
- Content-Acquisition
- Content-Progress
- Content-Safety
- Costs
- CRDT
- Cron
- DDNS
- Devices
- DLQ
- Documents
- Dogfood
- Donorbox
- DR
- E2EE
- Encryption
- Entitlements
- Event-Bus
- Family-Ancestry
- Family-FamilySearch
- Family-GEDCOM
- Family-MyHeritage
- Family-WikiTree
- Feature-Flags
- Federation
- File-Processing
- Flags
- Forgejo
- Functions-V8
- Game-Metadata
- Gateway
- Gauth
- GDPR
- Geocoding
- GitHub
- GitHub-Runner
- HIPAA
- Home
- IDme
- Infra
- Invitations
- Job-Queue
- Jobs
- K8s
- Link-Preview
- Maintenance
- MDNS
- Media-Processing
- Meetings
- MLflow
- Model
- Monitor
- Monitoring
- Notifications
- Notify
- nSelf-Cloud
- nSelf-Eval-Gate
- nSelf-Geo
- nSelf-Image
- nSelf-PDF
- nSelf-Scan
- nSelf-Sync
- nSelf-Vault
- Object-Storage
- Observability
- Ollama
- Payments
- PayPal
- Pentest
- Pentest-Kit
- Plugin-ClawDE
- Plugin-Gauth
- Plugin-LLM-Gateway
- Plugin-PTY
- Plugin-Retrieval
- Podcast
- Post
- Push
- Queue
- Region
- Release
- Retro-Gaming
- Rom-Discovery
- Search
- Sentry-CLI
- Shared-Utils
- Shopify
- SIEM
- SMS
- Soak
- Sports
- Storage
- Storage-Transform
- Stripe
- Subtitle-Manager
- Tenant
- Tenant-Controller
- TMDB
- Tokens
- Torrent-Manager
- Transactional-Email
- VPN
- WAF
- Warehouse
- Watchdog
- Web3
- Webhooks
- Workflows
Related