Skip to content
Closed
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
10 changes: 10 additions & 0 deletions .github/workflows/find-inactive-collaborators.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,13 @@ jobs:

- name: Find inactive collaborators
run: tools/find-inactive-collaborators.mjs ${{ env.NUM_COMMITS }}

- name: Open pull request
uses: gr2m/create-or-update-pull-request-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
title: "meta: move one or more collaborators to emeritus"
body: This PR was generated by tools/find-inactive-collaborators.yml.
commit-message: "meta: move one or more collaborators to emeritus"
labels: meta
27 changes: 17 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ For information on reporting security vulnerabilities in Node.js, see
For information about the governance of the Node.js project, see
[GOVERNANCE.md](./GOVERNANCE.md).

<!-- node-core-utils depends on the format of the TSC list. If the
format changes, those utilities need to be tested and updated. -->
### TSC (Technical Steering Committee)

<!--lint disable prohibited-strings-->
Expand Down Expand Up @@ -249,6 +251,9 @@ For information about the governance of the Node.js project, see

</details>

<!-- node-core-utils and find-inactive-collaborators.mjs depend on the format
of the collaborator list. If the format changes, those utilities need to be
tested and updated. -->
### Collaborators

* [addaleax](https://github.com/addaleax) -
Expand All @@ -273,8 +278,6 @@ For information about the governance of the Node.js project, see
**Beth Griggs** &lt;bgriggs@redhat.com&gt; (she/her)
* [bmeck](https://github.com/bmeck) -
**Bradley Farias** &lt;bradley.meck@gmail.com&gt;
* [bmeurer](https://github.com/bmeurer) -
**Benedikt Meurer** &lt;benedikt.meurer@gmail.com&gt;
* [boneskull](https://github.com/boneskull) -
**Christopher Hiller** &lt;boneskull@boneskull.com&gt; (he/him)
* [BridgeAR](https://github.com/BridgeAR) -
Expand Down Expand Up @@ -319,8 +322,6 @@ For information about the governance of the Node.js project, see
**Gerhard Stöbich** &lt;deb2001-github@yahoo.de&gt; (he/they)
* [gabrielschulhof](https://github.com/gabrielschulhof) -
**Gabriel Schulhof** &lt;gabrielschulhof@gmail.com&gt;
* [geek](https://github.com/geek) -
**Wyatt Preul** &lt;wpreul@gmail.com&gt;
* [gengjiawen](https://github.com/gengjiawen) -
**Jiawen Geng** &lt;technicalcute@gmail.com&gt;
* [GeoffreyBooth](https://github.com/geoffreybooth) -
Expand Down Expand Up @@ -377,8 +378,6 @@ For information about the governance of the Node.js project, see
**Milad Fa** &lt;mfarazma@redhat.com&gt; (he/him)
* [mildsunrise](https://github.com/mildsunrise) -
**Alba Mendez** &lt;me@alba.sh&gt; (she/her)
* [misterdjules](https://github.com/misterdjules) -
**Julien Gilli** &lt;jgilli@netflix.com&gt;
* [mmarchini](https://github.com/mmarchini) -
**Mary Marchini** &lt;oss@mmarchini.me&gt; (she/her)
* [mscdex](https://github.com/mscdex) -
Expand All @@ -397,8 +396,6 @@ For information about the governance of the Node.js project, see
**Stephen Belanger** &lt;admin@stephenbelanger.com&gt; (he/him)
* [RaisinTen](https://github.com/RaisinTen) -
**Darshan Sen** &lt;raisinten@gmail.com&gt; (he/him)
* [refack](https://github.com/refack) -
**Refael Ackermann (רפאל פלחי)** &lt;refack@gmail.com&gt; (he/him/הוא/אתה)
* [rexagod](https://github.com/rexagod) -
**Pranshu Srivastava** &lt;rexagod@gmail.com&gt; (he/him)
* [richardlau](https://github.com/richardlau) -
Expand Down Expand Up @@ -451,8 +448,6 @@ For information about the governance of the Node.js project, see
**Yash Ladha** &lt;yash@yashladha.in&gt; (he/him)
* [yhwang](https://github.com/yhwang) -
**Yihong Wang** &lt;yh.wang@ibm.com&gt;
* [yorkie](https://github.com/yorkie) -
**Yorkie Liu** &lt;yorkiefixer@gmail.com&gt;
* [yosuke-furukawa](https://github.com/yosuke-furukawa) -
**Yosuke Furukawa** &lt;yosuke.furukawa@gmail.com&gt;
* [ZYSzys](https://github.com/ZYSzys) -
Expand All @@ -462,6 +457,8 @@ For information about the governance of the Node.js project, see

<summary>Emeriti</summary>

<!-- find-inactive-collaborators.mjs depends on the format of the emeriti list.
If the format changes, those utilities need to be tested and updated. -->
### Collaborator emeriti

* [andrasq](https://github.com/andrasq) -
Expand All @@ -472,6 +469,8 @@ For information about the governance of the Node.js project, see
**Andreas Madsen** &lt;amwebdk@gmail.com&gt; (he/him)
* [aqrln](https://github.com/aqrln) -
**Alexey Orlenko** &lt;eaglexrlnk@gmail.com&gt; (he/him)
* [bmeurer](https://github.com/bmeurer) -
**Benedikt Meurer** &lt;benedikt.meurer@gmail.com&gt;
* [bnoordhuis](https://github.com/bnoordhuis) -
**Ben Noordhuis** &lt;info@bnoordhuis.nl&gt;
* [brendanashworth](https://github.com/brendanashworth) -
Expand All @@ -494,6 +493,8 @@ For information about the governance of the Node.js project, see
**Daniel Wang** &lt;wangyang0123@gmail.com&gt;
* [gdams](https://github.com/gdams) -
**George Adams** &lt;george.adams@microsoft.com&gt; (he/him)
* [geek](https://github.com/geek) -
**Wyatt Preul** &lt;wpreul@gmail.com&gt;
* [gibfahn](https://github.com/gibfahn) -
**Gibson Fahnestock** &lt;gibfahn@gmail.com&gt; (he/him)
* [glentiki](https://github.com/glentiki) -
Expand Down Expand Up @@ -538,6 +539,8 @@ For information about the governance of the Node.js project, see
**Nicu Micleușanu** &lt;micnic90@gmail.com&gt; (he/him)
* [mikeal](https://github.com/mikeal) -
**Mikeal Rogers** &lt;mikeal.rogers@gmail.com&gt;
* [misterdjules](https://github.com/misterdjules) -
**Julien Gilli** &lt;jgilli@netflix.com&gt;
* [monsanto](https://github.com/monsanto) -
**Christopher Monsanto** &lt;chris@monsan.to&gt;
* [MoonBall](https://github.com/MoonBall) -
Expand All @@ -564,6 +567,8 @@ For information about the governance of the Node.js project, see
**Prince John Wesley** &lt;princejohnwesley@gmail.com&gt;
* [psmarshall](https://github.com/psmarshall) -
**Peter Marshall** &lt;petermarshall@chromium.org&gt; (he/him)
* [refack](https://github.com/refack) -
**Refael Ackermann (רפאל פלחי)** &lt;refack@gmail.com&gt; (he/him/הוא/אתה)
* [rlidwka](https://github.com/rlidwka) -
**Alex Kocharin** &lt;alex@kocharin.ru&gt;
* [rmg](https://github.com/rmg) -
Expand Down Expand Up @@ -602,6 +607,8 @@ For information about the governance of the Node.js project, see
**Vse Mozhet Byt** &lt;vsemozhetbyt@gmail.com&gt; (he/him)
* [whitlockjc](https://github.com/whitlockjc) -
**Jeremy Whitlock** &lt;jwhitlock@apache.org&gt;
* [yorkie](https://github.com/yorkie) -
**Yorkie Liu** &lt;yorkiefixer@gmail.com&gt;

</details>
<!--lint enable prohibited-strings-->
Expand Down
87 changes: 85 additions & 2 deletions tools/find-inactive-collaborators.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,85 @@ async function getCollaboratorsFromReadme() {
return returnedArray;
}

async function moveCollaboratorToEmeritus(peopleToMove) {
const readmeText = readline.createInterface({
input: fs.createReadStream(new URL('../README.md', import.meta.url)),
crlfDelay: Infinity,
});
let fileContents = '';
let inCollaboratorsSection = false;
let inCollaboratorEmeritusSection = false;
let collaboratorFirstLine = '';
const textToMove = [];
for await (const line of readmeText) {
// If we've been processing collaborator emeriti and we reach the end of
// the list, print out the remaining entries to be moved because they come
// alphabetically after the last item.
if (inCollaboratorEmeritusSection && line === '' &&
fileContents.endsWith('&gt;\n')) {
while (textToMove.length) {
fileContents += textToMove.pop();
}
}

// If we've found the collaborator heading already, stop processing at the
// next heading.
if (line.startsWith('#')) {
inCollaboratorsSection = false;
inCollaboratorEmeritusSection = false;
}

const isCollaborator = inCollaboratorsSection && line.length;
const isCollaboratorEmeritus = inCollaboratorEmeritusSection && line.length;

if (line === '### Collaborators') {
inCollaboratorsSection = true;
}
if (line === '### Collaborator emeriti') {
inCollaboratorEmeritusSection = true;
}

if (isCollaborator) {
if (line.startsWith('* ')) {
collaboratorFirstLine = line;
} else if (line.startsWith('**')) {
const [, name, email] = /^\*\*([^*]+)\*\* &lt;(.+)&gt;/.exec(line);
if (peopleToMove.some((entry) => {
return entry.name === name && entry.email === email;
})) {
textToMove.push(`${collaboratorFirstLine}\n${line}\n`);
} else {
fileContents += `${collaboratorFirstLine}\n${line}\n`;
}
} else {
fileContents += `${line}\n`;
}
}

if (isCollaboratorEmeritus) {
if (line.startsWith('* ')) {
collaboratorFirstLine = line;
} else if (line.startsWith('**')) {
const currentLine = `${collaboratorFirstLine}\n${line}\n`;
// If textToMove is empty, this still works because when undefined is
// used in a comparison with <, the result is always false.
while (textToMove[0] < currentLine) {
fileContents += textToMove.shift();
}
fileContents += currentLine;
} else {
fileContents += `${line}\n`;
}
}

if (!isCollaborator && !isCollaboratorEmeritus) {
fileContents += `${line}\n`;
}
}

return fileContents;
}

// Get list of current collaborators from README.md.
const collaborators = await getCollaboratorsFromReadme();

Expand All @@ -113,9 +192,13 @@ const inactive = collaborators.filter((collaborator) =>
!authors.has(collaborator.mailmap) &&
!landers.has(collaborator.mailmap) &&
!approvingReviewers.has(collaborator.name)
).map((collaborator) => collaborator.name);
);

if (inactive.length) {
console.log('\nInactive collaborators:\n');
console.log(inactive.map((name) => `* ${name}`).join('\n'));
console.log(inactive.map((entry) => `* ${entry.name}`).join('\n'));
console.log('\nGenerating new README.md file...');
const newReadmeText = await moveCollaboratorToEmeritus(inactive);
fs.writeFileSync(new URL('../README.md', import.meta.url), newReadmeText);
console.log('Updated README.md generated. Please commit these changes.');
}