Skip to content

Commit 1c4ca4d

Browse files
authored
Add codeowners update (DefinitelyTyped#33654)
* Add update-codeowners script Right now it works but doesn't open a PR for you. Also not present as an npm script. * Dump in a bunch of code from TS * A few fixes and updates 1. Fix package.json formatting. 2. Adapt copied code from TS. * Ready to test locally * Fix git add * Put everything in one Promise chain Also start compiling JS files in scripts/
1 parent e004e12 commit 1c4ca4d

File tree

3 files changed

+131
-7
lines changed

3 files changed

+131
-7
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"scripts": {
1818
"compile-scripts": "tsc -p scripts",
1919
"not-needed": "node scripts/not-needed.js",
20+
"update-codeowners": "node scripts/update-codeowners.js",
2021
"test": "node node_modules/types-publisher/bin/tester/test.js --run-from-definitely-typed",
2122
"lint": "dtslint types"
2223
},

scripts/tsconfig.json

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
{
22
"compilerOptions": {
3+
"allowJs": true,
4+
"checkJs": true,
35
"module": "commonjs",
46
"target": "es6",
5-
"noImplicitAny": true,
6-
"strictNullChecks": true,
7-
"noImplicitReturns": true,
8-
"noImplicitThis": true,
9-
"noUnusedLocals": true,
10-
"noUnusedParameters": true,
7+
"strict": true,
118
"baseUrl": "../types",
129
"typeRoots": [
1310
"../types"
1411
],
1512
"types": [],
1613
"forceConsistentCasingInFileNames": true
1714
}
18-
}
15+
}

scripts/update-codeowners.js

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/// <reference lib="esnext.asynciterable" />
2+
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
3+
const cp = require("child_process");
4+
const Octokit = require("@octokit/rest");
5+
const { AllPackages, getDefinitelyTyped, loggerWithErrors,
6+
parseDefinitions, parseNProcesses, clean } = require("types-publisher");
7+
const { writeFile } = require("fs-extra");
8+
9+
async function main() {
10+
const options = { definitelyTypedPath: ".", progress: false, parseInParallel: true };
11+
const log = loggerWithErrors()[0];
12+
13+
clean();
14+
const dt = await getDefinitelyTyped(options, log);
15+
await parseDefinitions(dt, { nProcesses: parseNProcesses(), definitelyTypedPath: "." }, log);
16+
const allPackages = await AllPackages.read(dt);
17+
const typings = allPackages.allTypings();
18+
const maxPathLen = Math.max(...typings.map(t => t.subDirectoryPath.length));
19+
const entries = mapDefined(typings, t => getEntry(t, maxPathLen));
20+
await writeFile([options.definitelyTypedPath, ".github", "CODEOWNERS"].join("/"), `${header}\n\n${entries.join("\n")}\n`, { encoding: "utf-8" });
21+
}
22+
23+
const token = /** @type {string} */(process.env.GH_TOKEN);
24+
const gh = new Octokit();
25+
const reviewers = ["weswigham", "sandersn", "RyanCavanaugh"]
26+
const now = new Date();
27+
const branchName = `codeowner-update-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}`;
28+
const remoteUrl = `https://${token}@github.com/DefinitelyTyped/DefinitelyTyped.git`;
29+
runSequence([
30+
["git", ["checkout", "."]], // reset any changes
31+
]);
32+
33+
main().then(() => {
34+
runSequence([
35+
["git", ["checkout", "-b", branchName]], // create a branch
36+
["git", ["add", ".github/CODEOWNERS"]], // Add CODEOWNERS
37+
["git", ["commit", "-m", `"Update CODEOWNERS"`]], // Commit all changes
38+
["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork
39+
["git", ["push", "--set-upstream", "fork", branchName, "-f"]] // push the branch
40+
]);
41+
42+
gh.authenticate({
43+
type: "token",
44+
token,
45+
});
46+
return gh.pulls.create({
47+
owner: "DefinitelyTyped",
48+
repo: "DefinitelyTyped",
49+
maintainer_can_modify: true,
50+
title: `🤖 CODEOWNERS has changed`,
51+
head: `DefinitelyTyped:${branchName}`,
52+
base: "master",
53+
body:
54+
`Please review the diff and merge if no changes are unexpected.
55+
56+
cc ${reviewers.map(r => "@" + r).join(" ")}`,
57+
})
58+
}).then(r => {
59+
const num = r.data.number;
60+
console.log(`Pull request ${num} created.`);
61+
return gh.pulls.createReviewRequest({
62+
owner: "DefinitelyTyped",
63+
repo: "DefinitelyTyped",
64+
number: num,
65+
reviewers,
66+
});
67+
}).then(() => {
68+
console.log(`Reviewers requested, done.`);
69+
}).catch(e => {
70+
console.error(e);
71+
process.exit(1);
72+
});
73+
74+
/** @param {[string, string[]][]} tasks */
75+
function runSequence(tasks) {
76+
for (const task of tasks) {
77+
console.log(`${task[0]} ${task[1].join(" ")}`);
78+
const result = cp.spawnSync(task[0], task[1], { timeout: 100000, shell: true, stdio: "inherit" });
79+
if (result.status !== 0) throw new Error(`${task[0]} ${task[1].join(" ")} failed: ${result.stderr && result.stderr.toString()}`);
80+
}
81+
}
82+
83+
/** @param {number} number */
84+
function padNum(number) {
85+
const str = "" + number;
86+
return str.length >= 2 ? str : "0" + str;
87+
}
88+
89+
90+
const header =
91+
`# This file is generated.
92+
# Add yourself to the "Definitions by:" list instead.
93+
# See https://github.com/DefinitelyTyped/DefinitelyTyped#edit-an-existing-package`;
94+
95+
/**
96+
* @param { { contributors: ReadonlyArray<{githubUsername?: string }>, subDirectoryPath: string} } pkg
97+
* @param {number} maxPathLen
98+
* @return {string | undefined}
99+
*/
100+
function getEntry(pkg, maxPathLen) {
101+
const users = mapDefined(pkg.contributors, c => c.githubUsername);
102+
if (!users.length) {
103+
return undefined;
104+
}
105+
106+
const path = `${pkg.subDirectoryPath}/`.padEnd(maxPathLen);
107+
return `/types/${path} ${users.map(u => `@${u}`).join(" ")}`;
108+
}
109+
110+
/**
111+
* @template T,U
112+
* @param {ReadonlyArray<T>} arr
113+
* @param {(t: T) => U | undefined} mapper
114+
* @return U[]
115+
*/
116+
function mapDefined(arr, mapper) {
117+
const out = [];
118+
for (const a of arr) {
119+
const res = mapper(a);
120+
if (res !== undefined) {
121+
out.push(res);
122+
}
123+
}
124+
return out;
125+
}
126+

0 commit comments

Comments
 (0)