{"thread":{"id":"65020","subject":"[PATCH v2 1/7] ci: handle failures of test-slice helper","startedAt":"2026-02-19T06:25:36Z","lastAt":"2026-02-19T18:24:30Z","messageCount":9,"participants":["Patrick Steinhardt","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":7},"messages":[{"id":"536367","messageId":"20260219-b4-pks-ci-meson-improvements-v2-1-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 1/7] ci: handle failures of test-slice helper","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:27Z","receivedAt":"2026-02-19T06:25:36Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"run-test-slice.sh\" script executes the test helper to slice up\ntests passed to it. As the execution is part of a pipe though, we end up\nignoring any potential error code returned by the helper.\n\nMake the code more robust by storing the tests in a variable first so\nthat we can split up the pipeline.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n ci/run-test-slice.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh\nindex 0444c79c02..ff948e397f 100755\n--- a/ci/run-test-slice.sh\n+++ b/ci/run-test-slice.sh\n@@ -5,9 +5,9 @@\n \n . ${0%/*}/lib.sh\n \n-group \"Run tests\" make --quiet -C t T=\"$(cd t &&\n-\t./helper/test-tool path-utils slice-tests \"$1\" \"$2\" t[0-9]*.sh |\n-\ttr '\\n' ' ')\" ||\n+TESTS=$(cd t && ./helper/test-tool path-utils slice-tests \"$1\" \"$2\" t[0-9]*.sh)\n+\n+group \"Run tests\" make --quiet -C t T=\"$(echo \"$TESTS\" | tr '\\n' ' ')\" ||\n handle_failed_tests\n \n # We only have one unit test at the moment, so run it in the first slice\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536368","messageId":"20260219-b4-pks-ci-meson-improvements-v2-2-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 2/7] ci: don't skip smallest test slice in GitLab","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:28Z","receivedAt":"2026-02-19T06:25:38Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"ci/run-test-slice.sh\" script can be used to slice up all of our\ntests into N pieces and then run each of them on a separate CI job.\nThis is used by both GitLab and GitHub CI to speed up Windows tests,\nwhich would otherwise be painfully slow.\n\nThe infra itself is fueled by `test-tool path-utils slice-tests`. This\ntool receives as input an \"offset\" and a \"stride\" that can be combined\nto slice up tests. This framing can be misleading though: you are\nexpected to pass a zero-based index as \"offset\", and the complete number\nof slices to the \"stride\". The latter makes sense, but it is somewhat\nsurprising that the offset needs to be zero-based. And this is in fact\nbiting us: while GitHub passes zero-based indices, GitLab passes\n`$CI_NODE_INDEX`, which is a one-based indice.\n\nIdeally, we should have verification that the parameters make sense.\nAnd naturally, one would for example expect that it's an error to call\nthe binary with an offset larger than the stride. But with the current\nframing as \"offset\" it's not even wrong to do so, as it is of course\nwell-defined to start at a larger offset than the stride.\n\nThis means that we get this wrong on GitLab's CI, as we pass a one based\nindex there, and this causes us to skip one of the tests. Interestingly,\nit's not the lexicographically first test that we skip. Instead, as we\nsort tests by size before slicing them, we skip the _smallest_ test.\n\nReframe the problem to instead talk about \"slice number\" and \"total\nnumber of slices\". For all of our use cases this is semantically\nequivalent, but it allows us to perform some verifications:\n\n  - The total number of slices must be greater than 1.\n\n  - The selected slice must be between 1 <= nr <= slices_total.\n\nAs the indices are now one-based it means that GitLab's CI is fixed.\nThe GitHub workflow is updated accordingly.\n\nHelped-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml |  4 ++--\n t/helper/test-path-utils.c | 18 ++++++++++++------\n 2 files changed, 14 insertions(+), 8 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex f2e93f5461..ec1a660981 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -150,7 +150,7 @@ jobs:\n     - uses: git-for-windows/setup-git-for-windows-sdk@v1\n     - name: test\n       shell: bash\n-      run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10\n+      run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10\n     - name: print test failures\n       if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n       shell: bash\n@@ -237,7 +237,7 @@ jobs:\n       shell: bash\n       env:\n         NO_SVN_TESTS: 1\n-      run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10\n+      run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10\n     - name: print test failures\n       if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n       shell: bash\ndiff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c\nindex f5f33751da..874542ec34 100644\n--- a/t/helper/test-path-utils.c\n+++ b/t/helper/test-path-utils.c\n@@ -477,14 +477,20 @@ int cmd__path_utils(int argc, const char **argv)\n \n \tif (argc > 5 && !strcmp(argv[1], \"slice-tests\")) {\n \t\tint res = 0;\n-\t\tlong offset, stride, i;\n+\t\tlong slice, slices_total, i;\n \t\tstruct string_list list = STRING_LIST_INIT_NODUP;\n \t\tstruct stat st;\n \n-\t\toffset = strtol(argv[2], NULL, 10);\n-\t\tstride = strtol(argv[3], NULL, 10);\n-\t\tif (stride < 1)\n-\t\t\tstride = 1;\n+\t\tslices_total = strtol(argv[3], NULL, 10);\n+\t\tif (slices_total < 1)\n+\t\t\tdie(\"there must be at least one slice, got '%s'\",\n+\t\t\t    argv[3]);\n+\n+\t\tslice = strtol(argv[2], NULL, 10);\n+\t\tif (1 > slice || slice > slices_total)\n+\t\t\tdie(\"slice must be in the range 1 <= slice <= %ld, got '%s'\",\n+\t\t\t    slices_total, argv[2]);\n+\n \t\tfor (i = 4; i < argc; i++)\n \t\t\tif (stat(argv[i], &st))\n \t\t\t\tres = error_errno(\"Cannot stat '%s'\", argv[i]);\n@@ -492,7 +498,7 @@ int cmd__path_utils(int argc, const char **argv)\n \t\t\t\tstring_list_append(&list, argv[i])->util =\n \t\t\t\t\t(void *)(intptr_t)st.st_size;\n \t\tQSORT(list.items, list.nr, cmp_by_st_size);\n-\t\tfor (i = offset; i < list.nr; i+= stride)\n+\t\tfor (i = slice - 1; i < list.nr; i+= slices_total)\n \t\t\tprintf(\"%s\\n\", list.items[i].string);\n \n \t\treturn !!res;\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536369","messageId":"20260219-b4-pks-ci-meson-improvements-v2-4-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 4/7] github: fix Meson tests not executing at all","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:30Z","receivedAt":"2026-02-19T06:25:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"While the win+Meson test jobs run in GitHub workflows, the shell script\nthat is supposed to run the jobs is seemingly not running at all. All\nthat the CI job prints is the following:\n\n  Run ci/run-test-slice-meson.sh build 1 10\n    ci/run-test-slice-meson.sh build 1 10\n    shell: C:\\Program Files\\PowerShell\\7\\pwsh.EXE -command \". '{0}'\"\n    env:\n      DEVELOPER: 1\n\nThe step is currently defined to use PowerShell, and of course it\ndoesn't know how to execute POSIX shell scripts. What's surprising\nthough is that this step doesn't even lead to a CI failure.\n\nFix the issue by using Bash instead of PowerShell, as we do in other\nsteps that execute shell scripts.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex ec1a660981..a011d8d0f9 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -297,7 +297,7 @@ jobs:\n         name: windows-meson-artifacts\n         path: build\n     - name: Test\n-      shell: pwsh\n+      shell: bash\n       run: ci/run-test-slice-meson.sh build ${{matrix.nr}} 10\n     - name: print test failures\n       if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536370","messageId":"20260219-b4-pks-ci-meson-improvements-v2-3-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 3/7] meson: fix MERGE_TOOL_DIR with \"--no-bin-wrappers\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:29Z","receivedAt":"2026-02-19T06:25:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Windows, we execute tests with \"--no-bin-wrappers\". This has been\nintroduced via a87e427e35 (ci: speed up Windows phase, 2019-01-29) to\nsave some time: spawning processes is expensive on Windows, and shell\nscripts tend to spawn a bunch of them. So overall, the bin-wrappers led\nto a performance overhead of ~10-30%.\n\nThis causes test failures when using Meson on Windows:\n\n  failure: t7610.28 mergetool --tool-help shows recognized tools\n    ++ git mergetool --tool-help\n    /d/a/git/git/build/git-mergetool--lib: line 45: cd: D:/a/git/git/build/mergetools: No such file or directory\n\nThe root cause here is that our bin-wrappers are usually responsible for\nsetting up the `MERGE_TOOL_DIR` environment variable so that we can\nlocate these scripts. But as we don't use the bin-wrappers, we'll\ninstead use the default location for merge tools, which is derived from\n`GIT_EXEC_PATH`. And as `GIT_EXEC_PATH` points to our build directory,\nwhich won't ever contain any of the merge tools, we will fail to locate\nany of the merge tools.\n\nThis issue has went unnoticed for a long time given that we only skip\nbin-wrappers on Windows, and because the CI jobs on Windows didn't\nexecute due to a bug.\n\nFix the issue by always setting the `MERGE_TOOL_DIR` environment\nvariable to the correct directory.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/meson.build | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/t/meson.build b/t/meson.build\nindex 19e8306298..5ba7efd603 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -1208,6 +1208,7 @@ endif\n \n test_environment = script_environment\n test_environment.set('GIT_BUILD_DIR', git_build_dir)\n+test_environment.set('MERGE_TOOLS_DIR', meson.project_source_root() / 'mergetools')\n \n foreach integration_test : integration_tests\n   test(fs.stem(integration_test), shell,\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536371","messageId":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260211-b4-pks-ci-meson-improvements-v1-0-cb167cc80b86@pks.im","subject":"[PATCH v2 0/7] Some assorted fixes for GitLab CI","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:26Z","receivedAt":"2026-02-19T06:25:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nI recently had the pleasure of debugging a couple of failing\nMSVC+Windows jobs in GitLab CI, which hasn't been quite fun because we\ndidn't know to print error logs, and neither did we upload the failed\ntest artifacts. This patch series is the result of this frustration and\nfixes a couple of smaller issues in the context of our CI:\n\n  - I noticed that test slicing is slightly wrong because of a\n    difference between zero- and one-based indices, which causes us to\n    skip the first test on GitLab.\n\n  - I deduplicated how we run Meson tests so that both GitLab and GitHub\n    use the same \"run-test-slice-meson.sh\" script.\n\n  - I add logic to handle failing tests via \"print-test-failures.sh\".\n\nThe result can be found at [1]. Note that tests are failing, but those\nfailures are fixed in a separate patch series via [2]. In any case, I\nguess those test failures also serve as a good demonstration how the\nfailing tests show up now.\n\nChanges in v3:\n  - Correct a second invocation of \"ci/run-test-slice.sh\". I missed this\n    invocation, and because this job doesn't run by default I didn't\n    spot that it broke.\n  - Link to v1: https://lore.kernel.org/r/20260211-b4-pks-ci-meson-improvements-v1-0-cb167cc80b86@pks.im\n\nChanges in v2:\n  - Fix syntax in GitHub workflow.\n  - Add another patch on top that fixes win+Meson tests in GitHub. Those\n    tests didn't execute at all, even before this patch series.\n  - This uncovers another bug in how we set up MERGE_TOOLS_DIR, so this\n    results in another commit.\n  - I've now tested also tested the changes on GitHub [3].\n  - Link to v1: https://lore.kernel.org/r/20260209-b4-pks-ci-msvc-iconv-fixes-v1-0-1e3167cd8828@pks.im\n\nThanks!\n\nPatrick\n\n[1]: https://gitlab.com/gitlab-org/git/-/merge_requests/497\n[2]: <20260209-b4-pks-ci-msvc-iconv-fixes-v1-0-1e3167cd8828@pks.im>\n[3]: https://github.com/git/git/pull/2195\n\n---\nPatrick Steinhardt (7):\n      ci: handle failures of test-slice helper\n      ci: don't skip smallest test slice in GitLab\n      meson: fix MERGE_TOOL_DIR with \"--no-bin-wrappers\"\n      github: fix Meson tests not executing at all\n      ci: make test slicing consistent across Meson/Make\n      gitlab-ci: use \"run-test-slice-meson.sh\"\n      gitlab-ci: handle failed tests on MSVC+Meson job\n\n .github/workflows/main.yml |  8 ++++----\n .gitlab-ci.yml             | 17 +++++++++++++++--\n ci/run-test-slice-meson.sh |  2 +-\n ci/run-test-slice.sh       |  6 +++---\n t/helper/test-path-utils.c | 18 ++++++++++++------\n t/meson.build              |  1 +\n 6 files changed, 36 insertions(+), 16 deletions(-)\n\nRange-diff versus v1:\n\n1:  b5ad91e1bc = 1:  b55e0b145f ci: handle failures of test-slice helper\n2:  5bed073cfc ! 2:  fbdd1df05d ci: don't skip smallest test slice in GitLab\n    @@ Commit message\n         As the indices are now one-based it means that GitLab's CI is fixed.\n         The GitHub workflow is updated accordingly.\n     \n    +    Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n      ## .github/workflows/main.yml ##\n    @@ .github/workflows/main.yml: jobs:\n          - name: test\n            shell: bash\n     -      run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10\n    ++      run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10\n    +     - name: print test failures\n    +       if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n    +       shell: bash\n    +@@ .github/workflows/main.yml: jobs:\n    +       shell: bash\n    +       env:\n    +         NO_SVN_TESTS: 1\n    +-      run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10\n     +      run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10\n          - name: print test failures\n            if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n3:  6b061b829d = 3:  a5e411aade meson: fix MERGE_TOOL_DIR with \"--no-bin-wrappers\"\n4:  828147d641 = 4:  b7d868fc53 github: fix Meson tests not executing at all\n5:  05458adc6f = 5:  c9690b10a8 ci: make test slicing consistent across Meson/Make\n6:  49df181d3d = 6:  bee3a9d944 gitlab-ci: use \"run-test-slice-meson.sh\"\n7:  e7e9504c16 = 7:  ea1e1a4d87 gitlab-ci: handle failed tests on MSVC+Meson job\n\n---\nbase-commit: 3e0db84c88c57e70ac8be8c196dfa92c5d656fbc\nchange-id: 20260209-b4-pks-ci-meson-improvements-93d8a1ffdd27\n\n"},{"id":"536372","messageId":"20260219-b4-pks-ci-meson-improvements-v2-5-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 5/7] ci: make test slicing consistent across Meson/Make","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:31Z","receivedAt":"2026-02-19T06:25:46Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In the preceding commit we have adjusted test slicing to be one-based\nwhen using the \"ci/run-test-slice.sh\" script. But we also have an\nequivalent script for Meson that is still zero-based, which is of course\ninconsistent.\n\nAdapt the script to be one-based, as well, and adapt the GitHub workflow\naccordingly. Note that GitLab doesn't yet use the script, so it does not\nneed to be adapted. This will change in the next commit though.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml | 2 +-\n ci/run-test-slice-meson.sh | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex a011d8d0f9..826f2f5d3a 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -298,7 +298,7 @@ jobs:\n         path: build\n     - name: Test\n       shell: bash\n-      run: ci/run-test-slice-meson.sh build ${{matrix.nr}} 10\n+      run: ci/run-test-slice-meson.sh build $((${{matrix.nr}} + 1)) 10\n     - name: print test failures\n       if: failure() && env.FAILED_TEST_ARTIFACTS != ''\n       shell: bash\ndiff --git a/ci/run-test-slice-meson.sh b/ci/run-test-slice-meson.sh\nindex 961c94fba0..a6df927ba5 100755\n--- a/ci/run-test-slice-meson.sh\n+++ b/ci/run-test-slice-meson.sh\n@@ -9,5 +9,5 @@\n \n group \"Run tests\" \\\n \tmeson test -C \"$1\" --no-rebuild --print-errorlogs \\\n-\t\t--test-args=\"$GIT_TEST_OPTS\" --slice \"$((1+$2))/$3\" ||\n+\t\t--test-args=\"$GIT_TEST_OPTS\" --slice \"$(($2))/$3\" ||\n handle_failed_tests\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536373","messageId":"20260219-b4-pks-ci-meson-improvements-v2-6-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 6/7] gitlab-ci: use \"run-test-slice-meson.sh\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:32Z","receivedAt":"2026-02-19T06:25:49Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"While our GitHub workflow already uses \"ci/run-test-slice-meson.sh\",\nGitLab CI open-codes the parameters. Adapt the latter to also use the\nsame script so that we always use the same Meson options across both CI\nsystems.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitlab-ci.yml | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex b419a84e2c..04857b479d 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -183,7 +183,8 @@ test:msvc-meson:\n     - job: \"build:msvc-meson\"\n       artifacts: true\n   script:\n-    - meson test -C build --no-rebuild --print-errorlogs --slice $Env:CI_NODE_INDEX/$Env:CI_NODE_TOTAL\n+    - |\n+      & \"C:/Program Files/Git/usr/bin/bash.exe\" -l -c 'ci/run-test-slice-meson.sh build $CI_NODE_INDEX $CI_NODE_TOTAL'\n   parallel: 10\n   artifacts:\n     reports:\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536374","messageId":"20260219-b4-pks-ci-meson-improvements-v2-7-6047b8307ab2@pks.im","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"[PATCH v2 7/7] gitlab-ci: handle failed tests on MSVC+Meson job","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-19T06:25:33Z","receivedAt":"2026-02-19T06:25:52Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The MSVC+Meson job does not currently have any logic to print failing\ntests, nor does it upload the failed test artifacts. Backfill this logic\nto make help debugging efforts in case any of its jobs has failed.\n\nGitHub already knows to do this, so we don't need an equivalent change\nover there.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitlab-ci.yml | 14 +++++++++++++-\n 1 file changed, 13 insertions(+), 1 deletion(-)\n\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex 04857b479d..71b8a6e642 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -157,6 +157,8 @@ test:mingw64:\n   parallel: 10\n \n .msvc-meson:\n+  variables:\n+    TEST_OUTPUT_DIRECTORY: \"C:/Git-Test\"\n   tags:\n     - saas-windows-medium-amd64\n   before_script:\n@@ -164,12 +166,13 @@ test:mingw64:\n     - choco install -y git meson ninja rust-ms\n     - Import-Module $env:ChocolateyInstall\\helpers\\chocolateyProfile.psm1\n     - refreshenv\n+    - New-Item -Path $env:TEST_OUTPUT_DIRECTORY -ItemType Directory\n \n build:msvc-meson:\n   extends: .msvc-meson\n   stage: build\n   script:\n-    - meson setup build --vsenv -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred\n+    - meson setup build --vsenv -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred -Dtest_output_directory=\"$TEST_OUTPUT_DIRECTORY\"\n     - meson compile -C build\n   artifacts:\n     paths:\n@@ -185,10 +188,19 @@ test:msvc-meson:\n   script:\n     - |\n       & \"C:/Program Files/Git/usr/bin/bash.exe\" -l -c 'ci/run-test-slice-meson.sh build $CI_NODE_INDEX $CI_NODE_TOTAL'\n+  after_script:\n+    - |\n+      if ($env:CI_JOB_STATUS -ne \"success\") {\n+        & \"C:/Program Files/Git/usr/bin/bash.exe\" -l -c 'ci/print-test-failures.sh'\n+        Move-Item -Path \"$env:TEST_OUTPUT_DIRECTORY/failed-test-artifacts\" -Destination t/\n+      }\n   parallel: 10\n   artifacts:\n+    paths:\n+      - t/failed-test-artifacts\n     reports:\n       junit: build/meson-logs/testlog.junit.xml\n+    when: on_failure\n \n test:fuzz-smoke-tests:\n   image: ubuntu:latest\n\n-- \n2.53.0.414.gf7e9f6c205.dirty\n\n"},{"id":"536429","messageId":"xmqqldgo617o.fsf@gitster.g","threadId":"65020","inReplyTo":"20260219-b4-pks-ci-meson-improvements-v2-0-6047b8307ab2@pks.im","subject":"Re: [PATCH v2 0/7] Some assorted fixes for GitLab CI","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-19T18:24:27Z","receivedAt":"2026-02-19T18:24:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Changes in v3:\n>   - Correct a second invocation of \"ci/run-test-slice.sh\". I missed this\n>     invocation, and because this job doesn't run by default I didn't\n>     spot that it broke.\n>   - Link to v1: https://lore.kernel.org/r/20260211-b4-pks-ci-meson-improvements-v1-0-cb167cc80b86@pks.im\n\nThanks, all.  Let's mark the topic for 'next'.\n\n"}]}