diff --git a/.github/scripts/ci-policy.py b/.github/scripts/ci-policy.py index d49856f16b..26190be79c 100644 --- a/.github/scripts/ci-policy.py +++ b/.github/scripts/ci-policy.py @@ -46,6 +46,16 @@ "spark-connector-ci.yml": ["spark"], "hubble-ci.yml": ["hubble"], "codeql-analysis.yml": []}, } +# Exact maintenance inputs have no product consumers; their checks run in the planner. +MAINTENANCE_INPUTS = { + ".github/PULL_REQUEST_TEMPLATE.md": [], + ".github/dependabot.yml": [], + ".github/scripts/check-rerun.py": [], + ".github/scripts/test_check_rerun.py": [], + ".github/scripts/check-docker-images.sh": ["docker"], + ".github/scripts/docker-deployment.py": ["docker"], + ".github/scripts/test_docker_deployment.py": ["docker"], +} DEPENDENTS = { "server": {"commons": ["server", "pd", "store", "hstore", "cluster"], "struct": ["server", "pd", "store", "hstore", "cluster"], @@ -96,6 +106,9 @@ def select(project, paths): for path in paths: if documentation(path): continue + if project == "server" and path in MAINTENANCE_INPUTS: + selected.update(MAINTENANCE_INPUTS[path]) + continue if project == "server" and (Path(path).name == "pom.xml" or path.startswith("install-dist/")): selected.add("dependency_license") if path.startswith(".github/workflows/") and Path(path).name in WORKFLOWS[project]: @@ -110,7 +123,7 @@ def select(project, paths): selected.update(["client", "go"]) continue if project == "server": - if path == "hugegraph-server/hugegraph-api/pom.xml": + if path in {"hugegraph-server/pom.xml", "hugegraph-server/hugegraph-api/pom.xml"}: selected.add("docker") if path.startswith(("hugegraph-pd/hg-pd-dist/", "hugegraph-store/hg-store-dist/")): selected.add("docker") @@ -189,8 +202,11 @@ def create_plan(project, event, repository, fetch=api): if not all(isinstance(plan[key], str) and plan[key] for key in ("source", "base", "head", "branch")): raise StaleInputError("PR event has an empty input identity") parents = git("show", "-s", "--format=%P", plan["testedMergeSHA"]).split() - if parents != [plan["base"], plan["head"]]: + if (plan["testedMergeSHA"] != os.environ.get("GITHUB_SHA") + or len(parents) != 2 or parents[1] != plan["head"]): raise StaleInputError("checkout is not the event PR merge; start a new PR run") + # The event base may lag the synthetic merge after the target branch advances. + plan["base"] = parents[0] require_current_pr(plan, fetch) # head/base objects must exist locally; workflow fetches both before planning. ancestor = git("merge-base", plan["base"], plan["head"]) diff --git a/.github/scripts/docker-deployment.py b/.github/scripts/docker-deployment.py index 3b1283b1e5..12b253ec2f 100644 --- a/.github/scripts/docker-deployment.py +++ b/.github/scripts/docker-deployment.py @@ -24,6 +24,7 @@ import sys import urllib.error import urllib.request +import xml.etree.ElementTree as ET ADMIN_PASSWORD = "ci-compose-password" @@ -59,6 +60,33 @@ def expect_response(url, expected=200, credentials=None): return body +def expected_versions(): + root = Path(__file__).resolve().parents[2] + ns = {"m": "http://maven.apache.org/POM/4.0.0"} + revision = ET.parse(root / "pom.xml").findtext("m:properties/m:revision", namespaces=ns) + gremlin = ET.parse(root / "hugegraph-server/pom.xml").findtext( + "m:properties/m:tinkerpop.version", namespaces=ns) + properties = dict(line.split("=", 1) for line in + (root / "hugegraph-commons/hugegraph-common/src/main/resources/version.properties") + .read_text().splitlines() if "=" in line and not line.startswith("#")) + if properties["VersionInBash"] != revision: + raise RuntimeError("VersionInBash does not match the project revision") + # Packaged API classes use their manifest version before the resource fallback. + api = ET.parse(root / "hugegraph-server/hugegraph-api/pom.xml").findtext( + ".//m:manifestEntries/m:Implementation-Version", namespaces=ns) or properties["ApiVersion"] + expected = {"version": "v1", "core": revision, "gremlin": gremlin, "api": api} + if any(not isinstance(value, str) or not value for value in expected.values()): + raise RuntimeError("Source POMs did not define non-empty expected versions") + return expected + + +def verify_versions(payload): + versions = payload.get("versions") if isinstance(payload, dict) else None + expected = expected_versions() + if not isinstance(versions, dict) or any(versions.get(key) != value for key, value in expected.items()): + raise RuntimeError(f"Server did not return the expected versions object: {expected}; got {versions}") + + def verify_server(): url = "http://localhost:8080" expect_response(url + "/graphspaces/DEFAULT/graphs", 401) @@ -68,11 +96,7 @@ def verify_server(): if not isinstance(names, list) or "hugegraph" not in names: raise RuntimeError("Server did not return its initialized hugegraph in the graphs array") payload = json.loads(expect_response(url + "/versions")) - versions = payload.get("versions") if isinstance(payload, dict) else None - if not isinstance(versions, dict) or versions.get("version") != "v1" or any( - not isinstance(versions.get(key), str) or not versions[key] - for key in ("core", "gremlin", "api")): - raise RuntimeError("Server did not return the expected versions object") + verify_versions(payload) def verify_storage(): @@ -91,6 +115,15 @@ def verify_storage(): raise RuntimeError("Authenticated PD did not return its registered stores array") +def verify_graph(run_id): + root = Path(__file__).resolve().parents[2] + script = root / "hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh" + environment = dict(os.environ, HUGEGRAPH_USERNAME="admin", HUGEGRAPH_PASSWORD=ADMIN_PASSWORD) + # Reuse the write/read/Gremlin assertions; allow its readiness and bounded HTTP requests. + subprocess.run(["bash", str(script), "http://localhost:8080", "create", run_id], + check=True, timeout=960, env=environment) + + def smoke(tag, topology, images): root = Path(__file__).resolve().parents[2] project = f"hg-pr-{tag}-{Path(topology).stem}" @@ -113,6 +146,7 @@ def smoke(tag, topology, images): verify_server() if "pd" in images: verify_storage() + verify_graph(project.replace("-", "_")) except BaseException: failed = True for args in (["ps"], ["logs", "--no-color", "--tail", "200"]): diff --git a/.github/scripts/test_ci_policy.py b/.github/scripts/test_ci_policy.py index 9c8077aa6b..435b62bb3e 100644 --- a/.github/scripts/test_ci_policy.py +++ b/.github/scripts/test_ci_policy.py @@ -35,6 +35,9 @@ def live_pr(self): "base": {"sha": "base", "repo": {"full_name": "apache/server"}}} def setUp(self): + event_sha = patch.dict(os.environ, {"GITHUB_SHA": "merge"}) + self.addCleanup(event_sha.stop) + event_sha.start() # All tests stay local; successful PR gates query only this current-PR fixture. api_mock = patch.object(policy, "api", return_value=self.live_pr()) self.addCleanup(api_mock.stop) @@ -110,6 +113,22 @@ def test_single_workflow_has_no_global_fanout(self): self.assertEqual({"hubble"}, policy.select("toolchain", [".github/workflows/hubble-ci.yml"])) self.assertEqual({"docker"}, policy.select("server", [".github/workflows/docker-build-ci.yml"])) + def test_known_maintenance_inputs_have_specific_owners(self): + for path in [".github/PULL_REQUEST_TEMPLATE.md", ".github/dependabot.yml", + ".github/scripts/check-rerun.py", ".github/scripts/test_check_rerun.py"]: + with self.subTest(path=path): + self.assertEqual(set(), policy.select("server", [path])) + for path in [".github/scripts/check-docker-images.sh", ".github/scripts/docker-deployment.py", + ".github/scripts/test_docker_deployment.py"]: + with self.subTest(path=path): + self.assertEqual({"docker"}, policy.select("server", [path])) + selected = policy.select("server", [path, "hugegraph-pd/hg-pd-core/src/A.java"]) + self.assertTrue({"docker", "pd", "store", "hstore", "cluster"}.issubset(selected)) + for path in [".github/scripts/ci-policy.py", ".github/scripts/test_ci_policy.py", + ".github/workflows/rerun-ci.yml", ".github/dependabot-unknown.yml"]: + with self.subTest(path=path): + self.assertEqual(set(policy.MODULES["server"]), policy.select("server", [path])) + def test_unknown_and_proto_fail_conservative(self): for path in ["pom.xml", ".github/scripts/new.py", "hugegraph-pd/api.proto", "mystery"]: self.assertEqual(set(policy.MODULES["server"]), policy.select("server", [path])) @@ -192,8 +211,10 @@ def test_memory_gate_ignores_advisory_cancellation(self): self.assertEqual("cancelled", failure.exception.report["results"]["cluster"]) self.assertNotIn("server_memory", failure.exception.report["results"]) - def test_api_pom_is_a_docker_input(self): - self.assertIn("docker", policy.select("server", ["hugegraph-server/hugegraph-api/pom.xml"])) + def test_server_and_api_poms_are_docker_inputs(self): + for path in ["hugegraph-server/pom.xml", "hugegraph-server/hugegraph-api/pom.xml"]: + with self.subTest(path=path): + self.assertIn("docker", policy.select("server", [path])) self.assertNotIn("docker", policy.select("server", ["hugegraph-server/hugegraph-api/src/main/A.java"])) def test_codeql_and_smoke_follow_affected_inputs(self): @@ -359,7 +380,12 @@ def fetch(path): old = os.getcwd() try: os.chdir(root) + os.environ["GITHUB_SHA"] = merge plan = policy.create_plan("server", event, "apache/server", fetch) + git("checkout", "--detach", "-q", false_merge) + with self.assertRaises(policy.StaleInputError): + policy.create_plan("server", event, "apache/server", fetch) + git("checkout", "--detach", "-q", merge) finally: os.chdir(old) self.assertEqual(["repos/apache/server/pulls/7"], calls) @@ -446,6 +472,7 @@ def git(*args): old = os.getcwd() try: os.chdir(root) + os.environ["GITHUB_SHA"] = merge plan = policy.create_plan("server", event, "apache/server", lambda _: live) results = {suite: {"result": "success"} for suite in plan["expected"]} results.update(plan={"result": "success"}, fixture={"result": "success"}, @@ -461,6 +488,19 @@ def git(*args): policy.create_plan("server", event, "apache/server", lambda _: changed) with self.assertRaises(policy.StaleInputError): policy.gate(plan, results, lambda _: changed) + advanced_merge = git("commit-tree", tree, "-p", advanced_base, "-p", head, + "-m", "PR merge after master advanced") + git("checkout", "--detach", "-q", advanced_merge) + os.environ["GITHUB_SHA"] = advanced_merge + advanced_plan = policy.create_plan("server", event, "apache/server", lambda _: live) + self.assertEqual(base, event["pull_request"]["base"]["sha"]) + self.assertEqual(advanced_base, advanced_plan["base"]) + self.assertEqual(advanced_merge, advanced_plan["testedMergeSHA"]) + self.assertEqual(plan["changedPaths"], advanced_plan["changedPaths"]) + policy.gate(advanced_plan, results, lambda _: live) + with patch.dict(os.environ, {"GITHUB_SHA": ""}): + with self.assertRaises(policy.StaleInputError): + policy.create_plan("server", event, "apache/server", lambda _: live) with self.assertRaises(policy.StaleInputError): policy.gate(plan, results, lambda _: dict(live, state="closed")) git("checkout", "--detach", "-q", head) diff --git a/.github/scripts/test_docker_deployment.py b/.github/scripts/test_docker_deployment.py index 6595c13490..7eeca7ff8e 100644 --- a/.github/scripts/test_docker_deployment.py +++ b/.github/scripts/test_docker_deployment.py @@ -17,6 +17,8 @@ """Reject successful service checks performed against an unrelated image.""" import importlib.util +import json +import os from pathlib import Path import unittest from unittest.mock import patch @@ -73,18 +75,58 @@ def test_hstore_starts_only_pr_services_and_cleans_after_checks(self): with patch.object(deployment, "command", side_effect=identities + containers), \ patch.object(deployment.subprocess, "run") as run, \ patch.object(deployment, "verify_server") as server, \ - patch.object(deployment, "verify_storage") as storage: + patch.object(deployment, "verify_storage") as storage, \ + patch.object(deployment, "verify_graph") as graph: deployment.smoke("ci-1-1", "docker-compose-hstore.yml", images) startup = run.call_args_list[0].args[0] self.assertEqual(startup[-3:], ["pd", "store", "server"]) self.assertNotIn("hubble", startup) server.assert_called_once_with() storage.assert_called_once_with() + graph.assert_called_once_with("hg_pr_ci_1_1_docker_compose_hstore") self.assertEqual(run.call_args_list[-1].args[0][-3:], ["down", "-v", "--remove-orphans"]) +class GraphSmokeTest(unittest.TestCase): + def test_reuses_graph_write_read_and_gremlin_checks_with_auth(self): + with patch.dict(os.environ, {"PATH": "/existing/tools"}), \ + patch.object(deployment.subprocess, "run") as run: + deployment.verify_graph("ci_1_1") + invocation = run.call_args + self.assertTrue(invocation.args[0][1].endswith("run-server-e2e-smoke-test.sh")) + self.assertEqual(invocation.args[0][2:], ["http://localhost:8080", "create", "ci_1_1"]) + self.assertTrue(invocation.kwargs["check"]) + self.assertEqual(invocation.kwargs["timeout"], 960) + environment = invocation.kwargs["env"] + self.assertEqual(environment["PATH"], "/existing/tools") + self.assertEqual(environment["HUGEGRAPH_USERNAME"], "admin") + self.assertEqual(environment["HUGEGRAPH_PASSWORD"], deployment.ADMIN_PASSWORD) + + def test_graph_failure_propagates_and_cleans_both_topologies(self): + for topology, images in ( + ("docker-compose.yml", {"server": "hugegraph/hugegraph"}), + ("docker-compose-hstore.yml", {"pd": "hugegraph/pd", "store": "hugegraph/store", + "server": "hugegraph/server"})): + identities = [f"sha256:{service}" for service in images] + containers = [value for service in images for value in (service, f"sha256:{service}", "healthy")] + failure = deployment.subprocess.CalledProcessError(1, "graph smoke") + with self.subTest(topology=topology), \ + patch.object(deployment, "command", side_effect=identities + containers), \ + patch.object(deployment.subprocess, "run") as run, \ + patch.object(deployment, "verify_server"), \ + patch.object(deployment, "verify_storage"), \ + patch.object(deployment, "verify_graph", side_effect=failure) as graph: + with self.assertRaises(deployment.subprocess.CalledProcessError) as caught: + deployment.smoke("ci-1-1", topology, images) + self.assertIs(caught.exception, failure) + graph.assert_called_once() + calls = [call.args[0] for call in run.call_args_list] + self.assertTrue(any("logs" in args for args in calls)) + self.assertEqual(calls[-1][-3:], ["down", "-v", "--remove-orphans"]) + + class PayloadTest(unittest.TestCase): - VERSIONS = '{"versions":{"version":"v1","core":"1.7.0","gremlin":"3.7.3","api":"0.74"}}' + VERSIONS = json.dumps({"versions": deployment.expected_versions()}) GRAPHS = '{"graphs":["hugegraph"]}' def test_accepts_public_versions_and_authenticated_graphs(self): @@ -112,6 +154,26 @@ def test_rejects_invalid_versions_even_when_http_status_is_200(self): with self.assertRaisesRegex(RuntimeError, "versions object"): deployment.verify_server() + def test_rejects_wrong_release_gremlin_and_protocol_versions(self): + for key, wrong in (("core", "1.7.0"), ("gremlin", "3.7.3"), ("gremlin", None), + ("api", "1.8.0"), ("version", "v2")): + payload = json.loads(self.VERSIONS) + payload["versions"][key] = wrong + with self.subTest(key=key), self.assertRaisesRegex(RuntimeError, "versions object"): + deployment.verify_versions(payload) + + def test_rejects_missing_expected_gremlin_version(self): + parse = deployment.ET.parse + + def read_pom(path): + if path == Path(deployment.__file__).resolve().parents[2] / "hugegraph-server/pom.xml": + return deployment.ET.ElementTree(deployment.ET.Element("project")) + return parse(path) + + with patch.object(deployment.ET, "parse", side_effect=read_pom): + with self.assertRaisesRegex(RuntimeError, "non-empty expected versions"): + deployment.expected_versions() + def test_rejects_unauthenticated_server_access(self): with patch.object(deployment, "response", return_value=(200, self.GRAPHS)): with self.assertRaisesRegex(RuntimeError, "expected 401"): diff --git a/.github/workflows/cluster-test-ci.yml b/.github/workflows/cluster-test-ci.yml index 91d63afdbb..09ac85f193 100644 --- a/.github/workflows/cluster-test-ci.yml +++ b/.github/workflows/cluster-test-ci.yml @@ -9,6 +9,7 @@ permissions: jobs: cluster-test: + timeout-minutes: 120 runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml index 7a60c038ab..63d86230a3 100644 --- a/.github/workflows/commons-ci.yml +++ b/.github/workflows/commons-ci.yml @@ -14,6 +14,7 @@ jobs: contents: read build-commons: + timeout-minutes: 20 name: Commons tests (Java ${{ matrix.JAVA_VERSION }}) needs: java-runtime runs-on: ubuntu-latest @@ -47,7 +48,8 @@ jobs: - name: Install run: | - mvn install -Dmaven.javadoc.skip=true -ntp -Dmaven.test.skip=true + mvn install -pl hugegraph-commons/hugegraph-common,hugegraph-commons/hugegraph-rpc -am \ + -Dmaven.javadoc.skip=true -ntp -Dmaven.test.skip=true - name: Run common test run: | @@ -66,21 +68,3 @@ jobs: files: hugegraph-commons/target/jacoco.xml disable_search: true fail_ci_if_error: false - - # Temporary compatibility check; Commons becomes optional when .asf.yaml takes effect. - legacy-commons-required: - name: build-commons (11) - needs: [ java-runtime, build-commons ] - if: ${{ always() }} - runs-on: ubuntu-24.04 - permissions: {} - steps: - - name: Require the runtime configuration and all Commons tests to pass - env: - RUNTIME_RESULT: ${{ needs.java-runtime.result }} - COMMONS_RESULT: ${{ needs.build-commons.result }} - run: | - if [ "$RUNTIME_RESULT" != "success" ] || [ "$COMMONS_RESULT" != "success" ]; then - echo "::error::Runtime configuration: $RUNTIME_RESULT; Commons tests: $COMMONS_RESULT" - exit 1 - fi diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index 585127b601..915557415b 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -128,5 +128,5 @@ jobs: - name: Verify deployment checker contracts run: python3 -m unittest discover -s .github/scripts -p 'test_docker_deployment.py' - - name: Start the exact PR images and verify health and authentication + - name: Verify exact PR images, authentication and graph read/write run: python3 .github/scripts/docker-deployment.py "$IMAGE_TAG" diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index ccca9d878b..3a238fc4a6 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -87,7 +87,11 @@ jobs: - name: Run Codecov upload configuration tests run: hugegraph-server/hugegraph-dist/src/assembly/travis/test-codecov-upload-config.sh + - name: Check TinkerPop branch and report gates + run: bash hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh + - name: Use staged maven repo settings + if: ${{ env.USE_STAGE == 'true' }} run: | cp $HOME/.m2/settings.xml /tmp/settings.xml || true mv -vf .github/configs/settings.xml $HOME/.m2/settings.xml @@ -112,6 +116,7 @@ jobs: mvn -U -ntp -pl hugegraph-struct test pd: + timeout-minutes: 30 needs: struct runs-on: ubuntu-latest env: @@ -288,6 +293,7 @@ jobs: fail_ci_if_error: false store: + timeout-minutes: 45 needs: struct runs-on: ubuntu-latest env: @@ -488,23 +494,18 @@ jobs: TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis REPORT_DIR: target/site/jacoco BACKEND: hstore - # TODO: remove this temporary TP skip after the branch investigation. - SKIP_TINKERPOP_FOR_CURRENT_PR: ${{ github.head_ref == 'task/tp381-3-upgrade-validation' }} + # Long TP suites run only on dedicated validation branches. RUN_TINKERPOP_TESTS: >- ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') || + startsWith(github.ref_name, 'tinkerpop-') || startsWith(github.head_ref, 'release-') || startsWith(github.head_ref, 'test-') || + startsWith(github.head_ref, 'tinkerpop-') || startsWith(github.base_ref, 'release-') || startsWith(github.base_ref, 'test-') || - startsWith(github.head_ref, 'task/tp381-3-') || - startsWith(github.ref_name, 'task/tp381-3-') || - startsWith(github.base_ref, 'task/tp381-3-') || - github.base_ref == 'task/tinkerpop-3.7-upgrade' || - github.head_ref == 'task/tinkerpop-3.7-upgrade' || - github.base_ref == 'task/gsoc-phase2-java17' || - github.head_ref == 'task/gsoc-phase2-java17' + startsWith(github.base_ref, 'tinkerpop-') }} steps: @@ -513,12 +514,6 @@ jobs: with: fetch-depth: 2 - - name: Record temporary TinkerPop exception - if: env.SKIP_TINKERPOP_FOR_CURRENT_PR == 'true' - run: | - echo '## Temporary TP exception for this upgrade branch' >> "$GITHUB_STEP_SUMMARY" - echo 'TP suites intentionally skipped by the branch patch; no new TP execution evidence is claimed.' >> "$GITHUB_STEP_SUMMARY" - - name: Install project JDK uses: actions/setup-java@v6 with: @@ -601,7 +596,7 @@ jobs: # service setup above makes its structure/process suites exercise the # distributed backend rather than only the memory and RocksDB paths. - name: Run TinkerPop structure test - if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && env.SKIP_TINKERPOP_FOR_CURRENT_PR != 'true' }} + if: ${{ env.RUN_TINKERPOP_TESTS == 'true' }} # The HStore suite needs close to one hour before global cleanup, so # keep enough headroom to finish cleanup and emit Surefire results. timeout-minutes: 120 @@ -655,13 +650,13 @@ jobs: PYTHON - name: Run TinkerPop process standard test - if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && env.SKIP_TINKERPOP_FOR_CURRENT_PR != 'true' }} + if: ${{ env.RUN_TINKERPOP_TESTS == 'true' }} timeout-minutes: 120 run: | $TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND process-standard - name: Run TinkerPop process feature test - if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && env.SKIP_TINKERPOP_FOR_CURRENT_PR != 'true' }} + if: ${{ env.RUN_TINKERPOP_TESTS == 'true' }} timeout-minutes: 120 run: | $TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND process-feature diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index ffff8c587e..bcb527c604 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -6,6 +6,7 @@ on: - master - 'release-*' - 'test-*' + - 'tinkerpop-*' pull_request: workflow_dispatch: @@ -84,10 +85,9 @@ jobs: - name: Check TinkerPop report execution gates run: bash hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh - # Required coverage: memory on the project runtime and any additional test JDKs. + # RocksDB coverage uses the project runtime and any additional test JDKs. # The shared runtime comes from .github/workflows/.java-version, independent of bytecode targets. # Keep the job ID for the Codecov configuration validator. - # The old required check name is provided by the temporary result job below. server-rocksdb: needs: [plan, java-runtime] if: needs.plan.outputs.server == 'true' diff --git a/.github/workflows/server-memory-ci.yml b/.github/workflows/server-memory-ci.yml index 1379e70499..695ffd6ddb 100644 --- a/.github/workflows/server-memory-ci.yml +++ b/.github/workflows/server-memory-ci.yml @@ -6,6 +6,7 @@ on: - master - 'release-*' - 'test-*' + - 'tinkerpop-*' pull_request: workflow_dispatch: @@ -100,13 +101,3 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: python3 .github/scripts/ci-policy.py gate --mode memory --plan plan.json --results results.json --output test-results.json - - legacy-server-memory-required: - name: build-server (memory, 11) - needs: server-memory-required - if: ${{ always() }} - runs-on: ubuntu-24.04 - steps: - - env: - MEMORY_RESULT: ${{ needs.server-memory-required.result }} - run: test "$MEMORY_RESULT" = success diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index 409a14a9c3..f7bd18e9c0 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -26,21 +26,18 @@ jobs: HEAD_BRANCH_NAME: ${{ github.head_ref }} BASE_BRANCH_NAME: ${{ github.base_ref }} TARGET_BRANCH_NAME: ${{ github.base_ref != '' && github.base_ref || github.ref_name }} - # TODO: remove this temporary TP skip after the branch investigation. - SKIP_TINKERPOP_FOR_CURRENT_PR: ${{ github.head_ref == 'task/tp381-3-upgrade-validation' }} + # Long TP suites run only on dedicated validation branches. RUN_TINKERPOP_TESTS: >- ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') || + startsWith(github.ref_name, 'tinkerpop-') || startsWith(github.head_ref, 'release-') || startsWith(github.head_ref, 'test-') || - startsWith(github.head_ref, 'task/tp381-3-') || - startsWith(github.ref_name, 'task/tp381-3-') || - startsWith(github.base_ref, 'task/tp381-3-') || - github.base_ref == 'task/tinkerpop-3.7-upgrade' || - github.head_ref == 'task/tinkerpop-3.7-upgrade' || - github.base_ref == 'task/gsoc-phase2-java17' || - github.head_ref == 'task/gsoc-phase2-java17' + startsWith(github.head_ref, 'tinkerpop-') || + startsWith(github.base_ref, 'release-') || + startsWith(github.base_ref, 'test-') || + startsWith(github.base_ref, 'tinkerpop-') }} RAFT_MODE: ${{ startsWith(github.ref_name, 'raft-') || startsWith(github.head_ref, 'raft-') }} @@ -54,13 +51,6 @@ jobs: with: fetch-depth: 5 - - name: Record temporary TinkerPop exception - if: env.SKIP_TINKERPOP_FOR_CURRENT_PR == 'true' - run: | - echo '## Temporary TP exception for this upgrade branch' >> "$GITHUB_STEP_SUMMARY" - echo 'TP suites intentionally skipped by the branch patch; no new TP execution evidence is claimed.' >> "$GITHUB_STEP_SUMMARY" - - - name: Prepare HBase container if: inputs.backend == 'hbase' run: $TRAVIS_DIR/install-backend.sh hbase @@ -191,12 +181,12 @@ jobs: $TRAVIS_DIR/run-api-test-for-raft.sh $BACKEND $REPORT_DIR - name: Run TinkerPop structure test - if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && env.SKIP_TINKERPOP_FOR_CURRENT_PR != 'true' && (env.BACKEND == 'memory' || env.BACKEND == 'rocksdb') }} + if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && (env.BACKEND == 'memory' || env.BACKEND == 'rocksdb') }} timeout-minutes: 60 run: $TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND structure - name: Run TinkerPop process test - if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && env.SKIP_TINKERPOP_FOR_CURRENT_PR != 'true' && (env.BACKEND == 'memory' || env.BACKEND == 'rocksdb') }} + if: ${{ env.RUN_TINKERPOP_TESTS == 'true' && (env.BACKEND == 'memory' || env.BACKEND == 'rocksdb') }} timeout-minutes: 180 run: $TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND process diff --git a/README.md b/README.md index 98413218c8..401229df69 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,8 @@ flowchart TB ## Quick Start + + ### 5 Minutes Quick Start ```bash diff --git a/docker/README.md b/docker/README.md index a9d43dcb1f..81a02507e2 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,5 +1,7 @@ # HugeGraph Docker Compose + + ## Users ### Choose a topology diff --git a/docs/ci.md b/docs/ci.md index 97b0e5fd89..74b562ee63 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -13,7 +13,8 @@ Selection controls what runs; branch protection controls what must pass before m Each workflow can be cancelled independently. Jobs within a workflow share its cancellation scope. Cancelling advisory checks does not cancel Memory or license checks, and does not -prevent CodeQL from starting. Failed advisory checks retain their real failure result; +prevent CodeQL from starting. Failed advisory checks retain their real failure result +(except the existing RISC-V job, which still uses `continue-on-error`); maintainers decide whether they need another run or a requested change. ## Affected inputs @@ -25,8 +26,10 @@ maintainers decide whether they need another run or a requested change. | Commons or Struct | Their tests and affected Server, PD, Store, HStore and Cluster tests | | PD or Store distribution scripts, config, assembly or POM | PD/Store/HStore, Cluster and Docker | | Other PD or Store inputs | PD/Store/HStore and Cluster | -| Server API POM or Commons version resource | Normal module coverage plus Docker artifact checks | +| Server parent/API POM or Commons version resource | Normal module coverage plus Docker artifact checks | | Cluster, Docker or Helm | Their suite and known consumers | +| PR template, Dependabot configuration or retry checker/tests | Planner checks and license checks; no product suites | +| Docker image/deployment checkers and their tests | Docker | | Dependencies, shared build inputs or unknown paths | Conservative full coverage | The Memory required result depends only on its planner, runtime preparation and real Memory @@ -37,7 +40,7 @@ It does not stand in for Memory or control CodeQL and compatibility checks. The Docker suite builds the current four production images through a shared Maven build. Checks consume those final images, verify identity, health, version and authentication, and -exercise the PD/Store/Server topology. Published-image Hubble Compose smoke runs once in +exercise graph writes, reads and Gremlin queries on standalone and PD/Store/Server topologies. Published-image Hubble Compose smoke runs once in compatibility CI when RocksDB or Docker is selected; it does not verify the new PR images. HBase compatibility uses the existing HBase version in one standalone container with local @@ -46,6 +49,17 @@ Pull, startup and readiness preparation have a five-minute total budget. Prepara ends the advisory check without falling back to a tar download. Existing HBase behavior tests remain. This changes CI preparation, not product support or backend deprecation policy. +TinkerPop suites run only when the source, target or push/manual branch starts with +`release-`, `test-` or `tinkerpop-`. PRs run no TP suites when neither source nor target +branch matches these prefixes, including `upgrade/1.8.0` targeting `master`. +Historical task-branch exceptions and the temporary TP skip are removed. Executed TP suites +still require non-empty reports with actual executed tests. + +PD, Store and Commons have total job budgets of 30, 45 and 20 minutes, respectively, +based on six recent successful master runs across Org and ASF. Cluster has 120 minutes, +preserving its two existing 45-minute test windows and allowing build/diagnostic time. +Server and HStore budgets remain unchanged pending complete TP execution history. + ## Documentation and freshness Only explicitly allowed prose and static documentation assets qualify as plain documentation. @@ -54,21 +68,42 @@ PRs skip compilation, backend services, images and PR CodeQL; lightweight select checks still report. A source PR with a later documentation commit still tests its cumulative source changes. No result is reused from a previous run. -Plans record the event head, tested base and merge. Checkout and PR source identities must -match the event. A new source head invalidates the old run; target-branch advancement alone +Plans record the event head and the actual merge commit and base tested. Checkout must match +the event merge SHA, whose second parent must match the current PR head. Its first parent is +the tested base; the event base may lag when master advances before checkout. A new source +head invalidates the old run; target-branch advancement alone does not, matching non-strict branch protection. A selection/API failure conservatively selects all suites. A final metadata outage alone cannot invalidate completed Memory tests. Plans and actual results are diagnostics, not execution credentials for later runs. -## Protection migration and retries +## Protection and retries -`.asf.yaml` requests only `check-license` and `Server memory tests`. Keep existing check names -through migration and verify live branch protection after merging. The migration PR may need -one complete run under the old requirements. Do not remove a still-required context or forge -success for it. Remove obsolete `affected-module-tests`/CodeQL requirements from live protection -before relying on documentation skips or independently cancelling advisory workflows. +`.asf.yaml` requests only `check-license` and `Server memory tests`. Keep these required check +names stable. The Memory workflow runs real unit, core and API tests on the project runtime +and reports their results through `Server memory tests`; the former Java 11 placeholder is +removed. The former `build-commons (11)` placeholder is also removed; real Commons tests +remain advisory and install only the Commons reactor and its upstream modules. +`affected-module-tests` and CodeQL remain advisory. Verify live branch protection +when changing required checks; do not forge a successful result or leave retired contexts required. Only failed push runs of License Checker and Server Memory CI automatically retry, at most twice. The trusted checker verifies the workflow path, attempt, repository and unchanged branch head before and after the delay. PRs and advisory workflows never automatically retry. Use a manual rerun when appropriate; a rerun retains its original commit and event. + +## Follow-up work + +These changes need separate CI policy decisions or broader validation: + +- Split compatibility selection by backend, native code, JDK and shared startup/core impact, + retaining Server/PD/Store/Cluster coverage and periodic complete compatibility checks. +- Narrow PD/Store/HStore/Cluster reactors only after verifying every required distribution; + evaluate sharing artifacts between jobs separately. +- Choose an explicit RocksDB comparison baseline for the first push to a new release-/test- + branch, where `before` is all zeros. Do not silently compare a commit with itself. +- Revisit RISC-V `continue-on-error`; it remains advisory and is not a required check. +- Consider merging runtime resolution into planning and extracting long diagnostic scripts. +- Replace broad push failure reruns with bounded retries at known transient operations; + preserve workflow, repository, attempt and unchanged-head checks. +- Set total timeouts only where complete test history supports a budget, including diagnostics. + Do not size HStore or Server TP budgets from runs that skipped TP suites. diff --git a/helm/hugegraph/Chart.yaml b/helm/hugegraph/Chart.yaml index 0b7f7ccde1..deb1859d20 100644 --- a/helm/hugegraph/Chart.yaml +++ b/helm/hugegraph/Chart.yaml @@ -19,7 +19,8 @@ apiVersion: v2 name: hugegraph description: Helm chart for Apache HugeGraph HStore cluster (PD + Store + Server) type: application -version: 0.1.0 +version: 0.1.1 +# TODO: set appVersion to "1.8.0" when the release images are published. appVersion: "latest" kubeVersion: ">=1.23.0-0" keywords: diff --git a/helm/hugegraph/README.md b/helm/hugegraph/README.md index 25ba786c34..fb8a01b93d 100644 --- a/helm/hugegraph/README.md +++ b/helm/hugegraph/README.md @@ -172,8 +172,9 @@ A fresh install seeds PD with a partition shard count of 3 when default of 1. The seed applies at first bootstrap only; see Partition Sharding below. -The component image tags and `appVersion` track `latest` until the next -HugeGraph release tag is published. For production, pin the image tags (or +The component image tags and `appVersion` stay at `latest` until the 1.8.0 +release images are published. Empty component tags inherit `appVersion`; +explicit image tags still override it. For production, pin the image tags (or digests) and switch the component pull policies to `IfNotPresent`. Verify the release: diff --git a/helm/hugegraph/tests/__snapshot__/networkpolicy_test.yaml.snap b/helm/hugegraph/tests/__snapshot__/networkpolicy_test.yaml.snap index 447049801c..ca8ea46112 100644 --- a/helm/hugegraph/tests/__snapshot__/networkpolicy_test.yaml.snap +++ b/helm/hugegraph/tests/__snapshot__/networkpolicy_test.yaml.snap @@ -26,7 +26,7 @@ matches the reviewed cluster plus Hubble render: app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: hugegraph app.kubernetes.io/version: latest - helm.sh/chart: hugegraph-0.1.0 + helm.sh/chart: hugegraph-0.1.1 name: RELEASE-NAME-hugegraph-pd spec: egress: @@ -97,7 +97,7 @@ matches the reviewed cluster plus Hubble render: app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: hugegraph app.kubernetes.io/version: latest - helm.sh/chart: hugegraph-0.1.0 + helm.sh/chart: hugegraph-0.1.1 name: RELEASE-NAME-hugegraph-store spec: egress: @@ -174,7 +174,7 @@ matches the reviewed cluster plus Hubble render: app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: hugegraph app.kubernetes.io/version: latest - helm.sh/chart: hugegraph-0.1.0 + helm.sh/chart: hugegraph-0.1.1 name: RELEASE-NAME-hugegraph-server spec: egress: @@ -238,7 +238,7 @@ matches the reviewed cluster plus Hubble render: app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: hugegraph app.kubernetes.io/version: latest - helm.sh/chart: hugegraph-0.1.0 + helm.sh/chart: hugegraph-0.1.1 name: RELEASE-NAME-hugegraph-hubble spec: egress: diff --git a/helm/hugegraph/tests/image_digest_test.yaml b/helm/hugegraph/tests/image_digest_test.yaml index da518908bd..aa2237692c 100644 --- a/helm/hugegraph/tests/image_digest_test.yaml +++ b/helm/hugegraph/tests/image_digest_test.yaml @@ -17,6 +17,81 @@ suite: Image reference and digest pinning tests: + - it: keeps the default pd tag on latest until release images are published + template: pd-statefulset.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/pd:latest + + - it: keeps the default store tag on latest until release images are published + template: store-statefulset.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/store:latest + + - it: keeps the default server tag on latest until release images are published + template: server-deployment.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/server:latest + + - it: inherits appVersion for pd when the tag is empty + template: pd-statefulset.yaml + set: + pd.image.tag: "" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/pd:latest + + - it: inherits appVersion for store when the tag is empty + template: store-statefulset.yaml + set: + store.image.tag: "" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/store:latest + + - it: overrides appVersion with an explicit store tag + template: store-statefulset.yaml + set: + store.image.tag: pinned-for-test + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/store:pinned-for-test + + - it: inherits appVersion for server when the tag is empty + template: server-deployment.yaml + set: + server.image.tag: "" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/server:latest + + - it: overrides appVersion with an explicit server tag + template: server-deployment.yaml + set: + server.image.tag: pinned-for-test + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/server:pinned-for-test + + - it: keeps Hubble on its independent tag + template: hubble-deployment.yaml + set: + hubble.enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: hugegraph/hubble:latest + - it: renders repository and tag when no digest is set template: pd-statefulset.yaml set: @@ -29,6 +104,7 @@ tests: - it: pins by digest when one is supplied, ignoring the tag template: pd-statefulset.yaml set: + pd.image.tag: pinned-for-test pd.image.digest: sha256:43999a5ccda34883a9e4e458e25cb903ce34adbc66782d9f4a5260d68b2b5a82 asserts: - equal: @@ -41,6 +117,7 @@ tests: - it: supports digest pinning on store as well template: store-statefulset.yaml set: + store.image.tag: pinned-for-test store.image.digest: sha256:458d77a18542e8a2f7980b075f2fda32026d582200a8983921354398467ff860 asserts: - matchRegex: @@ -50,6 +127,7 @@ tests: - it: supports digest pinning on server as well template: server-deployment.yaml set: + server.image.tag: pinned-for-test server.image.digest: sha256:30f99c6b9ab605accf96e9c179434b13495547f532dcb89d840231c54f1cc101 asserts: - matchRegex: diff --git a/helm/hugegraph/tests/networkpolicy_test.yaml b/helm/hugegraph/tests/networkpolicy_test.yaml index 8782a53fb4..bd2f36a296 100644 --- a/helm/hugegraph/tests/networkpolicy_test.yaml +++ b/helm/hugegraph/tests/networkpolicy_test.yaml @@ -781,7 +781,43 @@ tests: set: hubble.enabled: true asserts: + - hasDocuments: + count: 4 - matchSnapshot: {} + # helm-unittest v1.0.0 skips full comparison for matchSnapshot: {}. + # Guard release metadata explicitly until that plugin issue is resolved. + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "latest" + documentIndex: 0 + - equal: + path: metadata.labels["helm.sh/chart"] + value: hugegraph-0.1.1 + documentIndex: 0 + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "latest" + documentIndex: 1 + - equal: + path: metadata.labels["helm.sh/chart"] + value: hugegraph-0.1.1 + documentIndex: 1 + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "latest" + documentIndex: 2 + - equal: + path: metadata.labels["helm.sh/chart"] + value: hugegraph-0.1.1 + documentIndex: 2 + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "latest" + documentIndex: 3 + - equal: + path: metadata.labels["helm.sh/chart"] + value: hugegraph-0.1.1 + documentIndex: 3 - it: appends extra rules verbatim values: diff --git a/helm/hugegraph/values.yaml b/helm/hugegraph/values.yaml index c9ab0cbf99..6205e17396 100644 --- a/helm/hugegraph/values.yaml +++ b/helm/hugegraph/values.yaml @@ -27,8 +27,8 @@ pd: replicas: 3 image: repository: hugegraph/pd - # Tracks latest until the next HugeGraph release tag is published. Pin the - # tag (or digest) and switch to IfNotPresent for production. + # TODO: leave tag empty to inherit Chart.appVersion after the 1.8.0 + # release images are published. Pin a tag or digest for production. tag: latest # Optional immutable digest, for example sha256:abc... When set it wins over # tag and the image is pulled by digest, which is what a release gate should @@ -189,8 +189,8 @@ store: replicas: 3 image: repository: hugegraph/store - # Tracks latest until the next HugeGraph release tag is published. Pin the - # tag (or digest) and switch to IfNotPresent for production. + # TODO: leave tag empty to inherit Chart.appVersion after the 1.8.0 + # release images are published. Pin a tag or digest for production. tag: latest # Optional immutable digest, for example sha256:abc... When set it wins over # tag and the image is pulled by digest, which is what a release gate should @@ -276,8 +276,8 @@ server: replicas: 3 image: repository: hugegraph/server - # Tracks latest until the next HugeGraph release tag is published. Pin the - # tag (or digest) and switch to IfNotPresent for production. + # TODO: leave tag empty to inherit Chart.appVersion after the 1.8.0 + # release images are published. Pin a tag or digest for production. tag: latest # Optional immutable digest, for example sha256:abc... When set it wins over # tag and the image is pulled by digest, which is what a release gate should diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml b/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml index 5c5acbfa57..1ab0fd3b7f 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/pom.xml @@ -38,6 +38,11 @@ ${revision} compile + + + org.apache.hugegraph + hugegraph-common + org.apache.hugegraph diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java index fa5d4501eb..0f2b0d492a 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/MultiClusterTest/BaseMultiClusterTest.java @@ -38,7 +38,7 @@ * MultiNode Test generate the cluster env with 3 pd node + 3 store node + 3 server node. * Or you can set different num of nodes by using env = new MultiNodeEnv(pdNum, storeNum, serverNum) * All nodes are deployed in ports generated randomly, the application of nodes are stored - * in /apache-hugegraph-ct-1.7.0, you can visit each node with rest api. + * in /apache-hugegraph-ct-1.8.0, you can visit each node with rest api. */ public class BaseMultiClusterTest { diff --git a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java index d6df82bcfa..996856f86c 100644 --- a/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java +++ b/hugegraph-cluster-test/hugegraph-clustertest-test/src/main/java/org/apache/hugegraph/SimpleClusterTest/BaseSimpleTest.java @@ -45,7 +45,7 @@ /** * Simple Test generate the cluster env with 1 pd node + 1 store node + 1 server node. * All nodes are deployed in ports generated randomly; The application of nodes is stored - * in /apache-hugegraph-ct-1.7.0, you can visit each node with rest api. + * in /apache-hugegraph-ct-1.8.0, you can visit each node with rest api. */ public class BaseSimpleTest { diff --git a/hugegraph-commons/hugegraph-common/src/main/resources/version.properties b/hugegraph-commons/hugegraph-common/src/main/resources/version.properties index 8d48ef39ca..c62e18ef71 100644 --- a/hugegraph-commons/hugegraph-common/src/main/resources/version.properties +++ b/hugegraph-commons/hugegraph-common/src/main/resources/version.properties @@ -20,4 +20,4 @@ Version=${revision} ApiVersion=0.72 ApiCheckBeginVersion=1.0 ApiCheckEndVersion=2.0 -VersionInBash=1.7.0 +VersionInBash=1.8.0 diff --git a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java index 591732749a..07eb893c7d 100644 --- a/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java +++ b/hugegraph-commons/hugegraph-rpc/src/test/java/org/apache/hugegraph/unit/ServerClientTest.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.List; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.rpc.RpcClientProvider; @@ -406,118 +408,140 @@ public void testFanoutCallServiceWithError() { @Test public void testLoadBalancer() { - // Init 3 servers - HugeConfig server3 = config("server3"); - RpcServer rpcServer3 = new RpcServer(server3); - - HugeConfig server4 = config("server4"); - RpcServer rpcServer4 = new RpcServer(server4); - - HugeConfig server5 = config("server5"); - RpcServer rpcServer5 = new RpcServer(server5); - - GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1"); - GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1"); - GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1"); - - rpcServer3.config().addService(HelloService.class, s3g1); - rpcServer4.config().addService(HelloService.class, s4g1); - rpcServer5.config().addService(HelloService.class, s5g1); - - startServer(rpcServer3); - startServer(rpcServer4); - startServer(rpcServer5); - - // Test LB "consistentHash" - HugeConfig clientLB = config("client-lb"); - RpcClientProvider rpcClientCHash = new RpcClientProvider(clientLB); - HelloService cHash = rpcClientCHash.config() - .serviceProxy(HelloService.class); - - Assert.assertEquals("g1: load", cHash.echo("load")); - Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); - Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - Assert.assertEquals("g1: load", cHash.echo("load")); - Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); - Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - Assert.assertEquals("g1: load", cHash.echo("load")); - Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); - Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - s3g1.resetResult(); - s4g1.resetResult(); - s5g1.resetResult(); - - // Test LB "roundRobin" - String lbKey = org.apache.hugegraph.config.RpcOptions.RPC_CLIENT_LOAD_BALANCER.name(); - clientLB.setProperty(lbKey, "roundRobin"); - RpcClientProvider rpcClientRound = new RpcClientProvider(clientLB); - HelloService round = rpcClientRound.config() - .serviceProxy(HelloService.class); - - Assert.assertEquals("g1: load", round.echo("load")); - Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); - Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - Assert.assertEquals("g1: load", round.echo("load")); - Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); - Assert.assertEquals(2.2, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - Assert.assertEquals("g1: load", round.echo("load")); - Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); - Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - s3g1.resetResult(); - s4g1.resetResult(); - s5g1.resetResult(); - - // Test LB "random" - clientLB.setProperty(lbKey, "random"); - RpcClientProvider rpcClientRandom = new RpcClientProvider(clientLB); - HelloService random = rpcClientRandom.config() - .serviceProxy(HelloService.class); - - Assert.assertEquals("g1: load", random.echo("load")); - Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); - Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - Assert.assertEquals("g1: load", random.echo("load")); - Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); - double sum = s3g1.result() + s4g1.result() + s5g1.result(); - Assert.assertTrue(2.2 == sum || 1.1 == sum); - - Assert.assertEquals("g1: load", random.echo("load")); - Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); - double sum2 = s3g1.result() + s4g1.result() + s5g1.result(); - Assert.assertTrue(sum == sum2 || sum + 1.1 == sum2); - - for (int i = 0; i < 9; i++) { - Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + List cleanup = new ArrayList<>(); + Throwable failure = null; + try { + // Init 3 servers + HugeConfig server3 = config("server3"); + RpcServer rpcServer3 = new RpcServer(server3); + cleanup.add(() -> stopServer(rpcServer3)); + + HugeConfig server4 = config("server4"); + RpcServer rpcServer4 = new RpcServer(server4); + cleanup.add(() -> stopServer(rpcServer4)); + + HugeConfig server5 = config("server5"); + RpcServer rpcServer5 = new RpcServer(server5); + cleanup.add(() -> stopServer(rpcServer5)); + + GraphHelloServiceImpl s3g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s4g1 = new GraphHelloServiceImpl("g1"); + GraphHelloServiceImpl s5g1 = new GraphHelloServiceImpl("g1"); + + rpcServer3.config().addService(HelloService.class, s3g1); + rpcServer4.config().addService(HelloService.class, s4g1); + rpcServer5.config().addService(HelloService.class, s5g1); + + startServer(rpcServer3); + startServer(rpcServer4); + startServer(rpcServer5); + + // Test LB "consistentHash" + HugeConfig clientLB = config("client-lb"); + RpcClientProvider rpcClientCHash = new RpcClientProvider(clientLB); + cleanup.add(rpcClientCHash::destroy); + HelloService cHash = rpcClientCHash.config() + .serviceProxy(HelloService.class); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", cHash.echo("load")); + Assert.assertEquals(16.8, cHash.sum(10, 6.8), 0.00000001d); + Assert.assertEquals(16.8, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Test LB "roundRobin" + String lbKey = org.apache.hugegraph.config.RpcOptions.RPC_CLIENT_LOAD_BALANCER.name(); + clientLB.setProperty(lbKey, "roundRobin"); + RpcClientProvider rpcClientRound = new RpcClientProvider(clientLB); + cleanup.add(rpcClientRound::destroy); + HelloService round = rpcClientRound.config() + .serviceProxy(HelloService.class); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(1.1, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(2.2, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + Assert.assertEquals("g1: load", round.echo("load")); + Assert.assertEquals(1.1, round.sum(1, 0.1), 0.00000001d); + Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(), + 0.00000001d); + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + + // Test LB "random" + clientLB.setProperty(lbKey, "random"); + RpcClientProvider rpcClientRandom = new RpcClientProvider(clientLB); + cleanup.add(rpcClientRandom::destroy); + HelloService random = rpcClientRandom.config() + .serviceProxy(HelloService.class); + + // Random routing can legitimately leave some providers unvisited. + GraphHelloServiceImpl[] services = {s3g1, s4g1, s5g1}; + int visited = 0; + for (int i = 0; i < 12; i++) { + if (i < 3) { + Assert.assertEquals("g1: load", random.echo("load")); + } + Assert.assertEquals(1.1, random.sum(1, 0.1), 0.00000001d); + int currentVisited = 0; + for (GraphHelloServiceImpl service : services) { + double result = service.result(); + Assert.assertTrue(result == 0.0 || result == 1.1); + if (result != 0.0) { + currentVisited++; + } + } + Assert.assertTrue(currentVisited > 0); + Assert.assertTrue(currentVisited >= visited && currentVisited <= visited + 1); + visited = currentVisited; + } + + s3g1.resetResult(); + s4g1.resetResult(); + s5g1.resetResult(); + } catch (RuntimeException | Error e) { + failure = e; + throw e; + } finally { + RuntimeException cleanupFailure = null; + for (int i = cleanup.size() - 1; i >= 0; i--) { + try { + cleanup.get(i).run(); + } catch (RuntimeException e) { + if (failure != null) { + failure.addSuppressed(e); + } else if (cleanupFailure == null) { + cleanupFailure = e; + } else { + cleanupFailure.addSuppressed(e); + } + } + } + if (cleanupFailure != null) { + throw cleanupFailure; + } } - Assert.assertEquals(3.3, s3g1.result() + s4g1.result() + s5g1.result(), - 0.00000001d); - - s3g1.resetResult(); - s4g1.resetResult(); - s5g1.resetResult(); - - // Destroy all - rpcClientCHash.destroy(); - rpcClientRound.destroy(); - rpcClientRandom.destroy(); - - stopServer(rpcServer3); - stopServer(rpcServer4); - stopServer(rpcServer5); } @Test diff --git a/hugegraph-commons/pom.xml b/hugegraph-commons/pom.xml index 12874e50ec..a3ef4983df 100644 --- a/hugegraph-commons/pom.xml +++ b/hugegraph-commons/pom.xml @@ -89,9 +89,6 @@ - - - 1.7.0 UTF-8 ${project.basedir}/.. 11 diff --git a/hugegraph-pd/README.md b/hugegraph-pd/README.md index 8f890efd98..4c1ce7f108 100644 --- a/hugegraph-pd/README.md +++ b/hugegraph-pd/README.md @@ -3,6 +3,8 @@ [![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Version](https://img.shields.io/badge/version-1.7.0-blue)](https://github.com/apache/hugegraph) + + ## Overview HugeGraph PD (Placement Driver) is a meta server that provides cluster management and coordination services for HugeGraph distributed deployments. It serves as the central control plane responsible for: diff --git a/hugegraph-server/README.md b/hugegraph-server/README.md index 819bece457..d8fe1d7746 100644 --- a/hugegraph-server/README.md +++ b/hugegraph-server/README.md @@ -1,5 +1,7 @@ # HugeGraph Server + + HugeGraph Server consists of two layers of functionality: the graph engine layer, and the storage layer. - Graph Engine Layer: diff --git a/hugegraph-server/hugegraph-dist/docker/README.md b/hugegraph-server/hugegraph-dist/docker/README.md index aa76092b82..6e230f9295 100644 --- a/hugegraph-server/hugegraph-dist/docker/README.md +++ b/hugegraph-server/hugegraph-dist/docker/README.md @@ -1,5 +1,7 @@ # Deploy HugeGraph Server with Docker + + > Note: > > 1. The HugeGraph Docker image is a convenience release, not an official ASF distribution artifact. See the [ASF Release Distribution Policy](https://infra.apache.org/release-distribution.html#dockerhub) for details. diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh index 9762e4fa26..a29ae76bae 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/run-server-e2e-smoke-test.sh @@ -144,7 +144,16 @@ verify_graph() { wait_for_server request GET /versions 200 -assert_json 'type == "object" and length > 0' +ROOT_DIR=$(cd "$(dirname "$0")/../../../../.." && pwd) +EXPECTED_CORE_VERSION=$(sed -n 's:.*\([^<]*\).*:\1:p' "$ROOT_DIR/pom.xml") +EXPECTED_GREMLIN_VERSION=$(sed -n 's:.*\([^<]*\).*:\1:p' \ + "$ROOT_DIR/hugegraph-server/pom.xml") +EXPECTED_API_VERSION=$(sed -n 's:.*\([^<]*\).*:\1:p' \ + "$ROOT_DIR/hugegraph-server/hugegraph-api/pom.xml") +assert_json '.versions.version == "v1" and .versions.core == $core and + .versions.gremlin == $gremlin and .versions.api == $api' \ + --arg core "$EXPECTED_CORE_VERSION" --arg gremlin "$EXPECTED_GREMLIN_VERSION" \ + --arg api "$EXPECTED_API_VERSION" if [[ "$MODE" == "create" ]]; then request POST "$GRAPH_PATH/schema/propertykeys" 202 \ diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-start-hugegraph-pd.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-start-hugegraph-pd.sh index 754e2baae1..db0ae37efe 100755 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-start-hugegraph-pd.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-start-hugegraph-pd.sh @@ -22,7 +22,7 @@ # # Usage: ./test-start-hugegraph-pd.sh [path-to-pd-dist-root] # path-to-pd-dist-root: path to extracted PD dist e.g. -# hugegraph-pd/apache-hugegraph-pd-1.7.0/ +# hugegraph-pd/apache-hugegraph-pd-1.8.0/ # defaults to current directory if not provided set -uo pipefail diff --git a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh index 83788f8fea..e3a8a88fcc 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh +++ b/hugegraph-server/hugegraph-dist/src/assembly/travis/test-tinkerpop-reports.sh @@ -53,6 +53,38 @@ check_report() { fi } +# Exercise the actual workflow expressions against representative event branches. +python3 - "$SCRIPT_DIR" <<'PYBRANCH' +from pathlib import Path +import re +import sys +from types import SimpleNamespace + +root = Path(sys.argv[1]).resolve().parents[4] +for filename in ("server-tests.yml", "pd-store-ci.yml"): + source = (root / ".github/workflows" / filename).read_text() + assert "SKIP_TINKERPOP_FOR_CURRENT_PR" not in source, filename + expression = re.search(r"RUN_TINKERPOP_TESTS: >-\s*\$\{\{(.*?)\}\}", source, re.S).group(1) + expression = " ".join(expression.split()).replace("||", "or") + cases = [ + ("123/merge", "upgrade/1.8.0", "master", False), + ("master", "", "", False), + ("123/merge", "task/tp381-3-upgrade-validation", "master", False), + ("123/merge", "task/tinkerpop-3.7-upgrade", "master", False), + ("123/merge", "task/gsoc-phase2-java17", "master", False), + ] + for prefix in ("release-", "test-", "tinkerpop-"): + cases.extend([(prefix + "validation", "", "", True), + ("123/merge", prefix + "validation", "master", True), + ("123/merge", "feature", prefix + "validation", True)]) + for ref, head, base, expected in cases: + github = SimpleNamespace(ref_name=ref, head_ref=head, base_ref=base) + actual = eval(expression, {"__builtins__": {}}, + {"github": github, "startsWith": str.startswith}) + assert actual is expected, (filename, ref, head, base, actual) +print("PASS: TP branch gates exclude ordinary upgrades and old task exceptions") +PYBRANCH + cd "$TEST_DIR" for suite in structure process process-standard process-feature tinkerpop; do check_report executed '' 0 "$suite" diff --git a/hugegraph-store/README.md b/hugegraph-store/README.md index 7d9575fb8c..58943bb94b 100644 --- a/hugegraph-store/README.md +++ b/hugegraph-store/README.md @@ -3,6 +3,8 @@ [![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Version](https://img.shields.io/badge/version-1.7.0-blue)](https://github.com/apache/hugegraph) + + > **Note**: From revision 1.5.0, the HugeGraph-Store code has been adapted to this location. ## Overview diff --git a/hugegraph-store/docs/deployment-guide.md b/hugegraph-store/docs/deployment-guide.md index a3339f6518..3d4f798a59 100644 --- a/hugegraph-store/docs/deployment-guide.md +++ b/hugegraph-store/docs/deployment-guide.md @@ -1,5 +1,7 @@ # Deployment Guide + + This guide provides comprehensive instructions for deploying HugeGraph Store in various environments, from development to production clusters. > **PD REST credential.** Calls to a PD REST endpoint on port 8620, other than `/v1/health`, `/v1/ready`, `/actuator/**` and `/v1/prom/targets/*`, need HTTP Basic auth: one of the internal service names (`hg`, `store`, `hubble`, `vermeer`) and PD's `auth.secret-key` value as the password. A call without it gets HTTP 401 and a `{"status":-1,"error":"Unauthorized"}` body, not the payloads shown below. Export the secret before following a step that uses `${PD_SECRET}`: diff --git a/hugegraph-store/docs/integration-guide.md b/hugegraph-store/docs/integration-guide.md index 13164872e0..9ead2464cb 100644 --- a/hugegraph-store/docs/integration-guide.md +++ b/hugegraph-store/docs/integration-guide.md @@ -1,5 +1,7 @@ # Integration Guide + + This guide explains how to integrate HugeGraph Store with HugeGraph Server, use the client library, and migrate from other storage backends. > **PD REST credential.** Calls to a PD REST endpoint on port 8620, other than `/v1/health`, `/v1/ready`, `/actuator/**` and `/v1/prom/targets/*`, need HTTP Basic auth: one of the internal service names (`hg`, `store`, `hubble`, `vermeer`) and PD's `auth.secret-key` value as the password. A call without it gets HTTP 401. Export the secret before following a procedure that uses `${PD_SECRET}`: diff --git a/hugegraph-store/docs/operations-guide.md b/hugegraph-store/docs/operations-guide.md index 1df19b8be6..78e1c718b5 100644 --- a/hugegraph-store/docs/operations-guide.md +++ b/hugegraph-store/docs/operations-guide.md @@ -685,6 +685,10 @@ curl http://192.168.1.10:8620/v1/partitionsAndStatus ## Rolling Upgrades + + +The 1.8.0 package paths below illustrate a future release upgrade. Run these steps only after that release is published. + ### Upgrade Strategy **Goal**: Upgrade cluster with zero downtime diff --git a/install-dist/release-docs/LICENSE b/install-dist/release-docs/LICENSE index 88e9caa90b..4008742f82 100644 --- a/install-dist/release-docs/LICENSE +++ b/install-dist/release-docs/LICENSE @@ -635,7 +635,6 @@ the corresponding per-component license file. https://central.sonatype.com/artifact/org.gridkit.jvmtool/sjk-stacktrace/0.22 -> Apache 2.0 https://central.sonatype.com/artifact/org.gridkit.lab/jvm-attach-api/1.5 -> Apache 2.0 https://central.sonatype.com/artifact/org.javassist/javassist/3.21.0-GA -> Apache 2.0 - https://central.sonatype.com/artifact/org.javassist/javassist/3.25.0-GA -> Apache 2.0 https://central.sonatype.com/artifact/org.javassist/javassist/3.28.0-GA -> Apache 2.0 https://central.sonatype.com/artifact/org.javatuples/javatuples/1.2 -> Apache 2.0 https://central.sonatype.com/artifact/org.jctools/jctools-core/2.1.1 -> Apache 2.0 diff --git a/install-dist/release-docs/licenses/LICENSE-javassist-3.25.0-GA.txt b/install-dist/release-docs/licenses/LICENSE-javassist-3.25.0-GA.txt deleted file mode 100644 index d645695673..0000000000 --- a/install-dist/release-docs/licenses/LICENSE-javassist-3.25.0-GA.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. diff --git a/install-dist/scripts/dependency/known-dependencies.txt b/install-dist/scripts/dependency/known-dependencies.txt index 5abf41d10b..dec9bf0e5c 100644 --- a/install-dist/scripts/dependency/known-dependencies.txt +++ b/install-dist/scripts/dependency/known-dependencies.txt @@ -223,7 +223,6 @@ jansi-2.4.0.jar javaparser-core-3.26.3.jar javapoet-1.13.0.jar javassist-3.21.0-GA.jar -javassist-3.25.0-GA.jar javassist-3.28.0-GA.jar javatuples-1.2.jar javax-websocket-client-impl-9.4.51.v20230217.jar diff --git a/pom.xml b/pom.xml index 9c0b36e692..32a4d7ef3f 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 5.6.0 - 1.7.0 + 1.8.0 4.0.25 2.15.2 4.1.137.Final @@ -113,6 +113,7 @@ UTF-8 bash + 1.5.0 8.10.2