1# Commit queue 2 3> Stability: 1 - Experimental 4 5_tl;dr: You can land pull requests by adding the `commit-queue` label to it._ 6 7Commit Queue is an experimental feature for the project which simplifies the 8landing process by automating it via GitHub Actions. With it, collaborators can 9land pull requests by adding the `commit-queue` label to a PR. All 10checks will run via node-core-utils, and if the pull request is ready to land, 11the Action will rebase it and push to `main`. 12 13This document gives an overview of how the Commit Queue works, as well as 14implementation details, reasoning for design choices, and current limitations. 15 16## Overview 17 18From a high-level, the Commit Queue works as follow: 19 201. Collaborators will add `commit-queue` label to pull requests ready to land 212. Every five minutes the queue will do the following for each pull request 22 with the label: 23 1. Check if the PR also has a `request-ci` label (if it has, skip this PR 24 since it's pending a CI run) 25 2. Check if the last Jenkins CI is finished running (if it is not, skip this 26 PR) 27 3. Remove the `commit-queue` label 28 4. Run `git node land <pr> --oneCommitMax` 29 5. If it fails: 30 1. Abort `git node land` session 31 2. Add `commit-queue-failed` label to the PR 32 3. Leave a comment on the PR with the output from `git node land` 33 4. Skip next steps, go to next PR in the queue 34 6. If it succeeds: 35 1. Push the changes to nodejs/node 36 2. Leave a comment on the PR with `Landed in ...` 37 3. Close the PR 38 4. Go to next PR in the queue 39 40To make the Commit Queue squash all the commits of a pull request into the 41first one, add the `commit-queue-squash` label. 42To make the Commit Queue land a pull request containing several commits, add the 43`commit-queue-rebase` label. When using this option, make sure 44that all commits are self-contained, meaning every commit should pass all tests. 45 46## Current limitations 47 48The Commit Queue feature is still in early stages, and as such it might not 49work for more complex pull requests. These are the currently known limitations 50of the commit queue: 51 521. All commits in a pull request must either be following commit message 53 guidelines or be a valid [`fixup!`](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---fixupamendrewordltcommitgt) 54 commit that will be correctly handled by the [`--autosquash`](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---autosquash) 55 option 562. A CI must've ran and succeeded since the last change on the PR 573. A collaborator must have approved the PR since the last change 584. Only Jenkins CI and GitHub Actions are checked (V8 CI and CITGM are ignored) 59 60## Implementation 61 62The [action](../../.github/workflows/commit-queue.yml) will run on scheduler 63events every five minutes. Five minutes is the smallest number accepted by 64the scheduler. The scheduler is not guaranteed to run every five minutes, it 65might take longer between runs. 66 67Using the scheduler is preferable over using pull\_request\_target for two 68reasons: 69 701. if two Commit Queue Actions execution overlap, there's a high-risk that 71 the last one to finish will fail because the local branch will be out of 72 sync with the remote after the first Action pushes. `issue_comment` event 73 has the same limitation. 742. `pull_request_target` will only run if the Action exists on the base commit 75 of a pull request, and it will run the Action version present on that 76 commit, meaning we wouldn't be able to use it for already opened PRs 77 without rebasing them first. 78 79`node-core-utils` is configured with a personal token and 80a Jenkins token from 81[@nodejs-github-bot](https://github.com/nodejs/github-bot). 82`octokit/graphql-action` is used to fetch all pull requests with the 83`commit-queue` label. The output is a JSON payload, so `jq` is used to turn 84that into a list of PR ids we can pass as arguments to 85[`commit-queue.sh`](../../tools/actions/commit-queue.sh). 86 87> The personal token only needs permission for public repositories and to read 88> profiles, we can use the GITHUB\_TOKEN for write operations. Jenkins token is 89> required to check CI status. 90 91`commit-queue.sh` receives the following positional arguments: 92 931. The repository owner 942. The repository name 953. The Action GITHUB\_TOKEN 964. Every positional argument starting at this one will be a pull request ID of 97 a pull request with commit-queue set. 98 99The script will iterate over the pull requests. `ncu-ci` is used to check if 100the last CI is still pending, and calls to the GitHub API are used to check if 101the PR is waiting for CI to start (`request-ci` label). The PR is skipped if CI 102is pending. No other CI validation is done here since `git node land` will fail 103if the last CI failed. 104 105The script removes the `commit-queue` label. It then runs `git node land`, 106forwarding stdout and stderr to a file. If any errors happen, 107`git node land --abort` is run, and then a `commit-queue-failed` label is added 108to the PR, as well as a comment with the output of `git node land`. 109 110If no errors happen during `git node land`, the script will use the 111`GITHUB_TOKEN` to push the changes to `main`, and then will leave a 112`Landed in ...` comment in the PR, and then will close it. Iteration continues 113until all PRs have done the steps above. 114 115## Reverting broken commits 116 117Reverting broken commits is done manually by collaborators, just like when 118commits are landed manually via `git node land`. An easy way to revert is a 119good feature for the project, but is not explicitly required for the Commit 120Queue to work because the Action lands PRs just like collaborators do today. If 121once we start using the Commit Queue we notice that the number of required 122reverts increases drastically, we can pause the queue until a Revert Queue is 123implemented, but until then we can enable the Commit Queue and then work on a 124Revert Queue as a follow-up. 125