This is an automated email from the ASF dual-hosted git repository.

hgruszecki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new 93d7f8970 ci: split post-merge monolith and harden Codecov uploads 
(#3006)
93d7f8970 is described below

commit 93d7f8970862cdf729aa49b5baa14f6839a6f363
Author: Hubert Gruszecki <[email protected]>
AuthorDate: Wed Mar 25 09:31:56 2026 +0100

    ci: split post-merge monolith and harden Codecov uploads (#3006)
---
 .github/actions/rust/pre-merge/action.yml          |   3 +
 .github/workflows/_test.yml                        |   1 +
 .../{post-merge.yml => coverage-baseline.yml}      | 262 ++---------
 .github/workflows/edge-release.yml                 | 123 +++++
 .github/workflows/post-merge.yml                   | 506 +--------------------
 .github/workflows/pre-merge.yml                    |   4 +
 codecov.yml                                        |  29 +-
 7 files changed, 199 insertions(+), 729 deletions(-)

diff --git a/.github/actions/rust/pre-merge/action.yml 
b/.github/actions/rust/pre-merge/action.yml
index 4edcd1f91..d1d07138d 100644
--- a/.github/actions/rust/pre-merge/action.yml
+++ b/.github/actions/rust/pre-merge/action.yml
@@ -146,6 +146,9 @@ runs:
         if command -v cargo-nextest &> /dev/null; then
           cargo nextest run --locked --no-fail-fast $PARTITION_FLAG
         else
+          if [[ -n "$PARTITION_FLAG" ]]; then
+            echo "::error::cargo-nextest not found, falling back to cargo test 
without partitioning (all tests will run on every partition)"
+          fi
           cargo test --locked --no-fail-fast
         fi
         test_end=$(date +%s)
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
index 6fd50003e..ac3eb6ca7 100644
--- a/.github/workflows/_test.yml
+++ b/.github/workflows/_test.yml
@@ -68,6 +68,7 @@ jobs:
         with:
           token: ${{ secrets.CODECOV_TOKEN }}
           files: codecov.json
+          disable_search: true
           flags: rust
           fail_ci_if_error: false
           verbose: true
diff --git a/.github/workflows/post-merge.yml 
b/.github/workflows/coverage-baseline.yml
similarity index 62%
copy from .github/workflows/post-merge.yml
copy to .github/workflows/coverage-baseline.yml
index 18c16eeba..8fe98cde7 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/coverage-baseline.yml
@@ -15,166 +15,27 @@
 # specific language governing permissions and limitations
 # under the License.
 
-name: Post-merge
+# Full coverage baseline for all 6 languages (Rust, Java, C#, Python,
+# Node, Go). Runs on every push to master so Codecov has complete data
+# for carryforward on PR builds where only a subset of SDKs is tested.
+
+name: Coverage baseline
 
 on:
   push:
     branches: [master]
 
 permissions:
-  contents: write
-  packages: write
-  id-token: write
+  contents: read
 
 concurrency:
-  group: post-merge-${{ github.ref }}
-  cancel-in-progress: false
+  group: coverage-baseline-${{ github.ref }}
+  cancel-in-progress: true
 
 env:
   IGGY_CI_BUILD: true
 
 jobs:
-  check-auto-publish:
-    name: Check auto-publish
-    runs-on: ubuntu-latest
-    if: ${{ !github.event.repository.fork }}
-    outputs:
-      docker_components: ${{ steps.check.outputs.docker_components }}
-      crates_to_publish: ${{ steps.check.outputs.crates_to_publish }}
-      sdks_to_publish: ${{ steps.check.outputs.sdks_to_publish }}
-    steps:
-      - uses: actions/checkout@v4
-        with:
-          fetch-depth: 0
-
-      - name: Setup yq
-        run: |
-          if ! command -v yq >/dev/null 2>&1; then
-            YQ_VERSION="v4.47.1"
-            
YQ_CHECKSUM="0fb28c6680193c41b364193d0c0fc4a03177aecde51cfc04d506b1517158c2fb"
-            curl -sSL -o /usr/local/bin/yq 
https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64
-            echo "${YQ_CHECKSUM}  /usr/local/bin/yq" | sha256sum -c - || exit 1
-            chmod +x /usr/local/bin/yq
-          fi
-
-      - name: Check all components
-        id: check
-        run: |
-          chmod +x scripts/extract-version.sh
-
-          # Get all Docker components (always publish :edge)
-          DOCKER_COMPONENTS=$(yq -r '.components | to_entries | .[] | 
select(.value.registry == "dockerhub") | .key' .github/config/publish.yml | tr 
'\n' ',' | sed 's/,$//')
-          echo "docker_components=$DOCKER_COMPONENTS" >> "$GITHUB_OUTPUT"
-          echo "Docker components: $DOCKER_COMPONENTS"
-
-          # Check Rust crates for pre-release versions without tags
-          CRATES_TO_PUBLISH=""
-          for crate in rust-common rust-binary-protocol rust-sdk rust-cli; do
-            VERSION=$(scripts/extract-version.sh "$crate")
-            TAG=$(scripts/extract-version.sh "$crate" --tag)
-
-            echo "Checking $crate: version=$VERSION, tag=$TAG"
-
-            if [[ ! "$VERSION" =~ -(edge|rc) ]]; then
-              echo "  ⏭️ Stable version - skipping"
-              continue
-            fi
-
-            if git rev-parse "$TAG" >/dev/null 2>&1; then
-              echo "  ⏭️ Tag exists - skipping"
-              continue
-            fi
-
-            echo "  ✅ Will publish"
-            CRATES_TO_PUBLISH="${CRATES_TO_PUBLISH:+$CRATES_TO_PUBLISH,}$crate"
-          done
-          echo "crates_to_publish=$CRATES_TO_PUBLISH" >> "$GITHUB_OUTPUT"
-          echo "Crates to publish: ${CRATES_TO_PUBLISH:-<none>}"
-
-          # Check SDKs for pre-release versions without tags
-          SDKS_TO_PUBLISH=""
-          for sdk in sdk-python sdk-node sdk-java sdk-csharp sdk-go; do
-            VERSION=$(scripts/extract-version.sh "$sdk")
-            TAG=$(scripts/extract-version.sh "$sdk" --tag)
-
-            echo "Checking $sdk: version=$VERSION, tag=$TAG"
-
-            # Maven SNAPSHOT versions are mutable -- republish when SDK 
sources change,
-            # skip tag gate since no tag will be created for SNAPSHOTs
-            if [[ "$VERSION" =~ -SNAPSHOT$ ]]; then
-              SDK_NAME="${sdk#sdk-}"
-              SDK_DIR="foreign/$SDK_NAME"
-              if ! git diff --name-only HEAD~1 HEAD -- "$SDK_DIR/" | grep -q 
.; then
-                echo "  ⏭️ SNAPSHOT - no changes in $SDK_DIR/"
-                continue
-              fi
-              echo "  ✅ SNAPSHOT version - will publish"
-              SDKS_TO_PUBLISH="${SDKS_TO_PUBLISH:+$SDKS_TO_PUBLISH,}$SDK_NAME"
-              continue
-            fi
-
-            if [[ ! "$VERSION" =~ -(edge|rc) ]] && [[ ! "$VERSION" =~ 
(\.dev|rc)[0-9]+$ ]]; then
-              echo "  ⏭️ Stable version - skipping"
-              continue
-            fi
-
-            if git rev-parse "$TAG" >/dev/null 2>&1; then
-              echo "  ⏭️ Tag exists - skipping"
-              continue
-            fi
-
-            echo "  ✅ Will publish"
-            # Convert sdk-csharp to csharp for publish.yml input format
-            SDK_NAME="${sdk#sdk-}"
-            SDKS_TO_PUBLISH="${SDKS_TO_PUBLISH:+$SDKS_TO_PUBLISH,}$SDK_NAME"
-          done
-          echo "sdks_to_publish=$SDKS_TO_PUBLISH" >> "$GITHUB_OUTPUT"
-          echo "SDKs to publish: ${SDKS_TO_PUBLISH:-<none>}"
-
-  call-publish:
-    name: Publish components
-    needs: check-auto-publish
-    uses: ./.github/workflows/publish.yml
-    with:
-      commit: ${{ github.sha }}
-      dry_run: false
-      use_latest_ci: false
-      skip_tag_creation: false
-      publish_crates: ${{ needs.check-auto-publish.outputs.crates_to_publish }}
-      publish_dockerhub: ${{ 
needs.check-auto-publish.outputs.docker_components }}
-      publish_other: ${{ needs.check-auto-publish.outputs.sdks_to_publish }}
-      create_edge_docker_tag: true
-    secrets: inherit
-
-  warm-cache:
-    name: Warm cache (${{ matrix.runner }})
-    runs-on: ${{ matrix.runner }}
-    strategy:
-      fail-fast: false
-      matrix:
-        # Don't cache ubuntu-24.04-arm due to size
-        runner: [ubuntu-latest, macos-14]
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "true"
-
-      - name: Build
-        run: cargo build --locked
-
-      - name: Compile tests
-        run: cargo test --no-run --locked
-
-  build-artifacts:
-    name: Build artifacts
-    uses: ./.github/workflows/_build_rust_artifacts.yml
-    with:
-      version: edge
-      upload_artifacts: true
-
   rust-coverage:
     name: Rust coverage baseline
     runs-on: ubuntu-latest
@@ -194,6 +55,7 @@ jobs:
       - name: Setup Rust with cache
         uses: ./.github/actions/utils/setup-rust-with-cache
         with:
+          # Also warms the GitHub Actions build cache for subsequent PR builds
           save-cache: "true"
 
       - name: Install cargo-llvm-cov
@@ -216,11 +78,7 @@ jobs:
           eval $(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)
           echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
 
-          if command -v cargo-nextest &> /dev/null; then
-            cargo nextest run --locked --no-fail-fast
-          else
-            cargo test --locked --no-fail-fast
-          fi
+          cargo test --locked --no-fail-fast
         shell: bash
 
       - name: Generate coverage report
@@ -234,6 +92,7 @@ jobs:
         with:
           token: ${{ secrets.CODECOV_TOKEN }}
           files: codecov.json
+          disable_search: true
           flags: rust
           fail_ci_if_error: false
 
@@ -547,11 +406,24 @@ jobs:
       - name: Merge coverage profiles
         run: |
           mkdir -p reports
+          if [[ ! -s reports/go-coverage-unit.out ]]; then
+            echo "::warning::Unit coverage profile is empty or missing"
+            if [[ -s reports/go-coverage-bdd.out ]]; then
+              cp reports/go-coverage-bdd.out reports/go-coverage.out
+            else
+              echo "::warning::Both unit and BDD coverage profiles are empty 
or missing, no coverage will be uploaded"
+            fi
+            exit 0
+          fi
           # Start with the mode line from the unit profile
           head -1 reports/go-coverage-unit.out > reports/go-coverage.out
           # Append data lines (skip mode line) from both profiles
           tail -n +2 reports/go-coverage-unit.out >> reports/go-coverage.out
-          tail -n +2 reports/go-coverage-bdd.out >> reports/go-coverage.out
+          if [[ -s reports/go-coverage-bdd.out ]]; then
+            tail -n +2 reports/go-coverage-bdd.out >> reports/go-coverage.out
+          else
+            echo "::warning::BDD coverage profile is empty or missing, using 
unit coverage only"
+          fi
 
       - name: Stop Iggy server
         if: always()
@@ -569,82 +441,20 @@ jobs:
           flags: go
           fail_ci_if_error: false
 
-  create-prerelease:
-    name: Create edge pre-release
-    runs-on: ubuntu-latest
-    needs: build-artifacts
-    if: needs.build-artifacts.result == 'success' && 
!github.event.repository.fork
-    permissions:
-      contents: write
+  warm-cache-macos:
+    name: Warm macOS cache
+    runs-on: macos-14
+    timeout-minutes: 30
     steps:
       - uses: actions/checkout@v4
 
-      - name: Get server version
-        id: meta
-        run: |
-          chmod +x scripts/extract-version.sh
-          server_version=$(scripts/extract-version.sh rust-server)
-          echo "server_version=${server_version}" >> "$GITHUB_OUTPUT"
-
-      - name: Download all artifacts
-        uses: actions/download-artifact@v4
+      - name: Setup Rust with cache
+        uses: ./.github/actions/utils/setup-rust-with-cache
         with:
-          name: rust-artifacts-all
-          path: ./artifacts
+          save-cache: "true"
 
-      - name: Delete existing edge release and tag
-        env:
-          GH_TOKEN: ${{ github.token }}
-        run: |
-          if gh release view edge &>/dev/null; then
-            echo "Deleting existing edge release and tag..."
-            gh release delete edge --cleanup-tag --yes || echo "Delete failed, 
continuing..."
-          fi
+      - name: Build
+        run: cargo build --locked
 
-      - name: Create edge pre-release
-        uses: softprops/action-gh-release@v2
-        with:
-          tag_name: edge
-          name: edge
-          draft: false
-          prerelease: true
-          make_latest: false
-          files: artifacts/*.tar.gz
-          body: |
-            Rolling edge build of Apache Iggy binaries and connector plugins.
-
-            **This release is automatically updated on every push to master.**
-
-            ## Binaries included
-            - `iggy-server` - The server binary
-            - `iggy` - The command-line interface
-            - `iggy-bench` - The benchmarking tool
-            - `iggy-connectors` - The connectors runtime
-
-            ## Connector plugins included (.so)
-            - `iggy_connector_elasticsearch_sink`
-            - `iggy_connector_elasticsearch_source`
-            - `iggy_connector_iceberg_sink`
-            - `iggy_connector_postgres_sink`
-            - `iggy_connector_postgres_source`
-            - `iggy_connector_quickwit_sink`
-            - `iggy_connector_random_source`
-            - `iggy_connector_stdout_sink`
-
-            ## Downloads
-
-            ### Binaries
-            - `iggy-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux x86_64 
(glibc)
-            - `iggy-x86_64-unknown-linux-musl-edge.tar.gz` - Linux x86_64 
(musl, static)
-            - `iggy-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux ARM64 
(glibc)
-            - `iggy-aarch64-unknown-linux-musl-edge.tar.gz` - Linux ARM64 
(musl, static)
-
-            ### Connector plugins
-            - `iggy-connectors-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux 
x86_64 (glibc)
-            - `iggy-connectors-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux 
ARM64 (glibc)
-
-            ## Build info
-            - Server version: ${{ steps.meta.outputs.server_version }}
-            - Commit: ${{ github.sha }}
-
-            **Not an official ASF release** - for development/testing only.
+      - name: Compile tests
+        run: cargo test --no-run --locked
diff --git a/.github/workflows/edge-release.yml 
b/.github/workflows/edge-release.yml
new file mode 100644
index 000000000..0cbc6e151
--- /dev/null
+++ b/.github/workflows/edge-release.yml
@@ -0,0 +1,123 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Builds cross-platform binaries and connector plugins, then publishes
+# them as a rolling "edge" GitHub pre-release updated on every master push.
+
+name: Edge release
+
+on:
+  push:
+    branches: [master]
+
+permissions:
+  contents: read
+
+concurrency:
+  group: edge-release-${{ github.ref }}
+  cancel-in-progress: true
+
+env:
+  IGGY_CI_BUILD: true
+
+jobs:
+  build-artifacts:
+    name: Build artifacts
+    uses: ./.github/workflows/_build_rust_artifacts.yml
+    with:
+      version: edge
+      upload_artifacts: true
+
+  create-prerelease:
+    name: Create edge pre-release
+    runs-on: ubuntu-latest
+    needs: build-artifacts
+    if: needs.build-artifacts.result == 'success' && 
!github.event.repository.fork
+    permissions:
+      contents: write
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Get server version
+        id: meta
+        run: |
+          chmod +x scripts/extract-version.sh
+          server_version=$(scripts/extract-version.sh rust-server)
+          echo "server_version=${server_version}" >> "$GITHUB_OUTPUT"
+
+      - name: Download all artifacts
+        uses: actions/download-artifact@v4
+        with:
+          name: rust-artifacts-all
+          path: ./artifacts
+
+      - name: Delete existing edge release and tag
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          if gh release view edge &>/dev/null; then
+            echo "Deleting existing edge release and tag..."
+            gh release delete edge --cleanup-tag --yes || echo "Delete failed, 
continuing..."
+          fi
+
+      - name: Create edge pre-release
+        uses: 
softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+        with:
+          tag_name: edge
+          name: edge
+          draft: false
+          prerelease: true
+          make_latest: false
+          files: artifacts/*.tar.gz
+          body: |
+            Rolling edge build of Apache Iggy binaries and connector plugins.
+
+            **This release is automatically updated on every push to master.**
+
+            ## Binaries included
+            - `iggy-server` - The server binary
+            - `iggy` - The command-line interface
+            - `iggy-bench` - The benchmarking tool
+            - `iggy-connectors` - The connectors runtime
+
+            ## Connector plugins included (.so)
+            - `iggy_connector_elasticsearch_sink`
+            - `iggy_connector_elasticsearch_source`
+            - `iggy_connector_iceberg_sink`
+            - `iggy_connector_postgres_sink`
+            - `iggy_connector_postgres_source`
+            - `iggy_connector_quickwit_sink`
+            - `iggy_connector_random_source`
+            - `iggy_connector_stdout_sink`
+
+            ## Downloads
+
+            ### Binaries
+            - `iggy-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux x86_64 
(glibc)
+            - `iggy-x86_64-unknown-linux-musl-edge.tar.gz` - Linux x86_64 
(musl, static)
+            - `iggy-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux ARM64 
(glibc)
+            - `iggy-aarch64-unknown-linux-musl-edge.tar.gz` - Linux ARM64 
(musl, static)
+
+            ### Connector plugins
+            - `iggy-connectors-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux 
x86_64 (glibc)
+            - `iggy-connectors-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux 
ARM64 (glibc)
+
+            ## Build info
+            - Server version: ${{ steps.meta.outputs.server_version }}
+            - Commit: ${{ github.sha }}
+
+            **Not an official ASF release** - for development/testing only.
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index 18c16eeba..9f49334f0 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -15,6 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
+# Auto-publish: detects pre-release crate/SDK versions without tags
+# and publishes them to crates.io, Docker Hub, PyPI, npm, Maven, NuGet.
+# Runs on every push to master.
+
 name: Post-merge
 
 on:
@@ -146,505 +150,3 @@ jobs:
       create_edge_docker_tag: true
     secrets: inherit
 
-  warm-cache:
-    name: Warm cache (${{ matrix.runner }})
-    runs-on: ${{ matrix.runner }}
-    strategy:
-      fail-fast: false
-      matrix:
-        # Don't cache ubuntu-24.04-arm due to size
-        runner: [ubuntu-latest, macos-14]
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "true"
-
-      - name: Build
-        run: cargo build --locked
-
-      - name: Compile tests
-        run: cargo test --no-run --locked
-
-  build-artifacts:
-    name: Build artifacts
-    uses: ./.github/workflows/_build_rust_artifacts.yml
-    with:
-      version: edge
-      upload_artifacts: true
-
-  rust-coverage:
-    name: Rust coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 45
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Cleanup disk space
-        run: sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc 
/opt/hostedtoolcache/CodeQL
-
-      - name: Install system dependencies
-        run: |
-          sudo apt-get update --yes
-          sudo apt-get install --yes gnome-keyring keyutils dbus-x11 
libsecret-tools
-          rm -f $HOME/.local/share/keyrings/*
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "true"
-
-      - name: Install cargo-llvm-cov
-        uses: taiki-e/install-action@v2
-        with:
-          tool: cargo-llvm-cov
-
-      - name: Build and test with coverage
-        run: |
-          source <(cargo llvm-cov show-env --export-prefix)
-          cargo build --locked
-          cargo test --locked --no-run
-
-          # Start D-Bus and unlock keyring right before test execution to avoid
-          # gnome-keyring auto-locking the collection during the build phase.
-          # Previously this ran before `cargo build`, leaving a 7+ minute idle
-          # window that triggered org.freedesktop.Secret.Error.IsLocked ~10% 
of runs.
-          eval $(dbus-launch --sh-syntax)
-          export DBUS_SESSION_BUS_ADDRESS
-          eval $(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)
-          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
-
-          if command -v cargo-nextest &> /dev/null; then
-            cargo nextest run --locked --no-fail-fast
-          else
-            cargo test --locked --no-fail-fast
-          fi
-        shell: bash
-
-      - name: Generate coverage report
-        run: |
-          source <(cargo llvm-cov show-env --export-prefix)
-          cargo llvm-cov report --codecov --output-path codecov.json
-        shell: bash
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: codecov.json
-          flags: rust
-          fail_ci_if_error: false
-
-  java-coverage:
-    name: Java coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 30
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Java with cache
-        uses: ./.github/actions/utils/setup-java-with-cache
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "false"
-
-      - name: Start Iggy server
-        id: iggy
-        uses: ./.github/actions/utils/server-start
-
-      - name: Run tests and generate coverage
-        working-directory: foreign/java
-        env:
-          USE_EXTERNAL_SERVER: true
-        run: |
-          ./gradlew test
-          ./gradlew jacocoAggregatedReport
-
-      - name: Stop Iggy server
-        if: always()
-        uses: ./.github/actions/utils/server-stop
-        with:
-          pid-file: ${{ steps.iggy.outputs.pid_file }}
-          log-file: ${{ steps.iggy.outputs.log_file }}
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: 
foreign/java/build/reports/jacoco/aggregate/jacocoAggregated.xml
-          disable_search: true
-          flags: java
-          fail_ci_if_error: false
-
-  csharp-coverage:
-    name: C# coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 30
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup .NET
-        uses: actions/setup-dotnet@v4
-        with:
-          dotnet-version: "10.0.x"
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "false"
-
-      - name: Build Iggy server Docker image
-        id: docker_build
-        uses: ./.github/actions/utils/docker-build-test-server
-        with:
-          image-tag: "iggy-server:test"
-          libc: "glibc"
-          profile: "debug"
-
-      - name: Restore and build
-        working-directory: foreign/csharp
-        run: |
-          dotnet restore Iggy_SDK.sln
-          dotnet build Iggy_SDK.sln --no-restore
-
-      - name: Run unit tests with coverage
-        working-directory: foreign/csharp
-        run: |
-          dotnet test \
-            --project Iggy_SDK_Tests \
-            --no-build \
-            --verbosity normal \
-            --coverage \
-            --coverage-output-format cobertura \
-            --coverage-output coverage.cobertura.xml \
-            --results-directory ./reports/unit
-
-      - name: Run integration tests with coverage
-        working-directory: foreign/csharp
-        env:
-          IGGY_SERVER_DOCKER_IMAGE: ${{ 
steps.docker_build.outputs.docker_image }}
-        run: |
-          dotnet test \
-            --project Iggy_SDK.Tests.Integration \
-            --no-build \
-            --verbosity normal \
-            --coverage \
-            --coverage-output-format cobertura \
-            --coverage-output coverage.cobertura.xml \
-            --results-directory ./reports/integration
-
-      - name: Merge coverage reports
-        working-directory: foreign/csharp
-        run: |
-          dotnet tool install --global dotnet-coverage
-          dotnet-coverage merge ./reports/**/*.cobertura.xml -f cobertura -o 
./reports/coverage.cobertura.xml
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: foreign/csharp/reports/coverage.cobertura.xml
-          disable_search: true
-          flags: csharp
-          fail_ci_if_error: false
-
-  python-coverage:
-    name: Python coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 30
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Python
-        uses: actions/setup-python@v5
-        with:
-          python-version: "3.10"
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "false"
-
-      - name: Install cargo-llvm-cov
-        uses: taiki-e/install-action@v2
-        with:
-          tool: cargo-llvm-cov
-
-      - name: Install uv
-        uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # 
v7.3.1
-
-      - name: Install dependencies
-        run: |
-          cd foreign/python
-          uv sync --frozen --extra dev --extra testing --extra testing-docker
-
-      - name: Build Python wheel with coverage instrumentation
-        run: |
-          cd foreign/python
-          source <(cargo llvm-cov show-env --sh)
-          export CARGO_TARGET_DIR=$CARGO_LLVM_COV_TARGET_DIR
-
-          # Propagate LLVM_PROFILE_FILE so the test step can write profraw data
-          echo "LLVM_PROFILE_FILE=${LLVM_PROFILE_FILE}" >> $GITHUB_ENV
-
-          cargo llvm-cov clean --workspace
-          echo "Building Python wheel with coverage instrumentation..."
-          uv run --no-sync maturin develop
-        shell: bash
-
-      - name: Start Iggy server
-        id: iggy
-        uses: ./.github/actions/utils/server-start
-
-      - name: Run tests
-        run: |
-          cd foreign/python
-          IGGY_SERVER_HOST=127.0.0.1 \
-          IGGY_SERVER_TCP_PORT=8090 \
-            uv run --no-sync pytest tests/ -v \
-              --junitxml=../../reports/python-junit.xml \
-              --tb=short \
-              --capture=no
-
-      - name: Stop Iggy server
-        if: always()
-        uses: ./.github/actions/utils/server-stop
-        with:
-          pid-file: ${{ steps.iggy.outputs.pid_file }}
-          log-file: ${{ steps.iggy.outputs.log_file }}
-
-      - name: Generate coverage report
-        run: |
-          mkdir -p reports
-          cd foreign/python
-          source <(cargo llvm-cov show-env --sh)
-          export CARGO_TARGET_DIR=$CARGO_LLVM_COV_TARGET_DIR
-
-          cargo llvm-cov report --lcov \
-            --ignore-filename-regex='(\.cargo/|/rustc/|/core/)' \
-            --output-path ../../reports/python-coverage.lcov
-
-          # Fix paths: cargo-llvm-cov outputs paths relative to the crate root 
(src/...)
-          # but Codecov expects paths relative to the repo root 
(foreign/python/src/...)
-          sed -i 's|^SF:src/|SF:foreign/python/src/|' 
../../reports/python-coverage.lcov
-
-          echo "Coverage report generated: $(wc -l < 
../../reports/python-coverage.lcov) lines"
-        shell: bash
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: reports/python-coverage.lcov
-          disable_search: true
-          flags: python
-          fail_ci_if_error: false
-
-  node-coverage:
-    name: Node coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 30
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: "23"
-          cache: "npm"
-          cache-dependency-path: foreign/node/package-lock.json
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "false"
-
-      - name: Install netcat
-        run: sudo apt-get update && sudo apt-get install -y netcat-openbsd
-
-      - name: Install dependencies
-        run: |
-          cd foreign/node
-          npm ci --ignore-scripts
-
-      - name: Start Iggy server
-        id: iggy
-        uses: ./.github/actions/utils/server-start
-        env:
-          IGGY_CLUSTER_ENABLED: true
-
-      - name: Run unit tests with coverage
-        run: |
-          cd foreign/node
-          mkdir -p ../../reports/node-coverage/unit
-          npx c8 --reporter=lcov 
--reports-dir=../../reports/node-coverage/unit npm run test:unit
-
-      - name: Run e2e tests with coverage
-        run: |
-          cd foreign/node
-          mkdir -p ../../reports/node-coverage/e2e
-          npx c8 --reporter=lcov --reports-dir=../../reports/node-coverage/e2e 
npm run test:e2e
-        env:
-          IGGY_SERVER_HOST: 127.0.0.1
-          IGGY_SERVER_TCP_PORT: 8090
-
-      - name: Stop Iggy server
-        if: always()
-        uses: ./.github/actions/utils/server-stop
-        with:
-          pid-file: ${{ steps.iggy.outputs.pid_file }}
-          log-file: ${{ steps.iggy.outputs.log_file }}
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: 
reports/node-coverage/unit/lcov.info,reports/node-coverage/e2e/lcov.info
-          disable_search: true
-          flags: node
-          fail_ci_if_error: false
-
-  go-coverage:
-    name: Go coverage baseline
-    runs-on: ubuntu-latest
-    timeout-minutes: 30
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Go
-        uses: ./.github/actions/utils/setup-go-with-cache
-
-      - name: Setup Rust with cache
-        uses: ./.github/actions/utils/setup-rust-with-cache
-        with:
-          save-cache: "false"
-
-      - name: Start Iggy server
-        id: iggy
-        uses: ./.github/actions/utils/server-start
-
-      - name: Run unit tests with coverage
-        run: |
-          cd foreign/go
-          mkdir -p ../../reports
-          go test -v -race -coverprofile=../../reports/go-coverage-unit.out 
./...
-
-      - name: Run BDD tests with coverage
-        run: |
-          cd bdd/go
-          mkdir -p ../../reports
-          # Run only tcp_test suite (ginkgo); godog leader_redirection
-          # tests require a multi-node cluster not available in CI.
-          go test -v -race \
-            -coverpkg=github.com/apache/iggy/foreign/go/... \
-            -coverprofile=../../reports/go-coverage-bdd.out \
-            ./tests/tcp_test/...
-
-      - name: Merge coverage profiles
-        run: |
-          mkdir -p reports
-          # Start with the mode line from the unit profile
-          head -1 reports/go-coverage-unit.out > reports/go-coverage.out
-          # Append data lines (skip mode line) from both profiles
-          tail -n +2 reports/go-coverage-unit.out >> reports/go-coverage.out
-          tail -n +2 reports/go-coverage-bdd.out >> reports/go-coverage.out
-
-      - name: Stop Iggy server
-        if: always()
-        uses: ./.github/actions/utils/server-stop
-        with:
-          pid-file: ${{ steps.iggy.outputs.pid_file }}
-          log-file: ${{ steps.iggy.outputs.log_file }}
-
-      - name: Upload to Codecov
-        uses: codecov/codecov-action@v5
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-          files: reports/go-coverage.out
-          disable_search: true
-          flags: go
-          fail_ci_if_error: false
-
-  create-prerelease:
-    name: Create edge pre-release
-    runs-on: ubuntu-latest
-    needs: build-artifacts
-    if: needs.build-artifacts.result == 'success' && 
!github.event.repository.fork
-    permissions:
-      contents: write
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Get server version
-        id: meta
-        run: |
-          chmod +x scripts/extract-version.sh
-          server_version=$(scripts/extract-version.sh rust-server)
-          echo "server_version=${server_version}" >> "$GITHUB_OUTPUT"
-
-      - name: Download all artifacts
-        uses: actions/download-artifact@v4
-        with:
-          name: rust-artifacts-all
-          path: ./artifacts
-
-      - name: Delete existing edge release and tag
-        env:
-          GH_TOKEN: ${{ github.token }}
-        run: |
-          if gh release view edge &>/dev/null; then
-            echo "Deleting existing edge release and tag..."
-            gh release delete edge --cleanup-tag --yes || echo "Delete failed, 
continuing..."
-          fi
-
-      - name: Create edge pre-release
-        uses: softprops/action-gh-release@v2
-        with:
-          tag_name: edge
-          name: edge
-          draft: false
-          prerelease: true
-          make_latest: false
-          files: artifacts/*.tar.gz
-          body: |
-            Rolling edge build of Apache Iggy binaries and connector plugins.
-
-            **This release is automatically updated on every push to master.**
-
-            ## Binaries included
-            - `iggy-server` - The server binary
-            - `iggy` - The command-line interface
-            - `iggy-bench` - The benchmarking tool
-            - `iggy-connectors` - The connectors runtime
-
-            ## Connector plugins included (.so)
-            - `iggy_connector_elasticsearch_sink`
-            - `iggy_connector_elasticsearch_source`
-            - `iggy_connector_iceberg_sink`
-            - `iggy_connector_postgres_sink`
-            - `iggy_connector_postgres_source`
-            - `iggy_connector_quickwit_sink`
-            - `iggy_connector_random_source`
-            - `iggy_connector_stdout_sink`
-
-            ## Downloads
-
-            ### Binaries
-            - `iggy-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux x86_64 
(glibc)
-            - `iggy-x86_64-unknown-linux-musl-edge.tar.gz` - Linux x86_64 
(musl, static)
-            - `iggy-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux ARM64 
(glibc)
-            - `iggy-aarch64-unknown-linux-musl-edge.tar.gz` - Linux ARM64 
(musl, static)
-
-            ### Connector plugins
-            - `iggy-connectors-x86_64-unknown-linux-gnu-edge.tar.gz` - Linux 
x86_64 (glibc)
-            - `iggy-connectors-aarch64-unknown-linux-gnu-edge.tar.gz` - Linux 
ARM64 (glibc)
-
-            ## Build info
-            - Server version: ${{ steps.meta.outputs.server_version }}
-            - Commit: ${{ github.sha }}
-
-            **Not an official ASF release** - for development/testing only.
diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml
index a3a976780..abbaa30ed 100644
--- a/.github/workflows/pre-merge.yml
+++ b/.github/workflows/pre-merge.yml
@@ -15,6 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
+# PR gate: detects changed components, builds test matrices, and runs
+# lint/test/build/compat/BDD/examples jobs only for affected languages.
+# All jobs must pass before merge.
+
 name: Pre-merge
 on:
   pull_request:
diff --git a/codecov.yml b/codecov.yml
index 6320624d0..77a1dfc53 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -66,8 +66,35 @@ flag_management:
       paths:
         - foreign/go/
 
+component_management:
+  individual_components:
+    - component_id: rust
+      name: Rust Core
+      paths:
+        - core/
+    - component_id: java
+      name: Java SDK
+      paths:
+        - foreign/java/
+    - component_id: csharp
+      name: "C# SDK"
+      paths:
+        - foreign/csharp/
+    - component_id: python
+      name: Python SDK
+      paths:
+        - foreign/python/
+    - component_id: node
+      name: Node SDK
+      paths:
+        - foreign/node/
+    - component_id: go
+      name: Go SDK
+      paths:
+        - foreign/go/
+
 comment:
-  layout: "header, diff, flags, files"
+  layout: "header, diff, components, files"
   behavior: default
   require_changes: true
   require_base: true


Reply via email to