diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml new file mode 100644 index 0000000000..e195374b22 --- /dev/null +++ b/.github/workflows/update-v8.yml @@ -0,0 +1,21 @@ +name: Update V8 + +on: + schedule: + - cron: '0 10 * * *' + workflow_dispatch: + +jobs: + update: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v1 + with: + fetch-depth: 10 + submodules: recursive + - uses: denoland/setup-deno@main + with: + deno-version: v1.x + - run: deno run -A ./tools/auto_update_v8.ts + \ No newline at end of file diff --git a/tools/auto_update_v8.ts b/tools/auto_update_v8.ts new file mode 100644 index 0000000000..e29dc66432 --- /dev/null +++ b/tools/auto_update_v8.ts @@ -0,0 +1,85 @@ +const V8_TRACKING_BRANCH = "9.1-lkgr"; +const AUTOROLL_BRANCH = "autoroll"; + +function extractVersion() { + const MAJOR_PREFIX = "#define V8_MAJOR_VERSION "; + const MINOR_PREFIX = "#define V8_MINOR_VERSION "; + const BUILD_PREFIX = "#define V8_BUILD_NUMBER "; + const PATCH_PREFIX = "#define V8_PATCH_LEVEL "; + + const versionDotH = Deno.readTextFileSync("./v8/include/v8-version.h"); + const lines = versionDotH.split("\n"); + const major = parseInt(lines.find((s) => s.startsWith(MAJOR_PREFIX))! + .substring(MAJOR_PREFIX.length)); + const minor = parseInt(lines.find((s) => s.startsWith(MINOR_PREFIX))! + .substring(MINOR_PREFIX.length)); + const build = parseInt(lines.find((s) => s.startsWith(BUILD_PREFIX))! + .substring(BUILD_PREFIX.length)); + const patch = parseInt(lines.find((s) => s.startsWith(PATCH_PREFIX))! + .substring(PATCH_PREFIX.length)); + + return `${major}.${minor}.${build}.${patch}`; +} + +await run(["git", "branch", "-f", AUTOROLL_BRANCH, "origin/main"]); +await run(["git", "checkout", AUTOROLL_BRANCH]); +await run(["git", "reset", "origin/main", "--hard"]); + +const currentVersion = extractVersion(); +console.log(`Starting auto update. Currently on ${currentVersion}`); + +async function run(cmd: string[], cwd?: string) { + const proc = Deno.run({ cmd, cwd }); + const status = await proc.status(); + if (!status.success) { + console.error(`Failed to run ${cmd.join(" ")}`); + Deno.exit(1); + } +} + +// Update v8 submodule +await run(["git", "checkout", `origin/${V8_TRACKING_BRANCH}`], "./v8"); + +const newVersion = extractVersion(); +if (currentVersion == newVersion) { + console.log(`No new version available. Staying on ${newVersion}`); + Deno.exit(0); +} + +console.log(`Updated to version ${newVersion}`); + +// Update version in readme +let readme = Deno.readTextFileSync("README.md"); +readme = readme.replace( + `V8 Version: ${currentVersion}`, + `V8 Version: ${newVersion}`, +); +Deno.writeTextFileSync("README.md", readme); + +// Stage the changes +await run(["git", "add", "v8", "README.md"]); + +// Commit the changes +await run(["git", "commit", "-m", `Rolling to V8 ${newVersion}`]); + +// Push to the `denoland/rusty_v8#autoroll` +await run(["git", "push", "--force", "origin", `HEAD:${AUTOROLL_BRANCH}`]); + +const proc = Deno.run({ + cmd: ["gh", "pr", "view", AUTOROLL_BRANCH], +}); +const status = await proc.status(); +if (status.code == 1) { + console.log("No PR open. Creating a new PR."); + await run([ + "gh", + "pr", + "create", + "--fill", + "--head", + AUTOROLL_BRANCH, + ]); +} else { + console.log("Already open PR. Not creating a new PR."); + // TODO(lucacasonato): update the title of the open PR here +}