|
1 | 1 | /* eslint-disable no-console */ |
2 | 2 | import fs from 'node:fs/promises'; |
3 | 3 | import path from 'node:path'; |
| 4 | +import readline from 'node:readline/promises'; |
| 5 | +import { fileURLToPath } from 'node:url'; |
4 | 6 | import { Octokit } from '@octokit/rest'; |
5 | 7 | import { persistentAuthStrategy } from '@mui/internal-code-infra/github'; |
6 | 8 |
|
7 | 9 | const OWNER = 'mui'; |
8 | 10 | const REPO = 'material-ui'; |
9 | 11 | // Pinned commit ref in mui/material-ui to import the static docs assets from. |
10 | | -// Override with IMPORT_DOCS_STATIC_REF env var only when intentionally bumping. |
| 12 | +// Self updates after confirmation on the next run. |
11 | 13 | const DEFAULT_REF = '2dc145f2d2bece8f30293137e276bdbdb4cda294'; |
12 | 14 | const BASE_DIR = 'docs/public/static'; |
13 | 15 | // Patterns are relative to BASE_DIR. Trailing `/*` or a bare dir means "all files under". |
@@ -67,8 +69,61 @@ async function downloadFile(filePath, ref) { |
67 | 69 | return Buffer.from(await res.arrayBuffer()); |
68 | 70 | } |
69 | 71 |
|
| 72 | +async function getLatestMasterSha() { |
| 73 | + const { data } = await octokit.rest.git.getRef({ |
| 74 | + owner: OWNER, |
| 75 | + repo: REPO, |
| 76 | + ref: 'heads/master', |
| 77 | + }); |
| 78 | + return data.object.sha; |
| 79 | +} |
| 80 | + |
| 81 | +async function promptYesNo(question) { |
| 82 | + if (!process.stdin.isTTY) { |
| 83 | + return false; |
| 84 | + } |
| 85 | + const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); |
| 86 | + try { |
| 87 | + const answer = await rl.question(question); |
| 88 | + return /^y(es)?$/i.test(answer.trim()); |
| 89 | + } finally { |
| 90 | + rl.close(); |
| 91 | + } |
| 92 | +} |
| 93 | + |
| 94 | +async function updateDefaultRefInSource(newSha) { |
| 95 | + const selfPath = fileURLToPath(import.meta.url); |
| 96 | + const src = await fs.readFile(selfPath, 'utf8'); |
| 97 | + const updated = src.replace( |
| 98 | + /const DEFAULT_REF = '[0-9a-f]+';/, |
| 99 | + `const DEFAULT_REF = '${newSha}';`, |
| 100 | + ); |
| 101 | + if (updated === src) { |
| 102 | + throw new Error(`Failed to update DEFAULT_REF in ${selfPath}`); |
| 103 | + } |
| 104 | + await fs.writeFile(selfPath, updated); |
| 105 | + console.log(`updated DEFAULT_REF in ${path.relative(process.cwd(), selfPath)}`); |
| 106 | +} |
| 107 | + |
| 108 | +async function resolveRef() { |
| 109 | + const latest = await getLatestMasterSha(); |
| 110 | + if (latest === DEFAULT_REF) { |
| 111 | + return DEFAULT_REF; |
| 112 | + } |
| 113 | + console.log( |
| 114 | + `Pinned ref ${DEFAULT_REF.slice(0, 7)} is behind ${OWNER}/${REPO}@master (${latest.slice(0, 7)}).`, |
| 115 | + ); |
| 116 | + const useLatest = await promptYesNo('Use latest master and update the pinned ref? [y/N] '); |
| 117 | + if (!useLatest) { |
| 118 | + console.log(`Keeping pinned ref ${DEFAULT_REF.slice(0, 7)}.`); |
| 119 | + return DEFAULT_REF; |
| 120 | + } |
| 121 | + await updateDefaultRefInSource(latest); |
| 122 | + return latest; |
| 123 | +} |
| 124 | + |
70 | 125 | async function run() { |
71 | | - const ref = process.env.IMPORT_DOCS_STATIC_REF || DEFAULT_REF; |
| 126 | + const ref = await resolveRef(); |
72 | 127 | console.log(`Importing static docs assets from ${OWNER}/${REPO}@${ref}`); |
73 | 128 |
|
74 | 129 | const baseSha = await resolveTreeSha(ref, BASE_DIR); |
|
0 commit comments