@jgbi/jgb-release
v0.5.0
Published
CLI for versioning, tagging and pushing releases (GitHub or NPM).
Maintainers
Readme
lang: en title: jgb-release README
jgb-release
- @jgbi/jgb-release (NPM public release)
- @jgbindustries/jgb-release (GitHub repository)
A tiny, batteries-included CLI for cutting releases of Node packages.
It performs:
- Runs
npm installto sync the lockfile - Commits and pushes lockfile changes
- Bumps the version via
npm version(patch/minor/major/prerelease) - Pushes code and tags (
--follow-tags) - Builds the package via
npm run buildif abuildscript exists in package.json (this step runs by default; skip with--no-npm-build) - Publishes the package to npmjs.org (if
npm-publicornpm-privateis set), or to GitHub Packages by default - Preflight: verifies you are authenticated to the target npm registry (npmjs.org or npm.pkg.github.com)
Requirements
- Node.js 18 or newer (ESM-only)
- Git (with access to your origin remote)
- npm (configured for the target registry)
- Optional for GitHub Release: GitHub CLI (
gh) authenticated, or an env tokenGH_TOKEN/GITHUB_TOKEN
Install
A) From npmjs (default)
npm i -D @jgbi/jgb-releaseB) From GitHub Packages (optional)
Add this to your project or user .npmrc (recommended to use user-level, not committed):
registry=https://registry.npmjs.org
@jgbi:registry=https://registry.npmjs.org
@jgbindustries:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${JGBI_GITHUB_TOKEN}Install that token on this computer:
Temporary (for current terminal session only)
$Env:JGBI_GITHUB_TOKEN = "ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX"Permanent (saved in your Windows profile):
setx JGBI_GITHUB_TOKEN "ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Restart PhpStorm, PowerShell, or any open terminal so they pick up the new variable.
You can confirm it’s set with:
echo $Env:JGBI_GITHUB_TOKENQuick test
- Once set, run this from your project root (where .npmrc lives):
npm whoami --registry=https://npm.pkg.github.com- If it returns your GitHub username, authentication is working 🎉
- If it says “unauthorized”, double-check the token scopes (must include read:packages and write:packages for publish).
Then install:
npm i -D @jgbi/jgb-releaseC) From Git (specific tag)
npm i -D git+ssh://[email protected]/jgbindustries/jgb-release.git#v0.1.0Usage
npx jgb-release <type> [options]<type>:patch(default),minor,major, orprerelease[options]: see below
Examples:
# Default: bump patch, push to Git, publish to GitHub Packages
npx jgb-release patch
# Publish as public to npmjs (no GitHub Packages by default)
npx jgb-release patch npm-public
# Publish as private to npmjs (no GitHub Packages by default)
npx jgb-release patch npm-private
# Publish to both npmjs and GitHub Packages
npx jgb-release patch npm-public --gh-publish
# Publish-only (no install, no git, no version bump) to npmjs public
# (still runs build if a build script exists unless you pass --no-npm-build)
npx jgb-release --publish-only npm-public
# Publish-only (no install, no git, no version bump) to GitHub Packages (default)
npx jgb-release --publish-only
# Also create a GitHub Release (releases page entry with notes)
npx jgb-release patch --gh-release
# Skip building even if package.json has a build script
npx jgb-release patch --no-npm-build
# Preview only, do nothing
npx jgb-release minor --dry-run
# Bump & push only, skip all publishing
npx jgb-release major --no-publishNotes
- If you use
npm-publicornpm-private, only npmjs.org is used (no GitHub Packages) unless you also pass--gh-publish.- By default, the CLI pushes to your Git repo (unless
--nogit) and publishes to GitHub Packages.- If your package.json defines a
buildscript,npm run buildwill be executed before publishing. This step runs by default and can be skipped with--no-npm-build.- Use
--no-publishto skip all publishing.- Use
--publish-onlyto publish the current version without running install, git, or version bump.- Additional
npm versionflags (for example--preid=beta) are passed through.- Tip: If you accidentally type
node-publicornode-private, the CLI will assume you meantnpm-public/npm-privateand print a warning.
What’s the difference between --gh-publish and --gh-release?
--gh-publishcontrols publishing your npm package to GitHub Packages (the npm registry athttps://npm.pkg.github.com). It’s about where the tarball is uploaded.--gh-releasecreates a GitHub Release on the repository’s Releases page (a tag plus human‑readable notes). It does not publish the npm package anywhere.
You can use them together or separately:
- Default: publish package to GitHub Packages, no GitHub Release page.
npm-publicornpm-private: publish to npmjs.org (no GitHub Packages), and if you also pass--gh-publishthen publish to both.--gh-release: add a GitHub Release page entry in addition to whatever publish targets are selected.
Configuration via package.json (optional)
You can set defaults in your consumer project’s package.json under the jgb-release key:
{
// ...
"jgb-release": {
"publish": "github" // or "npm" or ["npm", "github"],
"private": false // npm access when publishing to npmjs: false=public, true=private
}
}Behavior:
- If you run
jgb-releasewithout publish-related flags, these settings are used. - If you pass publish flags on the CLI (
npm-public,npm-private,--gh-publish, or--no-publish), they override thepackage.jsonconfig and a WARNING is printed. - The top‑level
package.jsonfieldprivate: trueis an npm safeguard that blocks publishing to any registry (including GitHub Packages). If present, the tool exits with a clear error. Remove it or setfalseto publish.
Examples:
- Default to GitHub Packages:
"jgb-release": { "publish": "github" } - Default to npmjs.org public:
"jgb-release": { "publish": "npm", "private": false } - Publish to both npmjs and GitHub Packages by default:
"jgb-release": { "publish": ["npm", "github"], "private": false }
npm authentication pre-check
Before publishing, the CLI verifies that you are logged into the target npm registry:
- npmjs.org:
npm whoami --registry=https://registry.npmjs.org/ - GitHub Packages:
npm whoami --registry=https://npm.pkg.github.com/
If not authenticated, the CLI exits early with guidance instead of failing mid-publish (ENEEDAUTH).
Quick setup:
npmjs.org
- Run
npm login(or configure a token in your user-level.npmrc).
- Run
GitHub Packages (npm)
- Use a scoped package name, e.g.
@your-scope/your-pkg. - Add to your user-level
.npmrc:@<your-scope>:registry=https://npm.pkg.github.com //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} - Set
GITHUB_TOKEN(orGH_TOKEN) withrepo:packagespermissions. - Verify:
npm whoami --registry=https://npm.pkg.github.com/
- Use a scoped package name, e.g.
GitHub Release prerequisites (important)
If you use --gh-release (and are publishing to GitHub Packages), you must have either the GitHub CLI (gh) installed and authenticated, or a GITHUB_TOKEN/GH_TOKEN set in your environment. The script will check for these before proceeding.
Choose one of the following:
- GitHub CLI (recommended)
- Install the CLI on Windows (powershell / cmd.exe):
winget install --id GitHub.cli -e- Authenticate: Restart powershell / cmd
gh auth loginFollow the prompts (HTTPS, GitHub.com, sign in with browser). Verify:
gh auth statusIf authenticated, the release step will work automatically - but you may have to restart the IDE or other CLI that you are using.
- Personal Access Token (env var)
- Create a token at https://github.com/settings/tokens
- Classic PAT: use scope
public_repofor public repos, orrepofor private. - Fine-grained: grant repo access and allow "Contents: Read and write" (plus default "Metadata: Read-only").
- Classic PAT: use scope
- Set it in your environment as
GH_TOKEN(orGITHUB_TOKEN). On Windows cmd.exe:
:: Current terminal only
set GH_TOKEN=ghp_yourTokenHere
:: Persist for future terminals (requires a new terminal afterwards)
setx GH_TOKEN "ghp_yourTokenHere"Then re-run your release command from a new terminal so Node picks up the variable.
Troubleshooting
- "Skipping GitHub Release: no gh CLI and no GITHUB_TOKEN/GH_TOKEN set." → Install
ghand login, or setGH_TOKEN/GITHUB_TOKEN. - 403 (forbidden/rate-limit) when using the API → Ensure the token scopes are correct; try a classic PAT with
public_repo/repo. - You can skip creating a GitHub Release (default) or use
--gh-releaseto enable it.
Project structure
The CLI is now split into small modules for readability and testability:
bin/jgb-release.js— thin entrypoint, delegates to the orchestratorsrc/main.js— orchestrates the release flowsrc/cli/args.js— parses CLI flags and prints helpsrc/utils/run.js— small wrapper aroundchild_process.execSyncsrc/utils/semverNext.js— local semver bump helpersrc/git/helpers.js— git utilities and reachability checkssrc/npm/checks.js— pre-publish checks (first-publish prompt, scope guidance, auth pre-check)src/npm/publish.js— publish helpers for npmjs and GitHub Packagessrc/github/release.js— create a GitHub Release via gh or REST API
Install instructions after publishing
After a release, the CLI prints install instructions. Typical case (GitHub Packages or npmjs):
- Add to your
package.jsondevDependencies:
"@jgbi/jgb-release": "^<new-version>"- Install with:
npm i -D @jgbi/jgb-releaseIf you published to a different registry via --registry, ensure your target project has an appropriate .npmrc.
Notes
- Default registry for publishing is GitHub Packages; you can publish to npmjs.org using
npm-privateornpm-public. - Auth is handled by your local npm config/login. For private/scoped packages to npmjs, you may need a paid npm account.
- For private GitHub repos, the tool first uses
git ls-remoteto verify reachability. If needed, setGITHUB_TOKEN(orGH_TOKEN) for an API fallback, or use--skip-gh-checkif yourgit pushworks. - Important: The top-level
package.jsonfield"private": trueprevents publishing to any registry (npm behavior), even if your GitHub repository is private. Remove it to publish.
License
MIT © JGB Industries
To update and release this project (jgb-release)
Make your code changes
Commit and push updates to the main branch of the
jgb-releaserepository.Bump version & publish
Run one of the following from the project root:
# --- Default (GitHub Packages) ---
node bin/jgb-release.js patch npm-public # small fixes
node bin/jgb-release.js minor npm-public # new features
node bin/jgb-release.js major npm-public # breaking changes
node bin/jgb-release.js prerelease npm-public --preid=rc # prerelease
# --- Publish only (no install, no git, no version bump) ---
# (runs build if present by default; skip with --no-npm-build)
node bin/jgb-release.js --publish-only # to GitHub Packages (default)
node bin/jgb-release.js --publish-only npm-public # to npmjs (public)
# --- Skip building explicitly (use this to skip the default build step) ---
node bin/jgb-release.js patch --no-npm-build
# --- Skip all publishing (tags/push only) ---
node bin/jgb-release.js patch --no-publish
# --- Private publish to npmjs (scoped package, paid npm account) ---
node bin/jgb-release.js patch npm-private
# --- Public publish to npmjs ---
node bin/jgb-release.js patch npm-public
# --- Use a different registry (e.g., custom) ---
node bin/jgb-release.js patch --registry=https://custom.registry/