diff --git a/README.md b/README.md index 1881bcc..c8383ae 100644 --- a/README.md +++ b/README.md @@ -13,35 +13,43 @@ Generate a changelog based on merged pull requests or commit messages npm install -g github-changes ``` +Optionally set your GitHub token using environment variable GITHUB_CHANGES_TOKEN. + ``` Usage: github-changes [options] Options: - -o, --owner (required) owner of the Github repository - -r, --repository (required) name of the Github repository - -d, --data (DEPRECATED) use pull requests or commits (choices: pulls, commits) [commits] - -b, --branch name of the default branch [master] - -n, --tag-name tag name for upcoming release [upcoming] - -a, --auth prompt to auth with Github - use this for private repos and higher rate limits - -k, --token need to use this or --auth for private repos and higher rate limits - -f, --file name of the file to output the changelog to [CHANGELOG.md] - -t, --title title to appear in the top of the changelog [Change Log] - -z, --time-zone time zone [UTC] - -m, --date-format date format [(YYYY/MM/DD HH:mm Z)] - -v, --verbose output details - --host alternate host name to use with github enterprise [api.github.com] - --path-prefix path-prefix for use with github enterprise - --between-tags only diff between these two tags, separate by 3 dots ... - --for-tag only get changes for this tag - --issue-body (DEPRECATED) include the body of the issue (--data MUST equal 'pulls') - --no-merges do not include merges - --only-merges only include merges - --only-pulls only include pull requests - --use-commit-body use the commit body of a merge instead of the message - "Merge branch..." - --order-semver use semantic versioning for the ordering instead of the tag date - --reverse-changes reverse the order of changes within a release (show oldest first) - --hide-tag-names hide tag names in changelog -``` + -V, --version output the version number + -o, --owner (required) owner of the Github repository + -r, --repository (required) name of the Github repository + -d, --data [type] (DEPRECATED) use pull requests or commits (choices: pulls, commits) (default: "commits") + -b, --branch [name] name of the default branch (default: "master") + -n, --tag-name [name] tag name for upcoming release (default: "upcoming") + -a, --auth prompt to auth with Github - use this for private repos and higher rate limits + -k, --token [token] need to use this or --auth for private repos and higher rate limits + -f, --file [name] name of the file to output the changelog to (default: "CHANGELOG.md") + -t, --title [title] title to appear in the top of the changelog (default: "Change Log") + -z, --time-zone [zone] time zone (default: "UTC") + -m, --date-format [format] date format (default: "(YYYY/MM/DD HH:mm Z)") + -v, --verbose output details + --host [domain] alternate host name to use with github enterprise (default: "api.github.com") + --path-prefix [path] path-prefix for use with github enterprise + --between-tags [range] only diff between these two tags, separate by 3 dots ... + --issue-body (DEPRECATED) include the body of the issue (--data MUST equal 'pulls') + --for-tag [tag] only get changes for this tag + --exclude-tag [regex] exclude changes matching these tags + --include-tag [regex] include changes matching only these tags + --no-merges do not include merges + --only-merges only include merges + --only-pulls only include pull requests + --use-commit-body use the commit body of a merge instead of the message - "Merge branch..." + --order-semver use semantic versioning for the ordering instead of the tag date + --reverse-changes reverse the order of changes within a release (show oldest first) + --hide-tag-names hide tag names in changelog + --hide-authors do not include authors + --timeout [milliseconds] Github API timeout (default: 10000) + -h, --help display help for command + ``` ### Example usage diff --git a/bin/index.js b/bin/index.js index 1df9ad4..0b6ace0 100755 --- a/bin/index.js +++ b/bin/index.js @@ -45,6 +45,8 @@ var opts = parser .option('--between-tags [range]', 'only diff between these two tags, separate by 3 dots ...') .option('--issue-body', '(DEPRECATED) include the body of the issue (--data MUST equal \'pulls\')') .option('--for-tag [tag]', 'only get changes for this tag') + .option('--exclude-tag [regex]', 'exclude changes matching these tags') + .option('--include-tag [regex]', 'include changes matching only these tags') .option('--no-merges', 'do not include merges') .option('--only-merges', 'only include merges') .option('--only-pulls', 'only include pull requests') @@ -52,6 +54,7 @@ var opts = parser .option('--order-semver', 'use semantic versioning for the ordering instead of the tag date') .option('--reverse-changes', 'reverse the order of changes within a release (show oldest first)') .option('--hide-tag-names', 'hide tag names in changelog') + .option('--hide-authors', 'do not include authors') .option('--timeout [milliseconds]', 'Github API timeout', 10000) .parse(process.argv); @@ -79,7 +82,8 @@ var currentDate = moment(); var github = null; // github auth token -var token = null; +//var token = null; +var token = process.env.GITHUB_CHANGES_TOKEN; // ~/.config/changelog.json will store the token var authOptions = { @@ -114,6 +118,14 @@ var getTags = function(){ } } + if (opts.excludeTag) { + const regex = new RegExp(opts.excludeTag, 'g'); + tagArray = tagArray.filter(tag => !tag.name.match(regex)); + } else if (opts.includeTag) { + const regex = new RegExp(opts.includeTag, 'g'); + tagArray = tagArray.filter(tag => tag.name.match(regex)); + } + return tagArray; }) .map(function(ref){ @@ -216,7 +228,7 @@ var tagger = function(sortedTags, data) { if (opts.data === 'commits') date = moment(data.commit.committer.date); else date = moment(data.merged_at); - var current = null; + var current = sortedTags[0] || null; for (var i=0, len=sortedTags.length; i < len; i++) { var tag = sortedTags[i]; if (tag.date < date) break; @@ -375,23 +387,27 @@ var commitFormatter = function(data) { var host = (opts.host === 'api.github.com') ? 'github.com' : opts.host; var url = "https://"+host+"/"+opts.owner+"/"+opts.repository+"/pull/"+prNumber; - output += "- [#" + prNumber + "](" + url + ") " + message; - - if (authors.length) { - output += ' (' + authors.map(function(author){return '@' + author}).join(', ') + ')'; - } else if (author) { - output += " (@" + author + ")"; - } else if (authorName) { - output += " (" + authorName + ")"; + output += "- " + message.replace((message.match(/ \(#\d+\)/) || [''])[0], '') + " [#" + prNumber + "](" + url + ") "; + + if (!opts.hideAuthors) { + if (authors.length) { + output += ' (' + authors.map(function(author){return '@' + author}).join(', ') + ')'; + } else if (author) { + output += " (@" + author + ")"; + } else if (authorName) { + output += " (" + authorName + ")"; + } } } else { //otherwise link to the commit - output += "- [" + commit.sha.substr(0, 7) + "](" + commit.html_url + ") " + message; + output += "- " + message.replace((message.match(/ \(#\d+\)/) || [''])[0], '') + " [" + commit.sha.substr(0, 7) + "](" + commit.html_url + ") "; - if (authors.length) - output += ' (' + authors.map(function(author){return '@' + author}).join(', ') + ')'; - else if (commit.author && commit.author.login) - output += " (@" + commit.author.login + ")"; + if (!opts.hideAuthors) { + if (authors.length) + output += ' (' + authors.map(function(author){return '@' + author}).join(', ') + ')'; + else if (commit.author && commit.author.login) + output += " (@" + commit.author.login + ")"; + } } // output += " " + moment(commit.commit.committer.date).utc().format(opts.dateFormat); @@ -406,6 +422,7 @@ var formatter = function(data) { }; var getGithubToken = function() { + if (token) return Promise.resolve({token}); if (opts.token) return Promise.resolve({token: opts.token}); if (opts.auth) return ghauth(authOptions); return Promise.resolve({}); @@ -464,6 +481,21 @@ var task = function() { if (a.tag.name === b.tag.name) tagCompare = 0; else if (a.tag.name === opts.tagName) tagCompare = 1; else if (b.tag.name === opts.tagName) tagCompare -1; + else if ((a.tag.name.split('.')).length > 3 || (b.tag.name.split('.')).length > 3) { + let tagA = a.tag.name; + let tagB = b.tag.name; + if (tagA.split('.').length > 3) { + tagA = a.tag.name.replace(/\.(?=[^.]*$)/, "+"); + } else { + tagA += '+0'; + } + if (tagB.split('.').length > 3) { + tagB = b.tag.name.replace(/\.(?=[^.]*$)/, "+"); + } else { + tagB += '+0'; + } + tagCompare = semver.compare(tagA, tagB); + } else tagCompare = semver.compare(a.tag.name, b.tag.name); return (tagCompare) ? tagCompare : compareSign * (moment(a.commit.committer.date) - moment(b.commit.committer.date)); }).reverse();