{"id":49072362,"url":"https://github.com/nxsjs/nxspub","last_synced_at":"2026-04-20T08:05:45.423Z","repository":{"id":350851540,"uuid":"1208484241","full_name":"nxsjs/nxspub","owner":"nxsjs","description":"Automated release tool tailored for modern multi-branch workflows","archived":false,"fork":false,"pushed_at":"2026-04-19T15:24:14.000Z","size":1014,"stargazers_count":42,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-19T15:30:55.732Z","etag":null,"topics":["angular","automatic","changelog","git-hooks","nxsjs","nxspub","publish","release","version","workflow"],"latest_commit_sha":null,"homepage":"https://nxsjs.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nxsjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-12T10:51:50.000Z","updated_at":"2026-04-19T15:24:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nxsjs/nxspub","commit_stats":null,"previous_names":["nxsjs/nxspub"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/nxsjs/nxspub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxsjs%2Fnxspub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxsjs%2Fnxspub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxsjs%2Fnxspub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxsjs%2Fnxspub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nxsjs","download_url":"https://codeload.github.com/nxsjs/nxspub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nxsjs%2Fnxspub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32038459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","automatic","changelog","git-hooks","nxsjs","nxspub","publish","release","version","workflow"],"created_at":"2026-04-20T08:05:44.657Z","updated_at":"2026-04-20T08:05:45.416Z","avatar_url":"https://github.com/nxsjs.png","language":"TypeScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://nxsjs.com\"\u003e\n    \u003cimg width=\"100\" alt=\"nxspub logo\" src=\"logo.svg\"\u003e\n  \u003c/a\u003e\n\n\u003chr/\u003e\n\n  \u003cdiv style=\"display: flex; justify-content: center; gap: 8px;\"\u003e\n    \u003ca href=\"https://nxsjs.com\"\u003e\u003cimg alt=\"Made by NxsJs\" src=\"https://img.shields.io/badge/MADE%20BY%20NxsJs-CCEE00.svg?logo=data:image/svg%2Bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgNCkiPjxwYXRoIGQ9Ik02IDI2VjZjMC0yLjIgMS44LTQgNC00aDQuNWw3IDEwVjZjMC0yLjIgMS44LTQgNC00SDMwdjIwYzAgMi4yLTEuOCA0LTQgNGgtNC41bC03LTEwdjZjMCAyLjItMS44IDQtNCA0SDZ6IiBmaWxsPSIjMDAwIi8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yLCAyKSI+PHBhdGggZD0iTTYgMjZWNmMwLTIuMiAxLjgtNCA0LTRoNC41bDcgMTBWNmMwLTIuMiAxLjgtNCA0LTRIMzB2MjBjMCAyLjItMS44IDQtNCA0aC00LjVsLTctMTB2NmMwIDIuMi0xLjggNC00IDRINnoiIGZpbGw9IiNDQ0ZGMDAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyLjUiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48L2c+PC9zdmc+\u0026style=for-the-badge\u0026labelColor=000000\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/nxspub\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/nxspub?style=for-the-badge\u0026color=000000\u0026labelColor=FF4400\" alt=\"npm version\"\u003e\u003c/a\u003e\n    \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/nxspub?style=for-the-badge\u0026color=000000\u0026labelColor=00AAFF\" alt=\"license\"\u003e\u003c/a\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n## Nxspub\n\n`nxspub` is a release automation CLI for npm packages and pnpm workspaces.\n\nIt handles:\n\n- commit-message linting\n- branch-based version policies\n- changelog generation\n- git tagging and pushing\n- npm publishing\n- monorepo release propagation\n\nThe project assumes a Conventional Commits workflow and is designed for multi-branch release lines such as `main`, `alpha`, `beta`, and `rc`.\n\n## Installation\n\n```bash\npnpm add -D nxspub\n```\n\n## Quick Start\n\n### 1. Add scripts\n\n```json\n{\n  \"scripts\": {\n    \"check\": \"tsc --incremental --noEmit\",\n    \"postinstall\": \"nxspub git-hooks\",\n    \"version\": \"nxspub version\",\n    \"release\": \"nxspub release\"\n  }\n}\n```\n\n### 2. Add minimal config\n\nYou can place config in `package.json`:\n\n```json\n{\n  \"nxspub\": {\n    \"git-hooks\": {\n      \"pre-commit\": \"pnpm lint-staged \u0026\u0026 pnpm check\"\n    }\n  }\n}\n```\n\nOr use `nxspub.config.ts`:\n\n```ts\nimport { defineConfig } from 'nxspub'\n\nexport default defineConfig({\n  branches: {\n    main: 'latest',\n    master: 'latest',\n    alpha: 'preminor',\n    beta: 'preminor',\n    rc: 'preminor',\n  },\n  'git-hooks': {\n    'pre-commit': 'pnpm lint-staged \u0026\u0026 pnpm check',\n  },\n})\n```\n\n### 3. Install hooks\n\n```bash\npnpm exec nxspub git-hooks\n```\n\n### 4. Release flow\n\n```bash\npnpm version\npnpm release\n```\n\n`nxspub version` updates versions, changelogs, commits the release, and creates tags.\n\n`nxspub release` builds the package and publishes it to npm.\n\n## Core Concepts\n\n### Branch Policies\n\nEach branch can define what kind of release it is allowed to produce.\n\nExample:\n\n```ts\nbranches: {\n  main: 'latest',\n  alpha: 'preminor',\n  beta: 'preminor',\n  hotfix: 'patch',\n}\n```\n\nAvailable branch policy types:\n\n- `major`\n- `minor`\n- `patch`\n- `latest`\n- `premajor`\n- `preminor`\n- `prepatch`\n\nPractical effect:\n\n- `latest` allows normal stable releases.\n- `pre*` branches generate prerelease versions such as `1.2.0-alpha.0`.\n- restrictive branches such as `patch` prevent larger bumps from being released on that branch.\n\n### Commit-Based Versioning\n\nBy default, `nxspub` maps commit messages to SemVer bumps:\n\n- `major`: `feat(scope)!:`, `feat!:`, `BREAKING CHANGE:`\n- `minor`: `feat:`, `feat(scope):`\n- `patch`: `fix:`, `perf:`, `refactor:`\n\nDefault patterns are configurable through `versioning`.\n\n### Changelog Generation\n\n`nxspub` parses conventional commit messages and generates grouped changelog sections such as:\n\n- `Features`\n- `Bug Fixes`\n- `Performance Improvements`\n- `Refactors`\n- `Reverts`\n\nIt also:\n\n- links commits, pull requests, and issues\n- extracts `BREAKING CHANGE:` details\n- appends contributor sections\n- archives oversized or major-version changelogs\n\nYou can restrict changelog writes to specific branches:\n\n```ts\nchangelog: {\n  writeOnBranches: ['main', 'master']\n}\n```\n\nWhen running `nxspub version` on non-allowed branches, nxspub writes draft files under `.nxspub/changelog-drafts/*`.  \nWhen you later run `nxspub version` on an allowed branch, matching drafts are auto-imported and deduplicated.\nDrafts that are behind/ahead of current target version are kept and reported as warnings, so they are not silently dropped.\n\nYou can audit draft health manually:\n\n```bash\nnxspub draft-doctor --cwd . --target 1.3.0\n```\n\nYou can also prune stale drafts (versions behind the current target):\n\n```bash\nnxspub draft-doctor --cwd . --target 1.3.0 --prune\n```\n\n`nxspub version` and `nxspub release` also use a repository lock file under Git metadata (for example `.git/nxspub/version.lock`) to prevent concurrent pipelines from mutating version/tag state at the same time.\n\n## Configuration\n\n### Full Example\n\n```ts\nimport { defineConfig } from 'nxspub'\n\nexport default defineConfig({\n  workspace: {\n    mode: 'locked',\n    passive: 'patch',\n  },\n  branches: {\n    main: 'latest',\n    master: 'latest',\n    alpha: 'preminor',\n    beta: 'preminor',\n    rc: 'preminor',\n  },\n  versioning: {\n    major: [/(\\w+)\\((.+)\\)!:/, /(\\w+)!:/, /BREAKING CHANGE:/],\n    minor: [/feat\\((.+)\\):/, /feat:/],\n    patch: [\n      /fix\\((.+)\\):/,\n      /fix:/,\n      /perf\\((.+)\\):/,\n      /perf:/,\n      /refactor\\((.+)\\):/,\n      /refactor:/,\n    ],\n  },\n  changelog: {\n    writeOnBranches: ['main', 'master'],\n    labels: {\n      feat: 'Features',\n      fix: 'Bug Fixes',\n      perf: 'Performance Improvements',\n      refactor: 'Refactors',\n      revert: 'Reverts',\n      deps: 'Dependencies',\n    },\n  },\n  lint: {\n    'commit-msg': {\n      pattern:\n        /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\\([^)]+\\))?(!)?: .{1,50}/,\n      message: 'Invalid commit message format.',\n    },\n  },\n  'git-hooks': {\n    'pre-commit': 'pnpm lint-staged \u0026\u0026 pnpm check',\n    'commit-msg': 'pnpm exec nxspub lint --edit \"$1\"',\n  },\n  scripts: {\n    releaseBuild: 'pnpm run build',\n  },\n})\n```\n\n### Config Locations\n\n`nxspub` reads config from:\n\n1. `nxspub.config.ts`\n2. `nxspub.config.mjs`\n3. `nxspub.config.js`\n4. `nxspub.config.cjs`\n5. `package.json#nxspub`\n\nFile-based config is merged with `package.json#nxspub` and defaults.\n\n### Workspace Options\n\n```ts\nworkspace: {\n  mode: 'locked' | 'independent',\n  passive: 'patch' | 'follow' | 'none'\n}\n```\n\n`mode`:\n\n- `locked`: all packages receive the same next version\n- `independent`: each package is versioned individually\n\n`passive`:\n\n- `patch`: dependents get a patch bump when internal dependencies change\n- `follow`: dependents inherit the highest bump from changed dependencies\n- `none`: internal dependency changes do not trigger passive bumps\n\n## Commands\n\n### `nxspub git-hooks`\n\nInstall configured hooks into `.git/hooks`.\n\nOptions:\n\n- `--cwd \u003ccwd\u003e`: run against a target repository instead of the current shell directory\n- `--dry`: preview generated hook content without writing files\n\nExample:\n\n```bash\npnpm exec nxspub git-hooks --cwd ./packages/app --dry\n```\n\n### `nxspub lint --edit \u003cpath\u003e`\n\nValidate a commit message file, typically from the `commit-msg` hook.\n\nOptions:\n\n- `--cwd \u003ccwd\u003e`: resolve relative paths and config from a target repository\n- `--edit \u003cpath\u003e`: path to the commit message file\n\nExample:\n\n```bash\npnpm exec nxspub lint --edit .git/COMMIT_EDITMSG\n```\n\n### `nxspub version`\n\nCalculate the next version, update `package.json`, generate changelog content, create a release commit, create tags, and push to remote.\n\nOptions:\n\n- `--cwd \u003ccwd\u003e`: operate on a target repository\n- `--dry`: preview version and changelog changes without writing files\n\nExample:\n\n```bash\npnpm exec nxspub version --dry\npnpm exec nxspub version --cwd /path/to/repo\n```\n\n### `nxspub release`\n\nBuild and publish a package or workspace.\n\nOptions:\n\n- `--cwd \u003ccwd\u003e`: operate on a target repository\n- `--dry`: run publish in preview mode\n- `--provenance`: pass `--provenance` to `pnpm publish`\n- `--registry [url]`: override the npm registry\n- `--access [access]`: publish access, default `public`\n- `--tag [tag]`: override the npm dist-tag\n- `--branch \u003cbranch\u003e`: override detected branch name\n- `--skipBuild`: skip the build step\n- `--skipSync`: skip remote synchronization checks\n\nExample:\n\n```bash\npnpm exec nxspub release --dry\npnpm exec nxspub release --registry https://registry.npmjs.org\npnpm exec nxspub release --cwd /path/to/repo --branch main\n```\n\n### `nxspub console`\n\nInteractive release console. It includes all previous preview capabilities (read-only release computation + risk checks) and web/API mode.\n\nOptions:\n\n- `--cwd \u003ccwd\u003e`: operate on a target repository\n- `--json`: print machine-readable preview output\n- `--branch \u003cbranch\u003e`: simulate policy/checks on a target branch\n- `--web`: start local preview web console\n- `--host \u003chost\u003e`: web bind host, default `127.0.0.1`\n- `--port \u003cport\u003e`: web bind port, default `4173`\n- `--open`: open browser after web service starts\n- `--readonly-strict`: disable write endpoints (for example draft prune and snapshot save/delete)\n- `--allow-remote`: required when `--host 0.0.0.0`\n- `--api-only`: serve API endpoints only, without web static assets\n\nFeature flag (rollout/rollback):\n\n- `NXSPUB_CONSOLE_WEB_ENABLED=false` disables `console --web` startup globally\n\nExamples:\n\n```bash\npnpm exec nxspub console --json\npnpm exec nxspub console --branch alpha --json\npnpm exec nxspub console --web --open\npnpm exec nxspub console --web --api-only --port 4173\n```\n\n#### Preview Web Workflow\n\nBuild frontend assets:\n\n```bash\npnpm run console:web:build\n```\n\nRun web preview server:\n\n```bash\npnpm exec nxspub console --web --host 127.0.0.1 --port 4173\n```\n\nPreview web stack:\n\n- Server: Nitro HTTP layer (`h3`) hosted by `nxspub console --web`\n- Client: React + Vite with TailwindCSS styling\n- UI language: auto-detects browser language (`zh*` -\u003e Chinese, otherwise English)\n\nRun API-only mode (for custom frontend or proxy):\n\n```bash\npnpm exec nxspub console --web --api-only --host 127.0.0.1 --port 4173\n```\n\nAll `/api/*` requests require header:\n\n```txt\nx-nxspub-console-token: \u003ctoken from server startup\u003e\n```\n\nDiagnostic bundle export endpoints:\n\n- `GET /api/export.bundle?format=json`\n- `GET /api/export.bundle?format=zip`\n\nBundle includes runtime context, preview result, checks report, and draft health data for troubleshooting.\n\nWeb console also supports branch-to-branch comparison (for example `main` vs `alpha`) to inspect target version and release scope differences.\nWorkspace mode includes a layered dependency propagation panel to inspect internal dependency edges and passive bump reasons.\n\nSnapshot endpoints:\n\n- `GET /api/snapshots` list saved snapshots\n- `POST /api/snapshots` save current comparison snapshot\n- `GET /api/snapshots/:id` load snapshot payload\n- `DELETE /api/snapshots/:id` delete a saved snapshot\n\nSnapshots are stored under `.nxspub/preview-snapshots`.\n\nRealtime status stream:\n\n- `GET /api/events?token=\u003csession-token\u003e` (Server-Sent Events)\n\n## Git Hook Setup\n\nTypical hook setup:\n\n```json\n{\n  \"nxspub\": {\n    \"git-hooks\": {\n      \"pre-commit\": \"pnpm lint-staged \u0026\u0026 pnpm check\",\n      \"commit-msg\": \"pnpm exec nxspub lint --edit \\\"$1\\\"\"\n    }\n  }\n}\n```\n\nIf `commit-msg` is not configured, `nxspub git-hooks` injects a default one automatically.\n\n## Monorepo Behavior\n\nWorkspace support is implemented.\n\n`nxspub` scans workspace packages from:\n\n- `pnpm-workspace.yaml`\n- `package.json#workspaces`\n\nFor workspace releases it will:\n\n- detect changed packages from git history\n- compute release bumps per package\n- propagate dependency-driven bumps\n- update internal dependency ranges\n- generate per-package changelogs\n- generate a root changelog summary\n- create package tags and global tags\n\n## `--cwd` Support\n\nAll commands support `--cwd`.\n\nUse it when:\n\n- running `nxspub` from outside the target repository\n- operating on a nested package from a larger shell session\n- automating releases from scripts or CI runners with a shared working directory\n\nExample:\n\n```bash\npnpm exec nxspub version --cwd /absolute/path/to/repo\npnpm exec nxspub release --cwd /absolute/path/to/repo\n```\n\n`--cwd` affects:\n\n- config loading\n- git branch detection\n- git history lookup\n- repository URL lookup\n- changelog link generation\n- package and workspace scanning\n\n## Requirements and Assumptions\n\n- Node.js `\u003e=20`\n- pnpm `\u003e=9.12.3`\n- git repository with a configured `origin`\n- Conventional Commits discipline\n- clean working tree before `version` and `release`\n\n## Typical CI Usage\n\n```bash\npnpm install --frozen-lockfile\npnpm run check\npnpm test\npnpm exec nxspub version --cwd .\npnpm exec nxspub release --cwd . --provenance\n```\n\nIf your CI already guarantees branch state and fetch depth, `--skipSync` can be used deliberately, but it weakens the preflight safety checks.\n\n## Troubleshooting\n\n### Branch not configured\n\nIf you see an error like:\n\n```text\nAdmission Denied: Branch \"feature/x\" not configured.\n```\n\nAdd the branch pattern to `branches`, or override the branch explicitly with:\n\n```bash\npnpm exec nxspub release --branch main\n```\n\n### No version bump detected\n\nIf `nxspub version` reports no version-triggering commits:\n\n- check your commit messages\n- ensure the commits are after the last release commit\n- verify your custom `versioning` regex rules\n\n### Publish skipped\n\nIf publish is skipped, `nxspub` has determined that the target package version is already present in the registry.\n\n## Development\n\n```bash\npnpm install\npnpm run check\npnpm test\npnpm run lint\n```\n\n## Resources\n\n- [Learn Nxspub](https://nxsjs.com)\n- [npm package](https://www.npmjs.com/package/nxspub)\n\n## Contribution\n\nRead the [Contributing Guide](https://github.com/nxsjs/nxspub/blob/main/.github/CONTRIBUTING.md) before opening a pull request.\n\n\u003ca href=\"https://github.com/nxsjs/nxspub/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=nxsjs/nxspub\u0026max=20\u0026columns=12\" /\u003e\n\u003c/a\u003e\n\n\u003csub\u003eNote: showing the first 500 contributors only due to GitHub image size limits.\u003c/sub\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnxsjs%2Fnxspub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnxsjs%2Fnxspub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnxsjs%2Fnxspub/lists"}