Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -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
24 changes: 0 additions & 24 deletions .github/scripts/test_ci_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"}),
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/commons-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions .github/workflows/pd-store-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ env.REPORT_FILE }}
flags: pd
disable_search: true
fail_ci_if_error: false

Expand Down Expand Up @@ -512,6 +513,7 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{ env.REPORT_FILE }}
flags: store
disable_search: true
fail_ci_if_error: false

Expand Down Expand Up @@ -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
34 changes: 0 additions & 34 deletions .github/workflows/server-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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' }}
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/server-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down
28 changes: 22 additions & 6 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,27 @@ 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. The [Codecov configuration](../.github/codecov.yml)
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. 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

Expand Down Expand Up @@ -85,7 +101,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<indent>\s*)(?P<dash>-\s+)?uses:\s*"
r"(?:(?P<quote>['\"])codecov/codecov-action@"
Expand Down Expand Up @@ -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(
Expand All @@ -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 "
Expand Down
Loading