Recently, I’ve been working on releasing a few SPFx components for an Intranet project I’m working on. Given how SharePoint automatically handles updating SPFx components when a new version is available, it made sense to automate versioning rather than changing a version number in three different files with every release.
A quick Google search took me to an old gem from Stefan Bauer as well as a more recent adaptation from Hugo Bernier - I needed a bit of both to achieve what I want.
By default, NPM includes npm version
which bumps the version in both package.json
(and package-lock.json
if you have one) using npm version major|minor|patch
. However, SPFx relies on the version number in package-solution.json
. The code below syncs both.
It is two-part: The main bit uses a gulp task to create a version-sync
task which updates the SPFx version to match the NPM package version. The other part is an NPM task to run the version-sync
gulp task every time the NPM package version is updated. There’s a postversion
event that’s triggered every time npm version
is run so it seemed like the right place for it. Depending on project structure, NPM may decide not to create a commit for npm version (but it does when you have the package file at the top level of the repo) so the last bit of the postversion
should change to reflect that.
Use this one when package file not at the top level of the solution (typically, multiple solutions in same repo)
"postversion": "gulp version-sync && git add . && git commit -m \"auto-versioning\""
Use this one when package file not at the top level of the solution (one solution generating one package hence a single package file at the top level)
"postversion": "gulp version-sync && git add . && git commit --amend --no-edit"
This is what the final gulp file looks like (SPFx 1.12.1)
'use strict';
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
var getTasks = build.rig.getTasks;
build.rig.getTasks = function () {
var result = getTasks.call(build.rig);
result.set('serve', result.get('serve-deprecated'));
return result;
};
build.initialize(require('gulp'));
gulp.task('version-sync', async function () {
// import gulp utilities to write error messages
const gutil = require('gulp-util');
// import file system utilities form nodeJS
const fs = require('fs');
// read package.json
var pkgConfig = require('./package.json');
// read configuration of web part solution file
var pkgSolution = require('./config/package-solution.json');
// log old version
gutil.log('Old Version:\t' + pkgSolution.solution.version);
// Generate new MS compliant version number
var newVersionNumber = pkgConfig.version.split('-')[0] + '.0';
// assign newly generated version number to web part version
pkgSolution.solution.version = newVersionNumber;
// log new version
gutil.log('New Version:\t' + pkgSolution.solution.version);
// write changed package-solution file
fs.writeFile('./config/package-solution.json', JSON.stringify(pkgSolution, null, 4), () => { });
});