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
2 changes: 1 addition & 1 deletion .asf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ github:
# contexts are the names of checks that must pass
contexts:
- check-license-header
- Analyze (java)
- affected-module-tests
required_pull_request_reviews:
dismiss_stale_reviews: true
require_code_owner_reviews: false
Expand Down
112 changes: 91 additions & 21 deletions .github/actions/setup-hugegraph-server/action.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,103 @@
name: 'Setup HugeGraph Server'
description: 'Prepare environment and install HugeGraph server from source'

name: Setup HugeGraph Server
description: Build an immutable fixture once, or start an independent test service
inputs:
travis-dir:
description: 'Path to the Travis assembly directory containing install scripts'
required: true
commit-id:
description: 'HugeGraph commit SHA to install'
required: true

mode:
description: 'standalone (legacy), build (upload), or start (download)'
default: standalone
artifact-name:
description: Workflow-local immutable fixture artifact name
default: ''
repository:
description: 'GitHub owner/repository containing the server source'
default: 'apache/hugegraph'
description: GitHub owner/repository containing the Server source
default: apache/hugegraph
fetch-ref:
description: 'Fetchable ref; the installer verifies its HEAD against commit-id'
description: Fetchable source ref (must resolve to commit-id)
default: ''

commit-id:
description: Exact Server commit SHA
required: true
java-version:
description: JDK major used for the build and runtime
default: '11'
java-home:
description: Optional fixture JDK scoped to this subprocess; keeps Toolchain JDK unchanged
default: ''
isolate-maven-repo:
description: Build fixtures without replacing Toolchain Maven dependencies
default: 'false'
travis-dir:
description: Module service setup directory
default: hugegraph-loader/assembly/travis
runs:
using: composite
steps:
- name: Prepare env and service
- name: Download shared Server fixture
if: inputs.mode == 'start'
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: ${{ runner.temp }}/hugegraph-fixture
- name: Restore exact Server build cache
if: inputs.mode == 'build'
uses: actions/cache@v4
with:
path: ~/hugegraph-fixture-cache
key: server-fixture-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.repository }}-${{ inputs.commit-id }}-jdk${{ inputs.java-version }}-${{ hashFiles('.github/actions/setup-hugegraph-server/action.yml', '.github/actions/setup-hugegraph-server/fixture.sh', '.github/actions/setup-hugegraph-server/manifest.py', '.github/actions/setup-java-env/action.yml', '.github/configs/settings.xml', 'hugegraph-client/assembly/travis/checkout-server.sh', 'hugegraph-client/assembly/travis/start-hugegraph-servers.sh', 'hugegraph-*/assembly/travis/install-hugegraph-from-source.sh', 'hugegraph-hubble/hubble-dist/assembly/travis/download-hugegraph.sh') }}
- name: Prepare fixture or start service
shell: bash
env:
TRAVIS_SCRIPT_DIR: ${{ inputs.travis-dir }}
SERVER_COMMIT: ${{ inputs.commit-id }}
FIXTURE_MODE: ${{ inputs.mode }}
FIXTURE_REPOSITORY: ${{ inputs.repository }}
FIXTURE_COMMIT: ${{ inputs.commit-id }}
FIXTURE_REF: ${{ inputs.fetch-ref }}
FIXTURE_BUILD_INPUTS: ${{ hashFiles('.github/actions/setup-hugegraph-server/action.yml', '.github/actions/setup-hugegraph-server/fixture.sh', '.github/actions/setup-hugegraph-server/manifest.py', '.github/actions/setup-java-env/action.yml', '.github/configs/settings.xml', 'hugegraph-client/assembly/travis/checkout-server.sh', 'hugegraph-client/assembly/travis/start-hugegraph-servers.sh', 'hugegraph-*/assembly/travis/install-hugegraph-from-source.sh', 'hugegraph-hubble/hubble-dist/assembly/travis/download-hugegraph.sh') }}
FIXTURE_PLATFORM: ${{ runner.os }}-${{ runner.arch }}
FIXTURE_JAVA: ${{ inputs.java-version }}
FIXTURE_JAVA_HOME: ${{ inputs.java-home }}
ISOLATE_FIXTURE_REPO: ${{ inputs.isolate-maven-repo }}
FIXTURE_DIR: ${{ runner.temp }}/hugegraph-fixture
SERVER_REPOSITORY: ${{ inputs.repository }}
SERVER_FETCH_REF: ${{ inputs.fetch-ref }}
TRAVIS_DIR: ${{ inputs.travis-dir }}
FIXTURE_ACTION: ${{ github.action_path }}
FIXTURE_ARTIFACT: ${{ inputs.artifact-name }}
run: |
installer=$(realpath "${TRAVIS_SCRIPT_DIR}/install-hugegraph-from-source.sh")
server_build=$(mktemp -d "$RUNNER_TEMP/hugegraph-build.XXXXXX")
cd "$server_build"
bash "$installer" "$SERVER_COMMIT"
set -euo pipefail
if [[ -n "$FIXTURE_JAVA_HOME" ]]; then
[[ -x "$FIXTURE_JAVA_HOME/bin/java" && -x "$FIXTURE_JAVA_HOME/bin/javac" ]]
export JAVA_HOME="$FIXTURE_JAVA_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
fi
if [[ "$ISOLATE_FIXTURE_REPO" == true && "$FIXTURE_MODE" != start ]]; then
fixture_repo=$(mktemp -d "$RUNNER_TEMP/hugegraph-fixture-m2.XXXXXX")
export MAVEN_ARGS="-Dmaven.repo.local=$fixture_repo"
export MAVEN_OPTS="${MAVEN_OPTS:-} -Dmaven.repo.local=$fixture_repo"
fi
if [[ "$FIXTURE_MODE" != standalone && -z "$FIXTURE_ARTIFACT" ]]; then
echo 'artifact-name is required for build/start mode' >&2
exit 1
fi
if [[ "$FIXTURE_MODE" == build ]]; then
bash "$FIXTURE_ACTION/fixture.sh"
else
# Keep downloaded archives and legacy source checkouts out of the caller's tree.
TRAVIS_DIR=$(cd "$TRAVIS_DIR" && pwd)
export TRAVIS_DIR
server_build=$(mktemp -d "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/hugegraph-build.XXXXXX")
cd "$server_build"
if [[ -f "$TRAVIS_DIR/install-hugegraph-from-source.sh" ]]; then
bash "$TRAVIS_DIR/install-hugegraph-from-source.sh" "$FIXTURE_COMMIT"
else
bash "$TRAVIS_DIR/install-hugegraph.sh" "$FIXTURE_COMMIT" "$FIXTURE_REF"
fi
fi
- name: Upload shared Server fixture
if: inputs.mode == 'build'
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: |
${{ runner.temp }}/hugegraph-fixture/server.tar.gz
${{ runner.temp }}/hugegraph-fixture/manifest.json
if-no-files-found: error
retention-days: 7
81 changes: 81 additions & 0 deletions .github/actions/setup-hugegraph-server/fixture.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with this
# work for additional information regarding copyright ownership. The ASF
# licenses this file to You under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
set -euo pipefail

# Identity includes every build input. Never restore an archive from another source.
FIXTURE_REPOSITORY=${FIXTURE_REPOSITORY:-${SERVER_REPOSITORY:-apache/hugegraph}}
FIXTURE_COMMIT=${FIXTURE_COMMIT:-${1:-}}
FIXTURE_REF=${FIXTURE_REF:-$FIXTURE_COMMIT}
FIXTURE_JAVA=${FIXTURE_JAVA:-11}
FIXTURE_DIR=${FIXTURE_DIR:-${RUNNER_TEMP:-${TMPDIR:-/tmp}}/hugegraph-fixture}
FIXTURE_HELPER=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/manifest.py
FIXTURE_BUILD_INPUTS=${FIXTURE_BUILD_INPUTS:-$(python3 "$FIXTURE_HELPER" inputs)}
FIXTURE_PLATFORM=${FIXTURE_PLATFORM:-$(uname -sm)}
FIXTURE_CONFIG="package -DskipTests -Dmaven.javadoc.skip=true -ntp;schema=1;inputs=$FIXTURE_BUILD_INPUTS;platform=$FIXTURE_PLATFORM"
export FIXTURE_REPOSITORY FIXTURE_COMMIT FIXTURE_JAVA FIXTURE_CONFIG FIXTURE_DIR
[[ "$FIXTURE_REPOSITORY" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]
[[ "$FIXTURE_COMMIT" =~ ^[0-9a-f]{40}$ ]]
[[ "$FIXTURE_JAVA" =~ ^[0-9]+$ ]]

fixture_validate_java() {
actual_java=$(java -version 2>&1 | sed -n 's/.*version "\([0-9][0-9]*\).*".*/\1/p' | head -1)
[[ "$actual_java" == "$FIXTURE_JAVA" ]] || { echo 'Fixture JDK mismatch' >&2; return 1; }
}

fixture_verify() { python3 "$FIXTURE_HELPER" verify; }
fixture_build() {
local cache_key cache_dir source_dir archive
cache_key=$(printf '%s\n' "$FIXTURE_REPOSITORY" "$FIXTURE_COMMIT" "$FIXTURE_JAVA" "$FIXTURE_CONFIG" | shasum -a 256 | cut -d ' ' -f 1)
cache_dir="${HOME}/hugegraph-fixture-cache/$cache_key"
mkdir -p "$FIXTURE_DIR"
if [[ -f "$cache_dir/server.tar.gz" && ! -L "$cache_dir/server.tar.gz" &&
-f "$cache_dir/manifest.json" && ! -L "$cache_dir/manifest.json" ]] &&
cp "$cache_dir"/server.tar.gz "$cache_dir"/manifest.json "$FIXTURE_DIR/"; then
if fixture_verify; then return; fi
fi
rm -f "$FIXTURE_DIR/server.tar.gz" "$FIXTURE_DIR/manifest.json"
fixture_validate_java
source_dir="$(mktemp -d "${TMPDIR:-/tmp}/hg-fixture-source.XXXXXX")/source"
SERVER_REPOSITORY=$FIXTURE_REPOSITORY SERVER_FETCH_REF=$FIXTURE_REF \
bash "${FIXTURE_HELPER%/*}/../../../hugegraph-client/assembly/travis/checkout-server.sh" "$FIXTURE_COMMIT" "$source_dir"
(cd "$source_dir" && mvn package -DskipTests -Dmaven.javadoc.skip=true -ntp)
archive=$(find "$source_dir/hugegraph-server" -maxdepth 1 -name 'apache-hugegraph-*.tar.gz' -print)
[[ -n "$archive" && -f "$archive" ]]
cp "$archive" "$FIXTURE_DIR/server.tar.gz"
export FIXTURE_ARCHIVE_NAME=${archive##*/}
python3 "$FIXTURE_HELPER" create
fixture_verify
mkdir -p "$cache_dir"
cp "$FIXTURE_DIR/server.tar.gz" "$FIXTURE_DIR/manifest.json" "$cache_dir/"
rm -rf "$source_dir"
}
fixture_copy_archive() {
fixture_validate_java
fixture_verify
local name
name=$(python3 "$FIXTURE_HELPER" name)
cp "$FIXTURE_DIR/server.tar.gz" "./$name"
}
source "${FIXTURE_HELPER%/*}/service-wait.sh"

case "${FIXTURE_MODE:-standalone}" in
build) fixture_build ;;
start) fixture_copy_archive ;;
standalone) fixture_build; fixture_copy_archive ;;
*) echo 'Invalid fixture mode' >&2; exit 1 ;;
esac
71 changes: 71 additions & 0 deletions .github/actions/setup-hugegraph-server/manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
#
# 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.
#
"""Verify immutable CI fixture identity and archive bytes with the standard library."""
import hashlib
import json
import os
import pathlib
import re
import sys

if sys.argv[1] == "inputs":
repo = pathlib.Path(__file__).resolve().parents[3]
patterns = (
'.github/actions/setup-hugegraph-server/action.yml',
'.github/actions/setup-hugegraph-server/fixture.sh',
'.github/actions/setup-hugegraph-server/manifest.py',
'.github/actions/setup-java-env/action.yml', '.github/configs/settings.xml',
'hugegraph-client/assembly/travis/checkout-server.sh',
'hugegraph-client/assembly/travis/start-hugegraph-servers.sh',
'hugegraph-*/assembly/travis/install-hugegraph-from-source.sh',
'hugegraph-hubble/hubble-dist/assembly/travis/download-hugegraph.sh',
)
inputs = hashlib.sha256()
files = sorted({p for pattern in patterns for p in repo.glob(pattern)})
for path in files:
inputs.update(str(path.relative_to(repo)).encode() + b"\0" + path.read_bytes())
print(inputs.hexdigest())
sys.exit(0)

root = pathlib.Path(os.environ["FIXTURE_DIR"])
identity = {key.lower(): os.environ["FIXTURE_" + key] for key in
("REPOSITORY", "COMMIT", "JAVA", "CONFIG")}
def digest():
h = hashlib.sha256()
with (root / "server.tar.gz").open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
try:
if sys.argv[1] == "create":
data = dict(identity, archive_name=os.environ["FIXTURE_ARCHIVE_NAME"], sha256=digest())
(root / "manifest.json").write_text(json.dumps(data, sort_keys=True) + "\n")
else:
if (root / "manifest.json").is_symlink() or (root / "server.tar.gz").is_symlink():
raise ValueError("fixture must contain regular files")
data = json.loads((root / "manifest.json").read_text())
if any(data.get(key) != value for key, value in identity.items()):
raise ValueError("fixture origin, commit, JDK or build configuration mismatch")
if not re.fullmatch(r"apache-hugegraph-[A-Za-z0-9_.-]+\.tar\.gz", data.get("archive_name", "")):
raise ValueError("invalid archive name")
if data.get("sha256") != digest():
raise ValueError("fixture checksum mismatch")
if sys.argv[1] == "name":
print(data["archive_name"])
except (OSError, ValueError, KeyError) as error:
sys.exit(str(error))
Loading
Loading