-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathgithub-release-from-changelog.js
executable file
·176 lines (158 loc) · 4.11 KB
/
github-release-from-changelog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env node
var changelogFileNames = [
"CHANGELOG.md",
"Changelog.md",
"changelog.md",
"CHANGES.md",
"Changes.md",
"changes.md",
"HISTORY.md",
"History.md",
"history.md",
"NEWS.md",
"News.md",
"news.md",
"RELEASES.md",
"Releases.md",
"releases.md"
];
/**
* GitHub release from an package.json + CHANGELOG
*
* Usage:
* $ GITHUB_TOKEN=aGitHubToken
* $ github-release-from-changelog [--filename CustomChangelog.md]
*
* we will use `grizzly` (https://github.com/coderaiser/node-grizzly)
* so we need
* - user (user from package.json repo field)
* - repo (same as)user
* - tag (version)
* - release name (tag)
* - description (changelog section corresponding to tag)
*/
// read command line arguments
var cp = require("child_process");
var minimist = require("minimist");
var argv = minimist(process.argv.slice(2));
var fs = require("fs");
// changelog file name
var changelogFileName = argv.filename;
if (!changelogFileName) {
for (var fileName of changelogFileNames) {
if (fs.existsSync(fileName)) {
changelogFileName = fileName;
break;
}
}
}
// console.log("changelog filename", changelogFileName);
// get dep
var release = require("grizzly");
// read package.json
var pkg;
try {
pkg = require(process.cwd() + "/package.json");
} catch (e) {
throw "No package.json found in " + process.cwd();
}
// read changelog
var changelog;
try {
changelog = fs.readFileSync(process.cwd() + "/" + changelogFileName, {
encoding: "utf8"
});
} catch (e) {
throw "No " + changelogFileName + " found in " + process.cwd();
}
// parse repository url to get user & repo slug
var repoUrl;
repoUrl = pkg.repository;
if (repoUrl === undefined) {
throw "No repository.url found in " + process.cwd() + "/repository(.url)";
}
if (typeof repoUrl === "object" && repoUrl.url) {
repoUrl = repoUrl.url;
}
var matches = repoUrl.match(
/(?:https?|git(?:\+ssh)?)(?::\/\/)(?:www\.)?github\.com\/(.*)/i
);
if (matches === null) {
throw "Unable to parse repository url";
}
var repoData = matches[1].split("/");
var user = repoData[0];
var repo = repoData[1].replace(/\.git$/, "");
// version
var version = pkg.version;
// Look for the tag in either X.Y.Z or vX.Y.X formats
var tags = cp.execSync("git tag", { encoding: "utf8" });
var tagMatches = tags.match(new RegExp("^(v?)" + version + "$", "gm"));
var tagName;
if (tagMatches === null) {
throw "Tag " + version + " or v" + version + " not found";
} else {
tagName = tagMatches[0];
}
// changelog
var body = [];
var start = false;
var changelogLines = changelog.replace(/\r\n/g, "\n").split("\n");
// accept various ways to specify version starting like
// # 1.0
// ## v1.0
// ## [v1.0
var versionStartStringRe = "^##? \\[?v?";
var versionStartRe = new RegExp(versionStartStringRe);
var versionRe = new RegExp(versionStartStringRe + version.replace(/\./, "."));
var footerLinkRe = new RegExp("^\\[");
changelogLines.some(function(line, i) {
argv.debug && console.log("MATCH", line.match(versionRe));
if (!start && line.match(versionRe)) {
start = true;
argv.debug && console.log("START");
} else if (
start &&
(line.match(versionStartRe) || line.match(footerLinkRe))
) {
argv.debug && console.log("END");
return true;
} else if (start) {
argv.debug && console.log(line);
// between start & end, collect lines
body.push(line);
}
argv.debug && console.log("IGNORED " + line);
});
body = body.join("\n").trim();
// prepare release data
var releaseOptions = {
user: user,
repo: repo,
tag: tagName,
name: tagName,
body: body
};
var githubReleaseUrl =
"https://github.com/" + user + "/" + repo + "/releases/tag/" + tagName;
if (argv.dryRun) {
console.log(tagName);
console.log();
console.log("---");
console.log(body);
console.log("---");
console.log();
console.log("NOT released, link below should not have the release notes");
console.log(githubReleaseUrl);
} else {
var token = process.env.GITHUB_TOKEN;
if (!token) {
throw "GITHUB_TOKEN required";
}
release(token, releaseOptions, function(err) {
if (err) {
throw err;
}
console.log(githubReleaseUrl);
});
}