Move "dependents count update" out of release (#20100)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
d5b0490aa9
commit
92ee7178a6
5 files changed
+160
-119
No files matched your search
@@ -0,0 +1,44 @@
|
|||||||
|
name: Update dependents count
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
# “At 00:00 on day-of-month 1.” https://crontab.guru/#0_0_1_*_*
|
||||||
|
- cron: "0 0 1 * *"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run:
|
||||||
|
name: Update dependents count
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'prettier/prettier'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||||
|
with:
|
||||||
|
cache: "yarn"
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: yarn --immutable
|
||||||
|
|
||||||
|
- name: Run script
|
||||||
|
run: node scripts/update-dependents-count.js
|
||||||
|
|
||||||
|
- name: Format website
|
||||||
|
run: yarn prettier website/src/pages/index.jsx --write
|
||||||
|
|
||||||
|
- name: Set current date env
|
||||||
|
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
||||||
|
with:
|
||||||
|
commit-message: Update dependents count (${{ env.CURRENT_DATE }})
|
||||||
|
branch: automated-update-dependents-count-${{ env.CURRENT_DATE }}
|
||||||
|
branch-suffix: timestamp
|
||||||
|
title: Update dependents count (${{ env.CURRENT_DATE }})
|
||||||
@@ -55,7 +55,6 @@ for (let step of [
|
|||||||
name: "Merge release notes PR",
|
name: "Merge release notes PR",
|
||||||
process: steps.mergeBlogPost,
|
process: steps.mergeBlogPost,
|
||||||
},
|
},
|
||||||
steps.updateDependentsCount,
|
|
||||||
{
|
{
|
||||||
name: "Cleaning changelog",
|
name: "Cleaning changelog",
|
||||||
process: steps.cleanChangelog,
|
process: steps.cleanChangelog,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ export { default as publishToNpm } from "./publish-to-npm.js";
|
|||||||
export { default as pushToGit } from "./push-to-git.js";
|
export { default as pushToGit } from "./push-to-git.js";
|
||||||
export { default as showInstructionsAfterNpmPublish } from "./show-instructions-after-npm-publish.js";
|
export { default as showInstructionsAfterNpmPublish } from "./show-instructions-after-npm-publish.js";
|
||||||
export { default as updateChangelog } from "./update-changelog.js";
|
export { default as updateChangelog } from "./update-changelog.js";
|
||||||
export { default as updateDependentsCount } from "./update-dependents-count.js";
|
|
||||||
export { default as updateVersion } from "./update-version.js";
|
export { default as updateVersion } from "./update-version.js";
|
||||||
export { default as validateNewVersion } from "./validate-new-version.js";
|
export { default as validateNewVersion } from "./validate-new-version.js";
|
||||||
export { default as waitForBotRelease } from "./wait-for-bot-release.js";
|
export { default as waitForBotRelease } from "./wait-for-bot-release.js";
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
import styleText from "node-style-text";
|
|
||||||
import { fetchText, logPromise, processFile, runGit } from "../utilities.js";
|
|
||||||
|
|
||||||
async function getNpmDependentsCount() {
|
|
||||||
const npmPage = await logPromise(
|
|
||||||
"Fetching npm dependents count",
|
|
||||||
fetchText("https://www.npmjs.com/package/prettier"),
|
|
||||||
);
|
|
||||||
const dependentsCountNpm = Number(
|
|
||||||
npmPage.match(/"dependentsCount":"(?<dependentsCount>\d+)",/).groups
|
|
||||||
.dependentsCount,
|
|
||||||
);
|
|
||||||
if (Number.isNaN(dependentsCountNpm)) {
|
|
||||||
throw new TypeError(
|
|
||||||
"Invalid data from https://www.npmjs.com/package/prettier",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dependentsCountNpm;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getGithubDependentsCount() {
|
|
||||||
const githubPage = await logPromise(
|
|
||||||
"Fetching github dependents count",
|
|
||||||
fetchText("https://github.com/prettier/prettier/network/dependents"),
|
|
||||||
);
|
|
||||||
const dependentsCountGithub = Number(
|
|
||||||
githubPage
|
|
||||||
.replaceAll("\n", "")
|
|
||||||
.match(
|
|
||||||
/<svg.*?octicon-code-square.*?>.*?<\/svg>\s*(?<dependentsCount>[\d,]+)\s*Repositories\s*<\/a>/,
|
|
||||||
)
|
|
||||||
.groups.dependentsCount.replaceAll(",", ""),
|
|
||||||
);
|
|
||||||
if (Number.isNaN(dependentsCountGithub)) {
|
|
||||||
throw new TypeError(
|
|
||||||
"Invalid data from https://github.com/prettier/prettier/network/dependents",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dependentsCountGithub;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update({ repo }) {
|
|
||||||
const [
|
|
||||||
{ value: dependentsCountNpm, reason: dependentsNpmError },
|
|
||||||
{ value: dependentsCountGithub, reason: dependentsGithubError },
|
|
||||||
] = await Promise.allSettled([
|
|
||||||
getNpmDependentsCount(),
|
|
||||||
getGithubDependentsCount(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (dependentsCountNpm || dependentsCountGithub) {
|
|
||||||
processFile("website/src/pages/index.jsx", (content) => {
|
|
||||||
if (dependentsCountNpm) {
|
|
||||||
content = content.replace(
|
|
||||||
/(<strong data-placeholder="dependent-npm">)(.*?)(<\/strong>)/,
|
|
||||||
`$1${formatNumber(dependentsCountNpm)}$3`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dependentsCountGithub) {
|
|
||||||
content = content.replace(
|
|
||||||
/(<strong data-placeholder="dependent-github">)(.*?)(<\/strong>)/,
|
|
||||||
`$1${formatNumber(dependentsCountGithub)}$3`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
});
|
|
||||||
|
|
||||||
const isUpdated = await logPromise(
|
|
||||||
"Checking if dependents count has been updated",
|
|
||||||
async () =>
|
|
||||||
(await runGit(["diff", "--name-only"])).stdout ===
|
|
||||||
"website/src/pages/index.jsx",
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isUpdated) {
|
|
||||||
await logPromise("Committing and pushing to remote", async () => {
|
|
||||||
await runGit(["add", "."]);
|
|
||||||
await runGit(["commit", "-m", "Update dependents count"]);
|
|
||||||
await runGit(["push", "--repo", repo]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dependentsNpmError) {
|
|
||||||
throw dependentsNpmError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dependentsGithubError) {
|
|
||||||
throw dependentsGithubError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatNumber(value) {
|
|
||||||
if (value < 1e4) {
|
|
||||||
return String(value).slice(0, 1) + "0".repeat(String(value).length - 1);
|
|
||||||
}
|
|
||||||
if (value < 1e6) {
|
|
||||||
return Math.floor(value / 1e2) / 10 + "k";
|
|
||||||
}
|
|
||||||
return Math.floor(value / 1e5) / 10 + " million";
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function updateDependentsCount({ dry, next, repo }) {
|
|
||||||
if (dry || next) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await update({ repo });
|
|
||||||
} catch (error) {
|
|
||||||
console.log(styleText.red.bold(error.message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
|
||||||
|
async function fetchText(url) {
|
||||||
|
const response = await fetch(url);
|
||||||
|
assert.ok(response.ok, `Failed to fetch ${url}: ${response.status}`);
|
||||||
|
return response.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNpmDependentsCount() {
|
||||||
|
const npmPage = await fetchText("https://www.npmjs.com/package/prettier");
|
||||||
|
const matches = npmPage.match(/"dependentsCount":"(?<dependentsCount>\d+)",/);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
matches,
|
||||||
|
"Invalid data from https://www.npmjs.com/package/prettier",
|
||||||
|
);
|
||||||
|
|
||||||
|
const dependentsCountNpm = Number(matches.groups.dependentsCount);
|
||||||
|
assert.ok(
|
||||||
|
!Number.isNaN(dependentsCountNpm),
|
||||||
|
"Invalid data from https://www.npmjs.com/package/prettier",
|
||||||
|
);
|
||||||
|
|
||||||
|
return dependentsCountNpm;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getGithubDependentsCount() {
|
||||||
|
const githubPage = await fetchText(
|
||||||
|
"https://github.com/prettier/prettier/network/dependents",
|
||||||
|
);
|
||||||
|
const dependentsCountGithub = Number(
|
||||||
|
githubPage
|
||||||
|
.replaceAll("\n", "")
|
||||||
|
.match(
|
||||||
|
/<svg.*?octicon-code-square.*?>.*?<\/svg>\s*(?<dependentsCount>[\d,]+)\s*Repositories\s*<\/a>/,
|
||||||
|
)
|
||||||
|
.groups.dependentsCount.replaceAll(",", ""),
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
!Number.isNaN(dependentsCountGithub),
|
||||||
|
"Invalid data from https://github.com/prettier/prettier/network/dependents",
|
||||||
|
);
|
||||||
|
|
||||||
|
return dependentsCountGithub;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update() {
|
||||||
|
const [
|
||||||
|
{ value: dependentsCountNpm, reason: dependentsNpmError },
|
||||||
|
{ value: dependentsCountGithub, reason: dependentsGithubError },
|
||||||
|
] = await Promise.allSettled([
|
||||||
|
getNpmDependentsCount(),
|
||||||
|
getGithubDependentsCount(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const file = new URL("../website/src/pages/index.jsx", import.meta.url);
|
||||||
|
const original = await fs.readFile(file, "utf8");
|
||||||
|
|
||||||
|
let content = original;
|
||||||
|
for (const { name, error, value, update } of [
|
||||||
|
{
|
||||||
|
name: "NPM dependents count",
|
||||||
|
error: dependentsNpmError,
|
||||||
|
value: dependentsCountNpm,
|
||||||
|
update: (text, value) =>
|
||||||
|
text.replace(
|
||||||
|
/(?<=<strong data-placeholder="dependent-npm">).*?(?=<\/strong>)/,
|
||||||
|
formatNumber(value),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitHub dependents count",
|
||||||
|
error: dependentsGithubError,
|
||||||
|
value: dependentsCountGithub,
|
||||||
|
update: (text, value) =>
|
||||||
|
text.replace(
|
||||||
|
/(?<=<strong data-placeholder="dependent-github">).*?(?=<\/strong>)/,
|
||||||
|
formatNumber(value),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]) {
|
||||||
|
if (error) {
|
||||||
|
console.log(`❌ Failed to update ${name}.`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ ${name} updated.`);
|
||||||
|
content = update(content, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (original !== content) {
|
||||||
|
await fs.writeFile(file, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependentsNpmError) {
|
||||||
|
console.log();
|
||||||
|
console.error(dependentsNpmError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependentsGithubError) {
|
||||||
|
console.log();
|
||||||
|
console.error(dependentsGithubError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatNumber(value) {
|
||||||
|
if (value < 1e4) {
|
||||||
|
return String(value).slice(0, 1) + "0".repeat(String(value).length - 1);
|
||||||
|
}
|
||||||
|
if (value < 1e6) {
|
||||||
|
return Math.floor(value / 1e2) / 10 + "k";
|
||||||
|
}
|
||||||
|
return Math.floor(value / 1e5) / 10 + " million";
|
||||||
|
}
|
||||||
|
|
||||||
|
await update();
|
||||||
Reference in new issue
Block a user