forked from w3c/webref
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclean-patches.js
134 lines (121 loc) · 4.07 KB
/
clean-patches.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
/**
* Check GitHub issues and pull requests referenced by patches and create
* a pull request to drop patches that should no longer be needed.
*/
const core = require('@actions/core');
const Octokit = require("./octokit");
const fs = require("fs");
const path = require("path");
/**
* Check GitHub issues and PR referenced by patch files and drop patch files
* that only reference closed issues and PR.
*
* @function
* @return {String} A GitHub flavored markdown string that describes what
* patches got dropped and why. To be used in a possible PR. Returns an
* empty string when there are no patches to drop.
*/
async function dropPatchesWhenPossible() {
const rootDir = path.join(__dirname, "..", "ed");
console.log("Gather patch files");
let patches = [];
const subDirs = fs.readdirSync(rootDir);
for (const subDir of subDirs) {
if (subDir.endsWith("patches")) {
const files = fs.readdirSync(path.join(rootDir, subDir));
for (const file of files) {
if (file.endsWith(".patch")) {
const patch = path.join(subDir, file);
console.log(`- add "${patch}"`);
patches.push({ name: patch });
}
}
}
}
console.log();
console.log("Extract list of issues");
const diffStart = /^---$/m;
const issueUrl = /(?<=^|\s)https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(issues|pull)\/(\d+)(?=\s|$)/g;
for (const patch of patches) {
const contents = fs.readFileSync(path.join(rootDir, patch.name), "utf8");
const desc = contents.substring(0, contents.match(diffStart)?.index);
const patchIssues = [...desc.matchAll(issueUrl)];
for (patchIssue of patchIssues) {
if (!patch.issues) {
patch.issues = [];
}
const issue = {
owner: patchIssue[1],
repo: patchIssue[2],
number: parseInt(patchIssue[4], 10),
url: `https://github.com/${patchIssue[1]}/${patchIssue[2]}/${patchIssue[3]}/${patchIssue[4]}`
}
console.log(`- "${patch.name}" linked to ${issue.url}`);
patch.issues.push(issue);
}
if (patchIssues.length === 0) {
console.log(`- "${patch.name}" not linked to any issue`);
}
}
patches = patches.filter(patch => patch.issues);
console.log();
console.log("Check status of GitHub issues/PR");
for (const patch of patches) {
for (const issue of patch.issues) {
const response = await octokit.issues.get({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number
});
issue.state = response?.data?.state ?? "unknown";
console.log(`- [${issue.state}] ${issue.url}`);
}
}
console.log();
console.log("Drop patches when possible");
patches = patches.filter(patch => patch.issues.every(issue => issue.state === "closed"));
if (patches.length > 0) {
const res = [];
for (const patch of patches) {
console.log(`- drop "${patch.name}"`);
fs.unlinkSync(path.join(rootDir, patch.name));
res.push(`- \`${patch.name}\` was linked to now closed: ` +
patch.issues.map(issue => `[${issue.owner}/${issue.repo}#${issue.number}](${issue.url})`).join(", "));
}
return res.join("\n");
}
else {
console.log("- No patch to drop at this time");
return "";
}
}
/*******************************************************************************
Retrieve GH_TOKEN from environment, prepare Octokit and kick things off
*******************************************************************************/
const GH_TOKEN = (() => {
try {
return require("../config.json").GH_TOKEN;
} catch {
return process.env.GH_TOKEN;
}
})();
if (!GH_TOKEN) {
console.error("GH_TOKEN must be set to some personal access token as an env variable or in a config.json file");
process.exit(1);
}
const octokit = new Octokit({
auth: GH_TOKEN,
//log: console
});
dropPatchesWhenPossible()
.then(res => {
core.exportVariable("dropped_patches", res);
console.log();
console.log("Set dropped_variables env variable");
console.log(res);
console.log("== The end ==");
})
.catch(err => {
console.error(err);
process.exit(1);
});