OPER-9D
[OPER-9D] Publish @operant-health/qa-inbox-ui to GitHub Packages
Suggested
Justin Cooke
Body
---
feature_id: FEAT-studio-qa
---
## Context
`@operant/qa-inbox-ui@0.1.0` (built and CI-green in OPER-QA-14) is not published to any npm registry. Portico's POR-QA-2 PR (#1702) is stuck as `[WIP]` because its `pnpm add @operant/qa-inbox-ui` cannot resolve. Blocks Fiesta UAT: without the mount, Ana Torres + Hannah Clement cannot see the QA Inbox even after POR-QA-4 seeds their data.
Same class of toil as the GitHub App migration (OPER-9C): a human-managed shared secret (`NPM_TOKEN`) needs a one-time registration, then all future publishes are automated. Sweet is the org owner who can register the npm token; dispatcher does the release workflow + first publish.
Chosen registry: **GitHub Packages** (npm.pkg.github.com), scoped to `@operant-health`. Rationale: same GitHub org, same access model, no separate npm.js account to manage, and it reuses the GitHub App auth landing in OPER-9C once that ships. Publishing to npmjs.org public is out of scope for this ticket (private cross-product package).
## Goal
`@operant-health/qa-inbox-ui@0.1.0` published to GitHub Packages, Portico consumes it via `.npmrc` + `pnpm add`, POR-QA-2 unblocks.
## Human-gate steps (Sweet)
1. On https://github.com/settings/tokens/new create a classic PAT scoped `write:packages, read:packages, repo` for the `operant-health` org. Name: `operant-npm-publish-2026-09`. Note the token value.
2. In https://github.com/organizations/Operant-Health/settings/secrets/actions add `NPM_PUBLISH_TOKEN` = <PAT value>. Environment scope: none (org-wide).
3. Post `sweet: NPM_PUBLISH_TOKEN registered` in this ticket to trigger dispatcher.
## Agent-owned steps (dispatcher)
1. Rename package from `@operant/qa-inbox-ui` to `@operant-health/qa-inbox-ui` in `packages/qa-inbox-ui/package.json` (matches GitHub org scope; required by GitHub Packages).
2. Add `.npmrc` at repo root:
```
@operant-health:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_PUBLISH_TOKEN}
```
3. Add `publishConfig` to package.json: `{ "registry": "https://npm.pkg.github.com", "access": "restricted" }`.
4. Add `.github/workflows/publish-qa-inbox-ui.yml`: triggered on tag `qa-inbox-ui-v*`, runs `pnpm --filter @operant-health/qa-inbox-ui build` then `pnpm --filter @operant-health/qa-inbox-ui publish --no-git-checks`. Uses `NPM_PUBLISH_TOKEN` for auth.
5. Tag `qa-inbox-ui-v0.1.0` and push. Workflow runs and publishes.
6. Portico consumer PR (linked child ticket POR-QA-2b): update Portico's `.npmrc` + `package.json` to `@operant-health/qa-inbox-ui: ^0.1.0`, retarget POR-771 branch onto that, drop the `[WIP]` prefix.
## Post-merge (Sweet)
- Confirm the package appears at https://github.com/orgs/Operant-Health/packages
- Rotate/remove the classic PAT once GitHub App (OPER-9C) supports package publishing (2026-Q4)
## Acceptance criteria
- `pnpm add @operant-health/qa-inbox-ui` succeeds from a fresh Portico checkout with only `NPM_PUBLISH_TOKEN` in the env
- GitHub Actions log shows successful `pnpm publish` on tag push
- POR-QA-2 (PR #1702) drops `[WIP]`, all checks green, ready to merge
- No public npmjs.org exposure of the package (private to Operant-Health org)
## Why this matters
Fiesta UAT is 100% gated on POR-QA-2 merging. This ticket is the single blocker. Estimated 20-min human-gate work for Sweet + 1 dispatcher run for the automation.
Attachments
Loading attachments…
Comments
Loading comments…