From 05b024bc21835f953ec82ef6c96cfc7257508114 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Wed, 8 Apr 2026 11:23:34 +0300
Subject: [PATCH v2] ci: Don't collect successful tests' logs

Add a Python script that removes subdirectories containing a test.success
file from a given testrun folder. This ensures that only failed tests'
logs are kept when uploading CI artifacts, reducing artifact size and
noise. This change affects only Meson CI builds as test.success file is
created only on Meson builds.
---
 .cirrus.tasks.yml                          | 32 ++++++++++++++
 meson.build                                |  4 ++
 src/tools/ci/ci_meson_clear_testrun_folder | 50 ++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100755 src/tools/ci/ci_meson_clear_testrun_folder

diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml
index a22cef063f3..476939a889b 100644
--- a/.cirrus.tasks.yml
+++ b/.cirrus.tasks.yml
@@ -157,6 +157,11 @@ task:
     EOF
 
   on_failure:
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      su postgres <<-EOF
+        meson compile clear_testrun_folder -C build
+      EOF
     <<: *on_failure_meson
     cores_script: |
       mkdir -m 770 /tmp/cores
@@ -274,6 +279,11 @@ task:
         set -e
         build/tmp_install/usr/local/pgsql/bin/pg_ctl -D build/runningcheck stop || true
       EOF
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      su postgres <<-EOF
+        meson compile clear_testrun_folder -C build
+      EOF
     <<: *on_failure_meson
     cores_script: src/tools/ci/cores_backtrace.sh freebsd /tmp/cores
 
@@ -389,6 +399,11 @@ task:
     EOF
 
   on_failure:
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      su postgres <<-EOF
+        meson compile clear_testrun_folder -C build
+      EOF
     <<: *on_failure_meson
     cores_script: |
       # Although we try to configure the OS to core dump inside
@@ -618,6 +633,13 @@ task:
         EOF
 
       on_failure:
+        # Remove logs of successful tests; keep only failed tests' logs for upload
+        meson_clear_testrun_folder_script: |
+          su postgres <<-EOF
+            # the build folder is removed if the failure is in the 32-bit build
+            [ -d build ] && meson compile clear_testrun_folder -C build
+            meson compile clear_testrun_folder -C build-32
+          EOF
         <<: *on_failure_meson
 
   on_failure:
@@ -738,6 +760,9 @@ task:
     meson test $MTEST_ARGS --num-processes ${TEST_JOBS}
 
   on_failure:
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      meson compile clear_testrun_folder -C build
     <<: *on_failure_meson
     cores_script: src/tools/ci/cores_backtrace.sh macos "${HOME}/cores"
 
@@ -818,6 +843,10 @@ task:
     meson test %MTEST_ARGS% --num-processes %TEST_JOBS%
 
   on_failure:
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      vcvarsall x64
+      meson compile clear_testrun_folder -C build
     <<: *on_failure_meson
     crashlog_artifacts:
       path: "crashlog-*.txt"
@@ -879,6 +908,9 @@ task:
     %BASH% -c "meson test %MTEST_ARGS% --num-processes %TEST_JOBS%"
 
   on_failure:
+    # Remove logs of successful tests; keep only failed tests' logs for upload
+    meson_clear_testrun_folder_script: |
+      %BASH% -c "meson compile clear_testrun_folder -C build"
     <<: *on_failure_meson
     crashlog_artifacts:
       path: "crashlog-*.txt"
diff --git a/meson.build b/meson.build
index be97e986e5d..3d4e33b2299 100644
--- a/meson.build
+++ b/meson.build
@@ -4134,6 +4134,10 @@ add_test_setup('tmp_install',
 add_test_setup('running',
   exclude_suites: ['setup'] + install_suites)
 
+clear_testrun_folder = files('src/tools/ci/ci_meson_clear_testrun_folder')
+run_target('clear_testrun_folder',
+  command: [python, clear_testrun_folder, test_result_dir]
+)
 
 
 ###############################################################
diff --git a/src/tools/ci/ci_meson_clear_testrun_folder b/src/tools/ci/ci_meson_clear_testrun_folder
new file mode 100755
index 00000000000..bb44066e1eb
--- /dev/null
+++ b/src/tools/ci/ci_meson_clear_testrun_folder
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+#
+# After a test run, each test that passed contains a test.success file in its
+# output directory. This script removes those directories so that only the logs
+# of failed tests remain, making it easier to inspect CI artifacts.
+#
+# Usage: ci_meson_clear_testrun_folder <path>
+#   e.g. ci_meson_clear_testrun_folder build/testrun
+
+import argparse
+import os
+import shutil
+import sys
+
+parser = argparse.ArgumentParser(
+    description="Remove subdirectories that contain a test.success file."
+)
+parser.add_argument(
+    "path",
+    help="Path to the directory to clear, e.g. 'build/testrun'",
+)
+args = parser.parse_args()
+
+testrun_dir = os.path.abspath(args.path)
+
+if not os.path.exists(testrun_dir):
+    print(f"Directory does not exist, nothing to do: {testrun_dir}")
+    sys.exit(0)
+
+if not os.path.isdir(testrun_dir):
+    print(f"Error: not a directory: {testrun_dir}")
+    sys.exit(1)
+
+print(f"Removing successful tests from {testrun_dir}:")
+for dirpath, dirnames, filenames in os.walk(testrun_dir):
+    if "test.success" in filenames:
+        print(f"Removing: {dirpath}")
+        shutil.rmtree(dirpath)
+        dirnames.clear()
+print("Done\n")
+
+print(f"Removing any empty directories from {testrun_dir}:")
+for dirpath, _, _ in os.walk(testrun_dir, topdown=False):
+    # Don't remove ${testrun_dir}
+    if dirpath == testrun_dir:
+        continue
+    if not os.listdir(dirpath):
+        print(f"Removing empty dir: {dirpath}")
+        os.rmdir(dirpath)
+print("Done\n")
-- 
2.47.3

