From d38d01c19b11b769bb917b67dc9f2c983c5250ce Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 10 Aug 2026 16:08:52 +0800 Subject: [PATCH] ci: move full WSL2 suite to nightly, keep per-PR contract gate - the full serial suite needs 50+ minutes on the 9P filesystem (2026/2343 lib tests finished in 39.5min before the 45min timeout) - per-PR job now runs only the atomic-write contract (~6min total) and builds just the lib test binary via --lib - new nightly workflow (schedule + workflow_dispatch, 90min timeout) runs the contract plus the full serial suite on the WSL2 home --- .github/workflows/ci.yml | 13 +---- .github/workflows/wsl2-nightly.yml | 89 ++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/wsl2-nightly.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc4c39fe7..aeedb771a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -157,7 +157,7 @@ jobs: - name: Compile backend tests with native temp # link.exe/mt.exe cannot create manifests when TEMP points at a WSL UNC path. - run: cargo test --tests --manifest-path src-tauri/Cargo.toml --no-run + run: cargo test --lib --manifest-path src-tauri/Cargo.toml --no-run - name: Run Windows-to-WSL2 filesystem contract shell: pwsh @@ -165,7 +165,7 @@ jobs: $env:TEMP = $env:CC_SWITCH_WSL_TEST_TEMP $env:TMP = $env:CC_SWITCH_WSL_TEST_TEMP $testName = "config::tests::atomic_write_replaces_existing_wsl_unc_file" - $testList = cargo test --tests --manifest-path src-tauri/Cargo.toml -- --ignored --list + $testList = cargo test --lib --manifest-path src-tauri/Cargo.toml -- --ignored --list if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } @@ -173,14 +173,7 @@ jobs: if ($testList -notcontains $expected) { throw "Expected ignored test was not discovered: $testName" } - cargo test --tests --manifest-path src-tauri/Cargo.toml $testName -- --ignored --exact --nocapture + cargo test --lib --manifest-path src-tauri/Cargo.toml $testName -- --ignored --exact --nocapture if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - - name: Run tests against WSL2-backed home - shell: pwsh - run: | - $env:TEMP = $env:CC_SWITCH_WSL_TEST_TEMP - $env:TMP = $env:CC_SWITCH_WSL_TEST_TEMP - cargo test --tests --manifest-path src-tauri/Cargo.toml -- --test-threads=1 diff --git a/.github/workflows/wsl2-nightly.yml b/.github/workflows/wsl2-nightly.yml new file mode 100644 index 000000000..6fa2e32c2 --- /dev/null +++ b/.github/workflows/wsl2-nightly.yml @@ -0,0 +1,89 @@ +name: WSL2 Nightly + +# The full backend suite takes 50+ minutes on a \\wsl.localhost 9P filesystem, +# so it runs nightly instead of per PR. The per-PR gate in ci.yml only runs the +# atomic-write contract test against the same WSL2-backed environment. +on: + schedule: + - cron: "23 18 * * *" # 02:23 Beijing time + workflow_dispatch: + +jobs: + backend-windows-wsl2-full: + name: Backend Full Suite (Windows + WSL2 home) + runs-on: windows-2025 + timeout-minutes: 90 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable + + - name: Setup WSL2 + uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7 + with: + distribution: Ubuntu-24.04 + wsl-version: 2 + + - name: Cache Cargo registry and build + uses: actions/cache@v5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + src-tauri/target + key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Create frontend dist placeholder + shell: bash + run: mkdir -p dist + + - name: Prepare WSL2-backed test environment + shell: pwsh + run: | + wsl.exe -d Ubuntu-24.04 -- bash -lc "rm -rf /tmp/cc-switch-windows-test-root && mkdir -p /tmp/cc-switch-windows-test-root/{home,temp} && chmod -R 0777 /tmp/cc-switch-windows-test-root" + $testRoot = "\\wsl.localhost\Ubuntu-24.04\tmp\cc-switch-windows-test-root" + $testHome = Join-Path $testRoot "home" + $testTemp = Join-Path $testRoot "temp" + foreach ($path in @($testRoot, $testHome, $testTemp)) { + if (-not (Test-Path -LiteralPath $path)) { + throw "WSL2-backed test path is unavailable: $path" + } + } + "CC_SWITCH_TEST_HOME=$testHome" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + "CC_SWITCH_WSL_TEST_DIR=$testRoot" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + "CC_SWITCH_WSL_TEST_TEMP=$testTemp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Compile backend tests with native temp + # link.exe/mt.exe cannot create manifests when TEMP points at a WSL UNC path. + run: cargo test --tests --manifest-path src-tauri/Cargo.toml --no-run + + - name: Run Windows-to-WSL2 filesystem contract + shell: pwsh + run: | + $env:TEMP = $env:CC_SWITCH_WSL_TEST_TEMP + $env:TMP = $env:CC_SWITCH_WSL_TEST_TEMP + $testName = "config::tests::atomic_write_replaces_existing_wsl_unc_file" + $testList = cargo test --tests --manifest-path src-tauri/Cargo.toml -- --ignored --list + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + $expected = "${testName}: test" + if ($testList -notcontains $expected) { + throw "Expected ignored test was not discovered: $testName" + } + cargo test --tests --manifest-path src-tauri/Cargo.toml $testName -- --ignored --exact --nocapture + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + + - name: Run full test suite against WSL2-backed home + shell: pwsh + run: | + $env:TEMP = $env:CC_SWITCH_WSL_TEST_TEMP + $env:TMP = $env:CC_SWITCH_WSL_TEST_TEMP + cargo test --tests --manifest-path src-tauri/Cargo.toml -- --test-threads=1