From b9312158d06ee339b50cd49958966dcdaeca2a5f Mon Sep 17 00:00:00 2001 From: imbajin Date: Wed, 14 Oct 2026 12:38:37 +0800 Subject: [PATCH 1/4] fix(ci): preserve selectively collected coverage - flag each coverage upload and enable native carryforward - show historical coverage explicitly in Codecov comments - remove the completed required-check migration bridge - clarify actual backend checks and baseline initialization --- .github/scripts/test_ci_policy.py | 24 ------------- .github/workflows/commons-ci.yml | 1 + .github/workflows/pd-store-ci.yml | 3 ++ .github/workflows/server-ci.yml | 34 ------------------- .github/workflows/server-tests.yml | 3 +- codecov.yml | 22 ++++++++++++ docs/ci.md | 24 +++++++++---- .../travis/test-codecov-upload-config.sh | 6 +++- 8 files changed, 51 insertions(+), 66 deletions(-) create mode 100644 codecov.yml diff --git a/.github/scripts/test_ci_policy.py b/.github/scripts/test_ci_policy.py index a60486ebec..a5e9e5301c 100644 --- a/.github/scripts/test_ci_policy.py +++ b/.github/scripts/test_ci_policy.py @@ -346,30 +346,6 @@ def test_real_coordinator_blocks_selection_runtime_failure_and_cancellation(self self.assertEqual({"helm"}, self.coordinator_jobs(full, java=state, result="failure")) self.assertEqual(set(), self.coordinator_jobs(full, cancelled=True)) - def test_legacy_memory_bridge_requires_real_results_and_retires_without_a_runner(self): - docs = self.plan_for(["README.md"]) - self.assertEqual(set(), self.coordinator_jobs(docs)) - docs["legacy_memory_required"] = True - self.assertEqual({"legacy-server-memory"}, self.coordinator_jobs(docs)) - self.assertEqual(set(), self.coordinator_jobs(docs, cancelled=True)) - workflow = (Path(__file__).resolve().parents[1] / "workflows/server-ci.yml").read_text() - bridge = re.search(r"^ legacy-server-memory:\n(.*?)(?=^ [\w-]+:|\Z)", workflow, re.M | re.S).group(1) - self.assertEqual("Server memory tests", re.search(r"^ name: (.+)$", bridge, re.M).group(1)) - script = textwrap.dedent(bridge.split(" run: |\n", 1)[1]) - cases = [("success", "true", "success", "success", True), - ("success", "false", "success", "skipped", True), - ("failure", "false", "success", "skipped", False), - ("success", "", "success", "skipped", False), - ("success", "true", "failure", "skipped", False)] - cases += [("success", "true", "success", result, False) - for result in ["failure", "cancelled", "skipped", ""]] - for selection, selected, java, memory, passes in cases: - with self.subTest(selection=selection, selected=selected, java=java, memory=memory): - result = subprocess.run(["bash", "-eo", "pipefail", "-c", script], capture_output=True, - env={**os.environ, "SELECTION_RESULT": selection, "SERVER_SELECTED": selected, - "JAVA_RESULT": java, "MEMORY_RESULT": memory}) - self.assertEqual(passes, result.returncode == 0, result.stderr) - def test_contract_scripts_reach_their_actual_inner_jobs_and_steps(self): workflows = Path(__file__).resolve().parents[1] / "workflows" cases = [("test-stop-hugegraph-store.sh", {"struct"}), diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml index d84c937af4..74087946bd 100644 --- a/.github/workflows/commons-ci.yml +++ b/.github/workflows/commons-ci.yml @@ -63,5 +63,6 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: hugegraph-commons/target/jacoco.xml + flags: commons disable_search: true fail_ci_if_error: false diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index 00adccfe64..ff53b0f5d4 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -310,6 +310,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ${{ env.REPORT_FILE }} + flags: pd disable_search: true fail_ci_if_error: false @@ -512,6 +513,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ${{ env.REPORT_FILE }} + flags: store disable_search: true fail_ci_if_error: false @@ -835,5 +837,6 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ${{ env.REPORT_DIR }}/*.xml + flags: hstore disable_search: true fail_ci_if_error: false diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index d27a83774e..f21f1f73a1 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -35,7 +35,6 @@ jobs: selection_result: ${{ steps.select.outcome }} java_result: ${{ steps.java.outcome }} java_versions: ${{ steps.java.outputs.versions }} - legacy_memory_required: ${{ steps.migration.outputs.required }} server: ${{ steps.select.outputs.server }} commons: ${{ steps.select.outputs.commons }} struct: ${{ steps.select.outputs.struct }} @@ -96,18 +95,6 @@ jobs: retention-days: 7 overwrite: true - - name: Check legacy required context - id: migration - if: ${{ !cancelled() && github.event_name == 'pull_request' && steps.checkout.outcome == 'success' }} - env: - GH_TOKEN: ${{ github.token }} - BASE_REF: ${{ github.event.pull_request.base.ref }} - run: | - BASE_REF=$(python3 -c 'import os, urllib.parse; print(urllib.parse.quote(os.environ["BASE_REF"], safe=""))') - REQUIRED=$(gh api "repos/$GITHUB_REPOSITORY/branches/$BASE_REF" \ - --jq '.protection.required_status_checks.contexts // [] | index("Server memory tests") != null') - echo "required=$REQUIRED" >> "$GITHUB_OUTPUT" - - name: Test CI policy and deployment checks if: ${{ !cancelled() && steps.checkout.outcome == 'success' }} run: python3 -m unittest discover -s .github/scripts -p 'test_*.py' @@ -145,27 +132,6 @@ jobs: java-versions: ${{ needs.preflight.outputs.java_versions }} secrets: inherit - legacy-server-memory: - name: Server memory tests - needs: [preflight, build-server] - if: ${{ !cancelled() && needs.preflight.outputs.legacy_memory_required == 'true' }} - runs-on: ubuntu-slim - timeout-minutes: 5 - env: - SELECTION_RESULT: ${{ needs.preflight.outputs.selection_result }} - SERVER_SELECTED: ${{ needs.preflight.outputs.server }} - JAVA_RESULT: ${{ needs.preflight.outputs.java_result }} - MEMORY_RESULT: ${{ needs.build-server.result }} - steps: - - name: Verify the selected Memory result during protection migration - run: | - test "$SELECTION_RESULT" = success - case "$SERVER_SELECTED" in - true) test "$JAVA_RESULT" = success && test "$MEMORY_RESULT" = success ;; - false) test "$MEMORY_RESULT" = skipped ;; - *) exit 1 ;; - esac - commons: needs: preflight if: ${{ !cancelled() && needs.preflight.outputs.selection_result == 'success' && needs.preflight.outputs.java_result == 'success' && needs.preflight.outputs.commons == 'true' }} diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index f86d0904bb..b4c65de874 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -15,7 +15,7 @@ permissions: jobs: build-server: - name: server_${{ inputs.backend }} (Java ${{ matrix.JAVA_VERSION }}) + name: Server ${{ inputs.backend }} tests (Java ${{ matrix.JAVA_VERSION }}) runs-on: ubuntu-24.04 env: USE_STAGE: 'false' # Whether to include the stage repository. @@ -204,6 +204,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ${{ env.REPORT_DIR }}/*.xml,hugegraph-server/target/site/jacoco/jacoco.xml + flags: server_${{ inputs.backend }} disable_search: true fail_ci_if_error: false diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000000..b359fe93cc --- /dev/null +++ b/codecov.yml @@ -0,0 +1,22 @@ +# 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. + +# Keep coverage from unexecuted test groups in affected-input CI reports. +flag_management: + default_rules: + carryforward: true + +comment: + show_carryforward_flags: true diff --git a/docs/ci.md b/docs/ci.md index a6dd9fc1e5..a262c4a164 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -11,11 +11,23 @@ is merged and synchronized by Gitbox; verify live protection then. Failed tests real failed results. Valid selection and Java outputs allow selected tests to run even when the preflight license checks fail. -For migration, preflight keeps the existing `check-license` check name on the same runner. -A temporary `Server memory tests` check verifies the selected Memory result while live protection -still requires that name. It uses one lightweight `ubuntu-slim` runner and repeats no tests. -After Gitbox applies the new configuration, this bridge skips without allocating a runner; -no Infra intervention or change to review protection is needed. +Preflight keeps its real `check-license` name. The temporary `Server memory tests` +protection bridge has been removed after confirming both ASF and org master required +contexts are empty. Actual backend jobs are named `Server memory tests (Java ...)` +and `Server rocksdb tests (Java ...)`; their native checks report real execution. + +## Coverage with selective tests + +Each coverage upload has a stable test-group flag. [Codecov carryforward](https://docs.codecov.com/docs/carryforward-flags) +preserves the last flagged report for unexecuted groups, so skipping unchanged Commons, +PD/Store or backend checks does not remove their previous data from project totals. +The PR comment explicitly marks carried-forward data. It is historical coverage, +not evidence that a skipped test ran; native job failures remain failures. + +New flags need a complete initial baseline. After rollout, the existing weekly full run +on master supplies every flagged group; before that baseline exists, the project report +may still be incomplete. Full and selected runs retain explicit report paths and uploads. +No extra coverage collector runner or unrelated backend run is added for ordinary PRs. ## What runs @@ -85,7 +97,7 @@ Plans and selection summaries describe this run; previous results are never reus A new PR head cancels the previous PR run, including its called workflows. Manual and weekly runs remain independent. Each job reports its own result; there are no separate post-test -aggregation runners after the protection migration or end-of-run metadata checks. +aggregation runners or end-of-run metadata checks. Startup contracts run inside RocksDB validation, and Store stop contracts run inside Struct. Docker's static checks, deployment contracts and current-image validation share one runner. diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-codecov-upload-config.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-codecov-upload-config.sh index 2aa0782f15..0a5137ad6f 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-codecov-upload-config.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-codecov-upload-config.sh @@ -41,6 +41,8 @@ expected_files = { "build-server": "${{ env.REPORT_DIR }}/*.xml,hugegraph-server/target/site/jacoco/jacoco.xml", }, } +expected_flags = {"build-commons": "commons", "pd": "pd", "store": "store", "hstore": "hstore", + "build-server": "server_${{ inputs.backend }}"} action_pattern = re.compile( r"^(?P\s*)(?P-\s+)?uses:\s*" r"(?:(?P['\"])codecov/codecov-action@" @@ -176,7 +178,7 @@ for workflow_path in workflow_paths: if not files_match(uploads, expected_workflow_files): errors.append(f"{relative_path}: unexpected Codecov files inputs") - for line_number, _, version, inputs in uploads: + for line_number, job, version, inputs in uploads: version_match = version_pattern.match(version) if version_match is None or int(version_match.group("major")) < 5: errors.append( @@ -189,6 +191,8 @@ for workflow_path in workflow_paths: f"{relative_path}:{line_number}: Codecov upload must pass " "secrets.CODECOV_TOKEN for trusted runs" ) + if inputs.get("flags") != expected_flags.get(job): + errors.append(f"{relative_path}:{line_number}: unexpected Codecov flag for {job}") if inputs.get("disable_search") != "true": errors.append( f"{relative_path}:{line_number}: Codecov upload must set " From 31aa77dec728cb1e61181bf47e3adfea5be7fd95 Mon Sep 17 00:00:00 2001 From: imbajin Date: Wed, 14 Oct 2026 13:23:08 +0800 Subject: [PATCH 2/4] chore(ci): relocate Codecov configuration - place configuration in the supported .github directory - link coverage documentation to the configuration - preserve carryforward settings and existing upload jobs --- codecov.yml => .github/codecov.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename codecov.yml => .github/codecov.yml (100%) diff --git a/codecov.yml b/.github/codecov.yml similarity index 100% rename from codecov.yml rename to .github/codecov.yml From 47ae6995e3b351fa06f467e8d26df83b0b4bd5a6 Mon Sep 17 00:00:00 2001 From: imbajin Date: Wed, 14 Oct 2026 13:23:23 +0800 Subject: [PATCH 3/4] docs(ci): link the Codecov configuration - document the supported .github configuration location - explain the existing carryforward behavior - keep the coverage initialization guidance unchanged --- docs/ci.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ci.md b/docs/ci.md index a262c4a164..b615b07c9d 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -18,7 +18,8 @@ and `Server rocksdb tests (Java ...)`; their native checks report real execution ## Coverage with selective tests -Each coverage upload has a stable test-group flag. [Codecov carryforward](https://docs.codecov.com/docs/carryforward-flags) +Each coverage upload has a stable test-group flag. The [Codecov configuration](../.github/codecov.yml) +enables [carryforward](https://docs.codecov.com/docs/carryforward-flags), which preserves the last flagged report for unexecuted groups, so skipping unchanged Commons, PD/Store or backend checks does not remove their previous data from project totals. The PR comment explicitly marks carried-forward data. It is historical coverage, From 9831d66da5d9161b0d26943c2cf725cdcf7788a1 Mon Sep 17 00:00:00 2001 From: imbajin Date: Wed, 14 Oct 2026 13:59:48 +0800 Subject: [PATCH 4/4] docs(ci): clarify carryforward baseline limits - describe the recorded parent-chain requirement - retain smoke-only master pushes without extra uploads - distinguish weekly flag seeding from fresh PR coverage --- docs/ci.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/ci.md b/docs/ci.md index b615b07c9d..a9f8866296 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -19,16 +19,19 @@ and `Server rocksdb tests (Java ...)`; their native checks report real execution ## Coverage with selective tests Each coverage upload has a stable test-group flag. The [Codecov configuration](../.github/codecov.yml) -enables [carryforward](https://docs.codecov.com/docs/carryforward-flags), which -preserves the last flagged report for unexecuted groups, so skipping unchanged Commons, -PD/Store or backend checks does not remove their previous data from project totals. +enables [carryforward](https://docs.codecov.com/docs/carryforward-flags). When Codecov can +find an earlier flagged report in its recorded parent chain, it preserves that historical +report for unexecuted groups such as Commons, PD/Store and backends. The PR comment explicitly marks carried-forward data. It is historical coverage, not evidence that a skipped test ran; native job failures remain failures. -New flags need a complete initial baseline. After rollout, the existing weekly full run -on master supplies every flagged group; before that baseline exists, the project report -may still be incomplete. Full and selected runs retain explicit report paths and uploads. -No extra coverage collector runner or unrelated backend run is added for ordinary PRs. +New flags need a complete initial baseline. The existing weekly full run supplies every +flagged group for that commit. Master pushes remain smoke-only and upload no coverage; +those commits can break Codecov's recorded parent chain. A fresh selective PR based on +such a commit is not guaranteed to inherit the weekly baseline, and its project report +may still be incomplete. Carryforward within an existing reported PR chain does not +prove this works for a fresh PR. Full and selected runs retain explicit report paths and +uploads; no extra collector runner or repeated master coverage tests are added. ## What runs