lib/deploy.js
const
colors = require('chalk'),
log = require('fancy-log'),
paqman = require('paqman'),
vinylFS = require('vinyl-fs')
const currentVersion = paqman.packageJSON.version
function getNextVersion (type) {
const SemVer = require('semver')
return SemVer.inc(currentVersion, type)
}
function isLernaPackage () {
const Path = require('path')
const inPackageFolder = Path.dirname(process.cwd()).match(/packages$/)
if (!inPackageFolder)
return false
const FS = require('fs')
const inLernaRepo = FS.readdirSync('../../').indexOf('lerna.json') !== -1
return inLernaRepo
}
module.exports = Object.create({
getNextVersion: getNextVersion,
withBumpType: function (options0, options1) {
const
ChildProcess = require('child_process'),
merge = require('lodash.merge'),
bump = require('gulp-bump'),
filter = require('gulp-filter'),
git = require('gulp-git'),
tagVersion = require('gulp-tag-version')
// Allow options merge through arguments list.
// This is useful for bind magic
const options = merge({ }, options0, options1),
bumpType = options.bumpType,
dryRun = options.dryRun,
noPublish = !options.publish,
noPush = !options.push
const
REF_HEAD_CMD = 'git rev-parse --abbrev-ref HEAD',
CURRENT_BRANCH = ChildProcess.execSync(REF_HEAD_CMD)
.toString().replace('\n',''),
NEXT_VERSION = getNextVersion(bumpType)
if (!dryRun) {
log('Utilizing bumpType', colors.magenta(options.bumpType))
log('Retrieving latest git commit...')
log('Getting next version of type: ', colors.magenta(bumpType))
log('Incrementing from version: ', colors.magenta(currentVersion))
}
const fileStream = vinylFS.src([ './package.json' ])
const
args = ' --tags',
remote = 'origin',
releaseCommitMsg = 'chore(release): release ' + NEXT_VERSION
const wouldPublish = !noPublish
const wouldPublishButNotPush = noPush && wouldPublish
const wouldPush = !noPush
let tagVersionConfig, pkgName
const isLPkg = isLernaPackage()
if (isLPkg) {
pkgName = paqman.packageJSON.name
tagVersionConfig = {
prefix : pkgName + '_v',
label : 'Tagging ' + pkgName + ' release as %t'
}
}
const tagPrefix = tagVersionConfig ? tagVersionConfig.prefix : 'v'
function publish () {
log('Loading NPM....')
const NPM = require('npm')
NPM.load(function () { // must be called first
NPM.publish(function (pubError) {
if (pubError) {
log.error('Publish failed')
log.error(pubError)
throw pubError
}
})
})
}
function revert () {
log(colors.bgRed(colors.black('~~~ ERROR ~~~')))
log('`git push` failed, reverting your unchanged files to their')
log(`state prior to running Unleash (${options.CURRENT_SHA})`)
ChildProcess.execSync(`git tag -d ${tagPrefix + NEXT_VERSION}`)
if (options.PKG_STATUS === '')
ChildProcess.execSync(`git checkout ${options.CURRENT_SHA} package.json`)
if (options.CL_STATUS === '')
ChildProcess.execSync(`git checkout ${options.CURRENT_SHA} CHANGELOG.md`)
ChildProcess.execSync(`git reset --mixed ${options.CURRENT_SHA}`)
}
function pushAndMaybePublish () {
return git.push(remote, CURRENT_BRANCH, { args: args }, function (error) {
if (error) {
revert()
throw error
}
if (!noPublish)
publish()
})
}
function warnLocalOnly () {
if (!options.publish && !options.push) {
const command = process.argv.slice(1).map(function (a) {
return a.split('/').reverse()[0]
}).join(' ')
log(colors.bgYellow(colors.black('~~~ WARNING ~~~')))
log('You\'ve turned both publishing & pushing off. Your ' +
'changelog & package files will be updated + committed locally but ' +
'nothing outside your machine will change.')
log(command
.replace('publish',
colors.bgYellow('publish'))
.replace('push',
colors.bgYellow('push'))
)
}
}
if (isLPkg)
log('Tagging ' + pkgName + ' as a package in a Lerna repo')
if (!dryRun) {
warnLocalOnly()
return fileStream
.pipe(bump({ type: bumpType }))
.pipe(vinylFS.dest('./'))
.pipe(git.commit(releaseCommitMsg))
.pipe(filter('package.json'))
.pipe(tagVersion(tagVersionConfig))
.on('end', function () {
if (wouldPublishButNotPush)
return publish()
else if (wouldPush)
return pushAndMaybePublish()
})
.on('error', console.error)
} else {
const pubLog = wouldPublish ? '* Publishing to NPM' : ''
const pushLog = wouldPush ? '* Pushing to ' + remote + ' branch ' + CURRENT_BRANCH : ''
log('* Bumping to a ' + bumpType + ' version with the commit "' + releaseCommitMsg + '"')
log('* Tagging the commit with "' + tagPrefix + NEXT_VERSION + '"')
pubLog && log(pubLog)
pushLog && log(pushLog)
warnLocalOnly()
return true
}
}
})