How to publish an NPM package from the CI build pipeline and still automate versioning?
Answering myself. As suggested in the comment above, I've decided to adopt semantic-release
for publishing from master
branch.
For building and publishing from development branches, I've created a custom node script to generate a semver-compatible pre-release version based on git commit's hash, current major.minor.patch version and current time:
const cp = require('child_process');
// get current semver version without prerelease suffix
const pkg = require('./package.json');
const curVer = pkg.version.trim().split(/[.-]/).slice(0, 3).join('.');
// get the commit id
const commit = cp.execSync('git rev-parse --short HEAD', {encoding: 'utf-8'}).trim();
console.log(`Package: ${pkg.name}, version: ${curVer}, commit: ${commit}`);
// generate a new unique semver-compliant version based the commit it and current time
const uniqueVer = `${curVer}-beta-${commit}-${Math.random().toFixed(8).substr(2)}.${Date.now()}`
// use npm version to update package.json
cp.execSync(`npm version ${uniqueVer} --no-git-tag-version`, {stdio: 'inherit'});
// publish and tag with commit id
cp.execSync(`npm publish --tag ${commit}`, {stdio: 'inherit'});
This way, I can check-in my stuff into my dev branch, have the CI pipeline build and publish the package for me and then consume it with npm install mypackage@commitid
. A pseudo-unique version will be generated and published to NPM registry, but the modded package.json
will not be checked-in.
This approach should work for me for now, but I'd still be very interested to learn about the best DevOps practices to publish internal/per-release NPM packages with CI during normal development cycle.
I did it as below, in my javascript project.
Note: get your key form .npmrc
publish:
image: <your project image>
stage: publish
script:
- echo _auth=$NPM_PUBLSH_KEY >> .npmrc
- echo email=<youremail> >> .npmrc
- echo always-auth=true >> .npmrc
# - cat .npmrc
- npm version --no-git-tag-version $(npm view <yourProject>@latest version)
- npm version --no-git-tag-version prerelease
- npm publish
dependencies:
- build
build:
image: <your project image>
stage: build
script:
- node --version
- npm --version
- npm ci
- npm run build -- --watch=false
- npm run build:prod
I'd still be very interested to learn about the best DevOps practices to publish internal/per-release NPM packages with CI during normal development cycle.
usually the maintainer of the project bumps the version, based on the features and\or changes made to the project.
for instance:
- if the changes are breaking changes (non-backwords compatiable), the maintainer will bump the major version
- if the changes are new features (helper functions, refactoring, etc.), the maintainer will bump the minor version
there are many approches for the patch version. here are 2:
- git pre-push hook, which bumps the patch number and commit it to the repository, which eliminates the build\ci system changing the project source code
- use the build number in the build\ci system as the patch number, ignoring the patch version commited to the repository