Trigger auto-fix auto-matically (#44947)

Conrad Irwin created

This updates our CI workflow to try to run the autofix.yml workflow
if any of prettier, cargo fmt, or cargo clippy fail.

Release Notes:

- N/A

Change summary

.github/workflows/autofix_pr.yml                |  3 +++
.github/workflows/release.yml                   |  6 ++++++
.github/workflows/run_tests.yml                 | 18 +++++++++++++++---
tooling/xtask/src/tasks/workflows/autofix_pr.rs |  6 ++++++
tooling/xtask/src/tasks/workflows/run_tests.rs  |  8 +++++---
tooling/xtask/src/tasks/workflows/steps.rs      | 10 ++++++++++
6 files changed, 45 insertions(+), 6 deletions(-)

Detailed changes

.github/workflows/autofix_pr.yml 🔗

@@ -123,3 +123,6 @@ jobs:
         GIT_AUTHOR_NAME: Zed Zippy
         GIT_AUTHOR_EMAIL: 234243425+zed-zippy[bot]@users.noreply.github.com
         GITHUB_TOKEN: ${{ steps.get-app-token.outputs.token }}
+concurrency:
+  group: ${{ github.workflow }}-${{ inputs.pr_number }}
+  cancel-in-progress: true

.github/workflows/release.yml 🔗

@@ -74,6 +74,12 @@ jobs:
     - name: steps::clippy
       run: ./script/clippy
       shell: bash -euxo pipefail {0}
+    - name: steps::trigger_autofix
+      if: failure() && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'
+      run: gh workflow run autofix_pr.yml -f pr_number=${{ github.event.pull_request.number }} -f run_clippy=true
+      shell: bash -euxo pipefail {0}
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large

.github/workflows/run_tests.yml 🔗

@@ -77,6 +77,15 @@ jobs:
     - name: ./script/prettier
       run: ./script/prettier
       shell: bash -euxo pipefail {0}
+    - name: steps::cargo_fmt
+      run: cargo fmt --all -- --check
+      shell: bash -euxo pipefail {0}
+    - name: steps::trigger_autofix
+      if: failure() && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'
+      run: gh workflow run autofix_pr.yml -f pr_number=${{ github.event.pull_request.number }} -f run_clippy=false
+      shell: bash -euxo pipefail {0}
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     - name: ./script/check-todos
       run: ./script/check-todos
       shell: bash -euxo pipefail {0}
@@ -87,9 +96,6 @@ jobs:
       uses: crate-ci/typos@2d0ce569feab1f8752f1dde43cc2f2aa53236e06
       with:
         config: ./typos.toml
-    - name: steps::cargo_fmt
-      run: cargo fmt --all -- --check
-      shell: bash -euxo pipefail {0}
     timeout-minutes: 60
   run_tests_windows:
     needs:
@@ -160,6 +166,12 @@ jobs:
     - name: steps::clippy
       run: ./script/clippy
       shell: bash -euxo pipefail {0}
+    - name: steps::trigger_autofix
+      if: failure() && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'
+      run: gh workflow run autofix_pr.yml -f pr_number=${{ github.event.pull_request.number }} -f run_clippy=true
+      shell: bash -euxo pipefail {0}
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large

tooling/xtask/src/tasks/workflows/autofix_pr.rs 🔗

@@ -18,6 +18,12 @@ pub fn autofix_pr() -> Workflow {
                 .add_input(pr_number.name, pr_number.input())
                 .add_input(run_clippy.name, run_clippy.input()),
         ))
+        .concurrency(
+            Concurrency::new(Expression::new(format!(
+                "${{{{ github.workflow }}}}-{pr_number}"
+            )))
+            .cancel_in_progress(true),
+        )
         .add_job(run_autofix.name.clone(), run_autofix.job)
         .add_job(commit_changes.name, commit_changes.job)
 }

tooling/xtask/src/tasks/workflows/run_tests.rs 🔗

@@ -237,10 +237,11 @@ fn check_style() -> NamedJob {
             .add_step(steps::cache_rust_dependencies_namespace())
             .add_step(steps::setup_pnpm())
             .add_step(steps::script("./script/prettier"))
+            .add_step(steps::cargo_fmt())
+            .add_step(steps::trigger_autofix(false))
             .add_step(steps::script("./script/check-todos"))
             .add_step(steps::script("./script/check-keymaps"))
-            .add_step(check_for_typos())
-            .add_step(steps::cargo_fmt()),
+            .add_step(check_for_typos()),
     )
 }
 
@@ -326,7 +327,8 @@ pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob {
             .add_step(steps::setup_node())
             .add_step(steps::clippy(platform))
             .when(platform == Platform::Linux, |job| {
-                job.add_step(steps::cargo_install_nextest())
+                job.add_step(steps::trigger_autofix(true))
+                    .add_step(steps::cargo_install_nextest())
             })
             .add_step(steps::clear_target_dir_if_large(platform))
             .add_step(steps::cargo_nextest(platform))

tooling/xtask/src/tasks/workflows/steps.rs 🔗

@@ -344,3 +344,13 @@ pub fn git_checkout(ref_name: &dyn std::fmt::Display) -> Step<Run> {
         "git fetch origin {ref_name} && git checkout {ref_name}"
     ))
 }
+
+pub fn trigger_autofix(run_clippy: bool) -> Step<Run> {
+    named::bash(format!(
+        "gh workflow run autofix_pr.yml -f pr_number=${{{{ github.event.pull_request.number }}}} -f run_clippy={run_clippy}"
+    ))
+    .if_condition(Expression::new(
+        "failure() && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'",
+    ))
+    .add_env(("GITHUB_TOKEN", vars::GITHUB_TOKEN))
+}