diff --git a/bin/semantic-release.js b/bin/semantic-release.js new file mode 100755 index 00000000..edcd96a3 --- /dev/null +++ b/bin/semantic-release.js @@ -0,0 +1,13 @@ +#!/usr/bin/env node + +/* istanbul ignore next */ +try { + require('../dist') +} catch (err) { + if (err.code === 'MODULE_NOT_FOUND') { + require('babel/register') + require('../src') + } else { + console.log(err) + } +} diff --git a/package.json b/package.json index 4a1cdc1f..39bd963e 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "dependencies": { "@semantic-release/commit-analyzer": "^1.0.0", "@semantic-release/release-notes-generator": "^1.0.0", + "lodash": "^3.9.3", + "nopt": "^3.0.3", "npm-registry-client": "^6.4.0", "npmconf": "^2.1.2", "npmlog": "^1.2.1", diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..877a1cc1 --- /dev/null +++ b/src/index.js @@ -0,0 +1,93 @@ +const { readFileSync, writeFileSync } = require('fs') + +const _ = require('lodash') +const log = require('npmlog') +const nopt = require('nopt') +const npmconf = require('npmconf') + +const env = process.env +const options = _.defaults(nopt({ + debug: Boolean, + 'github-token': String, + 'github-url': String +}, { + token: 'github-token', + dry: 'debug' +}), { + debug: !env.CI, + 'github-token': env.GH_TOKEN || env.GITHUB_TOKEN, + 'github-url': env.GH_URL +}) +const PREFIX = 'semantic-release' + +const pkg = JSON.parse(readFileSync('./package.json')) +const plugins = require('./lib/plugins')(pkg.release || {}) + +npmconf.load({}, (err, conf) => { + if (err) { + log.error(PREFIX, 'Failed to load npm config.', err) + process.exit(1) + } + + log.level = conf.get('loglevel') + + log.verbose(PREFIX, 'Verifying pkg, options and env.') + + const errors = require('./lib/verify')(pkg, options, env) + errors.forEach((err) => log.error(PREFIX, `${err.message} ${err.code}`)) + if (errors.length) process.exit(1) + + if (!options.argv.cooked.length || options.argv.cooked[0] === 'pre') { + log.verbose(PREFIX, 'Running pre-script.') + + const registry = conf.get('registry') + const nerfDart = require('./lib/nerf-dart')(registry) + + if (env.NPM_TOKEN) { + conf.set(`${nerfDart}:_authToken`, '${NPM_TOKEN}', 'project') + } else { + // Using the old auth token format is not considered part of the public API + // This might go away anytime (i.e. when we have a better testing strategy) + conf.set('_auth', '${NPM_OLD_TOKEN}', 'project') + conf.set('email', '${NPM_EMAIL}', 'project') + } + + conf.save('project', (err) => { + if (err) return log.error(PREFIX, 'Failed to save npm config.', err) + + log.verbose(PREFIX, 'Wrote authToken to .npmrc.') + + require('./pre')(pkg, { + auth: { + token: env.NPM_TOKEN + }, + loglevel: log.level, + registry + }, + plugins, + (err, release) => { + if (err) { + log.error(PREFIX, 'Failed to determine new version.') + + const args = [PREFIX, (err.code ? `${err.code} ` : '') + err.message] + if (err.stack) args.push(err.stack) + log.error(...args) + process.exit(1) + } + + log.verbose(PREFIX, `Determined version ${release.version}.`, release) + + writeFileSync('./package.json', JSON.stringify(_.assign(pkg, { + version: release.version + }), null, 2)) + + log.info(PREFIX, `Wrote version ${release.version} to package.json.`) + }) + }) + } else if (options.argv.cooked[0] === 'post') { + log.verbose(PREFIX, 'Running post-script.') + + } else { + log.error(PREFIX, `Command "${options.argv.cooked[0]}" not recognized. User either "pre" or "post"`) + } +})