This article originated from Create a Node.js command-line library with NRWL NX workspace.
In projects with a streamlined deployment process, I tend to use TheUnderScorer/nx-semantic-release: Package for automated releases for nx built on semantic-release. The nx-semantic-release library is powerful as it:
- leverages the NX workspace graph capabilities to determine which application/library was modified.
- has excellent integration with the semantic release.
- let you choose between Github actions and CLI.
- Offer effective configuration variations (environment variables, config file, nx project.json, CLI arguments).
Extend your project with automatic deployment to the NPM registry
First, follow the installation from the official library page https://github.com/TheUnderScorer/nx-semantic-release.
Review the created .nxreleaserc.json
file. You will probably need to change the branch from master
to main
in the file.
In file packages/{projectName}/project.json
, where you previously added the executor, add some options:
"semantic-release": {
"executor": "@theunderscorer/nx-semantic-release:semantic-release",
"options": {
"buildTarget": "${PROJECT_NAME}:build",
"outputPath": "dist/packages/${PROJECT_NAME}"
}
}
A few things to note:
- The properties
buildTarget
andoutputPath
are required fornx-semantic-release
to deploy to NPM or GitHub Actions. - Replace
{PROJECT_NAME}
with your actual project name.
Ensure you have the following settings in the file packages/{projectName}/package.json
.
{
"name": "obsidian-album",
"version": "1.0.0",
"type": "module",
"bin": "./src/cli.js",
"private": false,
"author": {
"email": "eran@sakalim.com",
"name": "Eran Sakal"
},
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/esakal/obsidian-album"
}
}
A few things to note:
- The properties
private
,author
, andrepository
are mandatory. - Make sure the version's initial value is accurate. If it is currently set to
0.0.0
, change it to1.0.0
. - The property
access
is needed if you publish a public library. - If you publish to GitHub packages, you should read section Deploy to GitHub packages registry using GitHub Actions.
Create file .github/workflows/release.yml
:
name: Release to NPM
on:
push:
branches:
- 'main'
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npx nx run-many --target=semantic-release --all --parallel=1
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
A few things to note:
- If you deploy multiple packages with change log creation, you should adjust the release.yml file. See section
Deploy multiple packages with change log feature enabled
. - The
NODE_AUTH_TOKEN
environment variable is used to publish to NPM. You should create an NPM token and assign it to this variable. - The
GITHUB_TOKEN
environment variable is used to let TheUnderScorer/nx-semantic-release: Package for automated releases for nx built on semantic-release push change logs to Github while deploying. - The
NODE_AUTH_TOKEN
andNPM_TOKEN
are used to allow deployment to the NPM registry - Passing
--parallel=1
is essential if you left the default behavior to commit artifacts during deployments like theCHANGELOG.md
file and the new version intopackage.json
. It will fail without it. If you decide to create theCHANGELOG.md
files, consider doing that only for official versions (not feature/pre-release versions).
Deploy to GitHub packages registry using GitHub Actions
When you need private libraries, using the GitHub packages registry instead of the NPM registry is very handy. Deploying the package to the GitHub registry requires some adjustments to the NPM configuration. Otherwise, it will try to deploy it to the NPM registry.
InfoThis article shows how to deploy GitHub packages. To learn how to install the library from GitHub packages, read the article How to use private GitHub packages in your repository and with Github Actions.
In .github/workflows/release.yml
- Add
registry-url
andscope
arguments
- name: Setup Node.js
uses: actions/setup-node@v3
with:
registry-url: 'https://npm.pkg.github.com'
scope: '@esakal'
- Use the GitHub token when running
- run: npx nx run-many --target=semantic-release --all
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Deploy to GitHub packages from CLI
If you deploy without Github actions, you can adjust the file packages/{projectName}/package.json
, add:
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
OR you can use file .npmrc
and bind the scope to GitHub Packages.
@esakal:registry=https://npm.pkg.github.com
Support feature/pre-release branches
Friendly warning
Usually, when working with the semantic release approach, people squash Pull requests instead of merging them. Squashing pull requests instead of merging them is a good approach in general, as it lets you work on a pull request peacefully and care about the commit message only when ready to squash it into the main branch.
When dealing with feature/pre-release versions, you should always merge (and not squash) them to avoid undesired conflicts that are extremely hard to resolve. And anyhow, it is the right thing to do regardless.
Having the ability to create feature/pre-release versions is super helpful. Not many people use it as, mostly due to dev-ops complexities. To learn more read What Is a Feature Branch + How they Improve the Dev Process | Bunnyshell |.
To support it in our workflow do the following adjustments.
In file .github/workflows/release.yml
, make sure it is also being triggered when changing the hotfix
branch or release/something
branches
on:
push:
branches:
- main
- hotfix
- 'release/*'
In the file .nxreleaserc.json
, add:
branches: [
{
name: 'release/*',
prerelease: '${name.replace(/^release\\//g, "")}'
},
'main',
{
name: 'hotfix',
pre-release: true
},
]
A few things to note:
- The
branches
configuration is used under the hood by the semantic release libraries; it instructs semantic release to create pre-releases for the branchhotfix
and for any feature branch whose name starts withrelease/
. So a branch namedrelease/studio
will create a pre-release version likecli-x1.2.3-studio.0
.