Skip to content

Commit

Permalink
Merge pull request #2 from mcfly-io/yana/test-cli
Browse files Browse the repository at this point in the history
  • Loading branch information
thaiat authored Jun 20, 2016
2 parents eb07d1e + 708b7c6 commit f4d5b26
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 92 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ In your `package.json`
}
```

Optionnaly additional files can be added to also have their version bumped

```json
"scripts": {
"release": "mcfly-semantic-release.js --files ./package.json ./bower.json ./config.xml"
}
```

Note that the path for the `--files` option is relative to your current root directory

Then, to publish a new version execute the following command:
```bash
npm run release
Expand Down
141 changes: 64 additions & 77 deletions bin/mcfly-semantic-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,57 @@

'use strict';
global.Promise = require('bluebird');
var execAsync = Promise.promisify(require('child_process').exec);
const simpleGit = require('simple-git')();

const args = require('yargs').argv;
const chalk = require('chalk');
const changelog = require('conventional-changelog');
const changelogScript = require('../lib/changelog-script');
const gitHelper = require('../lib/githelper');
const githubHelper = require('../lib/githubHelper');
const inquirer = require('inquirer');
const path = require('path');
const versionHelper = require('../lib/versionHelper');
const githubHelper = require('../lib/githubHelper');
const _ = require('lodash');

// Repo constants
// const repoOwner = 'hassony2';
// const repoName = 'deploy-test';
var files = args.files ? [].concat(args.files) : [];

function makeChangelog(version) {
return new Promise(function(resolve, reject) {
var changelogString = '';
var changeStream = changelog({
preset: 'angular'
}, {
version: version
});
changeStream.on('error', function(err) {
console.log(err);
reject(err);
});
changeStream.on('data', (chunk) => {
changelogString += chunk;
});
changeStream.on('end', () => {
resolve(changelogString);
});
});
if (files.length === 0) {
files.push('./package.json');
}

const pkg = require('../package.json');
const currentVersion = pkg.version;
let versionarg = process.argv[2];
if (versionarg !== 'patch' && versionarg !== 'minor' && versionarg !== 'major') {
versionarg = 'patch';
}
const nextVersion = versionHelper.bump(currentVersion, versionarg);
files = _.map(files, (file) => {
return path.isAbsolute(file) ? file : path.join(process.cwd(), file);
});

var msg = {};
var changelogContent;
msg.currentVersion = versionHelper.getCurrentVersion(path.join(process.cwd(), './package.json'));
msg.nextVersion = versionHelper.bump(msg.currentVersion, args.type);

githubHelper.getUsername()
gitHelper.getCurrentBranch()
.then((currentBranch) => {
if (currentBranch !== 'master') {
throw new Error('To create a release you must be on the master branch');
}
return;
})
.then(() => {
return gitHelper.isClean()
.then(res => {
if (!res) {
throw new Error('Your repository has unstaged changes, you must commit your work before releasing a new version');
}
return res;
});
})
.then(() => {
return gitHelper.getRemoteRepository();
})
.then((repoInfo) => {
msg.repo = repoInfo.repo;
msg.owner = repoInfo.owner;
msg.repoUrl = repoInfo.url;
})
.then(() => {
return githubHelper.getUsername();
})
.then((username) => {
msg.username = username;
return inquirer.prompt([{
Expand All @@ -70,60 +76,41 @@ githubHelper.getUsername()
}]);
})
.then((answers) => {
console.log(chalk.yellow('Github authentication...'));
msg.username = answers.username || msg.username;
msg.password = answers.password;

return githubHelper.getClient(msg.username, msg.password);
})
.then((github) => {
msg.github = github;
return makeChangelog(nextVersion);
return;
})
.then((changelogResult) => {
changelogContent = changelogResult;
console.log(changelogContent);
console.log('npm version ' + versionarg);
return execAsync('npm version ' + versionarg);

.then(() => {
console.log(chalk.yellow('Generating changelog...'));
changelogScript.init(msg.repoUrl);
return changelogScript.generate(msg.nextVersion)
.then((changelogContent) => {
msg.changelogContent = changelogContent;
return msg;
});
})
.then((result) => {
console.log('git push origin v' + nextVersion + ' --porcelain');
//return execAsync('git push origin v' + nextVersion + ' --porcelain');
return simpleGit.push('origin', 'v' + nextVersion);
.then((msg) => {
console.log(chalk.yellow('Bumping files...'));
return versionHelper.bumpFiles(files, msg.nextVersion)
.then(() => msg);
})
.then((result) => {
console.log('delay before release...');
.then((msg) => {
console.log(chalk.yellow('Commiting version...'));
return gitHelper.commitVersion(msg.nextVersion)
.then(() => msg);
})
.delay(1000)
.then(() => {
// var versionName = 'v' + nextVersion;

// github.authenticate({
// type: 'basic',
// username: msg.username,
// password: msg.password
// });

// return new Promise(function(resolve, reject) {
// github.repos.createRelease({
// user: repoOwner,
// repo: repoName,
// tag_name: versionName,
// name: versionName,
// body: changelogContent
// }, function(err, res) {
// if (err) {
// reject(err);
// } else {

// resolve(res);
// }
// });
// });
.then((msg) => {
console.log(chalk.yellow('Publishing version...'));
return githubHelper.createRelease(msg);
})
.then((res) => {
console.log('release published at ', res.published_at);
console.log(chalk.green('finished'));
console.log(chalk.green(`Release ${res.name} successfully published!`));
})
.catch(function(err) {
console.log(chalk.red(err));
Expand Down
4 changes: 2 additions & 2 deletions lib/changelog-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ var GIT_LOG_CMD = 'git log --grep="%s" -E --format=%s %s';
var GIT_TAG_CMD = 'git describe --tags --abbrev=0';

var HEADER_TPL = '<a name="%s"></a>\n# %s (%s)\n\n';
var LINK_ISSUE = ''; //= '[#%s](' + constants.repository + '/issues/%s)';
var LINK_COMMIT = ''; // = '[%s](' + constants.repository + '/commit/%s)';
var LINK_ISSUE = '';
var LINK_COMMIT = '';

var EMPTY_COMPONENT = '$$';

Expand Down
71 changes: 71 additions & 0 deletions lib/gitHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict';
global.Promise = require('bluebird');

const git = require('simple-git')();
const _ = require('lodash');

var getCurrentBranch = function() {
return Promise
.fromCallback((cb) => {
git.branch(cb);
})
.then(branches => {
return branches.current;
});
};

var commitVersion = function(version) {
return Promise
.fromCallback((cb) => {
git
.add('./*')
.commit('docs(changelog): version ' + version)
.addAnnotatedTag(version, 'v' + version)
.push('origin', 'master')
.pushTags('origin', cb);
});
};

var getRemoteRepository = function() {
return Promise
.fromCallback((cb) => {
git
.getRemotes(true, cb);
})
.then(remotes => {
return _.chain(remotes)
.find(remote => {
return remote.name === 'origin';
})
.value();
})
.then(remote => {
if (!remote) {
throw new Error('"origin" remote repository is not configured');
}
var repoUrl = remote.refs.push;
var ownerRepo = repoUrl.split('/').slice(-2);
return {
url: repoUrl,
owner: ownerRepo[0],
repo: ownerRepo[1]
};
});
};

var isClean = function() {
return Promise
.fromCallback(cb => {
git.status(cb);
})
.then(res => {
return res.deleted.length + res.modified.length + res.created.length + res.conflicted.length <= 0;
});
};

module.exports = {
getCurrentBranch,
commitVersion,
getRemoteRepository,
isClean
};
23 changes: 21 additions & 2 deletions lib/githubHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ var checkClient = function(github) {
});
};

var getClient = function(username, password){
var getClient = function(username, password) {
var github = buildClient(username, password);
return checkClient(github);
};
Expand Down Expand Up @@ -189,12 +189,31 @@ var createTokenFile = function(username, password, tokenName, filename) {

};

var createRelease = function(param) {
return new Promise(function(resolve, reject) {
param.github.repos.createRelease({
user: param.owner,
repo: param.repo,
tag_name: param.nextVersion,
name: 'v' + param.nextVersion,
body: param.changelogContent
}, function(err, res) {
if (err) {
reject(err);
} else {
resolve(res);
}
});
});
};

module.exports = {
getUsername,
buildClient,
getClient,
getRepo,
getAllRepos,
getPackageJson,
createTokenFile
createTokenFile,
createRelease
};
38 changes: 31 additions & 7 deletions lib/versionHelper.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
'use strict';

global.Promise = require('bluebird');

const fileHelper = require('./fileHelper');
const fs = require('fs');
const path = require('path');
const semver = require('semver');
const fileHelper = require('./fileHelper');
const XML = require('node-jsxml').XML;
const _ = require('lodash');

/**
* Filters a list of files given an extension
Expand Down Expand Up @@ -63,22 +65,44 @@ var bumpFiles = function(files, version, outputDir) {
var json = fileHelper.readJsonFile(file);

json.version = version;
let retval = JSON.stringify(json, null, 4);
return Promise.fromCallback(function(cb) {
fs.writeFile(getOutputFile(file, outputDir), JSON.stringify(json, null, 4), cb);
});
fs.writeFile(getOutputFile(file, outputDir), retval, cb);
})
.then(() => {
return {
file: file,
content: retval
};
});
});
var xmlBump = Promise.map(xmlFiles, (file) => {
var xml = new XML(String(fileHelper.readTextFile(file)));
let retval;
xml.attribute('version').setValue(version);
return Promise.fromCallback(function(cb) {
fs.writeFile(getOutputFile(file, outputDir), xml.toXMLString(), cb);
});
retval = xml.toXMLString();
fs.writeFile(getOutputFile(file, outputDir), retval, cb);
})
.then(() => {
return {
file: file,
content: retval
};
});
});
return Promise.all([xmlBump, jsonBump]);
return Promise.all([xmlBump, jsonBump])
.then(_.flatten);
};

var getCurrentVersion = function(file) {
var json = fileHelper.readJsonFile(file);
return json.version;
};

module.exports = {
filterFiles,
bump,
bumpFiles
bumpFiles,
getCurrentVersion
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"node-jsxml": "^0.7.0",
"semver": "^5.1.0",
"simple-git": "^1.37.0",
"strip-json-comments": "^2.0.1"
"strip-json-comments": "^2.0.1",
"yargs": "^4.7.1"
},
"devDependencies": {
"chai": "^3.5.0",
Expand Down
Loading

0 comments on commit f4d5b26

Please sign in to comment.