sharman
sharman

Reputation: 535

npm publish and git repo workflow

I am struggling a bit with setting a workflow for our npm repo publish and git work flow. I have implemented a solution as follows and I am not satisfied with it.

Developer --> ready to push to git --> npm version (i have a script that updates README.md with the changelog -- using sinopia which does not support changelog) --> commit and push --> accept and merge --> git ci pipeline --> builds, tests and publishes to npm repo.

The nit that I have is that if the developer forgets to version the repo then the pipeline fails. I can probably create a staging area in my git pipeline that will contain an updated README and version the repo as part of the git CI. But that does not feel right for several reasons. Mainly I would rather not pollute the GIT with dynamic changes to the source files.

So, to summarize. Is there a better way? Ideally, I would like to version the repo when the changes are ready to be accepted in GIT. But I am not sure how. BTW we are using gitlab.

Upvotes: 1

Views: 619

Answers (2)

sharman
sharman

Reputation: 535

const fs = require('fs');
const path = require('path');
let execSync = require('child_process').execSync;


let streamToString = (stream, callback) => {
  let str = '';
  stream.on('data', function(chunk) {
    str += chunk;
  });
  stream.on('end', function() {
    callback(str);
  });
};

const run = cmd => {
  return execSync(cmd, function(error, stdout) {

    streamToString(stdout, (data) => {
      console.log('Data ---- ', data);
      return data;
    });
  });
};

const packagejson = fs.readFileSync(
  path.join(__dirname, '..', 'package.json'), 'utf8');

run("cp package.json package.json.bkp");
const json = JSON.parse(packagejson);


// Update package.json

let semver = json.version.split('.');

semver[2] = Number(semver[2]) + 1;

let replacer = /,/gi;
json.version = semver.toString().replace(replacer, '.');

let changelog = {};

changelog.version = json.version;
changelog.author = run('npm config get init.author.name');

fs.writeFileSync(path.join(__dirname, '..', 'package.json'), JSON.stringify(json, null, 2));

if (changelog.author.byteLength <= 1) {
  throw Error('init.author.name is a required npm configuration attribute......');
}
run('cp README.md README.bkp');

const readme = fs.readFileSync(
  path.join(__dirname, '..', 'README.md'), 'utf8');

let header = readme.split('-----------');

console.log('Header ......... ', header);

fs.writeFileSync(
  path.join(__dirname, '..', 'README.md'), header[0] + '-----------' +
  '\r\nVersion ' + changelog.version + '\r\n' + 'Changed By ' + changelog.author + '\r\n' +
  'Change Date ' + new Date(), 'utf8'
);

run('git add package.json');
run('git add README.md');

Upvotes: 0

Marina Liu
Marina Liu

Reputation: 38106

You can use pre-commit hook to update the file’s version automatically (assume the file is package.json).

pre-commit hook will execute before commit changes, so you can get current version by shell script, and then use the increment version to replace current version. And then git commit will also commit package.json with new version.

Assume package.json file's format as below (version is in third line):

{
    "name": "Hello World",
    "version": 0.0.1,

And the version format is major.minor.patch. the bigest value for minor and patch versions are 9 (you can specify other values). The shell script to automatically increase version number as below:

#!/bin/sh

if [ -n "$(git status --porcelain)" ]; then 
  echo "there has uncommited changes"; 
else 
{
  echo "no changes to commit!";
  exit
}
fi

line=$(sed '3!d' package.json)
IFS=: read -r var1 var2 <<< "$line"
v=$(echo "$var2" | tr -d '"')
version=$(echo "$v" | tr -d ',')
IFS=. read -r major minor patch <<< "$version"

if  [ $patch != 9 ]
then 
  patch=$((patch+1))
elif [ $minor != 9 ]
then
{
  minor=$((minor+1))
  patch=0
}
else
{
  major=$((major+1))
  minor=0
  patch=0
}
fi

newversion=$major"."$minor"."$patch
echo  "The new version is $newversion"

placestr=$(echo $var1: \"$newversion\",)
sed -i "s/${line}/${placestr}/" package.json
git add package.json

Upvotes: 1

Related Questions