diff --git a/.github/workflows/open-v3-maintenance-prs.yml b/.github/workflows/open-v3-maintenance-prs.yml new file mode 100644 index 000000000000..37af221e6c9c --- /dev/null +++ b/.github/workflows/open-v3-maintenance-prs.yml @@ -0,0 +1,33 @@ +name: v3 Maintenance + +on: pull_request + +jobs: + open-pr: + if: ${{ github.repository_owner == 'cloudflare' }} + name: Open backport PR for patches + runs-on: macos-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + timeout-minutes: 30 + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Dependencies + uses: ./.github/actions/install-dependencies + + - uses: Ana06/get-changed-files@v1.2 + id: files + with: + format: "json" + + - run: node -r esbuild-register tools/deployments/open-v3-pr.ts + env: + FILES: ${{ steps.files.outputs.all }} + PR_NUMBER: ${{ github.event.number }} + GH_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} + LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} diff --git a/tools/deployments/open-v3-pr.ts b/tools/deployments/open-v3-pr.ts new file mode 100644 index 000000000000..48b273a69eb5 --- /dev/null +++ b/tools/deployments/open-v3-pr.ts @@ -0,0 +1,43 @@ +import { execSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import parseChangeset from "@changesets/parse"; + +/* eslint-disable turbo/no-undeclared-env-vars */ +if (require.main === module) { + const parsedLabels = JSON.parse(process.env.LABELS as string) as string[]; + if ( + isWranglerPatch(process.env.FILES as string) && + !parsedLabels.includes("skip-v3-pr") + ) { + // Create a new branch for the v3 maintenance PR + execSync(`git checkout -b v3-maintenance-${process.env.PR_NUMBER} -f`); + + execSync(`git push origin HEAD --force`); + + try { + // Open PR + execSync( + `gh pr create --base main --head v3-maintenance-${process.env.PR_NUMBER} --label "skip-pr-description-validation" --label "skip-v3-pr" --title "Backport #${process.env.PR_NUMBER} to Wrangler v3" --body "This is an automatically opened PR to backport patch changes from #${process.env.PR_NUMBER} to Wrangler v3"` + ); + } catch { + // Ignore "PR already created failures" + } + } +} + +export function isWranglerPatch(changedFilesJson: string) { + const changedFiles = JSON.parse(changedFilesJson) as string[]; + const changesets = changedFiles + .filter((f) => f.startsWith(".changeset/")) + .map((c) => parseChangeset(readFileSync(c, "utf8"))); + + let hasWranglerPatch = false; + for (const changeset of changesets) { + for (const release of changeset.releases) { + if (release.name === "wrangler" && release.type === "patch") { + hasWranglerPatch = true; + } + } + } + return hasWranglerPatch; +}