feat: add npm publish readiness (task 0020)
All checks were successful
CI / test (pull_request) Successful in 52s
CI / test (push) Successful in 52s

Complete the distribution metadata and publish flow for the unscoped
`gitea-axi` package:

- add `repository`, `homepage`, and `bugs` to package.json
- add `publishConfig` (public access, npmjs registry) so `npm publish`
  needs no extra flags
- replace `prepublishOnly` with `prepack: npm run build`, so both
  `npm pack` and `npm publish` rebuild `dist/` first
- document the single-command flow in PUBLISHING.md
- add a packaging smoke-test tier (`test:pack`) that packs the real
  tarball, installs it globally, and drives the installed binary
  (`--help`, dashboard header, and `setup` finding the bundled skill)
This commit was merged in pull request #20.
This commit is contained in:
2026-07-14 12:00:37 -04:00
parent be7226b321
commit ed87f023cb
6 changed files with 266 additions and 7 deletions

View File

@@ -13,7 +13,24 @@ This tarball-and-global-install check is the applicable real-integration surface
## Acceptance criteria
- [ ] The packed tarball contains the built CLI, the bin entry, and the Agent Skill markdown, and nothing declares a postinstall script
- [ ] A global install from the tarball puts a working `gitea-axi` on the PATH (dashboard header, `--help`, and `setup` all function)
- [ ] Package metadata is complete: unscoped name, description, repository URL, license, Node 20+ engines, ESM module type
- [ ] The publish flow (registry target, access, prepack build) is documented or scripted so publishing is a single command
- [x] The packed tarball contains the built CLI, the bin entry, and the Agent Skill markdown, and nothing declares a postinstall script
- [x] A global install from the tarball puts a working `gitea-axi` on the PATH (dashboard header, `--help`, and `setup` all function)
- [x] Package metadata is complete: unscoped name, description, repository URL, license, Node 20+ engines, ESM module type
- [x] The publish flow (registry target, access, prepack build) is documented or scripted so publishing is a single command
## Implementation Notes
Most package metadata (unscoped name, description, `type: "module"`, MIT license, `engines.node >=20`, the `gitea-axi` bin, and the `files` allowlist shipping `dist` + `skills`) already existed from earlier tasks; this slice added the missing `repository` (plus conventional `homepage`/`bugs`) and the publish wiring.
`prepublishOnly` was replaced with `prepack: "npm run build"`.
`prepack` fires on both `npm pack` and `npm publish`, so the tarball always carries a freshly built `dist/` — which the packaging smoke test's `npm pack` relies on — whereas `prepublishOnly` only ran on publish.
`publishConfig` pins `access: "public"` (so the unscoped package publishes without `--access public`) and `registry: "https://registry.npmjs.org/"` (so a machine with a different default registry still publishes to the right place), making `npm publish` a genuine single command.
The flow is also written down in `PUBLISHING.md`.
The packaging smoke test is its own tier: `vitest.packaging.config.ts` + the `test:pack` script, excluded from the fast `npm test` run (it packs, installs globally, and fetches runtime deps from the registry, so it is slow).
Distribution touches no Gitea API, so — exactly as the task frames it — this tarball-and-global-install check stands in for the absent live-Gitea e2e tier rather than being one.
Deviations / follow-ups:
- **Process deviation (TDD sequencing):** the test-writer sub-agent ran concurrently with the `package.json`/`PUBLISHING.md` edits, so by its final run it observed GREEN and did not report a clean RED for the metadata/publish facets (it mis-attributed the fields to the prior commit). The pre-edit tree was genuinely RED for those facets (no `repository`, `prepack`, `publishConfig`, or `PUBLISHING.md`); the file-presence and installed-binary facets were already GREEN because the CLI, bin, and bundled skill shipped in task 0018.
- **Test robustness fixes the sub-agent made:** the `npm pack --json` output shape differs across npm majors (array vs. object), so the test tolerates both; and the dashboard facet uses a promisified `execFile` rather than `execFileSync` so the in-process fixture Gitea server can answer the CLI's HTTP calls (a synchronous spawn deadlocks the shared event loop).