From 8f17247a93240ff8a08980d8e06352e4ff4e8fe3 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 28 Dec 2022 14:32:00 -0700 Subject: [PATCH] chore: Set up automatic updating of README (#16717) * chore: Set up automatic updating of README * Update tools/update-readme.js Co-authored-by: Milos Djermanovic Co-authored-by: Milos Djermanovic --- .github/workflows/update-readme.yml | 33 +++++++++++++ README.md | 36 ++++++++------ package.json | 1 + tools/commit-readme.sh | 18 +++++++ tools/update-readme.js | 73 +++++++++++++++++++++-------- 5 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/update-readme.yml create mode 100644 tools/commit-readme.sh diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml new file mode 100644 index 00000000000..e6399920b51 --- /dev/null +++ b/.github/workflows/update-readme.yml @@ -0,0 +1,33 @@ +name: Data Fetch + +on: + schedule: + - cron: "0 8 * * *" # Every day at 1am PDT + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Check out repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.WORKFLOW_PUSH_BOT_TOKEN }} + + - name: Set up Node.js + uses: actions/setup-node@v3 + + - name: Install npm packages + run: npm install + + - name: Update README with latest team and sponsor data + run: npm run build:readme + + - name: Setup Git + run: | + git config user.name "GitHub Actions Bot" + git config user.email "" + + - name: Save updated files + run: | + chmod +x ./tools/commit-readme.sh + ./tools/commit-readme.sh diff --git a/README.md b/README.md index 932d96bbc47..628d7aabc93 100644 --- a/README.md +++ b/README.md @@ -245,11 +245,6 @@ Nitin Kumar The people who review and fix bugs and help triage issues.
- -
-Brett Zamir -
-

Bryan Mishkin @@ -260,14 +255,25 @@ Bryan Mishkin Sara Soueidan
- -
-Pig Fang +
+
+YeonJuan +
+
+ +### Website Team + +Team members who focus specifically on eslint.org + +
+ +
+Bryan Mishkin
- -
-Anix +
+
+Sara Soueidan
@@ -285,10 +291,10 @@ The following companies, organizations, and individuals support ESLint's ongoing

Platinum Sponsors

-

Automattic

Gold Sponsors

-

Salesforce Airbnb American Express

Silver Sponsors

-

Liftoff

Bronze Sponsors

-

launchdarkly Nx (by Nrwl) Anagram Solver VPS Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Ignition HeroCoders

+

Chrome Frameworks Fund Automattic

Gold Sponsors

+

RIDI Salesforce Airbnb

Silver Sponsors

+

Sentry Liftoff

Bronze Sponsors

+

ThemeIsle Nx (by Nrwl) Anagram Solver Icons8: free icons, photos, illustrations, and music Discord Ignition HeroCoders QuickBooks Tool hub

## Technology Sponsors diff --git a/package.json b/package.json index 2ffa24d3aa8..e69e47ee41c 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "build:docs:update-links": "node tools/fetch-docs-links.js", "build:site": "node Makefile.js gensite", "build:webpack": "node Makefile.js webpack", + "build:readme": "node tools/update-readme.js", "lint": "node Makefile.js lint", "lint:docs:js": "node Makefile.js lintDocsJS", "lint:fix": "node Makefile.js lint -- fix", diff --git a/tools/commit-readme.sh b/tools/commit-readme.sh new file mode 100644 index 00000000000..f2341f0ddca --- /dev/null +++ b/tools/commit-readme.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +#------------------------------------------------------------------------------ +# Commits the data files if any have changed +#------------------------------------------------------------------------------ + +if [ -z "$(git status --porcelain)" ]; then + echo "Data did not change." +else + echo "Data changed!" + + # commit the result + git add README.md + git commit -m "docs: Update README" + + # push back to source control + git push origin HEAD +fi diff --git a/tools/update-readme.js b/tools/update-readme.js index 0704ceff137..ca2dcb9c71b 100644 --- a/tools/update-readme.js +++ b/tools/update-readme.js @@ -13,20 +13,19 @@ // Requirements //----------------------------------------------------------------------------- -const path = require("path"); const fs = require("fs"); const { stripIndents } = require("common-tags"); const ejs = require("ejs"); +const got = require("got"); //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- -const README_FILE_PATH = path.resolve(__dirname, "../README.md"); -const WEBSITE_DATA_PATH = path.resolve(__dirname, "../../website/_data"); +const SPONSORS_URL = "https://raw.githubusercontent.com/eslint/eslint.org/main/src/_data/sponsors.json"; +const TEAM_URL = "https://raw.githubusercontent.com/eslint/eslint.org/main/src/_data/team.json"; +const README_FILE_PATH = "./README.md"; -const team = JSON.parse(fs.readFileSync(path.join(WEBSITE_DATA_PATH, "team.json"))); -const allSponsors = JSON.parse(fs.readFileSync(path.join(WEBSITE_DATA_PATH, "sponsors.json"))); const readme = fs.readFileSync(README_FILE_PATH, "utf8"); const heights = { @@ -35,13 +34,31 @@ const heights = { bronze: 32 }; -// remove backers from sponsors list - not shown on readme -delete allSponsors.backers; - //----------------------------------------------------------------------------- // Helpers //----------------------------------------------------------------------------- +/** + * Fetches the latest sponsors data from the website. + * @returns {Object} The sponsors data object. + */ +async function fetchSponsorsData() { + const data = await got(SPONSORS_URL).json(); + + // remove backers from sponsors list - not shown on readme + delete data.backers; + + return data; +} + +/** + * Fetches the latest team data from the website. + * @returns {Object} The sponsors data object. + */ +async function fetchTeamData() { + return got(TEAM_URL).json(); +} + /** * Formats an array of team members for inclusion in the readme. * @param {Array} members The array of members to format. @@ -74,7 +91,7 @@ function formatSponsors(sponsors) { ${ nonEmptySponsors.map(tier => `

${tier[0].toUpperCase()}${tier.slice(1)} Sponsors

${ - sponsors[tier].map(sponsor => `${sponsor.name}`).join(" ") + sponsors[tier].map(sponsor => `${sponsor.name}`).join(" ") }

`).join("") } `; @@ -111,20 +128,38 @@ const HTML_TEMPLATE = stripIndents` <%- formatTeamMembers(team.committers) %> + <% } %> + + <% if (team.website.length > 0) { %> + ### Website Team + + Team members who focus specifically on eslint.org + + <%- formatTeamMembers(team.website) %> + <% } %> `; -// replace all of the section -let newReadme = readme.replace(/[\w\W]*?/u, ejs.render(HTML_TEMPLATE, { - team, - formatTeamMembers -})); +(async () => { + + const [allSponsors, team] = await Promise.all([ + fetchSponsorsData(), + fetchTeamData() + ]); + + // replace all of the section + let newReadme = readme.replace(/[\w\W]*?/u, ejs.render(HTML_TEMPLATE, { + team, + formatTeamMembers + })); + + newReadme = newReadme.replace(/[\w\W]*?/u, formatSponsors(allSponsors)); -newReadme = newReadme.replace(/[\w\W]*?/u, formatSponsors(allSponsors)); + // replace multiple consecutive blank lines with just one blank line + newReadme = newReadme.replace(/(?<=^|\n)\n{2,}/gu, "\n"); -// replace multiple consecutive blank lines with just one blank line -newReadme = newReadme.replace(/(?<=^|\n)\n{2,}/gu, "\n"); + // output to the file + fs.writeFileSync(README_FILE_PATH, newReadme, "utf8"); -// output to the file -fs.writeFileSync(README_FILE_PATH, newReadme, "utf8"); +})();