From 4a631fee36c2e4daece9af7ff31586678bbf8dac Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:27 +0100 Subject: [PATCH 1/7] ci: handle failures of test-slice helper The "run-test-slice.sh" script executes the test helper to slice up tests passed to it. As the execution is part of a pipe though, we end up ignoring any potential error code returned by the helper. Make the code more robust by storing the tests in a variable first so that we can split up the pipeline. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- ci/run-test-slice.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh index 0444c79c02..ff948e397f 100755 --- a/ci/run-test-slice.sh +++ b/ci/run-test-slice.sh @@ -5,9 +5,9 @@ . ${0%/*}/lib.sh -group "Run tests" make --quiet -C t T="$(cd t && - ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh | - tr '\n' ' ')" || +TESTS=$(cd t && ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh) + +group "Run tests" make --quiet -C t T="$(echo "$TESTS" | tr '\n' ' ')" || handle_failed_tests # We only have one unit test at the moment, so run it in the first slice From 3141df7ec44f5f2579fd839a6b5a457df109c5e6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:28 +0100 Subject: [PATCH 2/7] ci: don't skip smallest test slice in GitLab The "ci/run-test-slice.sh" script can be used to slice up all of our tests into N pieces and then run each of them on a separate CI job. This is used by both GitLab and GitHub CI to speed up Windows tests, which would otherwise be painfully slow. The infra itself is fueled by `test-tool path-utils slice-tests`. This tool receives as input an "offset" and a "stride" that can be combined to slice up tests. This framing can be misleading though: you are expected to pass a zero-based index as "offset", and the complete number of slices to the "stride". The latter makes sense, but it is somewhat surprising that the offset needs to be zero-based. And this is in fact biting us: while GitHub passes zero-based indices, GitLab passes `$CI_NODE_INDEX`, which is a one-based indice. Ideally, we should have verification that the parameters make sense. And naturally, one would for example expect that it's an error to call the binary with an offset larger than the stride. But with the current framing as "offset" it's not even wrong to do so, as it is of course well-defined to start at a larger offset than the stride. This means that we get this wrong on GitLab's CI, as we pass a one based index there, and this causes us to skip one of the tests. Interestingly, it's not the lexicographically first test that we skip. Instead, as we sort tests by size before slicing them, we skip the _smallest_ test. Reframe the problem to instead talk about "slice number" and "total number of slices". For all of our use cases this is semantically equivalent, but it allows us to perform some verifications: - The total number of slices must be greater than 1. - The selected slice must be between 1 <= nr <= slices_total. As the indices are now one-based it means that GitLab's CI is fixed. The GitHub workflow is updated accordingly. Helped-by: Johannes Schindelin Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- .github/workflows/main.yml | 4 ++-- t/helper/test-path-utils.c | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f2e93f5461..ec1a660981 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -150,7 +150,7 @@ jobs: - uses: git-for-windows/setup-git-for-windows-sdk@v1 - name: test shell: bash - run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 + run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10 - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' shell: bash @@ -237,7 +237,7 @@ jobs: shell: bash env: NO_SVN_TESTS: 1 - run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 + run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10 - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' shell: bash diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index f5f33751da..874542ec34 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -477,14 +477,20 @@ int cmd__path_utils(int argc, const char **argv) if (argc > 5 && !strcmp(argv[1], "slice-tests")) { int res = 0; - long offset, stride, i; + long slice, slices_total, i; struct string_list list = STRING_LIST_INIT_NODUP; struct stat st; - offset = strtol(argv[2], NULL, 10); - stride = strtol(argv[3], NULL, 10); - if (stride < 1) - stride = 1; + slices_total = strtol(argv[3], NULL, 10); + if (slices_total < 1) + die("there must be at least one slice, got '%s'", + argv[3]); + + slice = strtol(argv[2], NULL, 10); + if (1 > slice || slice > slices_total) + die("slice must be in the range 1 <= slice <= %ld, got '%s'", + slices_total, argv[2]); + for (i = 4; i < argc; i++) if (stat(argv[i], &st)) res = error_errno("Cannot stat '%s'", argv[i]); @@ -492,7 +498,7 @@ int cmd__path_utils(int argc, const char **argv) string_list_append(&list, argv[i])->util = (void *)(intptr_t)st.st_size; QSORT(list.items, list.nr, cmp_by_st_size); - for (i = offset; i < list.nr; i+= stride) + for (i = slice - 1; i < list.nr; i+= slices_total) printf("%s\n", list.items[i].string); return !!res; From 01b7be0d20afc9ac392d4b3906e471dea63df38d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:29 +0100 Subject: [PATCH 3/7] meson: fix MERGE_TOOL_DIR with "--no-bin-wrappers" On Windows, we execute tests with "--no-bin-wrappers". This has been introduced via a87e427e35 (ci: speed up Windows phase, 2019-01-29) to save some time: spawning processes is expensive on Windows, and shell scripts tend to spawn a bunch of them. So overall, the bin-wrappers led to a performance overhead of ~10-30%. This causes test failures when using Meson on Windows: failure: t7610.28 mergetool --tool-help shows recognized tools ++ git mergetool --tool-help /d/a/git/git/build/git-mergetool--lib: line 45: cd: D:/a/git/git/build/mergetools: No such file or directory The root cause here is that our bin-wrappers are usually responsible for setting up the `MERGE_TOOL_DIR` environment variable so that we can locate these scripts. But as we don't use the bin-wrappers, we'll instead use the default location for merge tools, which is derived from `GIT_EXEC_PATH`. And as `GIT_EXEC_PATH` points to our build directory, which won't ever contain any of the merge tools, we will fail to locate any of the merge tools. This issue has went unnoticed for a long time given that we only skip bin-wrappers on Windows, and because the CI jobs on Windows didn't execute due to a bug. Fix the issue by always setting the `MERGE_TOOL_DIR` environment variable to the correct directory. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- t/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/t/meson.build b/t/meson.build index 459c52a489..8537775c5b 100644 --- a/t/meson.build +++ b/t/meson.build @@ -1206,6 +1206,7 @@ endif test_environment = script_environment test_environment.set('GIT_BUILD_DIR', git_build_dir) +test_environment.set('MERGE_TOOLS_DIR', meson.project_source_root() / 'mergetools') foreach integration_test : integration_tests test(fs.stem(integration_test), shell, From 420b4ca2dce7143fcd79892393a879a1d8e276f7 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:30 +0100 Subject: [PATCH 4/7] github: fix Meson tests not executing at all While the win+Meson test jobs run in GitHub workflows, the shell script that is supposed to run the jobs is seemingly not running at all. All that the CI job prints is the following: Run ci/run-test-slice-meson.sh build 1 10 ci/run-test-slice-meson.sh build 1 10 shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" env: DEVELOPER: 1 The step is currently defined to use PowerShell, and of course it doesn't know how to execute POSIX shell scripts. What's surprising though is that this step doesn't even lead to a CI failure. Fix the issue by using Bash instead of PowerShell, as we do in other steps that execute shell scripts. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec1a660981..a011d8d0f9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -297,7 +297,7 @@ jobs: name: windows-meson-artifacts path: build - name: Test - shell: pwsh + shell: bash run: ci/run-test-slice-meson.sh build ${{matrix.nr}} 10 - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' From 2cca4ef34306c04a8ae891e0ea4a876922069dce Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:31 +0100 Subject: [PATCH 5/7] ci: make test slicing consistent across Meson/Make In the preceding commit we have adjusted test slicing to be one-based when using the "ci/run-test-slice.sh" script. But we also have an equivalent script for Meson that is still zero-based, which is of course inconsistent. Adapt the script to be one-based, as well, and adapt the GitHub workflow accordingly. Note that GitLab doesn't yet use the script, so it does not need to be adapted. This will change in the next commit though. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- .github/workflows/main.yml | 2 +- ci/run-test-slice-meson.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a011d8d0f9..826f2f5d3a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -298,7 +298,7 @@ jobs: path: build - name: Test shell: bash - run: ci/run-test-slice-meson.sh build ${{matrix.nr}} 10 + run: ci/run-test-slice-meson.sh build $((${{matrix.nr}} + 1)) 10 - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' shell: bash diff --git a/ci/run-test-slice-meson.sh b/ci/run-test-slice-meson.sh index 961c94fba0..a6df927ba5 100755 --- a/ci/run-test-slice-meson.sh +++ b/ci/run-test-slice-meson.sh @@ -9,5 +9,5 @@ group "Run tests" \ meson test -C "$1" --no-rebuild --print-errorlogs \ - --test-args="$GIT_TEST_OPTS" --slice "$((1+$2))/$3" || + --test-args="$GIT_TEST_OPTS" --slice "$(($2))/$3" || handle_failed_tests From 055f0b9f325e96d0692f0ee973c6298e303dc923 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:32 +0100 Subject: [PATCH 6/7] gitlab-ci: use "run-test-slice-meson.sh" While our GitHub workflow already uses "ci/run-test-slice-meson.sh", GitLab CI open-codes the parameters. Adapt the latter to also use the same script so that we always use the same Meson options across both CI systems. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b419a84e2c..04857b479d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -183,7 +183,8 @@ test:msvc-meson: - job: "build:msvc-meson" artifacts: true script: - - meson test -C build --no-rebuild --print-errorlogs --slice $Env:CI_NODE_INDEX/$Env:CI_NODE_TOTAL + - | + & "C:/Program Files/Git/usr/bin/bash.exe" -l -c 'ci/run-test-slice-meson.sh build $CI_NODE_INDEX $CI_NODE_TOTAL' parallel: 10 artifacts: reports: From 51338373928f47bfce2c345c97e753be67622ab6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 07:25:33 +0100 Subject: [PATCH 7/7] gitlab-ci: handle failed tests on MSVC+Meson job The MSVC+Meson job does not currently have any logic to print failing tests, nor does it upload the failed test artifacts. Backfill this logic to make help debugging efforts in case any of its jobs has failed. GitHub already knows to do this, so we don't need an equivalent change over there. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- .gitlab-ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 04857b479d..71b8a6e642 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -157,6 +157,8 @@ test:mingw64: parallel: 10 .msvc-meson: + variables: + TEST_OUTPUT_DIRECTORY: "C:/Git-Test" tags: - saas-windows-medium-amd64 before_script: @@ -164,12 +166,13 @@ test:mingw64: - choco install -y git meson ninja rust-ms - Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 - refreshenv + - New-Item -Path $env:TEST_OUTPUT_DIRECTORY -ItemType Directory build:msvc-meson: extends: .msvc-meson stage: build script: - - meson setup build --vsenv -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred + - meson setup build --vsenv -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred -Dtest_output_directory="$TEST_OUTPUT_DIRECTORY" - meson compile -C build artifacts: paths: @@ -185,10 +188,19 @@ test:msvc-meson: script: - | & "C:/Program Files/Git/usr/bin/bash.exe" -l -c 'ci/run-test-slice-meson.sh build $CI_NODE_INDEX $CI_NODE_TOTAL' + after_script: + - | + if ($env:CI_JOB_STATUS -ne "success") { + & "C:/Program Files/Git/usr/bin/bash.exe" -l -c 'ci/print-test-failures.sh' + Move-Item -Path "$env:TEST_OUTPUT_DIRECTORY/failed-test-artifacts" -Destination t/ + } parallel: 10 artifacts: + paths: + - t/failed-test-artifacts reports: junit: build/meson-logs/testlog.junit.xml + when: on_failure test:fuzz-smoke-tests: image: ubuntu:latest