npm package: @jgbi/jgb-release
Description: CLI for versioning, tagging and pushing releases (GitHub or NPM).
Latest version: 0.4.12

---
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:

1. Runs `npm install` to sync the lockfile
2. Commits and pushes lockfile changes
3. Bumps the version via `npm version` (patch/minor/major/prerelease)
4. Pushes code and tags (`--follow-tags`)
5. Builds the package via `npm run build` if a `build` script exists in package.json (this step runs by default; skip with `--no-npm-build`)
6. Publishes the package to **npmjs.org** (if `npm-public` or `npm-private` is set), or to **GitHub Packages** by default
7. 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 token `GH_TOKEN`/`GITHUB_TOKEN`

## Install

### A) From npmjs (default)

```sh
npm i -D @jgbi/jgb-release
```

### B) 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}
```

1. Install that token on this computer:
   1. Temporary (for current terminal session only) 
   
      `$Env:JGBI_GITHUB_TOKEN = "ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX"`

   2. Permanent (saved in your Windows profile):
   
      `setx JGBI_GITHUB_TOKEN "ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX"`

2.  Restart PhpStorm, PowerShell, or any open terminal so they pick up the new variable.
3.  You can confirm it’s set with: `echo $Env:JGBI_GITHUB_TOKEN`
4. Quick test 
   1. Once set, run this from your project root (where .npmrc lives):

    `npm whoami --registry=https://npm.pkg.github.com`

   2. If it returns your GitHub username, authentication is working 🎉 
   3. If it says “unauthorized”, double-check the token scopes (must include read:packages and write:packages for publish).


Then install:

```sh
npm i -D @jgbi/jgb-release
```

### C) From Git (specific tag)

```sh
npm i -D git+ssh://git@github.com/jgbindustries/jgb-release.git#v0.1.0
```

## Usage

```sh
npx jgb-release <type> [options]
```

- `<type>`: `patch` (default), `minor`, `major`, or `prerelease`
- `[options]`: see below

Examples:

```sh
# 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-publish
```

> Notes
> - If you use `npm-public` or `npm-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 `build` script, `npm run build` will be executed before publishing. This step runs by default and can be skipped with `--no-npm-build`.
> - Use `--no-publish` to skip all publishing.
> - Use `--publish-only` to publish the current version without running install, git, or version bump.
> - Additional `npm version` flags (for example `--preid=beta`) are passed through.
> - Tip: If you accidentally type `node-public` or `node-private`, the CLI will assume you meant `npm-public`/`npm-private` and print a warning.

## What’s the difference between --gh-publish and --gh-release?

- `--gh-publish` controls publishing your npm package to GitHub Packages (the npm registry at `https://npm.pkg.github.com`). It’s about where the tarball is uploaded.
- `--gh-release` creates 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-public` or `npm-private`: publish to npmjs.org (no GitHub Packages), and if you also pass `--gh-publish` then 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:

```jsonc
{
  // ...
  "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-release` without 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 the `package.json` config and a WARNING is printed.
- The top‑level `package.json` field `private: true` is an npm safeguard that blocks publishing to any registry (including GitHub Packages). If present, the tool exits with a clear error. Remove it or set `false` to publish.

Examples:
- Default to GitHub Packages:
  ```jsonc
  "jgb-release": { "publish": "github" }
  ```
- Default to npmjs.org public:
  ```jsonc
  "jgb-release": { "publish": "npm", "private": false }
  ```
- Publish to both npmjs and GitHub Packages by default:
  ```jsonc
  "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`).

- GitHub Packages (npm)
  1. Use a scoped package name, e.g. `@your-scope/your-pkg`.
  2. Add to your user-level `.npmrc`:
     ```
     @<your-scope>:registry=https://npm.pkg.github.com
     //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
     ```
  3. Set `GITHUB_TOKEN` (or `GH_TOKEN`) with `repo:packages` permissions.
  4. Verify: `npm whoami --registry=https://npm.pkg.github.com/`

## 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:

1) GitHub CLI (recommended)
- Install the CLI on Windows (powershell / cmd.exe):

```bat
winget install --id GitHub.cli -e
```

- Authenticate:
Restart powershell / cmd
```bat
gh auth login
```

Follow the prompts (HTTPS, GitHub.com, sign in with browser). Verify:

```bat
gh auth status
```
If authenticated, the release step will work automatically - but you may have to restart the IDE or other CLI that you are using.

2) Personal Access Token (env var)
- Create a token at https://github.com/settings/tokens
  - Classic PAT: use scope `public_repo` for public repos, or `repo` for private.
  - Fine-grained: grant repo access and allow "Contents: Read and write" (plus default "Metadata: Read-only").
- Set it in your environment as `GH_TOKEN` (or `GITHUB_TOKEN`). On Windows cmd.exe:

```bat
:: 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 `gh` and login, or set `GH_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-release` to 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 orchestrator
- `src/main.js` — orchestrates the release flow
- `src/cli/args.js` — parses CLI flags and prints help
- `src/utils/run.js` — small wrapper around `child_process.execSync`
- `src/utils/semverNext.js` — local semver bump helper
- `src/git/helpers.js` — git utilities and reachability checks
- `src/npm/checks.js` — pre-publish checks (first-publish prompt, scope guidance, auth pre-check)
- `src/npm/publish.js` — publish helpers for npmjs and GitHub Packages
- `src/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.json` devDependencies:

```
"@jgbi/jgb-release": "^<new-version>"
```

- Install with:

```sh
npm i -D @jgbi/jgb-release
```

If 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-private` or `npm-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-remote` to verify reachability. If needed, set `GITHUB_TOKEN` (or `GH_TOKEN`) for an API fallback, or use `--skip-gh-check` if your `git push` works.
- Important: The top-level `package.json` field `"private": true` prevents 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`)

1) Make your code changes

   Commit and push updates to the main branch of the `jgb-release` repository.

2) Bump version & publish

Run one of the following from the project root:

```sh
# --- 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/
```