Github browser tab
25.04.2023

Streamline Your JavaScript Publishing Workflow: Automate Releases with Semantic-Release and GitHub Actions

Introduction

Semantic versioning, or SemVer, is a versioning scheme that provides a standardized way to communicate changes in a software package or application. It follows the format of MAJOR.MINOR.PATCH, where:

  • MAJOR version is incremented when there are incompatible API changes.
  • MINOR version is incremented when new features are added in a backward-compatible manner.
  • PATCH version is incremented when there are backward-compatible bug fixes.

The benefits of semantic versioning are numerous, including:

  • Clarity: Semantic versioning conveys the nature and scope of changes between releases, making it easier for developers to understand the impact of updating a dependency.
  • Predictability: By following a standardized versioning scheme, developers can anticipate the types of changes they might encounter when updating a package.
  • Compatibility: Semantic versioning ensures that breaking changes are explicitly communicated, reducing the risk of introducing bugs due to incompatibilities.
  • Easier Dependency Management: It simplifies dependency management for package managers like NPM, enabling them to automatically update packages without introducing breaking changes.

Automating the versioning and release process using tools like semantic-release and GitHub Actions offers additional benefits:

  1. Reduced Human Error: Automating the versioning process reduces the risk of human error, such as forgetting to increment the version number or incorrectly determining the required version change.
  2. Streamlined Workflow: Using a standardized commit message convention, developers can trigger new releases automatically, saving time and effort.
  3. Faster Releases: Automation allows for more frequent releases, ensuring that bug fixes and new features are delivered to users more quickly.
  4. Improved Collaboration: A well-defined and automated release process promotes better collaboration among team members, as everyone follows the same conventions and understands the release workflow.
  5. Clear Release Notes: semantic-release automatically generates release notes based on the commit messages, providing clear documentation for each release.
  6. Enhanced Traceability: The commit history becomes more descriptive, and the generated changelog provides an easy-to-read summary of changes, improving traceability.

Let’s walk through the process of creating a test npm package, publishing the package to npm, and then automating the release process using semantic-release and GitHub Actions.

Set up the project

Make sure you have Node.js and NPM installed. If you don’t have it installed, follow the instructions on the official Node.js website.

Open your terminal and create a new directory for your new project:

mkdir my-npm-package
cd my-npm-package

Run npm init to create a package.json file (the -y flag auto-fills the prompts with default values):

npm init -y

Write the code

Create a new file called index.js:

touch index.js

Open index.js in your favorite text editor and write a simple JavaScript function:

function greet(name) {
return `Hello, ${name}!`;
}
module.exports = greet;

Create the NPM package

Add a files field to your package.json to specify which files should be included in the package:

"files": [
"index.js"
],

Ensure your package.json has the necessary fields, including name, version, description, main, and repository:

{
"name": "my-npm-package",
"version": "1.0.0",
"description": "A simple NPM package",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/yourusername/my-npm-package.git"
},
"files": [
"index.js"
]
}

Commit your changes and push them to a GitHub repository:

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/my-npm-package.git
git push -u origin main

Publish the package to the NPM registry

Log in to your NPM account (or create an account if you don’t have one):

npm login

Publish your package:

npm publish

Automate the publishing process using semantic-release and GitHub Actions

Set up semantic-release

Semantic-release is a powerful and versatile tool designed to streamline the process of versioning and releasing JavaScript packages. Automating the release workflow eliminates manual steps, reduces the risk of human error, and ensures adherence to semantic versioning principles. When combined with a standardized commit message convention, semantic-release makes it easy to automatically manage package versions, generate release notes, and publish releases to various platforms.

To further enhance its functionality, semantic-release can be extended with various plugins. Here, we introduce four popular plugins that work seamlessly with semantic-release to create a robust publishing workflow:

  • @semantic-release/commit-analyzer: This plugin analyzes commit messages to determine the appropriate version bump (major, minor, or patch) based on the commit history. Following a conventional commit message format, the commit-analyzer plugin can automatically identify breaking changes, new features, and bug fixes, ensuring your package’s version is updated accordingly.
  • @semantic-release/release-notes-generator: Generating comprehensive and informative release notes can be time-consuming. The release-notes-generator plugin alleviates this burden by automatically creating release notes based on the commit messages. This not only saves time but also ensures consistency and clarity in the documentation of each release.
  • @semantic-release/npm: The npm plugin publishes your package to the npm registry. It automatically updates the package version in your package.json file and then publishes the updated package to npm. This plugin simplifies publishing and ensures your package is always up-to-date in the npm registry.
  • @semantic-release/github: With the github plugin, semantic-release can automatically create GitHub releases and attach release notes generated by the release-notes-generator plugin. This provides seamless integration with the GitHub platform, making it easy for developers to track and manage releases directly from their repositories.

Let’s Install semantic-release and those four plugins that we’ve mentioned above as development dependencies:

npm install --save-dev semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/npm @semantic-release/github

Create a .releaserc file in the root of your project with the following content:

{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github"
]
}

Set up GitHub Actions

GitHub Actions is an integrated automation platform within GitHub that simplifies software development workflows. It allows developers to automate tasks like continuous integration, deployment, testing, and building using custom workflows defined in YAML. By responding to specific triggers, such as code pushes or pull requests, GitHub Actions reduces repetitive tasks, enforces best practices, and accelerates release cycles. With support for various languages, platforms, and tools, it’s a versatile and powerful solution for enhancing productivity and streamlining development processes.

We can use GitHub Actions to run semantic-release and fully automate releasing and publishing a new package version.

Before creating our GitHub Actions file, we need to set two environment variables correctly.

  • GITHUB_TOKEN – go to GitHub and select your repository. Then go to Settings/Actions/General. You should find a section called “Workflow permissions.” Ensure that “Read and write permissions” is selected for the GITHUB_TOKEN. We need this to push the newly generated package version to the repository.
  • NPM_TOKEN – in your NPM account, go to the “Access Tokens” page and create a new classic token. The type of the new access token should be “Automation”. Copy the token and go to GitHub. In your repository, navigate to “Settings” and “Secrets”. Add a new repository secret named NPM_TOKEN and paste the access token you created in NPM.

Create a new file called .github/workflows/release.yml in your project:

mkdir -p .github/workflows
touch .github/workflows/release.yml

Open the release.yml file and add the following GitHub Actions workflow configuration:

name: Release

on:
push:
branches:
- master

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install dependencies
run: npm ci

- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release

Commit and push the changes to your repository:

git add .
git commit -m "Add semantic-release and GitHub Actions workflow"
git push

The GitHub Actions workflow will automatically run when you push changes to the main branch. If there are any commits with a conventional commit message, semantic-release will update the package version, publish it to NPM, and create a GitHub release.

To trigger a new release, you can use commit messages like these:

  • fix: Fix a bug
  • feat: Add new feature
  • BREAKING CHANGE: Major change

Stay tuned for more updates and similar articles on our Droxic (check out our Droxic profile on DesignRush) blog.