# Release setup The repository uses one npm lockfile and GitHub Actions. Node 24 supplies the modern npm CLI needed for trusted publishing. Do not restore the retired Travis deploy key, old semantic-release setup, or duplicate lockfiles. ## One-time setup 1. In the npm settings for `yup-phone`, add a GitHub Actions trusted publisher: organization/user `abhisekp`, repository `yup-phone`, workflow `release.yml`, environment `npm`. Follow [npm's trusted publishing documentation](https://docs.npmjs.com/trusted-publishers/). Only a package owner can establish this trust; no npm token is committed or required by this workflow. Ensure the environment name matches exactly and enable the publisher's direct `npm publish` permission. 2. In repository Actions settings, allow Actions to create pull requests. This setting was already enabled when inspected on October 6, 2026. Release Please uses the built-in `GITHUB_TOKEN`. The workflow explicitly dispatches CI, CodeQL, and bundle refresh on each created or updated release PR, avoiding GitHub's suppression of ordinary events generated by that token. No personal access token or `RELEASE_PLEASE_TOKEN` is needed. 3. Protect master with CI and CodeQL checks. The `npm` environment was created on October 6, 2026 and permits only the master branch (no tags). It contains no secrets and does not require a separate publication approval. Optional environment reviewers can be added if each publication should need approval. 4. Resolve the account billing lock before running Actions. CodeQL had been disabled for inactivity and was re-enabled on October 6, 2026. Dependabot was also paused for inactivity when inspected; merge a reviewed Dependabot PR to resume its updates. Repository code cannot clear these account and service settings. ## Normal release Merge conventional commits into master. Use `fix:` for patches, `feat:` for features, and `feat!:` or a `BREAKING CHANGE:` footer for a major release. Release Please opens or updates a version/changelog PR. Merging that version PR creates a Git tag and GitHub Release. In the same workflow run, a read-only preparation job checks the tagged source, audits dependencies, tests the package, and creates its tarball and benchmark reports. A SHA-256 manifest binds those files to the version, tag, and exact source commit. Its digest passes through the job output independently of the downloaded artifact. The publication job receives only the prepared files. It installs no project dependencies and performs no build, test, or benchmark execution. First-party code from the workflow's own revision verifies the manifest digest, every file checksum, the current tag target, the version, and master ancestry before npm publication with provenance. It then attaches the tarball, reports, and manifest to the GitHub Release. Checkouts do not persist credentials, and publication only runs from master. This avoids relying on another workflow being triggered by a bot-created tag or release event. PR checks and release PR merging remain the review gate. Tagging, GitHub Release creation, packaging, npm publication, provenance, and evidence uploads run automatically after the version PR is merged. The initial migration PR must be merged before the new Release and Refresh dist workflows are registered on master. They are not expected to publish from migration PR #836. For the first migration, the release manifest starts at 1.3.2 and the breaking migration commit requests 2.0.0. Thereafter versions advance normally. ## Local checks ```sh npm ci --ignore-scripts npm run check npm run test:baseline npm run format:check npm audit --audit-level=low npm run benchmark npm pack --ignore-scripts ``` The CI compatibility matrix additionally installs Yup 0.32.11 and 1.0.0 without changing the lockfile. Types are checked with library checks enabled. Native TypeScript runs in single-thread mode to avoid excessive checker memory use on the older Yup declarations. Do not publish if required checks fail. When a scheduled audit or metadata comparison fails, update the dependency/lockfile and investigate any behavior change before accepting it. If tagging succeeded but publication failed, rerun the failed workflow jobs or dispatch the Release workflow from master with the existing tag (for example `v2.0.0`). It prepares and verifies the exact tag before handing the checked artifact to the publication job. Never move an existing release tag to retry. If npm publication already succeeded, a retry only continues when the packed tarball's integrity matches that existing npm version; differing contents fail. `npm run test:release` exercises real packing in a disposable local repository. It checks tampered manifests, packages and reports; extra files; missing digests; tag movement; master ancestry; older-tag retries from a newer workflow revision; disabled lifecycle scripts; and npm retry handling. Registry and publication calls are simulated, so these tests never publish a package. ## Commit formatting and checked-in builds Developers who want the Commitizen/cz-emoji menus install the [Commitizen CLI](https://github.com/commitizen/cz-cli#installing-the-command-line-tool) globally, then run it from the repository: ```sh npm install --global commitizen npm run commit ``` Commitizen is optional developer tooling and is not installed by `npm ci` or CI. The `commit` script uses the developer's `cz` executable on PATH. The project's adapter and cz-emoji dependency remain local so the menus and configuration are shared. Developers can also create commits directly with `git commit`. All original emoji categories and scopes remain in package.json. The small adapter translates aliases such as feature to feat and refactoring to refactor, retaining the emoji, so Release Please recognizes the change. The breaking category emits a major release marker. Conventional headers and historical Gitmoji headers both pass commitlint; new automated releases should use conventional headers, including those produced by the adapter. `npm install` installs the Husky commit-message hook, and `npm run prepare` installs it after a scripts-disabled checkout. Development requires Node 22.12+ for current commitlint. The library's production runtime requirement remains Node 18+. The audited overrides patch development dependency paths. No audit findings are ignored. Distribution files are tracked under dist/. CI rebuilds and verifies them. The Refresh dist workflow builds with a read-only token, then a separate job commits only generated bundles for branches in this repository. That job executes no project scripts and dispatches CI/CodeQL on the new commit, because GitHub's default token suppresses ordinary push-triggered workflows. Fork contributors can run `npm run build` and include the generated files in their own commits. The workflow can also be dispatched for a named repository branch. ## GitHub Pages The website is served from master under `/docs`, using the existing `yup-phone.js.org` custom domain. The `.nojekyll` file makes the HTML, styles, and scripts deploy as static files. Changes go live when their PR is merged into master; no separate hosting service or credentials are needed. The playground bundles the actual phone validator, its locked Yup version, and phone metadata locally. It does not send entered numbers to a server. Rebuild and preview it with: ```sh npm run build:docs python -m http.server 4187 --bind 127.0.0.1 --directory docs ``` Open `http://127.0.0.1:4187/` in a browser. The full `npm run build` also refreshes `docs/assets/playground.js`. CI checks this generated file alongside dist/, and Refresh dist updates both when package versions or dependencies change. Include the regenerated asset in commits that change the playground source. The complete usage guide remains in `docs/guide.md`. The workflow security scanner flags the deliberate `pull_request_target` trigger and the unlocked Yup installation in the compatibility matrix. Refresh dist rejects fork heads; its build job has read-only permissions, no secrets, and no persisted checkout credentials. Its separate write job executes no project scripts. The matrix installation tests old and latest Yup in read-only jobs; it does not change the locked release dependency tree. These reviewed findings remain visible rather than being globally suppressed. The retired Babel config targeted Node 9/core-js 2; esbuild now supplies the documented ES2020 outputs. TSLint is replaced by TypeScript checking, formatting, and code analysis. Release Please replaces .releaserc.json, and GitHub Actions and npm OIDC replace the unused Travis encrypted deploy key. These old files would imply active tools or credentials that the current workflow does not use. Commitlint is independent of those replacements and remains enabled.