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

hubcio 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 1e693b6d4 ci(php): add SDK coverage report (#3408)
1e693b6d4 is described below

commit 1e693b6d4621983897002db0386a220eadf99438
Author: WaterWhisperer <[email protected]>
AuthorDate: Fri Jun 5 15:54:57 2026 +0800

    ci(php): add SDK coverage report (#3408)
---
 .github/actions/php/pre-merge/action.yml           | 58 ++++++++++++++++++++--
 .../actions/python-maturin/pre-merge/action.yml    |  1 +
 .github/actions/rust/pre-merge/action.yml          |  1 +
 .github/workflows/_test.yml                        | 12 +++++
 .github/workflows/coverage-baseline.yml            | 26 +++++++++-
 codecov.yml                                        | 17 +++++--
 scripts/ci/validate-lcov.sh                        | 46 +++++++++++++++++
 7 files changed, 151 insertions(+), 10 deletions(-)

diff --git a/.github/actions/php/pre-merge/action.yml 
b/.github/actions/php/pre-merge/action.yml
index 698dd3ec2..9f4b117ce 100644
--- a/.github/actions/php/pre-merge/action.yml
+++ b/.github/actions/php/pre-merge/action.yml
@@ -65,6 +65,12 @@ runs:
       shell: bash
       run: echo "CARGO_TARGET_DIR=${GITHUB_WORKSPACE}/target" >> "$GITHUB_ENV"
 
+    - name: Install cargo-llvm-cov
+      if: inputs.task == 'test'
+      uses: taiki-e/install-action@v2
+      with:
+        tool: cargo-llvm-cov
+
     - name: Validate task
       shell: bash
       run: |
@@ -120,7 +126,14 @@ runs:
       if: inputs.task == 'test'
       shell: bash
       run: |
-        cargo build --manifest-path foreign/php/Cargo.toml
+        cd foreign/php
+        source <(cargo llvm-cov show-env --sh)
+        export CARGO_TARGET_DIR=$CARGO_LLVM_COV_TARGET_DIR
+
+        echo "LLVM_PROFILE_FILE=${LLVM_PROFILE_FILE}" >> "$GITHUB_ENV"
+
+        cargo llvm-cov clean --workspace
+        cargo build --manifest-path Cargo.toml
         extension="$(find "${CARGO_TARGET_DIR}/debug" -maxdepth 1 -name 
'libiggy_php.so' -print -quit)"
         if [ -z "$extension" ]; then
           echo "PHP extension was not produced"
@@ -150,7 +163,9 @@ runs:
         IGGY_PORT: 8090
         IGGY_USERNAME: iggy
         IGGY_PASSWORD: iggy
-      run: ./scripts/test.sh
+      run: |
+        mkdir -p ../../reports
+        ./scripts/test.sh --log-junit ../../reports/php-junit.xml
 
     - name: Stop Iggy server (plain)
       if: always() && inputs.task == 'test'
@@ -180,7 +195,32 @@ runs:
         IGGY_PORT: 8090
         IGGY_TLS_CONNECTION_STRING: 
iggy+tcp://iggy:[email protected]:8090?tls=true&tls_domain=localhost&tls_ca_file=${{
 github.workspace }}/core/certs/iggy_ca_cert.pem
         IGGY_TLS_PLAINTEXT_ADDRESS: 127.0.0.1:8090
-      run: ./scripts/test.sh tests/TlsTest.php
+      run: ./scripts/test.sh --log-junit ../../reports/php-tls-junit.xml 
tests/TlsTest.php
+
+    - name: Generate PHP coverage report
+      if: always() && inputs.task == 'test'
+      shell: bash
+      run: |
+        cd foreign/php
+        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/php-coverage.lcov
+
+        repo_root="$(git rev-parse --show-toplevel)"
+
+        # Fix paths: cargo-llvm-cov can output paths relative to the crate 
root (src/...)
+        # or absolute repo paths (.../foreign/php/src/...), but Codecov 
expects repo-root
+        # paths (foreign/php/src/...).
+        sed -i \
+          -e "s|^SF:${repo_root}/foreign/php/src/|SF:foreign/php/src/|" \
+          -e 's|^SF:src/|SF:foreign/php/src/|' \
+          ../../reports/php-coverage.lcov
+
+        echo "Coverage report generated: $(wc -l < 
../../reports/php-coverage.lcov) lines"
+        ../../scripts/ci/validate-lcov.sh ../../reports/php-coverage.lcov
 
     - name: Stop Iggy server (TLS)
       if: always() && inputs.task == 'test'
@@ -188,3 +228,15 @@ runs:
       with:
         pid-file: ${{ steps.iggy-tls.outputs.pid_file }}
         log-file: ${{ steps.iggy-tls.outputs.log_file }}
+
+    - name: Upload test artifacts
+      if: always() && inputs.task == 'test'
+      uses: actions/upload-artifact@v7
+      with:
+        name: php-test-results-${{ github.run_id }}-${{ github.run_attempt }}
+        path: |
+          reports/php-junit.xml
+          reports/php-tls-junit.xml
+          reports/php-coverage.lcov
+        retention-days: 7
+        if-no-files-found: ignore
diff --git a/.github/actions/python-maturin/pre-merge/action.yml 
b/.github/actions/python-maturin/pre-merge/action.yml
index 0eacd0587..25409e5ac 100644
--- a/.github/actions/python-maturin/pre-merge/action.yml
+++ b/.github/actions/python-maturin/pre-merge/action.yml
@@ -182,6 +182,7 @@ runs:
         sed -i 's|^SF:src/|SF:foreign/python/src/|' 
../../reports/python-coverage.lcov
 
         echo "Coverage report generated: $(wc -l < 
../../reports/python-coverage.lcov) lines"
+        ../../scripts/ci/validate-lcov.sh ../../reports/python-coverage.lcov
       shell: bash
 
     - name: Upload test artifacts
diff --git a/.github/actions/rust/pre-merge/action.yml 
b/.github/actions/rust/pre-merge/action.yml
index c7388b909..9e8d06fe0 100644
--- a/.github/actions/rust/pre-merge/action.yml
+++ b/.github/actions/rust/pre-merge/action.yml
@@ -33,6 +33,7 @@ runs:
     - name: Setup Rust with cache
       uses: ./.github/actions/utils/setup-rust-with-cache
       with:
+        read-cache: ${{ inputs.task == 'sort' && 'false' || 'true' }}
         # Miri builds against a nightly toolchain with a separate `target/miri`
         # subtree; isolate its cache from the stable `dev` namespace so the
         # two don't evict each other.
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
index 58c5e8d8b..7f4cc9bef 100644
--- a/.github/workflows/_test.yml
+++ b/.github/workflows/_test.yml
@@ -104,6 +104,18 @@ jobs:
         with:
           task: ${{ inputs.task }}
 
+      - name: Upload PHP coverage to Codecov
+        if: inputs.component == 'sdk-php' && inputs.task == 'test'
+        uses: codecov/codecov-action@v6
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
+          files: reports/php-coverage.lcov
+          disable_search: true
+          flags: php
+          fail_ci_if_error: false
+          verbose: true
+          override_pr: ${{ github.event.pull_request.number }}
+
       # Node SDK
       - name: Run Node SDK task
         if: inputs.component == 'sdk-node'
diff --git a/.github/workflows/coverage-baseline.yml 
b/.github/workflows/coverage-baseline.yml
index ccfd8f51a..42e2c8379 100644
--- a/.github/workflows/coverage-baseline.yml
+++ b/.github/workflows/coverage-baseline.yml
@@ -15,8 +15,8 @@
 # specific language governing permissions and limitations
 # under the License.
 
-# Full coverage baseline for all 6 languages (Rust, Java, C#, Python,
-# Node, Go). Runs on every push to master so Codecov has complete data
+# Full coverage baseline for all 7 languages (Rust, Java, C#, Python,
+# PHP, 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
@@ -297,6 +297,7 @@ jobs:
           sed -i 's|^SF:src/|SF:foreign/python/src/|' 
../../reports/python-coverage.lcov
 
           echo "Coverage report generated: $(wc -l < 
../../reports/python-coverage.lcov) lines"
+          ../../scripts/ci/validate-lcov.sh ../../reports/python-coverage.lcov
         shell: bash
 
       - name: Upload to Codecov
@@ -308,6 +309,27 @@ jobs:
           flags: python
           fail_ci_if_error: false
 
+  php-coverage:
+    name: PHP coverage baseline
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Run PHP SDK tests with coverage
+        uses: ./.github/actions/php/pre-merge
+        with:
+          task: test
+
+      - name: Upload to Codecov
+        uses: codecov/codecov-action@v6
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
+          files: reports/php-coverage.lcov
+          disable_search: true
+          flags: php
+          fail_ci_if_error: false
+
   node-coverage:
     name: Node coverage baseline
     runs-on: ubuntu-latest
diff --git a/codecov.yml b/codecov.yml
index 77a1dfc53..cf5bd5534 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -59,6 +59,9 @@ flag_management:
     - name: python
       paths:
         - foreign/python/
+    - name: php
+      paths:
+        - foreign/php/
     - name: node
       paths:
         - foreign/node/
@@ -69,11 +72,11 @@ flag_management:
 component_management:
   individual_components:
     - component_id: rust
-      name: Rust Core
+      name: "Rust Core"
       paths:
         - core/
     - component_id: java
-      name: Java SDK
+      name: "Java SDK"
       paths:
         - foreign/java/
     - component_id: csharp
@@ -81,15 +84,19 @@ component_management:
       paths:
         - foreign/csharp/
     - component_id: python
-      name: Python SDK
+      name: "Python SDK"
       paths:
         - foreign/python/
+    - component_id: php
+      name: "PHP SDK"
+      paths:
+        - foreign/php/
     - component_id: node
-      name: Node SDK
+      name: "Node SDK"
       paths:
         - foreign/node/
     - component_id: go
-      name: Go SDK
+      name: "Go SDK"
       paths:
         - foreign/go/
 
diff --git a/scripts/ci/validate-lcov.sh b/scripts/ci/validate-lcov.sh
new file mode 100755
index 000000000..558a5acc2
--- /dev/null
+++ b/scripts/ci/validate-lcov.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euo pipefail
+
+if [ "$#" -ne 1 ]; then
+  echo "Usage: $0 <lcov-file>"
+  exit 2
+fi
+
+lcov_file="$1"
+
+if [ ! -s "$lcov_file" ]; then
+  echo "LCOV report is missing or empty: $lcov_file"
+  exit 1
+fi
+
+source_file_count="$(grep -c '^SF:' "$lcov_file" || true)"
+line_data_count="$(grep -c '^DA:' "$lcov_file" || true)"
+
+if [ "$source_file_count" -eq 0 ]; then
+  echo "LCOV report has no source file records: $lcov_file"
+  exit 1
+fi
+
+if [ "$line_data_count" -eq 0 ]; then
+  echo "LCOV report has no line data records: $lcov_file"
+  exit 1
+fi
+
+echo "LCOV report valid: $lcov_file (${source_file_count} SF, 
${line_data_count} DA)"

Reply via email to