From 64a9384efafbea789bea0269ac693dda3d1659d4 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 4 Apr 2022 14:56:29 -0400 Subject: [PATCH] chore(ci): automatically open PR to forward patch release back to main (#14180) --- .github/workflows/cargo_publish.yml | 8 ++- tools/cut_a_release.md | 5 +- tools/release/04_create_release_tag.ts | 18 ----- tools/release/04_post_publish.ts | 94 ++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 22 deletions(-) delete mode 100755 tools/release/04_create_release_tag.ts create mode 100755 tools/release/04_post_publish.ts diff --git a/.github/workflows/cargo_publish.yml b/.github/workflows/cargo_publish.yml index 29eee22faf..4bb2ad6867 100644 --- a/.github/workflows/cargo_publish.yml +++ b/.github/workflows/cargo_publish.yml @@ -36,7 +36,11 @@ jobs: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: ./tools/release/03_publish_crates.ts --real - - name: Create release tag + - name: Create release tag and check forward commit to main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: ./tools/release/04_create_release_tag.ts + GH_WORKFLOW_ACTOR: ${{ github.actor }} + run: | + git config user.email "${{ github.actor }}@users.noreply.github.com" + git config user.name "${{ github.actor }}" + ./tools/release/04_post_publish.ts diff --git a/tools/cut_a_release.md b/tools/cut_a_release.md index 499642e0e0..3969793c66 100644 --- a/tools/cut_a_release.md +++ b/tools/cut_a_release.md @@ -112,8 +112,9 @@ verify on GitHub that everything looks correct. been updated to reflect Web API changes in this release. Usually done ahead of time by @lucacasonato. -9. **If you are cutting a patch release**: open a PR that forwards all commits - created in the release process to the `main` branch. +9. **If you are cutting a patch release**: a PR should have been automatically + opened that forwards the release commit back to main. If so, merge it. If not + and it failed, please manually create one. ## Updating `doc.deno.land` diff --git a/tools/release/04_create_release_tag.ts b/tools/release/04_create_release_tag.ts deleted file mode 100755 index 8eaac2514a..0000000000 --- a/tools/release/04_create_release_tag.ts +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env -S deno run --allow-read --allow-write --allow-run=cargo,git --no-check -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -import { DenoWorkspace } from "./deno_workspace.ts"; - -const workspace = await DenoWorkspace.load(); -const repo = workspace.repo; -const cliCrate = workspace.getCliCrate(); - -await repo.gitFetchTags("origin"); -const tags = await repo.getGitTags(); -const tagName = `v${cliCrate.version}`; - -if (tags.has(tagName)) { - console.log(`Tag ${tagName} already exists.`); -} else { - await repo.gitTag(tagName); - await repo.gitPush(tagName); -} diff --git a/tools/release/04_post_publish.ts b/tools/release/04_post_publish.ts new file mode 100755 index 0000000000..d437bb39a6 --- /dev/null +++ b/tools/release/04_post_publish.ts @@ -0,0 +1,94 @@ +#!/usr/bin/env -S deno run --allow-read --allow-write --allow-run=cargo,git --allow-net --no-check +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { DenoWorkspace } from "./deno_workspace.ts"; +import { createOctoKit, getGitHubRepository } from "./deps.ts"; + +const workspace = await DenoWorkspace.load(); +const repo = workspace.repo; +const cliCrate = workspace.getCliCrate(); + +console.log("Creating release tag..."); +await createReleaseTag(); + +console.log("Forwarding release commit to main..."); +try { + await forwardReleaseCommitToMain(); +} catch (err) { + console.error("Failed. Please manually open a PR.", err); +} + +async function createReleaseTag() { + await repo.gitFetchTags("origin"); + const tags = await repo.getGitTags(); + const tagName = `v${cliCrate.version}`; + + if (tags.has(tagName)) { + console.log(`Tag ${tagName} already exists.`); + } else { + await repo.gitTag(tagName); + await repo.gitPush(tagName); + } +} + +async function forwardReleaseCommitToMain() { + // if this is a patch release, open a PR to forward the most recent commit back to main + const currentBranch = await repo.gitCurrentBranch(); + const isPatchRelease = currentBranch !== "main"; + + if (!isPatchRelease) { + console.log("Not doing a patch release. Skipping."); + return; + } + + const releaseCommitHash = + (await repo.runCommand(["git", "rev-parse", "HEAD"])).trim(); + const newBranchName = `forward_v${cliCrate.version}`; + console.log(`Creating branch ${newBranchName}...`); + await repo.runCommand([ + "git", + "checkout", + "-b", + newBranchName, + "main", + ]); + await repo.runCommand([ + "git", + "cherry-pick", + releaseCommitHash, + ]); + await repo.gitPush("origin", newBranchName); + + console.log(`Opening PR...`); + const openedPr = await createOctoKit().request( + "POST /repos/{owner}/{repo}/pulls", + { + ...getGitHubRepository(), + base: "main", + head: newBranchName, + draft: true, + title: `chore: forward v${cliCrate.version} release commit to main`, + body: getPrBody(), + }, + ); + console.log(`Opened PR at ${openedPr.data.url}`); + + function getPrBody() { + let text = + `This is the release commit being forwarded back to main for ${cliCrate.version}\n\n` + + `Please ensure:\n` + + `- [ ] Everything looks ok in the PR\n` + + `- [ ] The release has been published\n\n` + + `To make edits to this PR:\n` + + "```shell\n" + + `git fetch upstream ${newBranchName} && git checkout -b ${newBranchName} upstream/${newBranchName}\n` + + "```\n\n" + + "Don't need this PR? Close it.\n"; + + const actor = Deno.env.get("GH_WORKFLOW_ACTOR"); + if (actor != null) { + text += `\ncc @${actor}`; + } + + return text; + } +}