Semantic releases
Introduction:
The purpose of having Semantic-Release is so that we can release workable versions to our users frequently. So we shouldn’t be releasing non-workable versions, so before we began to use semantic release, we should have our working branches ready, and releases should only happen in the master branch.
We need 3 main components:
- Git hook: we will use husky (opens in a new tab).
- commitlnt: it will act as linter for our commit messages.
- Semantic-release: It will use the commit history, that are respecting the Conventional commit standards, to generate Release notes and versions automatically.
Commit Conventions:
Conventional Commits provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of .
Conventional Commits standards Official website (opens in a new tab)
To achieve such, we need to install a package called Commitlint
.
Commitlint is the ESLint for commit messages. It performs validations on any text against a predefined commit format.
We can configure these formats to our needs or adopt pre-built-in conventions, such as conventional commits.
We create a file under .husky
folder, #!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --edit
And finally we create a config file commitlnt.config.js
where we specify the conventions
module.exports = {
extends: ['@commitlint/config-conventional'],
};
General structre of a commit message
<type>(<scope?>): <subject!>
Where:
type:
IThe type is mandatory and determines the intent of the change. Here are possible values:
build
: changes affecting build systems or external dependenciesci
: updating configuration files for continuous integration and deployment serviceschore
: updating grunt tasks etc.; no production code changedocs
: documentation-only changesfeat
: a new featurefix
: a bug fixperf
: a code change that improves performance -refactor
: a code change that neither fixes a bug nor adds a featurestyle
: changes that do not affect the meaning of the code (white-space, formatting, missing semicolons, etc.)test
: adding missing tests or correcting existing testsBREAKING CHANGE
: Major update.
Scope
A scope is an optional value that provides additional contextual information about the change. For example, when the module’s name, npm package, or particular routine was affected.
Subject
The subject is the headline of the commit. It should summarize in one sentence the nature of change.
For the subject, consider the following rules:
- use the imperative, present tense: “change,” not “changed” nor “changes”
- do not capitalize the first letter
- no dot (.) at the end
Github wokrflow for semantic release
First, we need to install package called Semantic-release
npm install -D semantic-release
.
Next, we add the plugings and config to package.json
so we inform semantic-release about pluging and the branch of release.
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/github",
"@semantic-release/npm",
"@semantic-release/git"
],
"release": {
"branches": [
"main"
],
"tagFormat": "${version}",
"publish": [
"@semantic-release/github"
],
"prepare": [
"@semantic-release/npm",
"@semantic-release/changelog",
{
"path": "@semantic-release/git",
"message": "release ${nextRelease.version}\n\n${nextRelease.notes}"
}
]
}
Finally,under .github/workflows/
, we create file called: semantic-release.yml
that will actually be triggered manually evertime we need to release a new version.
Workflow details are bellow :
name: Semantic release
# for manual action triggering.
on: [workflow_dispatch]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache node modules
id: cache
uses: actions/cache@v3
with:
path: node_modules
key: cache-node-${{ hashFiles('package-lock.json') }}
- name: Setup Node
uses: actions/setup-node@v1
if: steps.cache.outputs.cache-hit != 'true'
with:
node-version: 16
- name: Install packages
if: steps.cache.outputs.cache-hit != 'true'
run: npm install
- name: Launch Semantic release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
Since the build is triggered manually, we need to head to Github Actions section then find semantic Release
workflow, and trigger it on branch main.
Note that :
feat:....
commmit message will bump the minor version of the release 'major:minor:patch'fix:....
commit message will bump the patch version of the release 'major:minor:patch'BREAKING CHANGE
commit message will trigger a major bump to the version.
Result :