An open API service indexing awesome lists of open source software.

https://github.com/bcomnes/releasearoni

A modernized node-centric releaser tool with built in auto-changelog
https://github.com/bcomnes/releasearoni

Last synced: 3 months ago
JSON representation

A modernized node-centric releaser tool with built in auto-changelog

Awesome Lists containing this project

README

          

# releasearoni
[![latest version](https://img.shields.io/npm/v/releasearoni.svg)](https://www.npmjs.com/package/releasearoni)
[![Actions Status](https://github.com/bcomnes/releasearoni/workflows/tests/badge.svg)](https://github.com/bcomnes/releasearoni/actions)
[![downloads](https://img.shields.io/npm/dm/releasearoni.svg)](https://npmtrends.com/releasearoni)
![Types in JS](https://img.shields.io/badge/types_in_js-yes-brightgreen)
[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-7fffff?style=flat&labelColor=ff80ff)](https://github.com/neostandard/neostandard)
[![Socket Badge](https://socket.dev/api/badge/npm/package/releasearoni)](https://socket.dev/npm/package/releasearoni)

Image

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.

```console
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.

```console
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](https://cli.github.com) to be installed and authenticated.

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

| Field | Default source |
|---|---|
| `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](https://keepachangelog.com) 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.

```console
Usage: releasearoni npm-check
```

Typical `package.json` setup:

```json
{
"scripts": {
"prepublishOnly": "releasearoni"
}
}
```

### `releasearoni version`

Generates `CHANGELOG.md` via [auto-changelog](https://github.com/CookPete/auto-changelog) and stages it with `git add`. Designed for use as the npm [`version` lifecycle script](https://docs.npmjs.com/cli/v10/using-npm/scripts#life-cycle-scripts).

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

```json
{
"scripts": {
"version": "releasearoni version",
"prepublishOnly": "releasearoni"
}
}
```

Run `npm version patch` (or `minor`/`major`) and npm will:
1. Bump the version in `package.json`
2. Run `releasearoni version` → regenerates `CHANGELOG.md` and stages it
3. 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):

```json
"version": "releasearoni version --add package-lock.json"
```

## Example setup

A complete `package.json` wired up for versioning and publishing via GitHub Actions:

```jsonc
{
"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:

```yaml
# .github/workflows/release.yml
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 # required to push the version commit, tag, and create the GitHub release
id-token: write # required for OIDC publishing to npm (provenance)

jobs:
version_and_release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch full history so things like auto-changelog work properly
- 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 }} # used by releasearoni to create the GitHub release
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](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#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.

```js
import { createRelease } from 'releasearoni'

const release = await createRelease({
auth: { token: process.env.GITHUB_TOKEN },
workpath: process.cwd(), // optional, defaults to cwd
})

console.log(release.html_url)
```

Options:

| Option | Type | Description |
|---|---|---|
| `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](https://github.com/bcomnes/gh-release) — the original CLI this was forked from
- [gh CLI](https://cli.github.com) — official GitHub CLI used by `releasearoni-gh`
- [keepachangelog](https://keepachangelog.com) — CHANGELOG format expected by releasearoni
- [ghauth](https://github.com/nicolo-ribaudo/ghauth) — OAuth token management used by `releasearoni`

## License

MIT