Commit messages lean heavily towards the convention set out by conventional commits.
Each commit message must be in the format that includes a type, an optional scope and a subject:
type(scope?): subject #scope is optional
Limit the whole message to 72 characters or less!
Example:
build(terraform): burn it all down
Must be one of the following:
- build: Changes that affect the build system or external dependencies (example scopes: npm)
- chore: Changes that don't really fall under any other type
- ci: Changes to the CI configuration files and scripts
- docs: Documentation only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- revert: Revert a previous commit
- test: Adding missing tests or correcting existing tests
A scope may be provided to a commit’s type, to provide additional contextual information and is contained within a parenthesis
The subject contains a succinct description of the change:
- use the present tense ("Add feature" not "Added feature")
- use the imperative mood ("Move cursor to..." not "Moves cursor to...")
- don't capitalise the first letter
- don't use a fullstop (.) at the end. <- Not this
The branching strategy is loosely followed by the GitFlow git branching strategy. There are two permanent branches;
beta
branch, which should always contain the latest code, and is where all feature branches are merged. It can contain unstable code.main
branch should only receive code from thebeta
branch or, if necessary, mergehotfix
branches. It should only contain stable code.
- When a release is production ready, checkout the
main
branch and pull the latest:
git checkout main
git pull
- Now, we want the
main
branch to mirror the commit history ofbeta
, so we want to use Git's fast-forward option; so we use:
git merge origin/beta --ff-only
💡 TIP: If you want to merge up to a certain commit from
beta
, first checkout thebeta
branch and reset locally to the specific commit. Then checkoutmain
and merge from your localbeta
branch:git checkout beta git reset <commit_hash> --hard # use --hard flag to avoid add loads of files git checkout main git merge beta --ff-only # notice the absence of origin/ as we will be using our local branch
- Finally, we want to push the updated
main
branch, so we simply use:
git push
⚠️ NOTE: Any merge to themain
branch triggers a deployment to both the SANDBOX and PRODUCTION environments.
We now decide to work on a future major release, which will be composed of multiple features, some of them being breaking changes. We want to publish our package for each new feature developed for test purpose, however we do not want to increment our package version or make it available until all the features are developed and tested.
To implement that workflow we can commit our first feature to the beta
branch. When pushing that commit, semantic-release will publish the pre-release version 2.0.0-beta.1
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0
| \
| * feat: first feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0-beta.1
We can continue to work on our future release by committing and pushing other features or bug fixes on the beta
branch. With each push, semantic-release will publish a new pre-release.
With another feature, the Git history of the repository is now:
* feat: initial commit # => v1.0.0
| \
| * feat: first feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0-beta.1
| * feat: second feature # => v2.0.0-beta.2
In the meantime we can also continue to commit changes and release updates to 1.0.0
.
For example, we can commit a bug fix with the message fix: a fix
to main
. When pushing that commit, semantic-release will release the version 1.0.1
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0
| \
| * feat: first feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0-beta.1
| * feat: second feature # => v2.0.0-beta.2
| fix: a fix # => v1.0.1
Once we've developed and pushed all the features & fixes we want to include in the future version 2.0.0
in the beta
branch, we can release it to the default distribution channel.
- First, merge into
beta
any bug fixes:
git merge origin/main --ff-only
- Next, checkout the
main
branch and pull the latest:
git checkout main
git pull
- Now, we want the
main
branch to mirror the commit history ofbeta
, so we want to use Git's fast-forward option; so we use:
git merge origin/beta --ff-only
⚠️ NOTE: Asbeta
andmain
branches may have diverged, this merge might require to resolve conflicts.
Once beta branch has been rebased on to main
, semantic-release will release the version 2.0.0
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0
| \
| * feat: first feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0-beta.1
| * feat: second feature # => v2.0.0-beta.2
| fix: a fix # => v1.0.1
| /
| Merge branch beta into main # => v2.0.0
We can now start to work on a new future major release, version 3.0.0
.
To do so we first need to update the beta
branch with all the changes from main
(the commits fix: a fix
). As beta
and main
branches have diverged, this merge might require to resolve conflicts.
We can now commit our new feature on beta
. When pushing that commit, semantic-release will publish the pre-release version 3.0.0-beta.1
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0
| \
| * feat: first feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0-beta.1
| * feat: second feature # => v2.0.0-beta.2
| fix: a fix # => v1.0.1
| /
| Merge branch beta into main # => v2.0.0
| \
| | Merge branch main into beta
| | feat: new feature \n\n BREAKING CHANGE: it breaks another thing # => v3.0.0-beta.1