From b6fe4955780a5b399688c565baccf33ac2a88703 Mon Sep 17 00:00:00 2001 From: Kevin Boshold Date: Mon, 29 Jun 2026 19:48:22 +0200 Subject: [PATCH] feat(release): platform READMEs + npm linked-artifacts storage records - prepare-npm-platform-packages: emit a minimal per-platform README that points users to @bosdev/zaps, and ship it via the package files list - release.yml: after publish, register an org Artifact Metadata storage record per package (main + 4 platform) so they surface on the org's Linked Artifacts page; best-effort (continue-on-error) so a missing entitlement never breaks a release. Adds attestations + artifact-metadata write permissions. --- .github/workflows/release.yml | 30 ++++++++++++++++++++++++ scripts/prepare-npm-platform-packages.ts | 15 +++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7889b45..e54d8fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,8 @@ on: permissions: contents: write id-token: write + attestations: write + artifact-metadata: write jobs: build: @@ -106,6 +108,34 @@ jobs: npm publish --access public --provenance fi + # Register each published package on the org's Linked Artifacts page + # (https://github.com/orgs/boshold/artifacts) via the Artifact Metadata API. + # Best-effort: a failure here must never break a release. + - name: Register npm storage records + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + run: | + version=$(node -p "require('./package.json').version") + names=$(node -p "['@bosdev/zaps', ...Object.keys(require('./package.json').optionalDependencies || {})].join('\n')") + echo "$names" | while IFS= read -r name; do + [ -n "$name" ] || continue + integrity=$(npm view "$name@$version" dist.integrity 2>/dev/null || true) + if [ -z "$integrity" ]; then + echo "$name@$version: no integrity on registry — skipping" + continue + fi + digest=$(node -e 'process.stdout.write("sha512:"+Buffer.from(process.argv[1].replace(/^sha512-/,""),"base64").toString("hex"))' "$integrity") + echo "registering storage record for $name@$version ($digest)" + curl -fsSL -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GH_TOKEN" \ + -H "X-GitHub-Api-Version: 2026-03-10" \ + https://api.github.com/orgs/boshold/artifacts/metadata/storage-record \ + -d "{\"name\":\"$name\",\"version\":\"$version\",\"digest\":\"$digest\",\"registry_url\":\"https://registry.npmjs.org\",\"artifact_url\":\"https://www.npmjs.com/package/$name/v/$version\",\"status\":\"active\"}" \ + || echo "storage-record POST failed for $name@$version (non-fatal)" + done + release: name: Release runs-on: ubuntu-latest diff --git a/scripts/prepare-npm-platform-packages.ts b/scripts/prepare-npm-platform-packages.ts index 62599e9..cfe6e84 100644 --- a/scripts/prepare-npm-platform-packages.ts +++ b/scripts/prepare-npm-platform-packages.ts @@ -66,10 +66,23 @@ for (const platform of platforms) { repository: { type: "git", url: "git+https://github.com/boshold/zaps.git" }, os: [platform.os], cpu: [platform.cpu], - files: ["zaps"], + files: ["zaps", "README.md"], publishConfig: { access: "public" }, }; writeFileSync(path.join(dir, "package.json"), `${JSON.stringify(pkg, null, 2)}\n`); + + const readme = `# ${platform.name} + +Prebuilt native \`zaps\` binary for **${platform.os}/${platform.cpu}**. + +You don't install this package directly — it's an \`optionalDependencies\` target of +the main package, selected automatically for your platform. + +**Install [\`@bosdev/zaps\`](https://www.npmjs.com/package/@bosdev/zaps) instead.** + +Source & docs: https://github.com/boshold/zaps +`; + writeFileSync(path.join(dir, "README.md"), readme); console.log(`prepared ${platform.name}@${version}`); // eslint-disable-line no-console -- build script output }