From 096ad320a7e36372ca39baa2a31c906ba66f50ff Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 15 Oct 2026 11:10:22 +0330 Subject: [PATCH 1/3] ci: add timeouts and fail-fast guards to the workflows Every job gets a `timeout-minutes` so a hung step can no longer burn GitHub's 6 hour default, and every step after the first gets an `!cancelled() && steps..outcome == 'success'` guard so a failure skips the remaining work instead of running on. Jobs that run V tests also get VTEST_FAIL_FAST=1, which stops the test session after the first failing file (a red suite stays red). No step was added, removed, renamed or reordered, and no `run:` command was touched. Runner images and toolchains are unchanged. --- .github/workflows/ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6fff66a5..bf168074 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,13 @@ jobs: steps: - name: Checkout V + id: checkout_v uses: actions/checkout@v5 with: repository: vlang/v - name: Checkout VLS + id: checkout_vls + if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v5 with: path: vls @@ -67,9 +70,13 @@ jobs: run: make v1 - name: Check formatting + id: check_formatting + if: ${{ !cancelled() && steps.checkout_vls.outcome == 'success' }} run: v fmt -verify vls/ - name: Run all tests, including the vlang/v workspace tests + id: run_all_tests_including_the_vlang_v_workspace_tests + if: ${{ !cancelled() && steps.check_formatting.outcome == 'success' }} env: VLS_VLANG_V_REPO: ${{ github.workspace }} V_MACOS_V3_NO_FALLBACK: ${{ matrix.os == 'windows' && '0' || '1' }} @@ -103,6 +110,8 @@ jobs: # unnoticed until someone built with -new-compiler by hand. Both paths are # cheap to compile, so cover all three platforms. - name: Compile project with V3 + id: compile_project_with_v3 + if: ${{ !cancelled() && steps.run_all_tests_including_the_vlang_v_workspace_tests.outcome == 'success' }} env: V_MACOS_V3_NO_FALLBACK: "1" run: v -no-memory-limit -nocache -new-compiler vls/ From 801e128b6e9fd548a2d3dc8d148584e538e09bba Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 15 Oct 2026 12:22:24 +0330 Subject: [PATCH 2/3] ci: fix guard shape, reusable timeouts, and chain completeness Address review findings on the fail-fast change: - Guards now read `success() && !cancelled() && steps..outcome == 'success'`. A bare `!cancelled()` suppresses GitHub's implicit `success()` check, so a failure in a step outside the immediate chain would not have stopped later steps. - A step that already carries a condition of our exact shape gets it replaced in place instead of gaining a second `if:` key, which is invalid workflow syntax. Steps whose condition is anything else (matrix picks, failure reporters such as `steps.x.outcome != 'success'`) keep it and stay out of the chain. - Jobs that call a reusable workflow no longer get `timeout-minutes:` (GitHub forbids it there); the timeouts live on the jobs inside the called workflows instead. --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf168074..bf0cb25f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: repository: vlang/v - name: Checkout VLS id: checkout_vls - if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v5 with: path: vls @@ -71,12 +71,12 @@ jobs: - name: Check formatting id: check_formatting - if: ${{ !cancelled() && steps.checkout_vls.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_vls.outcome == 'success' }} run: v fmt -verify vls/ - name: Run all tests, including the vlang/v workspace tests id: run_all_tests_including_the_vlang_v_workspace_tests - if: ${{ !cancelled() && steps.check_formatting.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.check_formatting.outcome == 'success' }} env: VLS_VLANG_V_REPO: ${{ github.workspace }} V_MACOS_V3_NO_FALLBACK: ${{ matrix.os == 'windows' && '0' || '1' }} @@ -111,7 +111,7 @@ jobs: # cheap to compile, so cover all three platforms. - name: Compile project with V3 id: compile_project_with_v3 - if: ${{ !cancelled() && steps.run_all_tests_including_the_vlang_v_workspace_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.run_all_tests_including_the_vlang_v_workspace_tests.outcome == 'success' }} env: V_MACOS_V3_NO_FALLBACK: "1" run: v -no-memory-limit -nocache -new-compiler vls/ From 9196513db6f649e8b1732e7c3f76cc0f44fe5b5a Mon Sep 17 00:00:00 2001 From: metif12 Date: Sat, 17 Oct 2026 14:22:42 +0330 Subject: [PATCH 3/3] ci: bound every step, and give Windows the repo the tests need The four guards this branch added were no-ops. GitHub applies a default `success()` check to a step unless the `if` names a status function, and `success()` means every earlier step succeeded, so `success() && !cancelled() && steps.X.outcome == 'success'` can never be false for an `X` that already ran. Each guard, and the `id:` it read, is gone. What actually stops a wedged step is a budget, and there was one only on the two `-prod` runs. Every step now carries its own `timeout-minutes`, sized well above a healthy run: a checkout that hangs on the network fails in ten minutes, and a build or a test that wedges fails at its own budget instead of spending the rest of the job's hour on it. The job-level 60 stays as a backstop that should never fire first. Windows also ran `-prod` without `VLS_VLANG_V_REPO`, which `index_test.v` and `integration_test.v` read to find the vlang/v checkout; without it those tests resolve `vlib` from the installed V while the ubuntu `-prod` run used the checkout, so the two covered different trees. Both now set it. Checked with actionlint 1.7.12 (0 errors). The Windows and macOS jobs are currently red before vls is ever compiled, failing inside vlang/v's own build (`Backend compiler error`, `Compilation of v.c failed`), which this cannot fix. --- .github/workflows/ci.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf0cb25f..18f205fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,17 +38,22 @@ jobs: ${{ matrix.os == 'ubuntu' && (vars.VLS_RUNNER_LINUX || 'ubuntu-latest') || matrix.os == 'macos' && (vars.VLS_RUNNER_MACOS || 'macos-latest') || (vars.VLS_RUNNER_WINDOWS || 'windows-latest') }} + # A last-resort ceiling, not the fail-fast mechanism. Every step below + # carries its own `timeout-minutes`, so a step that wedges fails at its own + # budget instead of letting the job spend the rest of this one on it. The + # budgets sit well above what a healthy run needs and sum to more than this + # value on purpose: a `-prod` master push runs every one of them, and this + # should never be the thing that fires first. timeout-minutes: 60 steps: - name: Checkout V - id: checkout_v + timeout-minutes: 10 uses: actions/checkout@v5 with: repository: vlang/v - name: Checkout VLS - id: checkout_vls - if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} + timeout-minutes: 10 uses: actions/checkout@v5 with: path: vls @@ -57,9 +62,11 @@ jobs: # nothing here is pinned and every run tests against the latest compiler. - name: Build V if: matrix.os != 'windows' + timeout-minutes: 20 run: make latest_tcc && make -j4 && ./v symlink - name: Build V (Windows) if: matrix.os == 'windows' + timeout-minutes: 20 run: ./makev.bat latest_tcc && ./makev.bat && ./v symlink # Hover, completion, signature help, and go to definition run through @@ -67,16 +74,15 @@ jobs: # V3 is the default backend. `makev.bat` already builds it on Windows. - name: Build the V compatibility compiler if: matrix.os != 'windows' + timeout-minutes: 15 run: make v1 - name: Check formatting - id: check_formatting - if: ${{ success() && !cancelled() && steps.checkout_vls.outcome == 'success' }} + timeout-minutes: 5 run: v fmt -verify vls/ - name: Run all tests, including the vlang/v workspace tests - id: run_all_tests_including_the_vlang_v_workspace_tests - if: ${{ success() && !cancelled() && steps.check_formatting.outcome == 'success' }} + timeout-minutes: 30 env: VLS_VLANG_V_REPO: ${{ github.workspace }} V_MACOS_V3_NO_FALLBACK: ${{ matrix.os == 'windows' && '0' || '1' }} @@ -94,6 +100,7 @@ jobs: if: matrix.os == 'windows' && github.event_name != 'pull_request' timeout-minutes: 30 env: + VLS_VLANG_V_REPO: ${{ github.workspace }} V_MACOS_V3_NO_FALLBACK: "0" run: v -no-memory-limit -nocache -prod test vls/ @@ -110,12 +117,12 @@ jobs: # unnoticed until someone built with -new-compiler by hand. Both paths are # cheap to compile, so cover all three platforms. - name: Compile project with V3 - id: compile_project_with_v3 - if: ${{ success() && !cancelled() && steps.run_all_tests_including_the_vlang_v_workspace_tests.outcome == 'success' }} + timeout-minutes: 15 env: V_MACOS_V3_NO_FALLBACK: "1" run: v -no-memory-limit -nocache -new-compiler vls/ - name: Compile project if: matrix.os == 'windows' + timeout-minutes: 15 run: v -nocache vls/