From 47e014b58117320a4f7e237e93b93a9b2a4ccbf7 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 20 Sep 2022 15:25:46 -0700 Subject: [PATCH] Remove custom automerge workflow (#30984) --- .../update-merge-queue-branch.js | 158 ------------------ .github/workflows/autoupdate-branch.yml | 57 ------- 2 files changed, 215 deletions(-) delete mode 100644 .github/actions-scripts/update-merge-queue-branch.js delete mode 100644 .github/workflows/autoupdate-branch.yml diff --git a/.github/actions-scripts/update-merge-queue-branch.js b/.github/actions-scripts/update-merge-queue-branch.js deleted file mode 100644 index 94add99e8c..0000000000 --- a/.github/actions-scripts/update-merge-queue-branch.js +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env node - -import { getOctokit } from '@actions/github' -const token = process.env.GITHUB_TOKEN -const github = getOctokit(token) - -// Mergeable status documentation here: -// https://docs.github.com/en/graphql/reference/enums#mergestatestatus -// https://docs.github.com/en/graphql/reference/enums#mergeablestate - -/* - This script gets a list of automerge-enabled PRs and sorts them - by priority. The PRs with the skip-to-front-of-merge-queue label - are prioritized first. The rest of the PRs are sorted by the date - they were updated. This is basically a FIFO queue, while allowing - writers the ability to skip the line when high-priority ships are - needed but a freeze isn't necessary. -*/ - -const DRY_RUN = Boolean(JSON.parse(process.env.DRY_RUN || 'false')) - -main() - -async function main() { - const [org, repo] = process.env.GITHUB_REPOSITORY.split('/') - if (!org || !repo) { - throw new Error('GITHUB_REPOSITORY environment variable not set') - } - // Get a list of open PRs and order them from oldest to newest - const query = `query ($first: Int, $after: String, $firstLabels: Int, $repo: String!, $org: String!) { - organization(login: $org) { - repository(name: $repo) { - pullRequests(first: $first, after: $after, states: OPEN, orderBy: {field: UPDATED_AT, direction: ASC}) { - edges{ - node { - number - url - updatedAt - mergeable - mergeStateStatus - autoMergeRequest { - enabledBy { - login - } - enabledAt - } - labels (first:$firstLabels){ - nodes { - name - } - } - commits(last: 1) { - nodes { - commit { - statusCheckRollup { - state - } - } - } - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } - } - }` - - const queryVariables = { - repo, - org, - first: 100, - after: null, // when pagination in null it will get first page - firstLabels: 100, - headers: { - // required for the mergeStateStatus enum - accept: 'application/vnd.github.merge-info-preview+json', - }, - } - let hasNextPage = true - const autoMergeEnabledPRs = [] - - // we need to get all the paginated results in the case that - // there are more than 100 PRs - while (hasNextPage) { - const graph = await github.graphql(query, queryVariables) - const dataRoot = graph.organization.repository.pullRequests - const pullRequests = dataRoot.edges - // update pagination variables - hasNextPage = dataRoot.pageInfo.hasNextPage - // the endCursor is the start cursor for the next page - queryVariables.after = dataRoot.pageInfo.endCursor - - const filteredPrs = pullRequests - // this simplifies the format received from the graphql query to - // remove the unnecessary nested objects - .map((pr) => { - // make the labels object just an array of the label names - const labelArray = pr.node.labels.nodes.map((label) => label.name) - pr.node.labels = labelArray - // return the pr object and ✂️ the node property - return pr.node - }) - .filter((pr) => pr.autoMergeRequest !== null) - .filter((pr) => pr.mergeable === 'MERGEABLE') - // filter out prs that don't have a calculated mergeable state yet - .filter((pr) => pr.mergeStateStatus !== 'UNKNOWN') - // filter out prs that still need a review, have merge conflicts, - // or have failing ci tests - .filter((pr) => pr.mergeStateStatus !== 'BLOCKED') - // **NOTE**: In the future we may want to send slack message to initiators - // of PRs with the following merge states because these can happen after - // a PR is green and the automerge is enabled - .filter((pr) => pr.mergeStateStatus !== 'DIRTY') - .filter((pr) => pr.mergeStateStatus !== 'UNSTABLE') - .filter((pr) => { - const nodes = pr.commits.nodes - if (!nodes || !nodes.length) { - // If it has no commits, why is it even here? Anyway, skip it. - return false - } - return nodes[0].commit.statusCheckRollup.state !== 'FAILURE' - }) - - autoMergeEnabledPRs.push(...filteredPrs) - } - - // Get the list of prs with the skip label so they can - // be put at the beginning of the list - const prioritizedPrList = autoMergeEnabledPRs.sort( - (a, b) => - Number(b.labels.includes('skip-to-front-of-merge-queue')) - - Number(a.labels.includes('skip-to-front-of-merge-queue')) - ) - - if (prioritizedPrList.length) { - const nextInQueue = prioritizedPrList.shift() - // Update the branch for the next PR in the merge queue - if (DRY_RUN) { - console.log('DRY RUN! But *would* update on next-in-queue') - } else { - github.rest.pulls.updateBranch({ - owner: org, - repo, - pull_number: nextInQueue.number, - }) - } - console.log(`⏱ Total PRs in the merge queue: ${prioritizedPrList.length + 1}`) - console.log(`🚂 Updated branch for PR #${JSON.stringify(nextInQueue, null, 2)}`) - } - - prioritizedPrList.length - ? console.log(`🚏 Next up in the queue: \n ${JSON.stringify(prioritizedPrList, null, 2)}`) - : console.log(`⚡ The merge queue is empty`) -} diff --git a/.github/workflows/autoupdate-branch.yml b/.github/workflows/autoupdate-branch.yml deleted file mode 100644 index 9ab9c7eeaa..0000000000 --- a/.github/workflows/autoupdate-branch.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Autoupdate branch - -# **What it does**: The next pull request in the merge queue will get its -# branch updated with main. Only updating one branch ensures that pull requests -# in the queue are merged sequentially. -# **Why we have it**: So we don't have to watch pull requests and click -# update branch 1000x. -# **Who does it impact**: Our health. -# -# The merge queue consists of any pull requests with automerge enabled and -# are mergeable. There is a label that can be used to skip to the front of -# the queue (`skip-to-front-of-merge-queue`). -# -# This workflow is triggered when a `push` event occurs ON the `main` branch -# (e.g. a PR was merged or a force-push was done). -# -# This workflow runs on all PRs created from source branches within the -# public and private docs repos but is won't work for PRs created from -# forked repos. -# - -on: - push: - branches: - - main - -permissions: - contents: read - -# This allows a subsequently queued workflow run to take priority over -# previously queued runs but NOT interrupt currently executing runs -concurrency: - group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' - cancel-in-progress: false - -jobs: - autoupdate: - if: github.repository == 'github/docs-internal' || github.repository == 'github/docs' - name: autoupdate - runs-on: ubuntu-latest - steps: - - name: Check out repo content - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 - - - name: Setup Node - uses: actions/setup-node@17f8bd926464a1afa4c6a11669539e9c1ba77048 - with: - node-version: '16.15.0' - cache: npm - - - name: Install dependencies - run: npm ci - - - name: Update next PR in queue - env: - GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }} - run: node .github/actions-scripts/update-merge-queue-branch.js