By release workflow, i mean all the tasks starting to the commit to be published (excluding Work In Progress, aka WIP commits, to be squashed).
The tasks are :
The operational workflow varies depending on where theses tasks are executed.
They can be executed on the developer computer or/and in the CI pipeline.
The release workflow is highly coupled the Git workflow, anyway this is another matter.
We could resume the release workflow this way :
commit ---> CHANGELOG ---> tag ---> merge
|
|
V
package ---> release
Theses tools are based on Git, a common commits messages convention, the semver specification and obviously npm.
The famous Source Control Manager.
Manage the codebase contained in a repository.
Popularized by AngularJS team. Can be found here.
Each codebase revision is hold in a commit. Each commit contain a commit message.
Commit message standardization leads to :
Popularized by npm to manage the version system.
It is about how to structure a version number and for what meaning.
The node package manager.
The following npm CLI commands are especially involved :
Commands like npm build
, npm test
, npm ci
are obviously also involved, but they are already involved in the development process.
- Automate your releases and semantic versioning with
semantic-release
- Use
commitizen
withcz-convential-changelog
to capture additional details about each commit- Run Automated Tests that generate Code Coverage reports
- Maintain coverage standards with
Codecov
- Ensure consistent code formatting, and avoid simple mistakes by Linting your code
- Keep your dependencies up to date with
GreenKeeper
Semantic Release with Lerna and Conventional Commits - michaljanaszek.com/blog - 20180616
In this tutorial, I will show you how to configure Lerna with Conventional Commits to achieve automatic Semantic Release based only on the history of commits.
Conventional Commits + Conventional Changelog + Semantic Release + Commitlint
Lerna Independent Mode with Semver - samhogy.co.uk - 20180816
focus on lerna independent mode with semantic versioning.
lerna/lerna - github.com / lernajs.io
A tool for managing JavaScript projects with multiple packages
Lerna config belongs to lerna.json
file.
Logs goes into lerna-debug.log
file.
Features
devDependencies
(hoisting of common dependencies, most of the devDependencies
are commons)WARNING : lerna used with semantic-release is not mature at all. See issue on semantic-release repo.
greenkeeper.io greenkeeperio - github.com
Get safety & consistency with real-time monitoring and automatic updates for npm dependencies
A specification for adding human and machine readable meaning to commit messages
Commit message structure :
<type>[optional scope]: <description>
[optional body]
[optional footer]
conventional-changelog/commitlint - github.com
Lint commit messages
commitizen/cz-cli - github.com
The commitizen command line utility.
commitizen/cz-conventional-changelog - github.com
A commitizen adapter for the angular preset of conventional-changelog.
CHANGELOG.md
management2 years time range give a better view :
lob/generate-changelog - github.com
The simpler one.
Limited to the CHANGELOG.md
file generation.
Recommendations available for the tag and push tasks.
Executed on the developer computer manually by the developer.
conventional-changelog - github.com
standard-version is the high level entry point repo.
standard-version
does the following:
Others tools
releaser-tools - github.com/conventional-changelog
Create a GitHub/GitLab/etc. release using a project's commit messages and metadata.
Executed by a CI job.
semantic-release - semantic-release.gitbook.io
semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.
This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification.
explain the relationship to semantic-release - github.com/conventional-changelog
How is it different than semantic-release
- github.com/conventional-changelog
semantic-release
is a fully automated library/system for versioning, changelog generation, git tagging, and publishing to the npm registry.
standard-version
is different because it handles the versioning, changelog generation, and git tagging for you without automatic pushing (to GitHub) or publishing (to an npm registry). Use ofstandard-version
only affects your local git repo - it doesn't affect remote resources at all. After you runstandard-version
, you still have to ability to review things and correct mistakes if you want to.They are both based on the same foundation of structured commit messages (using Angular format), but
standard-version
is a good choice for folks who are not yet comfortable letting publishes go out automatically. In this way, you can viewstandard-version
as an incremental step to adoptingsemantic-release
.
Setup a continuous delivery workflow with as much automation as possible from commit to deployment.
The CI service used is TravisCI.
GitHooks are managed by Husky.
Commit message convention used is www.conventionalcommits.org.
Commit messages are linted by commitlint.
Commit can be produced with the help of the commitizen CLI with the cz-conventional-changelog config.
Automation is provided by semantic-release.
Two branches, master
and develop
, both must be protected.
develop
is the target for every PR. Set it as default branch instead of master
branch.
PR are done with classic features branches based on develop
, never based on master
.
master
is the distribution channel to deploy.
Every branch push trigger a CI job.
A CI job is composed of 3 stages :
commitlint
stage to reject malformed commit messagetest
stage to reject invalid commit content (test should execute at least lint + tests)deploy
stage triggered only by the master
branch to build the package and deploy it to the npm registry.
It also determine the version number, compute the release CHANGELOG, tag the tip of the branch and push it with release CHANGELOG to origin.To deploy, the git owner must merge locally develop
into master
. It should be always a fast-forward, develop
and master
are mirrors.
Never use a PR to merge develop
into master
, semantic-release will not trigger the deploy stage for a PR.
Before any steps, be sure to have a valid package.json
file, and especially a fulfilled "repository"
section in it.
You should also already have a .npmignore
file with a content like this :
node_modules/
public/
dist/
npm-debug.log
.DS_Store
.idea/
*.tgz
test-utils/
tests/
.editorconfig
.eslintignore
.eslintrc.json
.npmrc
tsconfig.json
tsconfig-dev.json
tslint.json
.travis.yml
install semantic-release in your project
npm i -D semantic-release
install semantic-release-cli
npm i -g semantic-release-cli
configure semantic-release
semantic-release-cli setup
Answer the questions, you will need to provide your logins / passwords for npm registry and github account. semantic-release will generate tokens with them and will push them to TravisCI to allows the CI job to push into them.
GitHub webhook will be automatically configured.
TravisCI job will be automatically created and configured during the first deploy attempt (push on the master
branch).
The version number in your package.json
will be set to 0.0.0-development
and will never move.
semantic-release modify only the package.json
put into the npm package sent to the registry.
install commitizen
npm i -D commitizen cz-conventional-changelog
commitizen provide a CLI wizard to help creating valid commit messages
cz-conventional-changelog describe the desired commit format (for this example it is the conventional changelog spec)
configure commitizen
In your package.json
, add this section to configure commitizen :
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
And under the script
section add this command :
"cz-commit": "git-cz"
To avoid conflict with husky, prefix the script with cz-
(defaut in the documentation is just commit
).
commitizen usage
Stages the files you want to commit, then use the CLI tool with npm run cz-commit
then answer the questions.
install commitlint
npm i -D @commitlint/cli @commitlint/config-conventional @commitlint/travis-cli
Same as commitizen, the commitlint CLI is configured with the @commitlint/config-conventional package to define the commit message convention used.
The @commitlint/travis-cli will be used in the TravisCI job to lint server side en enforce the convention.
configure commitlint
Add this section to your package.json
to configure commitlint :
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
Add a hook to the husky configuration in your package.json
:
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
Each local commit attempt will trigger commitlint.
Your husky configuraton in your package.json
should look like this :
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "npm test",
"pre-push": "npm test"
}
},
create and fill your .travis.yml
file
This content should do the job :
language: node_js
node_js:
- 10
cache: npm
install:
- npm ci
branches:
except:
- '/^v\d+\.\d+\.\d+$/'
jobs:
include:
- stage: commitlint
script:
- commitlint-travis
- stage: test
script:
- npm run test
- stage: deploy
if: branch == master && !fork
node_js: '10'
script:
- npm install -g semantic-release@^15
- semantic-release
semantic-release is tested only with the last LTS node version. So your app should do the same.
You should have already an initial commit. The message commit convention for this commit is not important.
The next commit should contain all this configuration and should be able to generate something to package and deliver to the npm registry.
Be careful to choose a feat or fix type for the commit message. Others type will not trigger a release.
The develop
branch should not exist yet.
When the commit is written, push it directly into master
to trigger the first CI job and the first deploy.
This deploy is mandatory because TravisCI needs the .travis.yml
files present into each branches in order to run.
So you need first to deploy a dummy app version, then the contribution branch which will be the destination for PR will be created based on master
.
Check the CI result. Check also the npm registry.
At this point, if everything is ok you have the CI up and runnning and a first package version in the npm registry.
Now you can create the develop
branch in your remote repository. Don't forget to protect it and to set it to the default branch.
The master branch needs also to be protected.
You can add rules to the protected branches to force some checks when a PR occurs. After the first CI completed job you are able to force a CI status check to validate a PR.
You're done.