From 96b63d1109f6009432c10e9882032142524792a2 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Thu, 5 Nov 2026 10:30:48 +0300
Subject: [PATCH v15 8/8] ci: Run compiler warning checks in parallel
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Use a GitHub Actions parallel step group for the CompilerWarnings job.

Give each configuration its own build directory and divide Ninja's job
count among the seven checks, with at least one job per check. Preserve
all build configurations and wait for every check before saving ccache
or uploading failure logs. Include the nested Meson log directories in
the uploaded artifacts.

Different methods are tested with cold and warm compiler caches on a
four-core GitHub-hosted runner. Total CompilerWarnings job times are:

                                           Cold       Warm
Default                                    20m 56s    3m 57s
Parallel configure, sequential builds      19m 47s    3m 04s
Pairs of checks, ninja -j 2                18m 10s    3m 49s
All checks in parallel, ninja -j 1         15m 26s    2m 30s
All checks in parallel, default ninja jobs 17m 03s    3m 48s

- Parallel configure, sequential builds: Configure all seven checks
  concurrently, then build them one at a time using Ninja’s default
  concurrency.

- Pairs of checks, ninja -j 2: Run configuration and build in three
  successive pairs with two Ninja jobs per check, then run the
  remaining header check alone with default concurrency.

- All checks in parallel, ninja -j 1: Run all seven configure/build
  sequences concurrently, limiting each Ninja invocation to one job.

- All checks in parallel, default Ninja jobs: Same as above but using
  Ninja's default concurrency.

Based on this result, 'all check in parallel, ninja -j 1' is selected.

Suggested-by: Andres Freund <andres@anarazel.de>
Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/CAN55FZ1BcWBsWgCCk2GQkYN6tzDxCw2hVK2m3qeiwaNXUnjLVg%40mail.gmail.com
---
 .github/workflows/pg-ci.yml | 214 ++++++++++++++++++++----------------
 1 file changed, 117 insertions(+), 97 deletions(-)

diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml
index 0497e9f207f..dafd9d14ebb 100644
--- a/.github/workflows/pg-ci.yml
+++ b/.github/workflows/pg-ci.yml
@@ -445,7 +445,7 @@ jobs:
               **/*.diffs
               **/regress_log_*
               **/crashlog-*.txt
-              build/meson-logs/**
+              build/**/meson-logs/**
               **/config.log
           if-no-files-found: ignore
 
@@ -1224,109 +1224,129 @@ jobs:
         -Dsystemd=enabled
         -Duuid=ossp
 
+      PARALLEL_CHECKS: 7
+
     steps:
       - *nix_sysinfo_step
       - *checkout_step
       - *ccache_restore_default_step
       - *ccache_restore_branch_step
 
-      # gcc, cassert off, dtrace on
-      - name: gcc warnings + (dtrace)
-        if: ${{ !cancelled() }}
-        env:
-          CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Ddtrace=enabled
-          CC: ccache gcc
-          CXX: ccache g++
-        run: &compiler_warnings_cmd |
-          echo "::group::configure"
-          rm -rf build
-          meson setup \
-            -Dwerror=true \
-            -Ddebug=false \
-            ${{env.CONF}} \
-            build
-          echo "::endgroup::"
-
-          ninja -C build --quiet ${{env.MBUILD_TARGET}}
-
-      # gcc, cassert on, dtrace off
-      - name: gcc warnings + (cassert)
-        if: ${{ !cancelled() }}
-        env:
-          CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Dcassert=true
-          CC: ccache gcc
-          CXX: ccache g++
-        run: *compiler_warnings_cmd
-
-      # clang, cassert off, dtrace off
-      - name: clang warnings
-        if: ${{ !cancelled() }}
-        env:
-          CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}}
-          CC: ccache clang
-          CXX: ccache clang++
-        run: *compiler_warnings_cmd
-
-      # clang, cassert on, dtrace on
-      - name: clang warnings + (cassert + dtrace)
-        if: ${{ !cancelled() }}
-        env:
-          CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Dcassert=true -Ddtrace=enabled
-          CC: ccache clang
-          CXX: ccache clang++
-        run: *compiler_warnings_cmd
-
-      - name: mingw warnings (cross compilation)
-        if: ${{ !cancelled() }}
-        env:
-          CONF: >-
-            --cross-file src/tools/ci/mingw-cross-file.txt
-            -Db_pch=true
-            -Dcassert=true
-            -Dauto_features=disabled
-            -Dzlib=enabled
-          MBUILD_TARGET: all
-        run: *compiler_warnings_cmd
-
-      ###
-      # Verify docs can be built
-      ###
-      # XXX: Only do this if there have been changes in doc/ since last build
-      - name: Build documentation
-        if: ${{ !cancelled() }}
-        env:
-          CONF: -Dauto_features=disabled -Ddocs=enabled
-          CC: ccache gcc
-          CXX: ccache g++
-          MBUILD_TARGET: docs
-        run: *compiler_warnings_cmd
-
-      ###
-      # Verify headerscheck / cpluspluscheck succeed
-      #
-      # - Run both in the same ninja invocation to increase parallelism, use
-      #   -k 0 to get the result of both
-      # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
-      ###
-      - name: headerscheck + cpluspluscheck
-        if: ${{ !cancelled() }}
-        env:
-          CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}}
-          CC: ccache gcc
-          CXX: ccache g++
-          EXTRAFLAGS: -fmax-errors=10
+      # Share the runner's CPUs between the seven parallel builds below,
+      # rather than letting each ninja invocation use all of them.
+      - name: Set build concurrency
         run: |
-          echo "::group::configure"
-          rm -rf build
-          meson setup \
-            -Dwerror=true \
-            -Ddebug=false \
-            ${{env.CONF}} \
-            build
-          echo "::endgroup::"
-
-          ninja -C build --quiet -k 0 \
-            headerscheck cpluspluscheck
+          jobs=$(( $(nproc) / $PARALLEL_CHECKS ))
+          if [ "$jobs" -lt 1 ]; then jobs=1; fi
+          echo "Ninja jobs per build: $jobs"
+          echo "NINJA_JOBS=$jobs" >> "$GITHUB_ENV"
+
+      # Each check needs its own build directory. The parallel group waits
+      # for all checks before the cache is saved and failure logs uploaded.
+      # Update PARALLEL_CHECKS when adding or removing a check.
+      - parallel:
+          # gcc, cassert off, dtrace on
+          - name: gcc warnings + (dtrace)
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/gcc-dtrace
+              CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Ddtrace=enabled
+              CC: ccache gcc
+              CXX: ccache g++
+            run: &compiler_warnings_cmd |
+              echo "::group::configure"
+              meson setup \
+                -Dwerror=true \
+                -Ddebug=false \
+                ${{env.CONF}} \
+                "$BUILD_DIR"
+              echo "::endgroup::"
+
+              ninja -C "$BUILD_DIR" --quiet -j "$NINJA_JOBS" ${{env.MBUILD_TARGET}}
+
+          # gcc, cassert on, dtrace off
+          - name: gcc warnings + (cassert)
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/gcc-cassert
+              CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Dcassert=true
+              CC: ccache gcc
+              CXX: ccache g++
+            run: *compiler_warnings_cmd
+
+          # clang, cassert off, dtrace off
+          - name: clang warnings
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/clang
+              CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}}
+              CC: ccache clang
+              CXX: ccache clang++
+            run: *compiler_warnings_cmd
+
+          # clang, cassert on, dtrace on
+          - name: clang warnings + (cassert + dtrace)
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/clang-cassert-dtrace
+              CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}} -Dcassert=true -Ddtrace=enabled
+              CC: ccache clang
+              CXX: ccache clang++
+            run: *compiler_warnings_cmd
+
+          - name: mingw warnings (cross compilation)
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/mingw
+              CONF: >-
+                --cross-file src/tools/ci/mingw-cross-file.txt
+                -Db_pch=true
+                -Dcassert=true
+                -Dauto_features=disabled
+                -Dzlib=enabled
+              MBUILD_TARGET: all
+            run: *compiler_warnings_cmd
+
+          ###
+          # Verify docs can be built
+          ###
+          # XXX: Only do this if there have been changes in doc/ since last build
+          - name: Build documentation
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/docs
+              CONF: -Dauto_features=disabled -Ddocs=enabled
+              CC: ccache gcc
+              CXX: ccache g++
+              MBUILD_TARGET: docs
+            run: *compiler_warnings_cmd
+
+          ###
+          # Verify headerscheck / cpluspluscheck succeed
+          #
+          # - Run both in the same ninja invocation to increase parallelism, use
+          #   -k 0 to get the result of both
+          # - Use -fmax-errors, as particularly cpluspluscheck can be very verbose
+          ###
+          - name: headerscheck + cpluspluscheck
+            if: ${{ !cancelled() }}
+            env:
+              BUILD_DIR: build/headers_cplusplus
+              CONF: ${{env.MESON_COMMON_FEATURES}} ${{env.MESON_FEATURES}}
+              CC: ccache gcc
+              CXX: ccache g++
+              EXTRAFLAGS: -fmax-errors=10
+            run: |
+              echo "::group::configure"
+              meson setup \
+                -Dwerror=true \
+                -Ddebug=false \
+                ${{env.CONF}} \
+                "$BUILD_DIR"
+              echo "::endgroup::"
+
+              ninja -C "$BUILD_DIR" --quiet -j "$NINJA_JOBS" -k 0 \
+                headerscheck cpluspluscheck
 
       - *ccache_decide_save_step
       - *ccache_save_step
-- 
2.47.3

