Attempt to fix the autofix auto scheduler (#45178)

Conrad Irwin created

Release Notes:

- N/A

Change summary

.github/workflows/extension_tests.yml          |  3 +
.github/workflows/release.yml                  |  7 ++++
.github/workflows/release_nightly.yml          |  3 +
.github/workflows/run_tests.yml                | 22 ++++++++++++--
tooling/xtask/src/tasks/workflows/run_tests.rs | 29 +++++++++++++++----
tooling/xtask/src/tasks/workflows/steps.rs     | 29 +++++++++++++++++++
6 files changed, 79 insertions(+), 14 deletions(-)

Detailed changes

.github/workflows/extension_tests.yml 🔗

@@ -61,7 +61,8 @@ jobs:
       uses: namespacelabs/nscloud-cache-action@v1
       with:
         cache: rust
-    - name: steps::cargo_fmt
+    - id: cargo_fmt
+      name: steps::cargo_fmt
       run: cargo fmt --all -- --check
       shell: bash -euxo pipefail {0}
     - name: extension_tests::run_clippy

.github/workflows/release.yml 🔗

@@ -76,6 +76,11 @@ jobs:
       name: steps::clippy
       run: ./script/clippy
       shell: bash -euxo pipefail {0}
+    - id: record_clippy_failure
+      name: steps::record_clippy_failure
+      if: always()
+      run: echo "failed=${{ steps.clippy.outcome == 'failure' }}" >> "$GITHUB_OUTPUT"
+      shell: bash -euxo pipefail {0}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large
@@ -90,7 +95,7 @@ jobs:
         rm -rf ./../.cargo
       shell: bash -euxo pipefail {0}
     outputs:
-      clippy_failed: ${{ steps.clippy.outcome == 'failure' }}
+      clippy_failed: ${{ steps.record_clippy_failure.outputs.failed == 'true' }}
     timeout-minutes: 60
   run_tests_windows:
     if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')

.github/workflows/release_nightly.yml 🔗

@@ -20,7 +20,8 @@ jobs:
       with:
         clean: false
         fetch-depth: 0
-    - name: steps::cargo_fmt
+    - id: cargo_fmt
+      name: steps::cargo_fmt
       run: cargo fmt --all -- --check
       shell: bash -euxo pipefail {0}
     - name: ./script/clippy

.github/workflows/run_tests.yml 🔗

@@ -74,12 +74,19 @@ jobs:
       uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2
       with:
         version: '9'
-    - name: ./script/prettier
+    - id: prettier
+      name: steps::prettier
       run: ./script/prettier
       shell: bash -euxo pipefail {0}
-    - name: steps::cargo_fmt
+    - id: cargo_fmt
+      name: steps::cargo_fmt
       run: cargo fmt --all -- --check
       shell: bash -euxo pipefail {0}
+    - id: record_style_failure
+      name: steps::record_style_failure
+      if: always()
+      run: echo "failed=${{ steps.prettier.outcome == 'failure' || steps.cargo_fmt.outcome == 'failure' }}" >> "$GITHUB_OUTPUT"
+      shell: bash -euxo pipefail {0}
     - name: ./script/check-todos
       run: ./script/check-todos
       shell: bash -euxo pipefail {0}
@@ -90,6 +97,8 @@ jobs:
       uses: crate-ci/typos@2d0ce569feab1f8752f1dde43cc2f2aa53236e06
       with:
         config: ./typos.toml
+    outputs:
+      style_failed: ${{ steps.record_style_failure.outputs.failed == 'true' }}
     timeout-minutes: 60
   run_tests_windows:
     needs:
@@ -162,6 +171,11 @@ jobs:
       name: steps::clippy
       run: ./script/clippy
       shell: bash -euxo pipefail {0}
+    - id: record_clippy_failure
+      name: steps::record_clippy_failure
+      if: always()
+      run: echo "failed=${{ steps.clippy.outcome == 'failure' }}" >> "$GITHUB_OUTPUT"
+      shell: bash -euxo pipefail {0}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large
@@ -176,7 +190,7 @@ jobs:
         rm -rf ./../.cargo
       shell: bash -euxo pipefail {0}
     outputs:
-      clippy_failed: ${{ steps.clippy.outcome == 'failure' }}
+      clippy_failed: ${{ steps.record_clippy_failure.outputs.failed == 'true' }}
     timeout-minutes: 60
   run_tests_mac:
     needs:
@@ -582,7 +596,7 @@ jobs:
     needs:
     - check_style
     - run_tests_linux
-    if: (needs.check_style.result == 'failure' || needs.run_tests_linux.outputs.clippy_failed == 'true') && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'
+    if: always() && (needs.check_style.outputs.style_failed == 'true' || needs.run_tests_linux.outputs.clippy_failed == 'true') && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'
     runs-on: namespace-profile-2x4-ubuntu-2404
     steps:
     - id: get-app-token

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

@@ -226,6 +226,8 @@ pub fn tests_pass(jobs: &[NamedJob]) -> NamedJob {
     named::job(job)
 }
 
+pub const STYLE_FAILED_OUTPUT: &str = "style_failed";
+
 fn check_style() -> NamedJob {
     fn check_for_typos() -> Step<Use> {
         named::uses(
@@ -241,11 +243,19 @@ fn check_style() -> NamedJob {
             .add_step(steps::checkout_repo())
             .add_step(steps::cache_rust_dependencies_namespace())
             .add_step(steps::setup_pnpm())
-            .add_step(steps::script("./script/prettier"))
+            .add_step(steps::prettier())
             .add_step(steps::cargo_fmt())
+            .add_step(steps::record_style_failure())
             .add_step(steps::script("./script/check-todos"))
             .add_step(steps::script("./script/check-keymaps"))
-            .add_step(check_for_typos()),
+            .add_step(check_for_typos())
+            .outputs([(
+                STYLE_FAILED_OUTPUT.to_owned(),
+                format!(
+                    "${{{{ steps.{}.outputs.failed == 'true' }}}}",
+                    steps::RECORD_STYLE_FAILURE_STEP_ID
+                ),
+            )]),
     )
 }
 
@@ -262,6 +272,10 @@ fn call_autofix(check_style: &NamedJob, run_tests_linux: &NamedJob) -> NamedJob
         .add_env(("GITHUB_TOKEN", "${{ steps.get-app-token.outputs.token }}"))
     }
 
+    let style_failed_expr = format!(
+        "needs.{}.outputs.{} == 'true'",
+        check_style.name, STYLE_FAILED_OUTPUT
+    );
     let clippy_failed_expr = format!(
         "needs.{}.outputs.{} == 'true'",
         run_tests_linux.name, CLIPPY_FAILED_OUTPUT
@@ -271,8 +285,8 @@ fn call_autofix(check_style: &NamedJob, run_tests_linux: &NamedJob) -> NamedJob
     let job = Job::default()
         .runs_on(runners::LINUX_SMALL)
         .cond(Expression::new(format!(
-            "(needs.{}.result == 'failure' || {}) && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'",
-            check_style.name, clippy_failed_expr
+            "always() && ({} || {}) && github.event_name == 'pull_request' && github.actor != 'zed-zippy[bot]'",
+            style_failed_expr, clippy_failed_expr
         )))
         .needs(vec![check_style.name.clone(), run_tests_linux.name.clone()])
         .add_step(authenticate)
@@ -364,6 +378,9 @@ 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::record_clippy_failure())
+            })
             .when(platform == Platform::Linux, |job| {
                 job.add_step(steps::cargo_install_nextest())
             })
@@ -374,8 +391,8 @@ pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob {
                 job.outputs([(
                     CLIPPY_FAILED_OUTPUT.to_owned(),
                     format!(
-                        "${{{{ steps.{}.outcome == 'failure' }}}}",
-                        steps::CLIPPY_STEP_ID
+                        "${{{{ steps.{}.outputs.failed == 'true' }}}}",
+                        steps::RECORD_CLIPPY_FAILURE_STEP_ID
                     ),
                 )])
             }),

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

@@ -54,8 +54,25 @@ pub fn setup_sentry() -> Step<Use> {
     .add_with(("token", vars::SENTRY_AUTH_TOKEN))
 }
 
+pub const PRETTIER_STEP_ID: &str = "prettier";
+pub const CARGO_FMT_STEP_ID: &str = "cargo_fmt";
+pub const RECORD_STYLE_FAILURE_STEP_ID: &str = "record_style_failure";
+
+pub fn prettier() -> Step<Run> {
+    named::bash("./script/prettier").id(PRETTIER_STEP_ID)
+}
+
 pub fn cargo_fmt() -> Step<Run> {
-    named::bash("cargo fmt --all -- --check")
+    named::bash("cargo fmt --all -- --check").id(CARGO_FMT_STEP_ID)
+}
+
+pub fn record_style_failure() -> Step<Run> {
+    named::bash(format!(
+        "echo \"failed=${{{{ steps.{}.outcome == 'failure' || steps.{}.outcome == 'failure' }}}}\" >> \"$GITHUB_OUTPUT\"",
+        PRETTIER_STEP_ID, CARGO_FMT_STEP_ID
+    ))
+    .id(RECORD_STYLE_FAILURE_STEP_ID)
+    .if_condition(Expression::new("always()"))
 }
 
 pub fn cargo_install_nextest() -> Step<Use> {
@@ -102,6 +119,7 @@ pub fn clear_target_dir_if_large(platform: Platform) -> Step<Run> {
 }
 
 pub const CLIPPY_STEP_ID: &str = "clippy";
+pub const RECORD_CLIPPY_FAILURE_STEP_ID: &str = "record_clippy_failure";
 
 pub fn clippy(platform: Platform) -> Step<Run> {
     match platform {
@@ -110,6 +128,15 @@ pub fn clippy(platform: Platform) -> Step<Run> {
     }
 }
 
+pub fn record_clippy_failure() -> Step<Run> {
+    named::bash(format!(
+        "echo \"failed=${{{{ steps.{}.outcome == 'failure' }}}}\" >> \"$GITHUB_OUTPUT\"",
+        CLIPPY_STEP_ID
+    ))
+    .id(RECORD_CLIPPY_FAILURE_STEP_ID)
+    .if_condition(Expression::new("always()"))
+}
+
 pub fn cache_rust_dependencies_namespace() -> Step<Use> {
     named::uses("namespacelabs", "nscloud-cache-action", "v1").add_with(("cache", "rust"))
 }