ci: Move clippy off of run_platform_tests and into a separate job (#47139)

Piotr Osiewicz created

This should slash our CI times a bit (1 minute or so)

Closes #ISSUE

Release Notes:

- N/A

Change summary

.github/workflows/release.yml                        | 79 +++++++++++-
.github/workflows/release_nightly.yml                | 26 +++
.github/workflows/run_tests.yml                      | 85 ++++++++++++-
tooling/xtask/src/tasks/workflows/release.rs         | 50 ++++++-
tooling/xtask/src/tasks/workflows/release_nightly.rs | 16 +-
tooling/xtask/src/tasks/workflows/run_tests.rs       | 27 ++++
6 files changed, 244 insertions(+), 39 deletions(-)

Detailed changes

.github/workflows/release.yml 🔗

@@ -26,9 +26,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy
-      shell: bash -euxo pipefail {0}
     - name: steps::clear_target_dir_if_large
       run: ./script/clear-target-dir-if-larger-than 300
       shell: bash -euxo pipefail {0}
@@ -71,9 +68,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy
-      shell: bash -euxo pipefail {0}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large
@@ -105,9 +99,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy.ps1
-      shell: pwsh
     - name: steps::clear_target_dir_if_large
       run: ./script/clear-target-dir-if-larger-than.ps1 250
       shell: pwsh
@@ -120,6 +111,70 @@ jobs:
         Remove-Item -Recurse -Path "./../.cargo" -Force -ErrorAction SilentlyContinue
       shell: pwsh
     timeout-minutes: 60
+  clippy_mac:
+    if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
+    runs-on: self-mini-macos
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        mkdir -p ./../.cargo
+        cp ./.cargo/ci-config.toml ./../.cargo/config.toml
+      shell: bash -euxo pipefail {0}
+    - name: steps::clippy
+      run: ./script/clippy
+      shell: bash -euxo pipefail {0}
+    timeout-minutes: 60
+  clippy_linux:
+    if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
+    runs-on: namespace-profile-16x32-ubuntu-2204
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        mkdir -p ./../.cargo
+        cp ./.cargo/ci-config.toml ./../.cargo/config.toml
+      shell: bash -euxo pipefail {0}
+    - name: steps::cache_rust_dependencies_namespace
+      uses: namespacelabs/nscloud-cache-action@v1
+      with:
+        cache: rust
+    - name: steps::setup_linux
+      run: ./script/linux
+      shell: bash -euxo pipefail {0}
+    - name: steps::install_mold
+      run: ./script/install-mold
+      shell: bash -euxo pipefail {0}
+    - name: steps::download_wasi_sdk
+      run: ./script/download-wasi-sdk
+      shell: bash -euxo pipefail {0}
+    - name: steps::clippy
+      run: ./script/clippy
+      shell: bash -euxo pipefail {0}
+    timeout-minutes: 60
+  clippy_windows:
+    if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
+    runs-on: self-32vcpu-windows-2022
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        New-Item -ItemType Directory -Path "./../.cargo" -Force
+        Copy-Item -Path "./.cargo/ci-config.toml" -Destination "./../.cargo/config.toml"
+      shell: pwsh
+    - name: steps::clippy
+      run: ./script/clippy.ps1
+      shell: pwsh
+    timeout-minutes: 60
   check_scripts:
     if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
     runs-on: namespace-profile-2x4-ubuntu-2404
@@ -177,6 +232,7 @@ jobs:
   bundle_linux_aarch64:
     needs:
     - run_tests_linux
+    - clippy_linux
     - check_scripts
     runs-on: namespace-profile-8x32-ubuntu-2004-arm-m4
     env:
@@ -220,6 +276,7 @@ jobs:
   bundle_linux_x86_64:
     needs:
     - run_tests_linux
+    - clippy_linux
     - check_scripts
     runs-on: namespace-profile-32x64-ubuntu-2004
     env:
@@ -263,6 +320,7 @@ jobs:
   bundle_mac_aarch64:
     needs:
     - run_tests_mac
+    - clippy_mac
     - check_scripts
     runs-on: self-mini-macos
     env:
@@ -309,6 +367,7 @@ jobs:
   bundle_mac_x86_64:
     needs:
     - run_tests_mac
+    - clippy_mac
     - check_scripts
     runs-on: self-mini-macos
     env:
@@ -355,6 +414,7 @@ jobs:
   bundle_windows_aarch64:
     needs:
     - run_tests_windows
+    - clippy_windows
     - check_scripts
     runs-on: self-32vcpu-windows-2022
     env:
@@ -393,6 +453,7 @@ jobs:
   bundle_windows_x86_64:
     needs:
     - run_tests_windows
+    - clippy_windows
     - check_scripts
     runs-on: self-32vcpu-windows-2022
     env:

.github/workflows/release_nightly.yml 🔗

@@ -44,9 +44,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy.ps1
-      shell: pwsh
     - name: steps::clear_target_dir_if_large
       run: ./script/clear-target-dir-if-larger-than.ps1 250
       shell: pwsh
@@ -59,10 +56,28 @@ jobs:
         Remove-Item -Recurse -Path "./../.cargo" -Force -ErrorAction SilentlyContinue
       shell: pwsh
     timeout-minutes: 60
+  clippy_windows:
+    if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
+    runs-on: self-32vcpu-windows-2022
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        New-Item -ItemType Directory -Path "./../.cargo" -Force
+        Copy-Item -Path "./.cargo/ci-config.toml" -Destination "./../.cargo/config.toml"
+      shell: pwsh
+    - name: steps::clippy
+      run: ./script/clippy.ps1
+      shell: pwsh
+    timeout-minutes: 60
   bundle_linux_aarch64:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: namespace-profile-8x32-ubuntu-2004-arm-m4
     env:
       CARGO_INCREMENTAL: 0
@@ -113,6 +128,7 @@ jobs:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: namespace-profile-32x64-ubuntu-2004
     env:
       CARGO_INCREMENTAL: 0
@@ -163,6 +179,7 @@ jobs:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: self-mini-macos
     env:
       CARGO_INCREMENTAL: 0
@@ -216,6 +233,7 @@ jobs:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: self-mini-macos
     env:
       CARGO_INCREMENTAL: 0
@@ -269,6 +287,7 @@ jobs:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: self-32vcpu-windows-2022
     env:
       CARGO_INCREMENTAL: 0
@@ -315,6 +334,7 @@ jobs:
     needs:
     - check_style
     - run_tests_windows
+    - clippy_windows
     runs-on: self-32vcpu-windows-2022
     env:
       CARGO_INCREMENTAL: 0

.github/workflows/run_tests.yml 🔗

@@ -91,6 +91,76 @@ jobs:
       with:
         config: ./typos.toml
     timeout-minutes: 60
+  clippy_windows:
+    needs:
+    - orchestrate
+    if: needs.orchestrate.outputs.run_tests == 'true'
+    runs-on: self-32vcpu-windows-2022
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        New-Item -ItemType Directory -Path "./../.cargo" -Force
+        Copy-Item -Path "./.cargo/ci-config.toml" -Destination "./../.cargo/config.toml"
+      shell: pwsh
+    - name: steps::clippy
+      run: ./script/clippy.ps1
+      shell: pwsh
+    timeout-minutes: 60
+  clippy_linux:
+    needs:
+    - orchestrate
+    if: needs.orchestrate.outputs.run_tests == 'true'
+    runs-on: namespace-profile-16x32-ubuntu-2204
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        mkdir -p ./../.cargo
+        cp ./.cargo/ci-config.toml ./../.cargo/config.toml
+      shell: bash -euxo pipefail {0}
+    - name: steps::cache_rust_dependencies_namespace
+      uses: namespacelabs/nscloud-cache-action@v1
+      with:
+        cache: rust
+    - name: steps::setup_linux
+      run: ./script/linux
+      shell: bash -euxo pipefail {0}
+    - name: steps::install_mold
+      run: ./script/install-mold
+      shell: bash -euxo pipefail {0}
+    - name: steps::download_wasi_sdk
+      run: ./script/download-wasi-sdk
+      shell: bash -euxo pipefail {0}
+    - name: steps::clippy
+      run: ./script/clippy
+      shell: bash -euxo pipefail {0}
+    timeout-minutes: 60
+  clippy_mac:
+    needs:
+    - orchestrate
+    if: needs.orchestrate.outputs.run_tests == 'true'
+    runs-on: self-mini-macos
+    steps:
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
+    - name: steps::setup_cargo_config
+      run: |
+        mkdir -p ./../.cargo
+        cp ./.cargo/ci-config.toml ./../.cargo/config.toml
+      shell: bash -euxo pipefail {0}
+    - name: steps::clippy
+      run: ./script/clippy
+      shell: bash -euxo pipefail {0}
+    timeout-minutes: 60
   run_tests_windows:
     needs:
     - orchestrate
@@ -110,9 +180,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy.ps1
-      shell: pwsh
     - name: steps::clear_target_dir_if_large
       run: ./script/clear-target-dir-if-larger-than.ps1 250
       shell: pwsh
@@ -157,9 +224,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy
-      shell: bash -euxo pipefail {0}
     - name: steps::cargo_install_nextest
       uses: taiki-e/install-action@nextest
     - name: steps::clear_target_dir_if_large
@@ -193,9 +257,6 @@ jobs:
       uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
       with:
         node-version: '20'
-    - name: steps::clippy
-      run: ./script/clippy
-      shell: bash -euxo pipefail {0}
     - name: steps::clear_target_dir_if_large
       run: ./script/clear-target-dir-if-larger-than 300
       shell: bash -euxo pipefail {0}
@@ -536,6 +597,9 @@ jobs:
     needs:
     - orchestrate
     - check_style
+    - clippy_windows
+    - clippy_linux
+    - clippy_mac
     - run_tests_windows
     - run_tests_linux
     - run_tests_mac
@@ -562,6 +626,9 @@ jobs:
 
         check_result "orchestrate" "${{ needs.orchestrate.result }}"
         check_result "check_style" "${{ needs.check_style.result }}"
+        check_result "clippy_windows" "${{ needs.clippy_windows.result }}"
+        check_result "clippy_linux" "${{ needs.clippy_linux.result }}"
+        check_result "clippy_mac" "${{ needs.clippy_mac.result }}"
         check_result "run_tests_windows" "${{ needs.run_tests_windows.result }}"
         check_result "run_tests_linux" "${{ needs.run_tests_linux.result }}"
         check_result "run_tests_mac" "${{ needs.run_tests_mac.result }}"

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

@@ -3,26 +3,53 @@ use gh_workflow::{Event, Expression, Push, Run, Step, Use, Workflow};
 use crate::tasks::workflows::{
     run_bundling::{bundle_linux, bundle_mac, bundle_windows},
     run_tests,
-    runners::{self, Arch},
+    runners::{self, Arch, Platform},
     steps::{self, FluentBuilder, NamedJob, dependant_job, named, release_job},
     vars::{self, assets},
 };
 
 pub(crate) fn release() -> Workflow {
-    let macos_tests = run_tests::run_platform_tests(runners::Platform::Mac);
-    let linux_tests = run_tests::run_platform_tests(runners::Platform::Linux);
-    let windows_tests = run_tests::run_platform_tests(runners::Platform::Windows);
+    let macos_tests = run_tests::run_platform_tests(Platform::Mac);
+    let linux_tests = run_tests::run_platform_tests(Platform::Linux);
+    let windows_tests = run_tests::run_platform_tests(Platform::Windows);
+    let macos_clippy = run_tests::clippy(Platform::Mac);
+    let linux_clippy = run_tests::clippy(Platform::Linux);
+    let windows_clippy = run_tests::clippy(Platform::Windows);
     let check_scripts = run_tests::check_scripts();
 
     let create_draft_release = create_draft_release();
 
     let bundle = ReleaseBundleJobs {
-        linux_aarch64: bundle_linux(Arch::AARCH64, None, &[&linux_tests, &check_scripts]),
-        linux_x86_64: bundle_linux(Arch::X86_64, None, &[&linux_tests, &check_scripts]),
-        mac_aarch64: bundle_mac(Arch::AARCH64, None, &[&macos_tests, &check_scripts]),
-        mac_x86_64: bundle_mac(Arch::X86_64, None, &[&macos_tests, &check_scripts]),
-        windows_aarch64: bundle_windows(Arch::AARCH64, None, &[&windows_tests, &check_scripts]),
-        windows_x86_64: bundle_windows(Arch::X86_64, None, &[&windows_tests, &check_scripts]),
+        linux_aarch64: bundle_linux(
+            Arch::AARCH64,
+            None,
+            &[&linux_tests, &linux_clippy, &check_scripts],
+        ),
+        linux_x86_64: bundle_linux(
+            Arch::X86_64,
+            None,
+            &[&linux_tests, &linux_clippy, &check_scripts],
+        ),
+        mac_aarch64: bundle_mac(
+            Arch::AARCH64,
+            None,
+            &[&macos_tests, &macos_clippy, &check_scripts],
+        ),
+        mac_x86_64: bundle_mac(
+            Arch::X86_64,
+            None,
+            &[&macos_tests, &macos_clippy, &check_scripts],
+        ),
+        windows_aarch64: bundle_windows(
+            Arch::AARCH64,
+            None,
+            &[&windows_tests, &windows_clippy, &check_scripts],
+        ),
+        windows_x86_64: bundle_windows(
+            Arch::X86_64,
+            None,
+            &[&windows_tests, &windows_clippy, &check_scripts],
+        ),
     };
 
     let upload_release_assets = upload_release_assets(&[&create_draft_release], &bundle);
@@ -38,6 +65,9 @@ pub(crate) fn release() -> Workflow {
         .add_job(macos_tests.name, macos_tests.job)
         .add_job(linux_tests.name, linux_tests.job)
         .add_job(windows_tests.name, windows_tests.job)
+        .add_job(macos_clippy.name, macos_clippy.job)
+        .add_job(linux_clippy.name, linux_clippy.job)
+        .add_job(windows_clippy.name, windows_clippy.job)
         .add_job(check_scripts.name, check_scripts.job)
         .add_job(create_draft_release.name, create_draft_release.job)
         .map(|mut workflow| {

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

@@ -5,7 +5,7 @@ use crate::tasks::workflows::{
         prep_release_artifacts,
     },
     run_bundling::{bundle_linux, bundle_mac, bundle_windows},
-    run_tests::run_platform_tests,
+    run_tests::{clippy, run_platform_tests},
     runners::{Arch, Platform, ReleaseChannel},
     steps::{CommonJobConditions, FluentBuilder, NamedJob},
 };
@@ -18,15 +18,16 @@ pub fn release_nightly() -> Workflow {
     let style = check_style();
     // run only on windows as that's our fastest platform right now.
     let tests = run_platform_tests(Platform::Windows);
+    let clippy_job = clippy(Platform::Windows);
     let nightly = Some(ReleaseChannel::Nightly);
 
     let bundle = ReleaseBundleJobs {
-        linux_aarch64: bundle_linux(Arch::AARCH64, nightly, &[&style, &tests]),
-        linux_x86_64: bundle_linux(Arch::X86_64, nightly, &[&style, &tests]),
-        mac_aarch64: bundle_mac(Arch::AARCH64, nightly, &[&style, &tests]),
-        mac_x86_64: bundle_mac(Arch::X86_64, nightly, &[&style, &tests]),
-        windows_aarch64: bundle_windows(Arch::AARCH64, nightly, &[&style, &tests]),
-        windows_x86_64: bundle_windows(Arch::X86_64, nightly, &[&style, &tests]),
+        linux_aarch64: bundle_linux(Arch::AARCH64, nightly, &[&style, &tests, &clippy_job]),
+        linux_x86_64: bundle_linux(Arch::X86_64, nightly, &[&style, &tests, &clippy_job]),
+        mac_aarch64: bundle_mac(Arch::AARCH64, nightly, &[&style, &tests, &clippy_job]),
+        mac_x86_64: bundle_mac(Arch::X86_64, nightly, &[&style, &tests, &clippy_job]),
+        windows_aarch64: bundle_windows(Arch::AARCH64, nightly, &[&style, &tests, &clippy_job]),
+        windows_x86_64: bundle_windows(Arch::X86_64, nightly, &[&style, &tests, &clippy_job]),
     };
 
     let nix_linux_x86 = build_nix(
@@ -55,6 +56,7 @@ pub fn release_nightly() -> Workflow {
         .add_env(("RUST_BACKTRACE", "1"))
         .add_job(style.name, style.job)
         .add_job(tests.name, tests.job)
+        .add_job(clippy_job.name, clippy_job.job)
         .map(|mut workflow| {
             for job in bundle.into_jobs() {
                 workflow = workflow.add_job(job.name, job.job);

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

@@ -48,6 +48,9 @@ pub(crate) fn run_tests() -> Workflow {
     let mut jobs = vec![
         orchestrate,
         check_style(),
+        should_run_tests.guard(clippy(Platform::Windows)),
+        should_run_tests.guard(clippy(Platform::Linux)),
+        should_run_tests.guard(clippy(Platform::Mac)),
         should_run_tests.guard(run_platform_tests(Platform::Windows)),
         should_run_tests.guard(run_platform_tests(Platform::Linux)),
         should_run_tests.guard(run_platform_tests(Platform::Mac)),
@@ -304,6 +307,29 @@ fn check_workspace_binaries() -> NamedJob {
     )
 }
 
+pub(crate) fn clippy(platform: Platform) -> NamedJob {
+    let runner = match platform {
+        Platform::Windows => runners::WINDOWS_DEFAULT,
+        Platform::Linux => runners::LINUX_DEFAULT,
+        Platform::Mac => runners::MAC_DEFAULT,
+    };
+    NamedJob {
+        name: format!("clippy_{platform}"),
+        job: release_job(&[])
+            .runs_on(runner)
+            .add_step(steps::checkout_repo())
+            .add_step(steps::setup_cargo_config(platform))
+            .when(platform == Platform::Linux, |this| {
+                this.add_step(steps::cache_rust_dependencies_namespace())
+            })
+            .when(
+                platform == Platform::Linux,
+                steps::install_linux_dependencies,
+            )
+            .add_step(steps::clippy(platform)),
+    }
+}
+
 pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob {
     let runner = match platform {
         Platform::Windows => runners::WINDOWS_DEFAULT,
@@ -324,7 +350,6 @@ pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob {
                 steps::install_linux_dependencies,
             )
             .add_step(steps::setup_node())
-            .add_step(steps::clippy(platform))
             .when(platform == Platform::Linux, |job| {
                 job.add_step(steps::cargo_install_nextest())
             })