feat: add auto release notes

This commit is contained in:
xuexb 2017-10-15 00:37:51 +08:00
parent a3643b1a25
commit 67b89e9bc6
3 changed files with 113 additions and 11 deletions

View File

@ -65,5 +65,32 @@ module.exports = {
number,
labels: Array.isArray(labels) ? labels : [labels]
});
},
createRelease(payload, {tag_name, target_commitish, name, body, draft, prerelease}) {
const owner = payload.repository.owner.login;
const repo = payload.repository.name;
github.repos.createRelease({
owner,
repo,
tag_name,
target_commitish,
name,
body,
draft,
prerelease
});
},
getReleaseByTag(payload, {tag_name}) {
const owner = payload.repository.owner.login;
const repo = payload.repository.name;
return github.repos.getReleaseByTag({
owner,
repo,
tag: tag_name
});
}
};

View File

@ -3,15 +3,79 @@
* @author xuexb <fe.xiaowu@gmail.com>
*/
const {getReleaseByTag} = require('../../github');
const {cloneRepo, getTags} = require('../../utils');
const {getReleaseByTag, createRelease} = require('../../github');
const {cloneRepo, getTags, getFirstCommitHash, getCommitLog} = require('../../utils');
const RELEASE_CHANGE_MAP = {
document: 'docs',
feature: 'feat',
bugfix: 'fix',
close: 'close'
};
function autoReleaseNote(on) {
on('create_tag', ({payload, repo}) => {
const repoDir = cloneRepo(payload.repository.clone_url, repo);
const tags = getTags(repoDir);
getReleaseByTag(payload, {
tag_name: payload.ref
}).then(() => {}, () => {
const repoDir = cloneRepo({
url: payload.repository.clone_url,
repo
});
const tags = getTags({
dir: repoDir
});
const after = tags[0];
const before = tags.length > 1 ? tags[1] : getFirstCommitHash({
dir: repoDir
});
const log = getCommitLog({
dir: repoDir,
before,
after
});
console.log(repoDir, tags);
const hash = getCommitLog({
dir: repoDir,
before,
after,
html_url: payload.repository.html_url,
hash: true
});
const changes = Object.keys(RELEASE_CHANGE_MAP).map(title => {
return {
title,
data: log.filter(log => log.indexOf(`- ${RELEASE_CHANGE_MAP[title]}:`) === 0)
}
}).filter(v => v.data.length);
let body = [];
if (changes.length) {
body.push('## Notable changes\n');
changes.forEach(v => {
body.push([
`- ${v.title}`
]);
v.data.forEach(line => body.push(' ' + line));
});
}
if (hash.length) {
body.push('\n## Commits\n');
body = body.concat(hash);
}
if (body.length) {
createRelease(payload, {
tag_name: payload.ref,
name: `${payload.ref} @${payload.repository.owner.login}`,
body: body.join('\n')
});
}
});
});
}

View File

@ -1,3 +1,4 @@
const format = require('string-template');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
@ -34,13 +35,23 @@ const utils = {
}
},
getActionLog({dir, before, after, action}) {
return execSync(`cd ${dir} && FORMAT="- %s, by @%cn"
git log ${before}..${after} --no-merges --pretty=format:"$FORMAT" | grep ${action}`).toString();
getFirstCommitHash({dir}) {
return execSync(`cd ${dir} && git log --oneline --pretty=format:"%h"`).toString()
.split(/\n+/).slice(-1)[0];
},
cloneRepo(url, repo) {
getCommitLog(options) {
const shell = [
'cd {dir}',
options.hash
? 'git log {before}..{after} --no-merges --pretty=format:"- [%h]({html_url}/commit/%H) - %s, by @%cn"'
: 'git log {before}..{after} --no-merges --pretty=format:"- %s, by @%cn"'
].join(' && ');
return execSync(format(shell, options)).toString().split(/\n+/);
},
cloneRepo({url, repo}) {
const repoDir = path.resolve(__dirname, '../github/', repo);
if (!utils.isDirectory(repoDir)) {
@ -52,7 +63,7 @@ git log ${before}..${after} --no-merges --pretty=format:"$FORMAT" | grep ${actio
return repoDir;
},
getTags(dir) {
getTags({dir}) {
return execSync(`cd ${dir} && git tag -l`).toString().split(/\n+/).filter(tag => !!tag).reverse();
}
};