Given that:
- npm registry requires versions to be immutable:
- trying to publish same version a 2nd time results with an error.
npm publish
uses theversion
it finds in thepackage.json
Then
- a build that should end with
npm publish
will fail - unless developers have bumped the version in theirpackage.json
file.
There are two approaches, pending the organization culture.
if the current version is occupied - it should not be published. if developers mean to publish a new version - they should have the version bumped.
If this is your approach - this package is not for your current project.
if changes were made and all tests have passed - I would like a new version to be published.
In this case, all you have to do is run versi
as part of your CI.
You can do it either in your project root, or provide it with -p/--path
to the package.json
you need it's version updated, and versi
will fix the version for you (explained better in How it works section below).
- developers must update manually the minor semver segment whenever they add functionality, and the major semver segment whenver they breack compatibility.
- whenever no new functionality is added and all changes are backward compatible - the increase of the patch part can be done in-build automatically.
This means, that the following workflow is the recommended workflow with versi
:
version
inpackage.json
are commited with0
for patch (although developers can force a jump by commiting a patch number higher than last published).versi
is run in build beforenpm publish
and is responsible to promote patch segment, relaying on what versions are published on the npm registry.- developers are responsible to promote
major
andminor
parts inpackage.json
Two options:
npm i versi -D
Then, ran from your npm hooks, e.g:
"scripts": {
//...
"prepublish": "versi"
//...
}
npm i versi -g
The advantage here is that you can run it immediately after your checkout phase, and use the worked version in your build output and side effects.
e.g. see it early in build log, set build-name even if your did not get to the publish stage(Jenkins/blue-ocean)
- uses the npm client installed on your build agent, and therefore, supports
.npmrc
and/or local npm-client users setup on your build agents. - the vanilla run works on the
package.json
in current directory - supports path injection via CLI argument
-p/--path
as absolute or relative topwd
, to the directory where targetpackage.json
should be found. - supports a prerelease mode - pass the prerelease tag using
-l/prerelease
CLI switch - ATM - it's slim and minimal (depends only on
minimist
,semver
anddebug
)
-
find the target
package.json
file, or fail with an error. -
extract
name
andversion
from the targetpackage.json
, and parse it'sversion
field usignsemver
-
find the published versions for your package, using the
npm
client found locally (or fail with error). -
compute the next available version using the version from the
package.json
file and the versions returned by npm. This is done in eitherrelease
mode, or inpre-release
mode - find the details below. -
update the package.json by replacing the version field using string manipulation - i.e - original file indentations are preserved.
-
prints a summary with:
- the path to the updated
package.json
file, - the version in
package.json
when the tool loaded, - and the version it has ended with.
e.g:
{ "packageFile": "/home/usr/versi/test/fixtures/package1/package.json", "foundVersion": "1.2.0", "nextVersion": "1.2.17" }
- the path to the updated
This mode assures that the end result is a clean semver version, includes only major, minor and patch.
e.g.: "2.3.1"
, "1.0.5"
, 0.8.4
This mode is used when no prerelease tag is found in both the package.json
, nor in a -t/--prerelease-tag
CLI switch.
The algorithm in this case is:
- filter from all published versions all versions that start with the same major and minor.
- Use the version from package.json in any of the following cases:
- no versions pass the filter - (this is the case of a new major/minor pair)
- the version from
package.json
is higher by semver rules than any of the filtered versions (this is a case of a jump in the running patch number imposed by developers).
- Otherwise - take the latest by semver rules, and increase it's patch by one - and return that as the new version.
This mode publishes a prerelease version - i.e - a version that includes a prerelease semver tag.
Package users will not get this versions unless they ask for them explicitly.
e.g.: "2.3.1-feat_users-api"
, "1.0.5-beta.3"
, 0.8.4-chore_refactor-for-resilience.12
This mode is used when a semver prerelease tag is found in either the package.json
, or in the -t/--prerelease-tag
CLI switch provided.
Notes:
- When both the tool and the
package.json
contain a prerelease tag value - the CLI switch cascades. - the tool knows to distinct the running number in the end of the prerelease tag when such number is found. If no prerelease running number is found in a version selected for incrementation - it will be added as 0, which complies with semver rules.
- when the passed prerelease tag contains characters unfit for preerelease tag (e.g. a name of a branch with slash inside) - it is sanitized by replacing any non
[a-zA-Z0-9.-]
with underscore.
The algorithm in this case is:
- filter from all published versions all versions that start with the same major and minor, patch and prerelease, not including the optional running number in the end of the tag.
- Use the version from package.json in any of the following cases:
- no versions pass the filter (this is the case of a new tag)
- the version from
package.json
is higher by semver rules than any of the filtered versions (this is a case of a jump in the running number imposed by developers).
- Otherwise - take the latest by semver rules, and increase it's tag's running numeric number - and return that as the new version.
- travis & coveralls integration based on in-build env vars
DEBUG=versi:* versi
npm run test
- ISC
- you may do with the source code anything you like
- there is no warranty on our end