2023-06-01 08:13:42 +00:00
|
|
|
/**
|
|
|
|
* Copyright 2023 Google Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
import {execSync, exec} from 'child_process';
|
2023-06-01 08:13:42 +00:00
|
|
|
import {writeFile, readFile} from 'fs/promises';
|
2023-06-06 14:59:58 +00:00
|
|
|
import {promisify} from 'util';
|
2023-06-01 08:13:42 +00:00
|
|
|
|
|
|
|
import actions from '@actions/core';
|
2023-06-02 13:37:48 +00:00
|
|
|
import {SemVer} from 'semver';
|
2023-06-01 08:13:42 +00:00
|
|
|
|
|
|
|
import packageJson from '../packages/puppeteer-core/package.json' assert {type: 'json'};
|
|
|
|
import {versionsPerRelease, lastMaintainedChromeVersion} from '../versions.js';
|
|
|
|
|
2023-10-12 13:04:29 +00:00
|
|
|
import {PUPPETEER_REVISIONS} from 'puppeteer-core/internal/revisions.js';
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
const execAsync = promisify(exec);
|
|
|
|
|
2023-06-01 08:13:42 +00:00
|
|
|
const CHROME_CURRENT_VERSION = PUPPETEER_REVISIONS.chrome;
|
|
|
|
const VERSIONS_PER_RELEASE_COMMENT =
|
|
|
|
'// In Chrome roll patches, use `NEXT` for the Puppeteer version.';
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
const touchedFiles = [];
|
|
|
|
|
2023-06-02 13:37:48 +00:00
|
|
|
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(
|
2023-11-02 15:31:34 +00:00
|
|
|
`Version ${newVersion} is older or the same as the current ${oldVersion}`
|
2023-06-02 13:37:48 +00:00
|
|
|
);
|
|
|
|
process.exit(0);
|
|
|
|
} else if (newSemVer.compareMain(oldSemVer) === 0) {
|
|
|
|
message = `fix: ${message}`;
|
|
|
|
} else {
|
|
|
|
message = `feat: ${message}`;
|
|
|
|
}
|
|
|
|
actions.setOutput('commit', message);
|
|
|
|
}
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
/**
|
|
|
|
* 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}`);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-06-01 08:13:42 +00:00
|
|
|
async function replaceInFile(filePath, search, replace) {
|
|
|
|
const buffer = await readFile(filePath);
|
2023-12-13 13:40:06 +00:00
|
|
|
const update = buffer.toString().replace(search, replace);
|
2023-06-01 08:13:42 +00:00
|
|
|
|
|
|
|
await writeFile(filePath, update);
|
2023-06-06 14:59:58 +00:00
|
|
|
|
|
|
|
touchedFiles.push(filePath);
|
2023-06-01 08:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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}"`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-06-14 07:59:01 +00:00
|
|
|
async function updateVersionFileLastMaintained(oldVersion, newVersion) {
|
2023-06-01 08:13:42 +00:00
|
|
|
const versions = [...versionsPerRelease.keys()];
|
2023-06-14 07:59:01 +00:00
|
|
|
if (versions.indexOf(newVersion) !== -1) {
|
2023-06-01 08:13:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
// If we have manually rolled Chrome but not yet released
|
|
|
|
// We will have NEXT as value in the Map
|
2023-06-14 07:59:01 +00:00
|
|
|
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);
|
2023-06-01 08:13:42 +00:00
|
|
|
|
2023-06-14 07:59:01 +00:00
|
|
|
if (newSemVer.compareMain(oldSemVer) !== 0) {
|
2023-11-02 15:31:34 +00:00
|
|
|
const lastMaintainedSemVer = new SemVer(lastMaintainedChromeVersion, true);
|
|
|
|
const newLastMaintainedMajor = lastMaintainedSemVer.major + 1;
|
|
|
|
|
|
|
|
const nextMaintainedVersion = versions.find(version => {
|
|
|
|
return new SemVer(version, true).major === newLastMaintainedMajor;
|
|
|
|
});
|
2023-06-01 08:13:42 +00:00
|
|
|
|
2023-06-06 15:38:58 +00:00
|
|
|
await replaceInFile(
|
|
|
|
'./versions.js',
|
|
|
|
`const lastMaintainedChromeVersion = '${lastMaintainedChromeVersion}';`,
|
|
|
|
`const lastMaintainedChromeVersion = '${nextMaintainedVersion}';`
|
|
|
|
);
|
|
|
|
}
|
2023-06-01 08:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const {version, revision} = await getVersionAndRevisionForStable();
|
|
|
|
|
2023-06-02 13:37:48 +00:00
|
|
|
checkIfNeedsUpdate(CHROME_CURRENT_VERSION, version, revision);
|
|
|
|
|
2023-06-01 08:13:42 +00:00
|
|
|
await replaceInFile(
|
|
|
|
'./packages/puppeteer-core/src/revisions.ts',
|
|
|
|
CHROME_CURRENT_VERSION,
|
|
|
|
version
|
|
|
|
);
|
|
|
|
|
2023-06-06 14:59:58 +00:00
|
|
|
await updateVersionFileLastMaintained(CHROME_CURRENT_VERSION, version);
|
2023-06-01 08:13:42 +00:00
|
|
|
await updateDevToolsProtocolVersion(revision);
|
|
|
|
|
2023-06-02 13:37:48 +00:00
|
|
|
// 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
|
2023-06-06 14:59:58 +00:00
|
|
|
await formatUpdateFiles();
|
2023-06-02 13:37:48 +00:00
|
|
|
|
|
|
|
// Keep this as they can be used to debug GitHub Actions if needed
|
2023-06-01 08:13:42 +00:00
|
|
|
actions.setOutput('version', version);
|
|
|
|
actions.setOutput('revision', revision);
|