Visitar URL original
Group by labels by alexcanessa · Pull Request #62 · github-tools/github-release-notes · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions .grenrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ module.exports = {
"help wanted"
],
"template": {
issue: ({ text, name, url, labels }) => {
labels = labels.slice(0, -1);

return `- [${text}](${url}) ${name} - ${labels}`;
},
"label": "_{{label}}_,"
"issue": "- [{{text}}]({{url}}) {{name}}"
},
"groupBy": {
"Framework Enhancements:": ["enhancement"],
"Bug Fixes:": ["bug"]
}
}
};
35 changes: 35 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,41 @@ gren --tags=all

![exec gren all tags]({{ "images/examples/exec_gren_all_tags.gif" | relative_rul }})

### Group by

You can group the issues in the release notes. So far the only way to group them is by label and you can do it in two different ways:

1. Just using the first label of an issue to group it.

```json
{
"groupBy": "label"
}
```

2. Using an object where the keys are the group names, and the values are the arrays of labels included in that group.

```json
{
"groupBy": {
"Bug fixes:": ["bug"],
"Framework Enhancements:": ["enhancement"]
}
}
```

An issue with no label will be included using the template option `no-label` (default "_closed_") as group name.
To list all the issues that have any other label, use `"..."` as label name.

```json
{
"groupBy": {
"Bug fixes:": ["bug"],
"Other stuff:": ["..."] // This will include the issues that have any label but not "bug"
}
}
```

### Changelog

There different ways to generate the changelog:
Expand Down
7 changes: 5 additions & 2 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To pass it to the `GithubReleaseNotes` class, in the [configuration file](#confi
| `username` | **Required** | The username of the repo _e.g. `github-tools`_ | `null` |
| `repo` | **Required** | The repository name _e.g. `github-release-notes`_ | `null` |
| `action`| `release` `changelog` | The **gren** action to run. _(see details below for changelog generator)_ | `release` |
| `ignore-labels` | `wont_fix` `wont_fix,duplicate` | Ignore issues that contains one of the specified labels. | `false` |
| `ignore-labels` | `wont_fix` `wont_fix,duplicate` | Ignore the specified labels. | `false` |
| `ignore-issues-with` | `wont_fix` `wont_fix,duplicate` | Ignore issues that contains one of the specified labels. | `false` |
| `data-source` | `issues` `commits` | The informations you want to use to build release notes. | `issues` |
| `prefix` | **String** `e.g. v` | Add a prefix to the tag version. | `null` |
Expand All @@ -33,6 +33,7 @@ To pass it to the `GithubReleaseNotes` class, in the [configuration file](#confi
| `draft` | **Flag** | Set the release as a draft. | `false` |
| `prerelease` | **Flag** | To set the release as a prerelease. | `false` |
| `tags` | `0.1.0` `0.2.0,0.1.0` `all` | A specific tag or the range of tags to build the release notes from. You can also specify `all` to write all releases. _(To override existing releases use the --override flag)_ | `false` |
| `group-by` | `label` `{...}` | Group the issues using the labels as group headings. You can set custom headings for groups of labels. [See example]({{ "example#group-by" | relative_url }}) | `false` |

### Changelog options

Expand Down Expand Up @@ -79,7 +80,9 @@ You can configure the output of **gren** using templates. Set your own configura
"commit": "- {{message}}",
"issue": "- {{labels}} {{name}} [{{text}}]({{url}})",
"label": "[**{{label}}**]",
"release": "## {{release}} {{date}}"
"noLabel": "closed",
"release": "## {{release}} {{date}}",
"group": "#### {{heading}}\n"
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "github-release-notes",
"version": "0.7.1",
"version": "0.7.2",
"description": "Node module to publish release notes based on commits between the last two tags.",
"main": "./github-release-notes.js",
"scripts": {
Expand Down
136 changes: 123 additions & 13 deletions src/gren.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var defaults = {
override: false,
ignoreLabels: false, // || array of labels
ignoreIssuesWith: false, // || array of labels
template: templateConfig
template: templateConfig,
groupBy: false
};

/**
Expand Down Expand Up @@ -293,7 +294,7 @@ function getLastTwoReleases(gren) {
}

/**
* Return a string with a - to be a bulvar list (used for a mapping)
* Return the templated commit message
*
* @since 0.1.0
* @private
Expand All @@ -319,8 +320,8 @@ function templateCommits(gren, message) {
* @return {string}
*/
function templateLabels(gren, issue) {
if (!issue.labels.length) {
issue.labels.push({name: 'closed'});
if (!issue.labels.length && gren.options.template.noLabel) {
issue.labels.push({name: gren.options.template.noLabel});
}

return issue.labels
Expand Down Expand Up @@ -404,6 +405,31 @@ function templateIssueBody(body, rangeBody) {
return (body.length ? body.join('\n') : rangeBody || '*No changelog for this release.*') + '\n';
}

/**
* Generates the template for the groups
*
* @since 0.8.0
* @private
*
* @param {GithubReleaseNotes} gren
* @param {Object} groups The groups to template e.g.
* {
* 'bugs': [{...}, {...}, {...}]
* }
*
* @return {string}
*/
function templateGroups(gren, groups) {
return Object.keys(groups).map(function(group) {
var heading = template.generate({
heading: group
}, gren.options.template.group);
var body = groups[group].join('\n');

return heading + '\n' + body;
});
}

/**
* Return a commit messages generated body
*
Expand Down Expand Up @@ -567,6 +593,90 @@ function getClosedIssues(gren, releaseRanges) {
});
}

/**
* Group the issues based on their first label
*
* @since 0.8.0
* @private
*
* @param {GithubReleaseNotes} gren
* @param {Array} issues
*
* @return {string}
*/
function groupByLabel(gren, issues) {
var groups = [];

issues.forEach(function(issue) {
if (!issue.labels.length && gren.options.template.noLabel) {
issue.labels.push({name: gren.options.template.noLabel});
}

var labelName = issue.labels[0].name;

if (!groups[labelName]) {
groups[labelName] = [];
}

groups[labelName].push(templateIssue(gren, issue));
});

return templateGroups(gren, utils.sortObject(groups));
}

/**
* Create groups of issues based on labels
*
* @since 0.8.0
* @private
*
* @param {GithubReleaseNotes} gren
* @param {Array} issues The array of all the issues.
*
* @return {Array}
*/
function groupBy(gren, issues) {
var groupBy = gren.options.groupBy;

if (!groupBy) {
return issues.map(templateIssue.bind(null, gren));
}

if (groupBy === 'label') {
return groupByLabel(gren, issues);
}

if (typeof groupBy !== 'object') {
throw chalk.red('The option for groupBy is invalid, please check the documentation');
}

var allLabels = Object.keys(groupBy).reduce(function(carry, group) {
return carry.concat(groupBy[group]);
}, []);

var groups = Object.keys(groupBy).reduce(function(carry, group) {
var groupIssues = issues.filter(function(issue) {
if (!issue.labels.length && gren.options.template.noLabel) {
issue.labels.push({name: gren.options.template.noLabel});
}

return issue.labels.some(function(label) {
var isOtherLabel = groupBy[group].indexOf('...') !== -1 && allLabels.indexOf(label.name) === -1;

return groupBy[group].indexOf(label.name) !== -1 || isOtherLabel;
});
}).map(templateIssue.bind(null, gren));

if (groupIssues.length) {
carry[group] = groupIssues;
}

return carry;
}, {});

return templateGroups(gren, groups);
}

/**
* Get the blocks of issues based on release dates
*
Expand All @@ -585,15 +695,15 @@ function getIssueBlocks(gren, releaseRanges) {
.then(function(issues) {
return releaseRanges
.map(function(range) {
var body = (!range[0].body || gren.options.override) &&
issues.filter(function(issue) {
return utils.isInRange(
Date.parse(issue.closed_at),
Date.parse(range[1].date),
Date.parse(range[0].date)
);
})
.map(templateIssue.bind(null, gren));
var filteredIssues = issues.filter(function(issue) {
return utils.isInRange(
Date.parse(issue.closed_at),
Date.parse(range[1].date),
Date.parse(range[0].date)
);
});

var body = (!range[0].body || gren.options.override) && groupBy(gren, filteredIssues);

return {
id: range[0].id,
Expand Down
4 changes: 3 additions & 1 deletion src/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
"commit": "- {{message}}",
"issue": "- {{labels}} {{name}} [{{text}}]({{url}})",
"label": "[**{{label}}**]",
"release": "## {{release}} {{date}}"
"noLabel": "closed",
"release": "## {{release}} {{date}}",
"group": "#### {{heading}}\n"
}
20 changes: 20 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ var chalk = require('chalk');
var fs = require('fs');
require('require-yaml');

/**
* Sort an object by its keys
*
* @since 0.8.0
* @public
*
* @param {Object} object
* @return {Object}
*/
function sortObject(object) {
return Object.keys(object)
.sort()
.reduce(function(result, key) {
result[key] = object[key];

return result;
}, {});
}

/**
* Print a task name in a custom format
*
Expand Down Expand Up @@ -213,6 +232,7 @@ function getConfigFromFile(path) {
}

module.exports = {
sortObject: sortObject,
printTask: printTask,
task: task,
clearTasks: clearTasks,
Expand Down