summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/tools/update_chrome_revision.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'remote/test/puppeteer/tools/update_chrome_revision.mjs')
-rw-r--r--remote/test/puppeteer/tools/update_chrome_revision.mjs162
1 files changed, 162 insertions, 0 deletions
diff --git a/remote/test/puppeteer/tools/update_chrome_revision.mjs b/remote/test/puppeteer/tools/update_chrome_revision.mjs
new file mode 100644
index 0000000000..64eeef74d5
--- /dev/null
+++ b/remote/test/puppeteer/tools/update_chrome_revision.mjs
@@ -0,0 +1,162 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {execSync, exec} from 'child_process';
+import {writeFile, readFile} from 'fs/promises';
+import {promisify} from 'util';
+
+import actions from '@actions/core';
+import {SemVer} from 'semver';
+
+import packageJson from '../packages/puppeteer-core/package.json' assert {type: 'json'};
+import {versionsPerRelease, lastMaintainedChromeVersion} from '../versions.js';
+
+import {PUPPETEER_REVISIONS} from 'puppeteer-core/internal/revisions.js';
+
+const execAsync = promisify(exec);
+
+const CHROME_CURRENT_VERSION = PUPPETEER_REVISIONS.chrome;
+const VERSIONS_PER_RELEASE_COMMENT =
+ '// In Chrome roll patches, use `NEXT` for the Puppeteer version.';
+
+const touchedFiles = [];
+
+function checkIfNeedsUpdate(oldVersion, newVersion, newRevision) {
+ const oldSemVer = new SemVer(oldVersion, true);
+ const newSemVer = new SemVer(newVersion, true);
+ let message = `roll to Chrome ${newVersion} (r${newRevision})`;
+
+ if (newSemVer.compare(oldSemVer) <= 0) {
+ // Exit the process without setting up version
+ console.warn(
+ `Version ${newVersion} is older or the same as the current ${oldVersion}`
+ );
+ process.exit(0);
+ } else if (newSemVer.compareMain(oldSemVer) === 0) {
+ message = `fix: ${message}`;
+ } else {
+ message = `feat: ${message}`;
+ }
+ actions.setOutput('commit', message);
+}
+
+/**
+ * We cant use `npm run format` as it's too slow
+ * so we only scope the files we updated
+ */
+async function formatUpdateFiles() {
+ await Promise.all(
+ touchedFiles.map(file => {
+ return execAsync(`npx eslint --ext js --ext ts --fix ${file}`);
+ })
+ );
+ await Promise.all(
+ touchedFiles.map(file => {
+ return execAsync(`npx prettier --write ${file}`);
+ })
+ );
+}
+
+async function replaceInFile(filePath, search, replace) {
+ const buffer = await readFile(filePath);
+ const update = buffer.toString().replaceAll(search, replace);
+
+ await writeFile(filePath, update);
+
+ touchedFiles.push(filePath);
+}
+
+async function getVersionAndRevisionForStable() {
+ const result = await fetch(
+ 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json'
+ ).then(response => {
+ return response.json();
+ });
+
+ const {version, revision} = result.channels['Stable'];
+
+ return {
+ version,
+ revision,
+ };
+}
+
+async function updateDevToolsProtocolVersion(revision) {
+ const currentProtocol = packageJson.dependencies['devtools-protocol'];
+ const command = `npm view "devtools-protocol@<=0.0.${revision}" version | tail -1`;
+
+ const bestNewProtocol = execSync(command, {
+ encoding: 'utf8',
+ })
+ .split(' ')[1]
+ .replace(/'|\n/g, '');
+
+ await replaceInFile(
+ './packages/puppeteer-core/package.json',
+ `"devtools-protocol": "${currentProtocol}"`,
+ `"devtools-protocol": "${bestNewProtocol}"`
+ );
+}
+
+async function updateVersionFileLastMaintained(oldVersion, newVersion) {
+ const versions = [...versionsPerRelease.keys()];
+ if (versions.indexOf(newVersion) !== -1) {
+ return;
+ }
+
+ // If we have manually rolled Chrome but not yet released
+ // We will have NEXT as value in the Map
+ if (versionsPerRelease.get(oldVersion) === 'NEXT') {
+ await replaceInFile('./versions.js', oldVersion, newVersion);
+ return;
+ }
+
+ await replaceInFile(
+ './versions.js',
+ VERSIONS_PER_RELEASE_COMMENT,
+ `${VERSIONS_PER_RELEASE_COMMENT}\n ['${version}', 'NEXT'],`
+ );
+
+ const oldSemVer = new SemVer(oldVersion, true);
+ const newSemVer = new SemVer(newVersion, true);
+
+ if (newSemVer.compareMain(oldSemVer) !== 0) {
+ const lastMaintainedSemVer = new SemVer(lastMaintainedChromeVersion, true);
+ const newLastMaintainedMajor = lastMaintainedSemVer.major + 1;
+
+ const nextMaintainedVersion = versions.find(version => {
+ return new SemVer(version, true).major === newLastMaintainedMajor;
+ });
+
+ await replaceInFile(
+ './versions.js',
+ `const lastMaintainedChromeVersion = '${lastMaintainedChromeVersion}';`,
+ `const lastMaintainedChromeVersion = '${nextMaintainedVersion}';`
+ );
+ }
+}
+
+const {version, revision} = await getVersionAndRevisionForStable();
+
+checkIfNeedsUpdate(CHROME_CURRENT_VERSION, version, revision);
+
+await replaceInFile(
+ './packages/puppeteer-core/src/revisions.ts',
+ CHROME_CURRENT_VERSION,
+ version
+);
+
+await updateVersionFileLastMaintained(CHROME_CURRENT_VERSION, version);
+await updateDevToolsProtocolVersion(revision);
+
+// Create new `package-lock.json` as we update devtools-protocol
+execSync('npm install --ignore-scripts');
+// Make sure we pass CI formatter check by running all the new files though it
+await formatUpdateFiles();
+
+// Keep this as they can be used to debug GitHub Actions if needed
+actions.setOutput('version', version);
+actions.setOutput('revision', revision);