From ba499236d2c29d30405166ea0812211340cc302f Mon Sep 17 00:00:00 2001 From: Ahmed Tokyo Date: Wed, 15 Jul 2026 21:00:17 +0100 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20prep=20npm=20release=20=E2=80=94=20?= =?UTF-8?q?activate=20publish=20workflow,=20add=20registry=20metadata=20?= =?UTF-8?q?=E2=80=94=200.1.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Un-dormants release.yml now that the zoldytech npm org exists: enables OIDC-based `npm publish --provenance`, and creates the GitHub Release only after publish succeeds (so a failed publish can never leave a tag/release with no matching npm version). Adds package.json registry metadata (publishConfig, repository, homepage, bugs) and drops `private: true`. Updates README to the real npm install command and adds npm/CI badges. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/release.yml | 17 +++++++++-------- README.md | 8 +++++--- package.json | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 17541be..769d680 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,8 @@ -# DORMANT until Phase 2 (npm publish). Phase 1 distributes via GitHub URL + git -# tags, so this workflow is disabled by the `if: false` guard below. To go live: -# 1. Create the `zoldytech` npm org and enable OIDC trusted publishing for this repo. -# 2. Remove `"private": true` from package.json and uncomment `publishConfig`. -# 3. Delete the `if: false` line. -# Publishing is then gated on pushing a `v*` git tag whose version matches package.json. +# Publishing is gated on pushing a `v*` git tag whose version matches package.json. +# Requires OIDC trusted publishing to be enabled for this repo on the @zoldytech npm org +# (npmjs.com -> package settings -> Trusted Publisher -> GitHub Actions -> Zoldytech/javascript -> +# release.yml). The GitHub Release is only created after npm publish succeeds, so a failed +# publish can never leave behind a release/tag with no matching npm version. name: Release on: @@ -12,10 +11,9 @@ on: jobs: publish: - if: false # DORMANT — see header runs-on: ubuntu-latest permissions: - contents: read + contents: write # create the GitHub Release id-token: write # npm provenance (OIDC), no long-lived NPM_TOKEN steps: - uses: actions/checkout@v4 @@ -28,3 +26,6 @@ jobs: - run: npm run lint - run: npm test - run: npm publish --provenance --access public + - run: gh release create "${{ github.ref_name }}" --generate-notes + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/README.md b/README.md index dcd46e6..4bc9779 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # @zoldytech/javascript +[![npm version](https://img.shields.io/npm/v/@zoldytech/javascript.svg)](https://npmjs.com/package/@zoldytech/javascript) +[![npm downloads](https://img.shields.io/npm/dm/@zoldytech/javascript.svg)](https://npmjs.com/package/@zoldytech/javascript) +[![CI](https://img.shields.io/github/actions/workflow/status/Zoldytech/javascript/ci.yml?branch=main)](https://github.com/Zoldytech/javascript/actions/workflows/ci.yml) + A general-purpose ESLint **house style**, built on [`@antfu/eslint-config`](https://github.com/antfu/eslint-config) and made **SonarQube-compatible**: local ESLint mirrors what the SonarQube gate flags, so you fix Sonar issues before they reach CI. Five stack presets — **plain JS/TS**, **React + Vite**, @@ -26,10 +30,8 @@ Sonar issues before they reach CI. Five stack presets — **plain JS/TS**, **Rea ## Install -Distributed via GitHub URL, pinned to a tag (no build step runs on install — raw ESM): - ```bash -npm i -D "github:zoldytech/javascript#0.1.2" +npm i -D @zoldytech/javascript ``` ## Usage diff --git a/package.json b/package.json index d164126..68d151b 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,20 @@ { "name": "@zoldytech/javascript", "type": "module", - "version": "0.1.3", - "private": true, + "version": "0.1.4", "description": "Zoldytech's JavaScript/TypeScript standards: SonarQube-compatible ESLint presets (Next.js, NestJS, React+Vite, plain JS/TS) plus shared Prettier and tsconfig configs.", "license": "MIT", + "homepage": "https://github.com/Zoldytech/javascript#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/Zoldytech/javascript.git" + }, + "bugs": { + "url": "https://github.com/Zoldytech/javascript/issues" + }, + "publishConfig": { + "access": "public" + }, "prettier": "./prettier/prettierrc.json", "exports": { "./eslint": "./eslint/index.js", From e8b6a10819e9b42ad61786a944b489aa39301c19 Mon Sep 17 00:00:00 2001 From: Ahmed Tokyo Date: Wed, 22 Jul 2026 20:26:57 +0100 Subject: [PATCH 2/2] fix(release): split publish/release into separate least-privilege jobs Addresses Copilot review on #2: contents:write wasn't needed for npm publish itself; the tag-vs-package.json version gate was documented but never enforced; and a failed `gh release create` after a successful publish had no clean retry path (rerunning the job would rerun npm publish, which fails on an already-published version). Splitting into publish -> release jobs fixes all three, and lets the release job be rerun independently. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/release.yml | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 769d680..0c52299 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,13 @@ -# Publishing is gated on pushing a `v*` git tag whose version matches package.json. -# Requires OIDC trusted publishing to be enabled for this repo on the @zoldytech npm org -# (npmjs.com -> package settings -> Trusted Publisher -> GitHub Actions -> Zoldytech/javascript -> -# release.yml). The GitHub Release is only created after npm publish succeeds, so a failed -# publish can never leave behind a release/tag with no matching npm version. +# Publishing is gated on pushing a `v*` git tag whose version matches package.json (verified in +# the `publish` job below — a mismatch fails the job). Requires OIDC trusted publishing to be +# enabled for this repo on the @zoldytech npm org (npmjs.com -> package settings -> Trusted +# Publisher -> GitHub Actions -> Zoldytech/javascript -> release.yml). +# +# Publish and release-creation are separate jobs, each with least-privilege permissions. The tag +# itself already exists once pushed (that's what triggers this workflow) regardless of outcome, +# but the GitHub Release is only created after `publish` succeeds — and lives in its own job so it +# can be re-run on its own if it fails, without re-attempting `npm publish` (which would fail once +# the version is already on the registry). name: Release on: @@ -13,7 +18,7 @@ jobs: publish: runs-on: ubuntu-latest permissions: - contents: write # create the GitHub Release + contents: read id-token: write # npm provenance (OIDC), no long-lived NPM_TOKEN steps: - uses: actions/checkout@v4 @@ -23,9 +28,24 @@ jobs: cache: npm registry-url: https://registry.npmjs.org - run: npm ci + - name: Verify tag matches package.json version + run: | + PKG_VERSION="v$(node -p "require('./package.json').version")" + if [ "$PKG_VERSION" != "${{ github.ref_name }}" ]; then + echo "::error::Tag ${{ github.ref_name }} does not match package.json version ($PKG_VERSION)" + exit 1 + fi - run: npm run lint - run: npm test - run: npm publish --provenance --access public + + release: + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write # create the GitHub Release + steps: + - uses: actions/checkout@v4 - run: gh release create "${{ github.ref_name }}" --generate-notes env: GITHUB_TOKEN: ${{ github.token }}