
Security News
Next.js moves to scheduled security releases
Vercel is formalizing a monthly release program for Next.js. The change follows React2Shell and a sharp rise in AI-assisted vulnerability discovery.
@ossjs/release
Advanced tools
Minimalistic, opinionated, and predictable release automation tool.
Think Prettier but for automated releases: minimalistic, opinionated, and, most of all, predictable. This tool combines the usual expectations from a release manager but brings practicality to the table.
Here's the publishing pipeline this tool implements:
While this sounds like what any other release tool would do, the beauty lies in details. Let's take a more detailed look then at what this tool does differently.
The workflow above is the default (and the only) behavior.
That's the release process I personally want for all of my libraries, and that's why it's the default behavior for this tool. If you wish for the release automation tool to do something differently or skip certain steps, then this tool is not for you. I want a predictable, consistent release process, and that's largely achieved by the predictable release workflow for all my projects.
A release tag and a release commit are automatically created.
commit cee5327f0c7fc9048de7a18ef7b5339acd648a98 (tag: v1.2.0)
Author: GitHub Actions <actions@github.com>
Date: Thu Apr 21 12:00:00 2022 +0100
chore(release): v1.2.0
Release is a part of the project's history so it's crucial to have explicit release marker in Git presented by a release commit and a release tag.
If publishing fails, no release commits/tags will be created or pushed to Git.
Here's an average experience you'd have if your release (read "publishing to NPM") fails with an average release manager in the wild:
For an automated tooling there's sure a lot of the word "manual" in this scenario. The worst part is that you cannot just "retry" the release—you need to clean up all the artifacts the release manager has left you otherwise it'll treat the release as successful, stating there's nothing new to release.
The bottom line is: failed releases happen. The package registry may be down, your publishing credentials may be wrong, or the entire internet may just decide to take a hiccup. The tooling you use should acknowledge that and support you in those failure cases, not leave you on your own to do manual cleanup chores after the automated solution.
v${version} (i.e. v1.2.3).chore(release): v${version}.CHANGELOG file. This tool generates automatic release notes from your commits and creates a new GitHub release with those notes. Use GitHub releases instead of changelogs.npm install @ossjs/release --save-dev
Create a release.config.json file at the root of your project. Open the newly created file and specify the use command that publishes your package:
// release.config.json
{
"profiles": [
{
"name": "latest",
"use": "npm publish"
}
]
}
Generate a Personal Access Token for your GitHub user with the following permissions:
repoadmin:repo_hookadmin:org_hookExpose the generated access token in the GITHUB_TOKEN environmental variable in your local and/or CI environment. This tool uses the GITHUB_TOKEN variable to communicate with GitHub on your behalf: read and write releases, post comments on relevant issues, etc.
Commit and push your changes following the Conventional Commit message structure. Once done, run the following command to generate the next release automatically:
release publish
Congratulations! :tada: You've successfully published your first release!
This tool expects a configuration file at release.config.json. The configuration file must export an object of the following shape:
{
profiles: Array<{
/**
* Profile name.
* @default "latest"
*/
name: string
/**
* The publishing script to run.
* @example "npm publish"
* @example "pnpm publish --no-git-checks"
*/
use: string
/**
* Treat major version bumps as minor.
* This prevents publishing a package that is in a
* pre-release phase (< 1.0).
*/
prerelease?: boolean
}>
use: string
}
publishPublishes a new version of the package.
| Option name | Type | Description |
|---|---|---|
--profile, -p | string (Default: "latest") | Release profile name from release.config.json. |
--dry-run, -d | boolean | Creates a release in a dry-run mode. Note: this still requires a valid GITHUB_TOKEN environmental variable, as the dry-run mode will perform read operations on your repository. |
Running this command will publish the package according to the latest defined profile:
release publish
Providing an explicit --profile option allows to publish the package accordig to another profile from release.config.json:
release publish --profile nightly
notesGenerates release notes and creates a new GitHub release for the given release tag.
This command is designed to recover from a partially failed release process, as well as to generate changelogs for old releases.
| Argument name | Type | Description |
|---|---|---|
tag | string | Tag name of the release. |
# Generate release notes and create a GitHub release
# for the release tag "v1.0.3".
release notes v1.0.3
showDisplays information about a particular release.
Release information includes the following:
| Argument name | Type | Description |
|---|---|---|
tag | string | (Optional) Tag name of the release to show. |
# Display info about the latest release.
release show
# Display info about a specific release.
release show v0.19.2
This tool exposes a CLI which you can use with any continuous integration providers. No need to install actions, configure things, and pray for it to work.
{
"name": "my-package",
"scripts": {
"release": "release publish"
}
}
Before you proceed, make sure you've generated GitHub Personal Access Token. Create a new repository/organization secret called CI_GITHUB_TOKEN and use your Personal Access Token as the value for that secret.
You will be using secrets.CI_GITHUB_TOKEN instead of the default secrets.GITHUB_TOKEN in the workflow file in order to have correct GitHub permissions during publishing. For example, your Personal Access Token will allow for Release to push release commits/tags to protected branches, while the default secrets.GITHUB_TOKEN will not.
# .github/workflows/release.yml
name: release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
# Fetch the entire commit history to include all commits.
# By default, "actions/checkout" checks out the repository
# at the commit that's triggered the workflow. This means
# that the "@ossjs/release" may not be able to read older
# commits that may affect the next release version number.
fetch-depth: 0
# Provide your custom "CI_GITHUB_TOKEN" secret that holds
# your GitHub Personal Access Token.
token: ${{ secrets.CI_GITHUB_TOKEN }}
- uses: actions/setup-node@v3
with:
always-auth: true
registry-url: https://registry.npmjs.org
# Configure the Git user that'd author release commits.
- name: Setup Git
run: |
git config --local user.name "GitHub Actions"
git config --local user.email "actions@github.com"
- run: npm ci
- run: npm test
- run: npm run release
env:
# Set the "GITHUB_TOKEN" environmental variable
# required by "@ossjs/release" to communicate with GitHub.
GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}
# Set the "NODE_AUTH_TOKEN" environmental variable
# that "actions/setup-node" uses as the "_authToken"
# in the generated ".npmrc" file to authenticate
# publishing to NPM registry.
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Create the configuration file and specify the release script:
// release.config.json
{
"profiles": [
{
"name": "latest",
// Note that NPM doesn't need the next release version.
// It will read the incremented version from "package.json".
"use": "npm publish"
}
]
}
If publishing a scoped package, use the
npm publish --access publicscript instead.
Running yarn publish will prompt you for the next release version. Use the --new-version option and provide it with the RELEASE_VERSION environmental variable injected by Release that indicates the next release version based on your commit history.
// release.config.json
{
"profiles": [
{
"name": "latest",
"use": "yarn publish --new-version $RELEASE_VERSION"
}
]
}
Yarn also doesn't seem to respect the NODE_AUTH_TOKEN environment variable. Please use the NPM_AUTH_TOKEN variable instead:
- run: yarn release
env:
GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}
# Use the "NPM_AUTH_TOKEN" instead of "NODE_AUTH_TOKEN".
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
// release.config.json
{
"profiles": [
{
"name": "latest",
// Prevent PNPM from checking for a clean Git state
// to ignore the intermediate release state of the repository.
"use": "pnpm publish --no-git-checks"
}
]
}
Leverage GitHub Actions and multiple Release configurations to release different tags from different Git branches.
// release.config.json
{
"profiles": [
{
"name": "latest",
"use": "npm publish"
},
{
"name": "nightly",
"use": "npm publish --tag nightly"
}
]
}
name: release
on:
push:
# Set multiple branches to trigger this workflow.
branches: [main, dev]
jobs:
release:
runs-on: ubuntu-latest
steps:
# Release to the default ("latest") tag on "main".
- name: Release latest
if: github.ref == "refs/heads/main"
run: npx release publish
# Release to the "nightly" tag on "dev'.
- name: Release nightly
if: github.ref == "refs/heads/dev"
run: npx release publish -p nightly
Below you see how Release compares to other tools. Keep in mind that I'm only comparing how those tools work by default because that's the only thing I care about. Unlike Release, other tools here can satisfy different use-cases through configuration, which is both a blessing and a curse.
| Release | Semantic Release | Auto | Changesets | |
|---|---|---|---|---|
| First-class citizen | CLI | Commit | Pull request (labels) | Changeset |
| Derives next version from commits | ✅ | ✅ | ✅ | ❌ |
| Creates a GitHub release | ✅ | ✅ | ✅ | ✅ |
| Creates a release commit in Git | ✅ | ❌ 1 | ✅ | ✅ |
| Comments on relevant GitHub issues | ✅ | ✅ | ✅ | ❌ |
| Comments on relevant GitHub pull requests | ✅ | ✅ | ✅ | ? |
| Reverts tags/commits if publishing fails | ✅ | ❌ | ? | ? |
| Supports monorepos | ❌ | ✅ | ✅ | ✅ |
| Supports dry run | ✅ | ✅ | ✅ | ❌ |
1 - requires additional plugins.
FAQs
Minimalistic, opinionated, and predictable release automation tool.
The npm package @ossjs/release receives a total of 1,217 weekly downloads. As such, @ossjs/release popularity was classified as popular.
We found that @ossjs/release demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Vercel is formalizing a monthly release program for Next.js. The change follows React2Shell and a sharp rise in AI-assisted vulnerability discovery.

Research
/Security News
11 malicious NuGet tools pose as game cheats to deploy Windows payloads, track hosts, and use Google Sheets for telemetry and control.

Research
/Security News
4 compromised asyncapi packages deliver miasma botnet loader on macOS, Linux and Windows.