diff --git a/.agents/skills/verify-source-changes/SKILL.md b/.agents/skills/verify-source-changes/SKILL.md index cc01f77a..cb83490e 100644 --- a/.agents/skills/verify-source-changes/SKILL.md +++ b/.agents/skills/verify-source-changes/SKILL.md @@ -26,7 +26,7 @@ description: >- `src/index.ts`. 5. Inspect changelog and generated changes. Keep only updates caused by the source change. -6. Run the relevant focused Jest test, then: +6. Run the relevant focused Vitest test, then: - `pnpm exec biome check .` - `pnpm run test:ci` - `pnpm run build` diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index fab1c755..c7305bc2 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -3,11 +3,13 @@ name: Publish Package to npmjs on: release: types: [published] +permissions: + contents: read jobs: - build: + validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v6 name: Install pnpm @@ -15,15 +17,64 @@ jobs: version: 11.2.2 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version-file: .nvmrc - cache: pnpm - cache-dependency-path: pnpm-lock.yaml + package-manager-cache: false - name: Install dependencies run: pnpm install --frozen-lockfile - - run: npm publish + - name: Validate + run: | + pnpm exec biome check . + pnpm run typecheck + pnpm test + + - name: Verify release tag env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + PACKAGE_VERSION=$(node -p "require('./package.json').version") + test "$RELEASE_TAG" = "v$PACKAGE_VERSION" + + - name: Pack + run: | + mkdir -p package-artifact + pnpm pack --pack-destination package-artifact + + - name: Upload package + uses: actions/upload-artifact@v7 + with: + name: npm-package + path: package-artifact/*.tgz + if-no-files-found: error + retention-days: 1 + + publish: + needs: validate + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + package-manager-cache: false + + - name: Verify npm version + run: | + NPM_VERSION=$(npm --version) + node -e 'const [major, minor] = process.argv[1].split(".").map(Number); if (major < 11 || (major === 11 && minor < 5)) process.exit(1)' "$NPM_VERSION" + + - name: Download package + uses: actions/download-artifact@v8 + with: + name: npm-package + path: package-artifact + + - name: Publish + run: npm publish package-artifact/*.tgz --access public diff --git a/.npmignore b/.npmignore index 63d1266b..62673d45 100644 --- a/.npmignore +++ b/.npmignore @@ -4,7 +4,5 @@ coverage/* docs/* .babelrc -.eslintignore -.eslintrc.js .npmignore webpack.config.js diff --git a/.vscode/settings.json b/.vscode/settings.json index abf1f024..85a1f5e1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,5 +36,8 @@ }, "files.readonlyInclude": { "**/routeTree.gen.ts": true + }, + "files.exclude": { + "**/dist": false } } diff --git a/AGENTS.md b/AGENTS.md index 2884f105..23ba7721 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,8 +6,8 @@ `.nvmrc` and pnpm 11.2.2 from `package.json`; do not substitute npm or yarn. - Install with `pnpm install --frozen-lockfile`. Add dependencies with `pnpm add -E` so versions remain exact. -- The package builds strict ES2020 TypeScript with tsup into CommonJS, ESM, and - declaration outputs. Tests use Jest with ts-jest; formatting and linting use +- The package builds strict ES2020 TypeScript with esbuild and tsc into CommonJS, + ESM, and declaration outputs. Tests use Vitest; formatting and linting use Biome. Treat Biome as authoritative over legacy ESLint/Prettier references. ## Source And Generated Files @@ -29,7 +29,7 @@ - Match existing structure and reuse existing types and helpers. Keep changes minimal, localized, and limited to the requested behavior. -- Add or update the smallest focused colocated Jest tests for behavior changes. +- Add or update the smallest focused colocated Vitest tests for behavior changes. - After adding, updating, moving, or removing source code, use the project `$verify-source-changes` skill to determine the next SemVer version, update `docs-md/changelog.md`, regenerate documentation and exports, then inspect diff --git a/README.md b/README.md index fd41fb5d..4f73697e 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,6 @@ Read more about the methods available [here](https://iamdevlinph.github.io/commo - Coverage using [Istanbul](https://github.com/gotwarlost/istanbul) with [nyc](https://github.com/istanbuljs/nyc) and report by [Codecov](https://github.com/codecov/codecov-node) - Create the bundle using [webpack](https://github.com/webpack/webpack) - Run tests using [Mocha](https://github.com/mochajs/mocha) and [chai](https://github.com/chaijs/chai) -- Lint stuff using [ESLint](https://github.com/eslint/eslint) - Build status by [Travis](https://github.com/travis-ci/travis-ci) - Precommit using [lint-staged](https://github.com/okonet/lint-staged) and [husky](https://github.com/typicode/husky) - Provides TypeScript type definitions --> @@ -113,9 +112,39 @@ src/ # Publishing -### Publish to NPM +Maintainers should validate a release locally before publishing: -To publish version, just create a relase tag and a github workflow will automatically handle the publishing to npm. +```sh +pnpm run typecheck +pnpm test +pnpm run pack:check +``` + +Configure **Settings → Trusted Publisher** for this package on npmjs.com: + +| Setting | Value | +| --- | --- | +| Provider | GitHub Actions | +| Organization / user | `iamdevlinph` | +| Repository | `common-utils-pkg` | +| Workflow filename | `publish-package.yml` | +| Environment | *(blank)* | +| Allowed action | `npm publish` | + +Enter only the workflow filename, not its full path. Trusted Publishing uses +OIDC; do not add `NPM_TOKEN`, `NODE_AUTH_TOKEN`, or a package PAT. It requires a +GitHub-hosted runner, Node 22.14 or newer, and npm 11.5.1 or newer. The workflow +uses Node 24 (from `.nvmrc`), verifies npm 11.5.1 or newer, and uses pnpm 11.2.2. + +To release, update the version in `package.json`, create and push the matching +tag `v`, then publish a GitHub Release for that tag. The workflow +requires the release tag to equal `v` plus the package version. + +If publishing fails only because of external configuration, rerun the failed +job. If code or workflow changes are required, publish a new version unless the +failed tag was never released and is intentionally recreated. After the first +successful OIDC publish, delete the obsolete GitHub `NPM_TOKEN` secret and set +npm publishing access to require two-factor authentication and disallow tokens. ### Publish doc updates @@ -132,7 +161,6 @@ Run by `npm run