From 84393be7851d7e2fb1b3b87cdf49769dcb6b88c4 Mon Sep 17 00:00:00 2001 From: ilia Date: Wed, 15 Jul 2026 11:06:20 -0400 Subject: [PATCH] Close playkit ops gap: require npm publish, mark Outline/npm done. Remove release soft-fail now that NPM_PUBLISH_TOKEN works; refresh OPS/OUTLINE/ROADMAP for the live Outline doc and published 0.4.0 registry package. --- .gitea/workflows/ci.yml | 8 ++---- CHANGELOG.md | 4 +++ ROADMAP.md | 7 +++-- docs/NPM_REGISTRY.md | 5 ++-- docs/OPS.md | 63 +++++++++++++---------------------------- docs/OUTLINE.md | 7 ++--- 6 files changed, 37 insertions(+), 57 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2ed646b..443467a 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -155,15 +155,13 @@ jobs: -F "attachment=@${TARBALL}" \ "https://git.levkin.ca/api/v1/repos/ilia/playkit/releases/${RELEASE_ID}/assets" - name: Publish to Gitea npm registry - # RELEASE_TOKEN (or optional NPM_PUBLISH_TOKEN) needs write:package — docs/NPM_REGISTRY.md - # Soft-fail: Gitea Release + tarball already published above; package registry - # auth is a separate token scope and should not block the git release. - continue-on-error: true + # Prefer NPM_PUBLISH_TOKEN (write:package); fall back to RELEASE_TOKEN if it has package scope. + # See docs/NPM_REGISTRY.md / docs/OPS.md. run: | TOKEN="${{ secrets.NPM_PUBLISH_TOKEN }}" if [ -z "$TOKEN" ]; then TOKEN="${{ secrets.RELEASE_TOKEN }}"; fi if [ -z "$TOKEN" ]; then - echo "::error::set RELEASE_TOKEN or NPM_PUBLISH_TOKEN with write:package" + echo "::error::set NPM_PUBLISH_TOKEN (or RELEASE_TOKEN) with write:package" exit 1 fi echo "@levkin:registry=https://git.levkin.ca/api/packages/ilia/npm/" > /tmp/playkit.npmrc diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d79cf..bc5ca2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Ops: npm publish is hard-required in the tag release job (removed soft-fail); `NPM_PUBLISH_TOKEN` + Outline update scopes documented as done in `docs/OPS.md` / `ROADMAP.md` + ## 0.4.0 — 2026-07-15 - **CLI** — `playkit init` scaffolds `e2e/` + CI snippet; `playkit smoke` post-deploy public-host + health ping diff --git a/ROADMAP.md b/ROADMAP.md index 470bba9..315362f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -14,8 +14,11 @@ Living plan for making `@levkin/playkit` more useful across Levkin repos. - [ ] End adoption pause — migrate first extra consumer (`screening` candidate) - [ ] Evaluate `playwright-exporter` for scheduled synthetics (may supersede bespoke cron wrappers around `playkit smoke`) -- [ ] **Wire `NPM_PUBLISH_TOKEN` / `write:package`** — `v0.4.0` git release OK; first npm publish hit E401. Soft-fail in CI until fixed. Checklist: `docs/OPS.md` -- [ ] **Outline API key scopes** — vault key needs `documents.update` (+ delete/archive). Living page synced to v0.4.0 via UI; script thereafter. Checklist: `docs/OPS.md` + +## Done since v0.4.0 (ops) + +- [x] **Wire `NPM_PUBLISH_TOKEN` / `write:package`** — `@levkin/playkit@0.4.0` published; Actions secret + `vault_playkit_npm_token`; release job no longer soft-fails (`docs/OPS.md`) +- [x] **Outline API key scopes** — `documents.update` / `delete` working; living page synced via API (`docs/OUTLINE.md`) ## Adoption pause diff --git a/docs/NPM_REGISTRY.md b/docs/NPM_REGISTRY.md index 2aed268..6c7876b 100644 --- a/docs/NPM_REGISTRY.md +++ b/docs/NPM_REGISTRY.md @@ -46,5 +46,6 @@ npm view @levkin/playkit versions --registry https://git.levkin.ca/api/packages/ ## Token setup -See **`docs/OPS.md`** (Outstanding → Gitea npm publish token). First `v0.4.0` -publish hit E401 until a package-scoped token is stored as `NPM_PUBLISH_TOKEN`. +`@levkin/playkit@0.4.0` is on the registry. Tag/CI publish uses Actions secret +`NPM_PUBLISH_TOKEN` (`write:package`). Local ops: vault +`vault_playkit_npm_token` / `./scripts/publish-gitea-npm.sh`. See **`docs/OPS.md`**. diff --git a/docs/OPS.md b/docs/OPS.md index fc07507..32c13bd 100644 --- a/docs/OPS.md +++ b/docs/OPS.md @@ -9,53 +9,28 @@ Living ops/status after releases. Update when an item closes. | Pushgateway + `live-playkit` Grafana board | Applied (`10.0.10.24:9091`) | | Tag release workflow + `RELEASE_TOKEN` | Working (`v0.3.1`, `v0.4.0` Gitea releases) | | Selftest CI | Green (Playwright image pinned to package version) | -| Outline **QA & Dev → Playkit** content @ v0.4.0 | Updated 2026-07-15 (browser sync); keep in sync via script once API scopes fixed | +| Outline **QA & Dev → Playkit** @ v0.4.0 | Synced via API 2026-07-15 → https://notes.levkin.ca/doc/playkit-CrPJq5x2qQ | +| Playkit sync probe cleanup | Deleted via API 2026-07-15 | +| Outline API key (`documents.update` / `delete`) | Vault + `.env` updated (`vault_outline_api_key`) | +| Gitea npm publish (`write:package`) | `@levkin/playkit@0.4.0` on registry; Actions secret `NPM_PUBLISH_TOKEN` set; vault `vault_playkit_npm_token` | | v0.4 CLI / retry presets / registry wiring | Shipped on `main` | -## Outstanding (needs human UI once) +## Outstanding -### 1. Gitea npm publish token (`write:package`) - -`v0.4.0` **Gitea Release** succeeded; `npm publish` failed with **E401** because -Actions `RELEASE_TOKEN` lacks package scopes. - -1. Gitea → **Settings → Applications → Generate New Token** -2. Scopes: **`write:package`** (implies read) + keep `write:repository` if this token also cuts releases -3. Prefer a dedicated token named `playkit-npm-publish` -4. Store as repo Action secret **`NPM_PUBLISH_TOKEN`** on `ilia/playkit` - (optional: also `vault_playkit_npm_token` in ansible vault — see ansible `docs/hardening/SECRETS.md`) -5. Publish once: - -```bash -cd /path/to/playkit # on main @ v0.4.0 -npm ci && npm run build -npm publish --registry https://git.levkin.ca/api/packages/ilia/npm/ -# or: ./scripts/publish-gitea-npm.sh -``` - -6. Verify: `npm view @levkin/playkit version --registry https://git.levkin.ca/api/packages/ilia/npm/` - -Until then consumers use the git pin: `#v0.4.0`. - -### 2. Outline API key scopes - -Vault `vault_outline_api_key` can **list/create/info/export** but **not** -`documents.update` / `delete` / `archive` (HTTP 403). - -1. Outline → **Settings → API** (API & Access) -2. Edit/recreate key with scopes at least: - -``` -collections.list documents.list documents.info documents.create documents.update documents.delete documents.archive documents.search -``` - -(Full recommended list: ansible `docs/guides/authentik-apps.md` → Outline API key) - -3. Update vault + `make vault-export-env` -4. `python3 scripts/outline-sync-playkit.py` -5. Delete leftover **QA & Dev → Playkit sync probe** if still present - -### 3. Adoption soak +### Adoption soak Keep **no new consumer repos** until punimtag e2e + kit CI + metrics stay green for a few days. Then prefer `screening` as the next adopter. + +## Recurring (after each release) + +```bash +# Outline living page +cd /path/to/ansible && make vault-export-env +set -a && source .env && set +a +cd /path/to/playkit +python3 scripts/outline-sync-playkit.py + +# Manual publish (CI also publishes on tag when NPM_PUBLISH_TOKEN is set) +./scripts/publish-gitea-npm.sh +``` diff --git a/docs/OUTLINE.md b/docs/OUTLINE.md index 46386d4..af2406a 100644 --- a/docs/OUTLINE.md +++ b/docs/OUTLINE.md @@ -2,7 +2,7 @@ Canonical prose stays in git (`README.md`, `docs/*`, `ROADMAP.md`). Browsable front door: **Outline** → collection **QA & Dev** → doc **Playkit** -(`https://notes.levkin.ca/doc/playkit-3ekU0eghbV`). +(`https://notes.levkin.ca/doc/playkit-CrPJq5x2qQ`). Ops status for this page (scopes, last sync): **`docs/OPS.md`**. @@ -23,12 +23,11 @@ version, install pin, what’s-in-the-box digest, and links to repo docs. **Required API scopes** (Outline → Settings → API & Access): at least `collections.list`, `documents.list`, `documents.info`, `documents.create`, `documents.update`, and preferably `documents.delete` / `documents.archive`. +Empty (unrestricted) scopes = full user access — fine for a personal kit-ops key. Without `documents.update` the script can create a first doc but cannot refresh an existing Playkit page (HTTP 403). -As of 2026-07-15 the living page was synced to **v0.4.0** via signed-in UI -because the vault API key still lacked `documents.update`. Fix the key scopes, -then prefer this script for every future release. +API sync to **v0.4.0** works as of 2026-07-15 (`vault_outline_api_key` has update/delete). ## When to update Outline -- 2.49.1