releasearoni

Publish GitHub releases from the command line or Node.js. Reads defaults from package.json and CHANGELOG.md (keepachangelog format) so you rarely need to pass any flags. Ships two bins: releasearoni uses the GitHub API directly via @octokit/rest, and releasearoni-gh is a thin wrapper around the gh CLI.
npm install releasearoni
CLI
Both bins share the same flags and read the same defaults. Run either from a directory that contains package.json and CHANGELOG.md.
releasearoni
Uses @octokit/rest + ghauth for authentication. No gh CLI required.
Usage: releasearoni [options]
Example: releasearoni
--tag-name, -t Tag for this release
--target-commitish, -c Commitish value for tag
--name, -n Release title
--body, -b Release body text
--owner, -o Repo owner
--repo, -r Repo name
--draft, -d Publish as draft (default: false)
--prerelease, -p Publish as prerelease (default: false)
--workpath, -w Path to working directory (default: cwd)
--endpoint, -e GitHub API endpoint URL (default: https://api.github.com)
--assets, -a Comma-delimited list of assets to upload
--dry-run Preview release without creating it (default: false)
--no-upsert Fail if a release for this tag already exists (default: false)
--prompt Prompt for confirmation before publishing (default: false)
--no-npm-check Skip npm auth check before publishing (default: false)
--no-push Skip git push --follow-tags before publishing (default: false)
--no-build Skip npm run build even if a build script is present (default: false)
--help, -h Show help
--version, -v Show version
releasearoni (v0.0.0)
releasearoni-gh
Delegates to gh release create. Requires the gh CLI to be installed and authenticated.
Usage: releasearoni-gh [options]
Example: releasearoni-gh
--tag-name, -t Tag for this release
--target-commitish, -c Commitish value for tag
--name, -n Release title
--body, -b Release body text
--owner, -o Repo owner
--repo, -r Repo name
--draft, -d Publish as draft (default: false)
--prerelease, -p Publish as prerelease (default: false)
--workpath, -w Path to working directory (default: cwd)
--endpoint, -e GitHub API endpoint URL (default: https://api.github.com)
--assets, -a Comma-delimited list of assets to upload
--dry-run Preview release without creating it (default: false)
--no-upsert Fail if a release for this tag already exists (default: false)
--prompt Prompt for confirmation before publishing (default: false)
--no-npm-check Skip npm auth check before publishing (default: false)
--no-push Skip git push --follow-tags before publishing (default: false)
--no-build Skip npm run build even if a build script is present (default: false)
--help, -h Show help
--version, -v Show version
releasearoni-gh (v0.0.0)
Defaults
Both bins derive release defaults automatically:
tag_name | v + version from package.json |
name | Same as tag_name |
body | Latest versioned entry from CHANGELOG.md |
target_commitish | Current HEAD commit SHA (git rev-parse HEAD) |
owner / repo | Parsed from repository field in package.json |
draft | false |
prerelease | false |
endpoint | https://api.github.com |
The CHANGELOG.md must be in keepachangelog format. Releases are blocked if an [Unreleased] section contains content.
If a release for the tag already exists (e.g. when re-running a failed publish), both bins will update the existing release in place rather than failing. Pass --no-upsert to get a hard failure instead, which is useful for enforcing that a tag is never accidentally re-released.
releasearoni npm-check
Checks whether you are logged in to npm. If not logged in and the CI environment variable is not set, runs npm login interactively. In CI, exits non-zero with an actionable error if not authenticated. Designed to run at the top of a prepublishOnly script so login issues are caught before any build, push, or release work has started.
Usage: releasearoni npm-check
Typical package.json setup:
{
"scripts": {
"prepublishOnly": "releasearoni"
}
}
releasearoni version
Generates CHANGELOG.md via auto-changelog and stages it with git add. Designed for use as the npm version lifecycle script.
Usage: releasearoni version [options]
--changelog, -c Changelog file to generate and stage (default: CHANGELOG.md)
--add, -a Additional files to stage after changelog (repeatable)
--breaking-pattern Regex for breaking changes (default: 'BREAKING CHANGE:')
--template auto-changelog template (default: keepachangelog)
--workpath, -w Working directory (default: cwd)
--help, -h Show help
Typical package.json setup — no separate auto-changelog install needed:
{
"scripts": {
"version": "releasearoni version",
"prepublishOnly": "releasearoni"
}
}
Run npm version patch (or minor/major) and npm will:
- Bump the version in
package.json
- Run
releasearoni version → regenerates CHANGELOG.md and stages it
- Commit and tag
Then npm publish triggers prepublishOnly, which checks npm auth, pushes the tag, and creates the GitHub release.
To stage extra files (e.g. a lock file your project manages separately):
"version": "releasearoni version --add package-lock.json"
Example setup
A complete package.json wired up for versioning and publishing via GitHub Actions:
{
"name": "my-package",
"version": "1.0.0",
"repository": {
"type": "git",
"url": "git+https://github.com/my-org/my-package.git"
},
"scripts": {
// Runs during `npm version`: regenerates CHANGELOG.md and stages it
// Use --add to stage additional files that should be part of the version commit
"version": "releasearoni version --add dist/manifest.json --add src/generated/version.js",
// Runs before `npm publish`:
// 1. checks npm login / OIDC status
// 2. runs `npm run build` if a build script is present
// 3. pushes the version commit + tag to GitHub
// 4. creates the GitHub release
// Use releasearoni-gh instead if you prefer the gh CLI.
"prepublishOnly": "releasearoni",
// Clean up build artifacts after npm has published them
"postpublish": "npm run clean"
},
"devDependencies": {
"releasearoni": "^0.1.0"
}
}
releasearoni and releasearoni-gh are interchangeable in the scripts above — swap in releasearoni-gh if you prefer to delegate to the gh CLI.
A matching GitHub Actions workflow that triggers on manual dispatch:
name: npm bump
on:
workflow_dispatch:
inputs:
version_type:
description: 'Version type'
type: choice
options: [major, minor, patch]
default: patch
required: true
permissions:
contents: write
id-token: write
jobs:
version_and_release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version-file: package.json
- run: npm install
- run: npm test
- name: Configure git author
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
- name: npm version
run: npm version "${{ github.event.inputs.version_type }}"
- name: npm publish
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm publish
npm version runs the version lifecycle script (changelog + commit + tag), then npm publish triggers prepublishOnly which pushes the tag and creates the GitHub release.
Environment variables (releasearoni only)
Authentication for the direct API bin is resolved in this order:
GH_TOKEN
GITHUB_TOKEN
- Interactive GitHub device flow via
ghauth — opens a browser prompt, stores the token in the OS keychain for future runs. Press Enter at the device flow prompt to fall back to pasting a personal access token instead.
API
import { createRelease } from 'releasearoni'
Programmatic release creation using @octokit/rest.
release = await createRelease(options)
Create a GitHub release. Reads package.json and CHANGELOG.md from workpath to fill in defaults, then calls the GitHub Releases API.
import { createRelease } from 'releasearoni'
const release = await createRelease({
auth: { token: process.env.GITHUB_TOKEN },
workpath: process.cwd(),
})
console.log(release.html_url)
Options:
auth | { token: string } | Required. GitHub API token. |
workpath | string | Path to directory with package.json and CHANGELOG.md. Default: cwd. |
owner | string | Repo owner. Default: parsed from package.json. |
repo | string | Repo name. Default: parsed from package.json. |
tag_name | string | Tag to create. Default: v + package version. |
target_commitish | string | Branch or SHA for the tag. Default: current HEAD. |
name | string | Release title. Default: same as tag_name. |
body | string | Release body. Default: latest CHANGELOG entry. |
draft | boolean | Publish as draft. Default: false. |
prerelease | boolean | Mark as prerelease. Default: false. |
endpoint | string | GitHub API base URL. Default: https://api.github.com. |
assets | string[] | {name, path}[] | Files to upload as release assets. |
upsert | boolean | Update existing release if tag already exists. Default: true. Pass false to fail instead. |
Returns the GitHub release object from the API response.
See also
- gh-release — the original CLI this was forked from
- gh CLI — official GitHub CLI used by
releasearoni-gh
- keepachangelog — CHANGELOG format expected by releasearoni
- ghauth — OAuth token management used by
releasearoni
License
MIT