From 3ed0ee6616e927312fde26140fea978df6c938b2 Mon Sep 17 00:00:00 2001 From: Robbie McKinstry Date: Thu, 17 Oct 2024 12:02:19 -0400 Subject: [PATCH] Enable Merge Queue This commit add CI jobs to set up GitHub Merge Queues. Merge queues ensure builds are always green before landing on `trunk`, and allow multiple PRs to be tested and merged in sequence, reducing overall CI time. chore: Enable GitHub Merge Queues. --- .github/workflows/on-merge.yml | 68 ++++++++++++++++++++++++++++++++++ .github/workflows/on-pr.yml | 67 +++++++++++++++++++++++++++++++++ .github/workflows/push.yml | 4 +- README.md | 25 +++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/on-merge.yml create mode 100644 .github/workflows/on-pr.yml diff --git a/.github/workflows/on-merge.yml b/.github/workflows/on-merge.yml new file mode 100644 index 0000000..869bb16 --- /dev/null +++ b/.github/workflows/on-merge.yml @@ -0,0 +1,68 @@ +name: "On Merge | Validate Build" + +on: + # Use a merge queue to gate the creation and storage + # of these Docker images. + merge_group: + # Allow this job to be executed manually from the GH UI. + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + pr-ready: + if: always() + name: "⚡ PR Ready" + runs-on: ubuntu-latest + needs: + - "build" + steps: + - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} + run: | + echo "One or more dependent jobs failed, was skipped, or was cancelled. All jobs must pass for the PR to be ready." + exit 1 + - run: echo "OK" + + # TODO: Exfiltrate this job into one or more action/jobs so it can be reused + # for on-pr and on-merge. + # This job installs Cargo Make and Cargo Nextest before running + # the CI workflow using Cargo Make. Most of the time, it should + # restore Cargo Make and other dependencies from cache. + build: + name: Validate Rust Build + runs-on: ubuntu-latest + steps: + - name: Checkout the Repo + uses: actions/checkout@v4 + + - name: "Install Rust (Nightly)" + uses: dtolnay/rust-toolchain@nightly + with: + components: rustfmt,clippy + + - name: "Install Rust (Stable)" + uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview,rustfmt,clippy + + - name: "Restore Rust Cache" + uses: Swatinem/rust-cache@v2 + + - name: "Install Cargo Tools from Binaries." + uses: "taiki-e/install-action@v2" + with: + tool: "cargo-tarpaulin,cargo-make,cargo-nextest,cargo-llvm-cov" + + - name: "Install Cargo Sort" + uses: taiki-e/cache-cargo-install-action@v1 + with: + tool: cargo-sort + + - name: "Install Taplo CLI" + uses: taiki-e/cache-cargo-install-action@v1 + with: + tool: taplo-cli + + - name: "Cargo Make" + run: cargo make ci-flow diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml new file mode 100644 index 0000000..b655d58 --- /dev/null +++ b/.github/workflows/on-pr.yml @@ -0,0 +1,67 @@ +name: "On PR | Validate Build" +on: + # When a PR is initiated, we want to validate the PR before running + # the merge queue. + pull_request: + # Allow this job to be executed manually from the GH UI. + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + # Do not change this job's name without also changing "pr-ready"'s + # job name in "on-merge.yml". These jobs must have the same name. + # See the README for more details. + pr-ready: + if: always() + name: "⚡ PR Ready" + runs-on: ubuntu-latest + needs: + - "build" + steps: + - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} + run: | + echo "One or more dependent jobs failed, was skipped, or was cancelled. All jobs must pass for the PR to be ready." + exit 1 + - run: echo "OK" + + # TODO: Exfiltrate this job into one or more action/jobs so it can be reused + # for on-pr and on-merge. + build: + name: Validate Rust Build + runs-on: ubuntu-latest + steps: + - name: Checkout the Repo + uses: actions/checkout@v4 + + - name: "Install Rust (Nightly)" + uses: dtolnay/rust-toolchain@nightly + with: + components: rustfmt,clippy + + - name: "Install Rust (Stable)" + uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview,rustfmt,clippy + + - name: "Restore Rust Cache" + uses: Swatinem/rust-cache@v2 + + - name: "Install Cargo Tools from Binaries." + uses: "taiki-e/install-action@v2" + with: + tool: "cargo-tarpaulin,cargo-make,cargo-nextest,cargo-llvm-cov" + + - name: "Install Cargo Sort" + uses: taiki-e/cache-cargo-install-action@v1 + with: + tool: cargo-sort + + - name: "Install Taplo CLI" + uses: taiki-e/cache-cargo-install-action@v1 + with: + tool: taplo-cli + + - name: "Cargo Make" + run: cargo make ci-flow diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index fc4c0e4..e9a019a 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -1,4 +1,4 @@ -name: Rust +name: "On Push – Validate Build" on: push: @@ -7,6 +7,8 @@ env: CARGO_TERM_COLOR: always jobs: + # TODO: Exfiltrate this job into one or more action/jobs so it can be reused + # for on-pr and on-merge. # This job installs Cargo Make and Cargo Nextest before running # the CI workflow using Cargo Make. Most of the time, it should # restore Cargo Make and other dependencies from cache. diff --git a/README.md b/README.md index c48b12e..d59a432 100644 --- a/README.md +++ b/README.md @@ -1 +1,26 @@ # Canary + +## Working with Merge Queues + +This repository uses GitHub Merge Queues to control the delivery of +Docker images. + +*N.B.*: GitHub Merge Queues are a fairly new feature, so there's still +some unintuitive behavior to work through. For example, please note +that "required status checks" must pass *both* before enqueueing a PR is +allowed *and* for an enqueued PR to successfully merge. To facilitate +running separate checks for PR readiness (*i.e.* light-weight tests to check if +a PR ready to be merged) and validation (*i.e.* run heavy-weight tests +running immediately before merging), we give two jobs the same name +even though they fire on different events. + +The job `⚡PR Ready` is a special name we use for both jobs. The +emoiji character is specifically used to distinguish it as a special +type of job. The workflow should only ever call into other workflows, +giving us the most flexibility with workflow reuse. + +Below, you'll find resources for working with and +understanding merge queues. It's pretty light for now, so feel free +to add more links. + +* [GitHub Actions Patterns](https://github.com/orgs/community/discussions/103114#discussioncomment-8359045)