Skip to content

Commit e7a73be

Browse files
committed
Merge pull request #1 from nomi9995/feat/changelog
feat: add changelog template
2 parents f5988bd + 1b235ba commit e7a73be

File tree

11 files changed

+156
-8
lines changed

11 files changed

+156
-8
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
Generate release notes from git commit history either **commit range** or **tag range**.
1414

15-
![](media/appstore.png)
15+
| ![](media/appstore.png) | ![](media/changeLog.png) |
16+
| :---------------------: | :----------------------: |
17+
| App Store Template | Changelog Template |
1618

1719
### Installation
1820

@@ -43,6 +45,7 @@ Where
4345
Three sample templates are included as a reference in the `templates` folder
4446

4547
- `appstore` [(sample)](https://github.com/nomi9995/release-notes-cli/blob/master/samples/output-appstore.txt)
48+
- `changelog` [(sample)](https://github.com/nomi9995/release-notes-cli/blob/master/samples/output-changelog.md)
4649
- `markdown` [(sample)](https://github.com/nomi9995/release-notes-cli/blob/master/samples/output-markdown.md)
4750
- `html` [(sample)](http://htmlpreview.github.io/?https://github.com/nomi9995/release-notes-cli/blob/master/samples/output-html.html)
4851
- `html-bootstrap` [(sample)](http://htmlpreview.github.io/?https://github.com/nomi9995/release-notes-cli/blob/master/samples/output-html-bootstrap.html)
@@ -69,6 +72,23 @@ fix(server): send cors headers
6972
feat(blog): add comment section
7073
```
7174

75+
#### Changelog Template
76+
77+
You need to get **GitHub personal** access token from github for setting committer username like this: [@nomi9995](https://github.com/nomi9995)
78+
79+
Since `release-notes-cli` interacts with the GitHub API you may run into rate
80+
limiting issues which can be resolved by supplying a "personal access token":
81+
82+
```
83+
export GITHUB_AUTH="..."
84+
```
85+
86+
You'll need a [personal access token](https://github.com/settings/tokens)
87+
for the GitHub API with the `repo` scope for private repositories or just
88+
`public_repo` scope for public repositories.
89+
90+
**Note:** if you dont set `GITHUB_AUTH` then it will not print committer username for all commits, it will print email instead of github username
91+
7292
#### Custom template
7393

7494
The second parameter of `release-notes-cli` can be any path to a valid ejs template files.

media/appstore.png

15.6 KB
Loading

media/bootstrap.png

38.9 KB
Loading

media/changeLog.png

53.7 KB
Loading

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
},
1212
"keywords": [
1313
"git",
14+
"markdown",
15+
"changelog",
16+
"changelog-generator",
17+
"commitlint",
1418
"log",
1519
"release notes",
1620
"compare",
@@ -39,11 +43,13 @@
3943
"watch": "yarn build -- --watch"
4044
},
4145
"dependencies": {
46+
"@octokit/rest": "^19.0.4",
4247
"chalk": "4.1.2",
4348
"clipboardy": "2.3.0",
4449
"date-fns": "^2.29.2",
4550
"debug": "^4.3.4",
4651
"ejs": "^3.1.8",
52+
"gitconfiglocal": "^2.1.0",
4753
"yargs": "^17.1.0"
4854
},
4955
"devDependencies": {

samples/output-changelog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
###Others
2+
3+
- release 1.5.2 ([bccb6f28fd](https://github.com/Shobbak/react-native-compressor/commit/bccb6f28fdeecd0915f12fbe990b9b170217ff90) by [@nomi9995](https://github.com/nomi9995))
4+
- release 1.5.1 ([f58a268b0b](https://github.com/Shobbak/react-native-compressor/commit/f58a268b0bfb940a34b1643080b28e6339417169) by [@nomi9995](https://github.com/nomi9995))
5+
- release 1.5.0 ([e696968913](https://github.com/Shobbak/react-native-compressor/commit/e696968913cf0aa1a309345b0e75e38695be1516) by [@nomi9995](https://github.com/nomi9995))
6+
- release 1.4.0 ([30b7bedd78](https://github.com/Shobbak/react-native-compressor/commit/30b7bedd78d22ab6096dfed04895fcc5e94bbf49) by [@nomi9995](https://github.com/nomi9995))
7+
8+
###docs
9+
10+
- update table of content ([b77bdb2105](https://github.com/Shobbak/react-native-compressor/commit/b77bdb21058187c13eef7ad9942b870e815538e7) by [@nomi9995](https://github.com/nomi9995))
11+
- update docs ([8321e362d3](https://github.com/Shobbak/react-native-compressor/commit/8321e362d3adc1cd341130e1bf7b5039109330ac) by [@nomi9995](https://github.com/nomi9995))
12+
13+
###Features
14+
15+
- add getVideoMetaData function for video metadata ([490c8cb884](https://github.com/Shobbak/react-native-compressor/commit/490c8cb88489dc7201a57ba213642a3121c1b203) by [@nomi9995](https://github.com/nomi9995))

src/index.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ let dateFnsFormat = require("date-fns/format");
77
import type { OPTIONS, ICommit } from "./types";
88
import * as clipboard from "clipboardy";
99
import chalk = require("chalk");
10+
const githubUsername = require("./utils/github-username");
1011

1112
export default (cliOptions: OPTIONS, positionalRange: string, positionalTemplate: string = "appstore") => {
1213
return fileSystem.resolveTemplate(positionalTemplate).then((template: string) => {
@@ -33,7 +34,7 @@ export default (cliOptions: OPTIONS, positionalRange: string, positionalTemplate
3334
});
3435
};
3536

36-
const render = (
37+
const render = async (
3738
range: string,
3839
templateContent: string,
3940
data: any,
@@ -42,16 +43,45 @@ const render = (
4243
) => {
4344
debug("Rendering template");
4445
let renderedContent = "";
45-
if (type === "appstore") {
46+
if (type === "appstore" || type === "changelog") {
47+
let gitRemote = "";
48+
let isError = false;
4649
const allCommits: { [key: string]: ICommit } = commitFormateForAppstore(data.commits);
47-
for (let [key, value] of Object.entries(allCommits)) {
48-
renderedContent += ejs.render(templateContent, { title: key, commits: value }) + "\n";
50+
if (type === "changelog") {
51+
gitRemote = await git.gitRemoteOriginUrl();
52+
for (let [key, value] of Object.entries(allCommits)) {
53+
//@ts-ignore
54+
const valueCommits: ICommit[] = value;
55+
const x = valueCommits.map(async commit => {
56+
try {
57+
const username = await githubUsername(commit.committerEmail, { token: process.env.GITHUB_AUTH });
58+
//@ts-ignore
59+
commit.username = username;
60+
} catch (error) {
61+
isError = true;
62+
}
63+
});
64+
await Promise.all(x);
65+
66+
renderedContent += ejs.render(templateContent, { title: key, gitRemote, commits: valueCommits }) + "\n";
67+
}
68+
} else {
69+
for (let [key, value] of Object.entries(allCommits)) {
70+
renderedContent += ejs.render(templateContent, { title: key, commits: value }) + "\n";
71+
}
4972
}
5073
console.log(chalk.magentaBright(renderedContent));
5174
if (copy) {
5275
clipboard.writeSync(renderedContent);
5376
console.log(chalk.green("Copied to clipboard successfully\n"));
5477
}
78+
if (isError) {
79+
console.log(
80+
chalk.red(
81+
'You need to get personal access token from github for setting committer username like this:\n\nexport GITHUB_AUTH="..."'
82+
)
83+
);
84+
}
5585
return;
5686
}
5787

@@ -94,7 +124,7 @@ const commitLintTypesMapper: string[] = [
94124
"Features",
95125
"Fixes",
96126
"perf",
97-
"Fixes",
127+
"Changed",
98128
"revert",
99129
"style",
100130
"test",

src/utils/git.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//@ts-ignore
22
let debug = require("debug")("release-notes:git");
33
let parser = require("debug")("release-notes:parser");
4+
const gitconfig = require("gitconfiglocal");
5+
const { promisify } = require("util");
6+
const pGitconfig = promisify(gitconfig);
47

58
exports.log = function (options: any) {
69
return new Promise(function (resolve, reject) {
@@ -156,3 +159,10 @@ function parseTag(line: string) {
156159
function normalizeNewlines(message: string) {
157160
return message.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, "");
158161
}
162+
163+
export async function gitRemoteOriginUrl({ cwd = process.cwd(), remoteName = "origin" } = {}) {
164+
const config = await pGitconfig(cwd);
165+
const url: string = (config.remote && config.remote[remoteName] && config.remote[remoteName].url) || "";
166+
167+
return url.replace(/\.git$/, "");
168+
}

src/utils/github-username.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const { Octokit } = require("@octokit/rest");
2+
3+
async function searchCommits(octokit: any, email: string) {
4+
const { data } = await octokit.search.commits({
5+
q: `author-email:${email}`,
6+
sort: "author-date",
7+
// eslint-disable-next-line camelcase
8+
per_page: 1,
9+
});
10+
11+
if (data.total_count === 0) {
12+
throw new Error(`Couldn't find username for \`${email}\``);
13+
}
14+
15+
return data.items[0].author.login;
16+
}
17+
18+
//@ts-ignore
19+
module.exports = async function githubUsername(email: string, { token } = {}) {
20+
if (!(typeof email === "string" && email.includes("@"))) {
21+
throw new Error("Email required");
22+
}
23+
24+
const octokit = new Octokit({
25+
auth: token,
26+
userAgent: "https://github.com/nomi9995/github-username",
27+
});
28+
29+
const { data } = await octokit.search.users({
30+
q: `${email} in:email`,
31+
});
32+
33+
if (data.total_count === 0) {
34+
return searchCommits(octokit, email);
35+
}
36+
37+
return data.items[0].login;
38+
};

templates/changelog.ejs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
###<%= title -%>
2+
3+
<% commits.forEach(function (commit) { -%>
4+
-<%= commit.title -%> ([<%= commit.sha1.slice(0,10) -%>](<%= gitRemote -%>/commit/<%= commit.sha1 -%>) by [@<%= commit.username?commit.username:commit.committerEmail-%>](https://github.com/<%= commit.username?commit.username:commit.committerEmail-%>))
5+
<% }) -%>

0 commit comments

Comments
 (0)