Publish to npm #17
Workflow file for this run
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
| name: Publish to npm | |
| # Triggered by publishing a GitHub Release. Builds, verifies, then publishes | |
| # engramgraph to npm via OIDC Trusted Publishing — NO token needed. | |
| # | |
| # Setup (one-time, on npmjs.com → engramgraph → Settings → Trusted | |
| # Publisher): add a GitHub Actions trusted publisher with | |
| # organization/user: AsiaOstrich repository: EngramGraph workflow: publish.yml | |
| # npm then mints short-lived credentials from this job's OIDC id-token; the repo | |
| # must be public. Provenance is generated automatically. | |
| on: | |
| release: | |
| types: [published] | |
| jobs: | |
| publish: | |
| name: Publish to npm | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write # OIDC trusted publishing + provenance | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # NOTE: no `registry-url` — it makes setup-node write an empty | |
| # //registry.npmjs.org/:_authToken to .npmrc, which suppresses OIDC | |
| # trusted publishing (npm takes the empty-token path → anonymous → E404). | |
| # Without it, npm uses the default registry and engages OIDC. | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| # OIDC trusted publishing requires npm >= 11.5.1 (newer than the bundled npm). | |
| - run: npm install -g npm@latest | |
| - run: npm --version | |
| # npm >= 11 gates native install scripts behind an approval list by | |
| # default (this broke this exact workflow on 2026-07-10 once `npm | |
| # install -g npm@latest` above started pulling npm 11.x: DTS build | |
| # failed with "Cannot find module 'ryugraph'", because ryugraph's own | |
| # install step — which copies its native binary into place — never | |
| # ran). The fix lives in package.json's `allowScripts` field | |
| # (declarative, version-pinned pre-approval for this repo's known | |
| # native deps: ryugraph/tree-sitter*/esbuild) rather than an | |
| # imperative `--all` here, so a plain install picks it up with no | |
| # extra step and no silent trust extended to future dependencies. | |
| - run: npm install --legacy-peer-deps | |
| # ryugraph's `god-nodes`/`communities`/`related` commands need its ALGO | |
| # extension (PageRank/Louvain), which isn't bundled — ryugraph normally | |
| # downloads it on first use from extension.ryugraph.io. That host is | |
| # unreliable (confirmed 2026-07-11: unreachable from this exact runner, | |
| # TCP connect just hangs — not a DNS issue). Without a fallback, tests | |
| # that trigger the download hang for 10+ minutes before finally timing | |
| # out (see structural-memory.test.ts's L3 tests on 2026-07-10 run | |
| # 29105565151). Building the extension from the source ryugraph already | |
| # ships (node_modules/ryugraph/ryu-source) and dropping it straight into | |
| # the cache path ryugraph checks first means `INSTALL ALGO` never has to | |
| # touch the network at all — verified locally with the download host | |
| # blackholed via /etc/hosts (full 81/81 tests, ~7s, vs. 617s+ hanging | |
| # before this step existed). | |
| # | |
| # `EXTENSION_LIST=algo` + the Makefile's `extension-release` target | |
| # (-DBUILD_RYU=FALSE) builds only this extension, not the whole engine. | |
| # Cache path/version/platform-string format taken from ryujs.node's own | |
| # embedded path template and cross-checked against predictable-labs/ | |
| # ryugraph#48's real-world report (25.9.0 is the extension catalog | |
| # version — distinct from, and older than, the ryugraph@25.9.1 npm | |
| # package version). | |
| - name: Build ryugraph ALGO extension from source (bypass unreliable download host) | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y -qq cmake | |
| cd node_modules/ryugraph/ryu-source | |
| make extension-release EXTENSION_LIST=algo NUM_THREADS="$(nproc)" | |
| mkdir -p "$HOME/.ryu/extension/25.9.0/linux_amd64/algo" | |
| cp extension/algo/build/libalgo.ryu_extension "$HOME/.ryu/extension/25.9.0/linux_amd64/algo/" | |
| # Build + verify before publishing (native: kuzu + tree-sitter compile here). | |
| - run: npm run build | |
| - run: npm run typecheck | |
| # XSPEC-073 G2 — test:coverage rather than test. | |
| # The thresholds added to vitest.config.ts only apply when coverage is | |
| # collected, so plain `vitest run` would leave them as decoration — the | |
| # state UDS cli's thresholds sat in for months. This is also the only | |
| # workflow in the repo that runs tests at all (both workflows here trigger | |
| # on `release` only, so there is no push/PR CI to attach a gate to). | |
| - run: npm run test:coverage | |
| - name: Determine npm dist-tag | |
| id: tag | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| if echo "$VERSION" | grep -qE '\-(beta|alpha|rc)\.'; then | |
| echo "tag=next" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tag=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| # No NODE_AUTH_TOKEN: npm authenticates via the OIDC id-token against the | |
| # trusted publisher configured on npmjs. Provenance is automatic. | |
| - name: Publish engramgraph (OIDC trusted publishing) | |
| run: npm publish --access public --tag ${{ steps.tag.outputs.tag }} |