Skip to content
This repository was archived by the owner on Dec 28, 2025. It is now read-only.

Validate Apache Release (New) #1

Validate Apache Release (New)

Validate Apache Release (New) #1

name: "Validate Apache Release (New)"
on:
workflow_dispatch:
inputs:
release_version:
required: true
description: svn release version
default: '1.7.0'
gpg_user:
required: true
description: current release manager (gpg username)
default: 'pengjunzhi'
java_version:
required: false
description: Java version to validate
default: '11'
type: choice
options:
- '11'
- '17'
push:
branches:
- 'release-*'
pull_request:
branches:
- 'release-*'
jobs:
validate:
name: "Validate Release On ${{ matrix.os }} (java-${{ matrix.java_version }})"
runs-on: ${{ matrix.os }}
env:
RELEASE_VERSION: ${{ inputs.release_version || '1.7.0' }}
GPG_USER: ${{ inputs.gpg_user || 'pengjunzhi' }}
JAVA_VERSION: ${{ inputs.java_version || matrix.java_version || '11' }}
SVN_URL_PREFIX: https://dist.apache.org/repos/dist/dev/incubator/hugegraph
KEYS_URL: https://downloads.apache.org/incubator/hugegraph/KEYS
MAX_FILE_SIZE: 800k
SERVER_START_DELAY: 3
# License Patterns (ASF Category X - Prohibited)
CATEGORY_X: '\bGPL|\bLGPL|Sleepycat License|BSD-4-Clause|\bBCL\b|JSR-275|Amazon Software License|\bRSAL\b|\bQPL\b|\bSSPL|\bCPOL|\bNPL1|Creative Commons Non-Commercial|JSON\.org'
# License Patterns (ASF Category B - Must be documented)
CATEGORY_B: '\bCDDL1|\bCPL|\bEPL|\bIPL|\bMPL|\bSPL|OSL-3.0|UnRAR License|Erlang Public License|\bOFL\b|Ubuntu Font License Version 1.0|IPA Font License Agreement v1.0|EPL2.0|CC-BY'
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Install JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'adopt'
- name: Install dependencies
run: |
if [[ "${{ runner.os }}" == "macOS" ]]; then
brew install svn wget perl
elif [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y subversion wget perl
fi
# Verify all required commands
for cmd in svn gpg shasum mvn java wget tar curl awk grep find perl; do
if ! command -v "$cmd" &> /dev/null; then
echo "Error: Missing required dependency: $cmd"
exit 1
fi
echo "✓ $cmd: $(command -v $cmd)"
done
- name: Cache Maven packages
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Step 1 - Check Dependencies
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [1/9]: Check Dependencies"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Check Java version
CURRENT_JAVA=$(java -version 2>&1 | head -n 1 | awk -F '"' '{print $2}' | awk -F '.' '{print $1}')
echo "Current Java version: $CURRENT_JAVA (Required: ${{ env.JAVA_VERSION }})"
if [[ "$CURRENT_JAVA" != "${{ env.JAVA_VERSION }}" ]]; then
echo "Error: Java version mismatch! Current: Java $CURRENT_JAVA, Required: Java ${{ env.JAVA_VERSION }}"
exit 1
fi
echo "✓ Java version check passed: Java $CURRENT_JAVA"
- name: Step 2 - Prepare Release Files
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [2/9]: Prepare Release Files"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
DIST_DIR="dist/${{ env.RELEASE_VERSION }}"
echo "Downloading from SVN to: ${DIST_DIR}"
rm -rf "${DIST_DIR}"
mkdir -p "${DIST_DIR}"
if ! svn co "${SVN_URL_PREFIX}/${{ env.RELEASE_VERSION }}" "${DIST_DIR}"; then
echo "Error: Failed to download from SVN: ${SVN_URL_PREFIX}/${{ env.RELEASE_VERSION }}"
exit 1
fi
echo "✓ Downloaded release files from SVN"
cd "${DIST_DIR}"
ls -lh
- name: Step 3 - Import & Trust GPG Keys
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [3/9]: Import & Trust GPG Keys"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
echo "Downloading KEYS file from ${KEYS_URL}..."
if ! wget -q "${KEYS_URL}" -O KEYS; then
echo "Error: Failed to download KEYS file from ${KEYS_URL}"
exit 1
fi
echo "✓ KEYS file downloaded"
echo "Importing GPG keys..."
IMPORT_OUTPUT=$(gpg --import KEYS 2>&1)
IMPORTED_COUNT=$(echo "$IMPORT_OUTPUT" | grep -c "imported" || echo "0")
if [[ "$IMPORTED_COUNT" == "0" ]]; then
echo "⚠ No new keys imported (may already exist in keyring)"
else
echo "✓ Imported GPG keys"
fi
# Trust specific user key
if ! gpg --list-keys "${{ env.GPG_USER }}" &>/dev/null; then
echo "Error: User '${{ env.GPG_USER }}' key not found in imported keys. Please verify the username."
exit 1
fi
echo "Trusting GPG key for user: ${{ env.GPG_USER }}"
echo -e "5\ny\n" | gpg --batch --command-fd 0 --edit-key "${{ env.GPG_USER }}" trust 2>/dev/null
echo "✓ Trusted key for ${{ env.GPG_USER }}"
# Trust all imported keys
echo "Trusting all imported public keys..."
TRUSTED=0
for key in $(gpg --no-tty --list-keys --with-colons | awk -F: '/^pub/ {print $5}'); do
echo -e "5\ny\n" | gpg --batch --command-fd 0 --edit-key "$key" trust 2>/dev/null
TRUSTED=$((TRUSTED + 1))
done
echo "✓ Trusted $TRUSTED GPG keys"
- name: Step 4 - Verify SHA512 & GPG Signatures
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [4/9]: Verify SHA512 & GPG Signatures"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
PACKAGE_COUNT=0
for pkg in *.tar.gz; do
if [[ -f "$pkg" ]]; then
PACKAGE_COUNT=$((PACKAGE_COUNT + 1))
fi
done
CURRENT=0
for pkg in *.tar.gz; do
if [[ ! -f "$pkg" ]]; then
continue
fi
CURRENT=$((CURRENT + 1))
echo " [${CURRENT}/${PACKAGE_COUNT}] $pkg"
# Check SHA512
if shasum -a 512 --check "${pkg}.sha512"; then
echo " ✓ SHA512 verified: $pkg"
else
echo " ✗ SHA512 verification failed: $pkg"
exit 1
fi
# Check GPG signature
if gpg --verify "${pkg}.asc" "$pkg" 2>&1 | grep -q "Good signature"; then
echo " ✓ GPG signature verified: $pkg"
else
echo " ✗ GPG signature verification failed: $pkg"
exit 1
fi
done
- name: Step 5 - Validate Source Packages
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [5/9]: Validate Source Packages"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
SRC_PACKAGES=()
for pkg in *-src.tar.gz; do
if [[ -f "$pkg" ]]; then
SRC_PACKAGES+=("$pkg")
fi
done
echo "Found ${#SRC_PACKAGES[@]} source package(s)"
for src_pkg in "${SRC_PACKAGES[@]}"; do
echo ""
echo "Validating source package: $src_pkg"
# Extract package
PACKAGE_DIR=$(basename "$src_pkg" .tar.gz)
rm -rf "$PACKAGE_DIR"
tar -xzf "$src_pkg"
if [[ ! -d "$PACKAGE_DIR" ]]; then
echo "Error: Failed to extract package: $src_pkg"
exit 1
fi
pushd "$PACKAGE_DIR"
# 5.1: Check incubating name
if [[ ! "$src_pkg" =~ "incubating" ]]; then
echo "Error: Package name '$src_pkg' should include 'incubating'"
exit 1
fi
echo " ✓ Package name includes 'incubating'"
# 5.2: Check required files
if [[ ! -f "LICENSE" ]]; then
echo "Error: Package '$src_pkg' missing LICENSE file"
exit 1
fi
echo " ✓ LICENSE file exists"
if [[ ! -f "NOTICE" ]]; then
echo "Error: Package '$src_pkg' missing NOTICE file"
exit 1
fi
echo " ✓ NOTICE file exists"
if [[ ! -f "DISCLAIMER" ]]; then
echo "Error: Package '$src_pkg' missing DISCLAIMER file"
exit 1
fi
echo " ✓ DISCLAIMER file exists"
# 5.3: Check license categories (Category X - Prohibited)
CAT_X_MATCHES=$(grep -r -E "${{ env.CATEGORY_X }}" LICENSE NOTICE 2>/dev/null || true)
CAT_X_COUNT=$(echo "$CAT_X_MATCHES" | grep -v '^$' | wc -l | tr -d ' ')
if [[ $CAT_X_COUNT -ne 0 ]]; then
echo "Error: Package '$src_pkg' contains $CAT_X_COUNT prohibited ASF Category X license(s):"
echo "$CAT_X_MATCHES"
exit 1
fi
echo " ✓ No Category X licenses found"
# 5.4: Check license categories (Category B - Warning)
CAT_B_COUNT=$(grep -r -E "${{ env.CATEGORY_B }}" LICENSE NOTICE 2>/dev/null | wc -l | tr -d ' ' || echo "0")
if [[ $CAT_B_COUNT -ne 0 ]]; then
echo " ⚠ Warning: Package '$src_pkg' contains $CAT_B_COUNT ASF Category B license(s) - please verify documentation"
else
echo " ✓ No Category B licenses found"
fi
# 5.5: Check empty files and directories
EMPTY_DIRS=$(find . -type d -empty 2>/dev/null || true)
EMPTY_FILES=$(find . -type f -empty 2>/dev/null || true)
if [[ -n "$EMPTY_DIRS" ]]; then
echo "Error: Package '$src_pkg' contains empty director(y/ies):"
echo "$EMPTY_DIRS"
exit 1
fi
if [[ -n "$EMPTY_FILES" ]]; then
echo "Error: Package '$src_pkg' contains empty file(s):"
echo "$EMPTY_FILES"
exit 1
fi
echo " ✓ No empty files or directories"
# 5.6: Check file sizes
LARGE_FILES=$(find . -type f -size "+${{ env.MAX_FILE_SIZE }}" 2>/dev/null || true)
if [[ -n "$LARGE_FILES" ]]; then
echo "Error: Package '$src_pkg' contains file(s) larger than ${{ env.MAX_FILE_SIZE }}:"
echo "$LARGE_FILES"
exit 1
fi
echo " ✓ All files are within size limit"
# 5.7: Check binary files
BINARY_COUNT=0
UNDOCUMENTED_COUNT=0
while IFS= read -r binary_file; do
BINARY_COUNT=$((BINARY_COUNT + 1))
FILE_NAME=$(basename "$binary_file")
if ! grep -q "$FILE_NAME" LICENSE 2>/dev/null; then
echo "Error: Undocumented binary file: $binary_file"
UNDOCUMENTED_COUNT=$((UNDOCUMENTED_COUNT + 1))
fi
done < <(find . -type f 2>/dev/null | perl -lne 'print if -B $_' || true)
if [[ $BINARY_COUNT -eq 0 ]]; then
echo " ✓ No binary files found"
elif [[ $UNDOCUMENTED_COUNT -eq 0 ]]; then
echo " ✓ All $BINARY_COUNT binary file(s) are documented"
else
echo "Error: Found $UNDOCUMENTED_COUNT undocumented binary file(s)"
exit 1
fi
# 5.8: Check license headers in source files
echo " Checking for ASF license headers in source files..."
# Define file patterns to check
FILE_PATTERNS=("*.java" "*.sh" "*.py" "*.go" "*.js" "*.ts" "*.jsx" "*.tsx" "*.c" "*.h" "*.cpp" "*.cc" "*.cxx" "*.hpp" "*.scala" "*.groovy" "*.gradle" "*.rs" "*.kt" "*.proto")
# Files to exclude
EXCLUDE_PATTERNS=("*.min.js" "*.min.css" "*node_modules*" "*target*" "*build*" "*.pb.go" "*generated*" "*third_party*" "*vendor*")
FILES_WITHOUT_LICENSE=()
TOTAL_CHECKED=0
EXCLUDED_COUNT=0
DOCUMENTED_COUNT=0
# Build find command
FIND_CMD="find . -type f \\("
FIRST=1
for pattern in "${FILE_PATTERNS[@]}"; do
if [[ $FIRST -eq 1 ]]; then
FIND_CMD="$FIND_CMD -name \"$pattern\""
FIRST=0
else
FIND_CMD="$FIND_CMD -o -name \"$pattern\""
fi
done
FIND_CMD="$FIND_CMD \\) 2>/dev/null"
# Check each source file
while IFS= read -r source_file; do
# Skip if file matches exclude patterns
SHOULD_EXCLUDE=0
for exclude_pattern in "${EXCLUDE_PATTERNS[@]}"; do
if [[ "$source_file" == $exclude_pattern ]]; then
SHOULD_EXCLUDE=1
EXCLUDED_COUNT=$((EXCLUDED_COUNT + 1))
break
fi
done
if [[ $SHOULD_EXCLUDE -eq 1 ]]; then
continue
fi
TOTAL_CHECKED=$((TOTAL_CHECKED + 1))
# Check first 30 lines for Apache license header
if ! head -n 30 "$source_file" | grep -q "Licensed to the Apache Software Foundation"; then
# Check if documented in LICENSE file
FILE_NAME=$(basename "$source_file")
FILE_PATH_RELATIVE=$(echo "$source_file" | sed 's|^\./||')
if [[ -f "LICENSE" ]] && (grep -q "$FILE_NAME" LICENSE 2>/dev/null || grep -q "$FILE_PATH_RELATIVE" LICENSE 2>/dev/null); then
DOCUMENTED_COUNT=$((DOCUMENTED_COUNT + 1))
else
FILES_WITHOUT_LICENSE+=("$source_file")
fi
fi
done < <(eval "$FIND_CMD")
echo " Checked $TOTAL_CHECKED source file(s) for ASF license headers (excluded $EXCLUDED_COUNT generated/vendored files)"
if [[ $DOCUMENTED_COUNT -gt 0 ]]; then
echo " Found $DOCUMENTED_COUNT source file(s) documented in LICENSE as third-party code (allowed)"
fi
if [[ ${#FILES_WITHOUT_LICENSE[@]} -gt 0 ]]; then
echo "Error: Found ${#FILES_WITHOUT_LICENSE[@]} source file(s) without ASF license headers:"
SHOW_COUNT=${#FILES_WITHOUT_LICENSE[@]}
if [[ $SHOW_COUNT -gt 20 ]]; then
SHOW_COUNT=20
fi
for ((i=0; i<SHOW_COUNT; i++)); do
echo " ${FILES_WITHOUT_LICENSE[$i]}"
done
if [[ ${#FILES_WITHOUT_LICENSE[@]} -gt 20 ]]; then
echo " ... and $((${#FILES_WITHOUT_LICENSE[@]} - 20)) more files"
fi
echo "All source files must include the Apache License header or be documented in LICENSE file"
exit 1
else
echo " ✓ All $TOTAL_CHECKED source file(s) have ASF license headers or are documented in LICENSE"
fi
# 5.9: Check version consistency (skip for Python projects)
if [[ ! "$src_pkg" =~ 'hugegraph-ai' ]]; then
echo " Checking version consistency (revision property)..."
ROOT_POM=""
REVISION_VALUE=""
while IFS= read -r pom_file; do
if grep -q "<revision>" "$pom_file" 2>/dev/null; then
REVISION_VALUE=$(grep "<revision>" "$pom_file" | head -1 | sed 's/.*<revision>\(.*\)<\/revision>.*/\1/')
ROOT_POM="$pom_file"
break
fi
done < <(find . -name "pom.xml" -type f 2>/dev/null)
if [[ -n "$ROOT_POM" ]]; then
echo " Found revision property in $ROOT_POM: <revision>$REVISION_VALUE</revision>"
if [[ "$REVISION_VALUE" != "${{ env.RELEASE_VERSION }}" ]]; then
echo "Error: Version mismatch: <revision>$REVISION_VALUE</revision> in $ROOT_POM (expected: ${{ env.RELEASE_VERSION }})"
exit 1
fi
echo " ✓ Version consistency check passed: revision=$REVISION_VALUE"
else
echo " ⚠ Warning: No <revision> property found in pom.xml files - skipping version check"
fi
else
echo " Skipping version check for Python project: $src_pkg"
fi
# 5.10: Check NOTICE year
if [[ -f "NOTICE" ]]; then
CURRENT_YEAR=$(date +%Y)
if ! grep -q "$CURRENT_YEAR" NOTICE; then
echo " ⚠ Warning: NOTICE file may not contain current year ($CURRENT_YEAR). Please verify copyright dates."
else
echo " ✓ NOTICE file contains current year"
fi
fi
# 5.11: Compile source package
echo " Compiling source package: $src_pkg"
if [[ "$src_pkg" =~ 'hugegraph-ai' ]]; then
echo " ⚠ Skipping compilation for AI module (not required)"
elif [[ "$src_pkg" =~ "hugegraph-computer" ]]; then
if cd computer 2>/dev/null && mvn clean package -DskipTests -Dcheckstyle.skip=true -ntp -e; then
echo " ✓ Compilation successful: $src_pkg"
else
echo "Error: Compilation failed: $src_pkg"
exit 1
fi
cd ..
else
if mvn clean package -DskipTests -Dcheckstyle.skip=true -ntp -e; then
echo " ✓ Compilation successful: $src_pkg"
else
echo "Error: Compilation failed: $src_pkg"
exit 1
fi
fi
popd
echo "✓ Finished validating source package: $src_pkg"
done
- name: Step 6 - Test Compiled Server Package
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [6/9]: Test Compiled Server Package"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
# Find server directory
SERVER_DIR=$(find . -maxdepth 3 -type d -path "*hugegraph-incubating*src/hugegraph-server/*hugegraph*${{ env.RELEASE_VERSION }}" 2>/dev/null | head -n1)
if [[ -z "$SERVER_DIR" ]]; then
echo "Error: Could not find compiled server directory"
exit 1
fi
echo "Starting HugeGraph server from: $SERVER_DIR"
pushd "$SERVER_DIR"
if bin/init-store.sh; then
echo " ✓ Store initialized"
else
echo "Error: Failed to initialize store"
exit 1
fi
sleep ${{ env.SERVER_START_DELAY }}
if bin/start-hugegraph.sh; then
echo " ✓ Server started"
else
echo "Error: Failed to start server"
exit 1
fi
popd
- name: Step 7 - Test Compiled Toolchain Packages
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [7/9]: Test Compiled Toolchain Packages"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
TOOLCHAIN_SRC=$(find . -maxdepth 3 -type d -path "*toolchain*src" 2>/dev/null | head -n1)
if [[ -n "$TOOLCHAIN_SRC" ]]; then
pushd "$TOOLCHAIN_SRC"
TOOLCHAIN_DIR=$(find . -maxdepth 1 -type d -name "*toolchain*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$TOOLCHAIN_DIR" ]]; then
pushd "$TOOLCHAIN_DIR"
# Test Loader
echo "Testing HugeGraph Loader..."
LOADER_DIR=$(find . -maxdepth 1 -type d -name "*loader*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$LOADER_DIR" ]]; then
pushd "$LOADER_DIR"
if bin/hugegraph-loader.sh -f ./example/file/struct.json -s ./example/file/schema.groovy -g hugegraph; then
echo " ✓ Loader test passed"
else
echo "Error: Loader test failed"
exit 1
fi
popd
fi
# Test Tool
echo "Testing HugeGraph Tool..."
TOOL_DIR=$(find . -maxdepth 1 -type d -name "*tool*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$TOOL_DIR" ]]; then
pushd "$TOOL_DIR"
if bin/hugegraph gremlin-execute --script 'g.V().count()' && \
bin/hugegraph task-list && \
bin/hugegraph backup -t all --directory ./backup-test; then
echo " ✓ Tool test passed"
else
echo "Error: Tool test failed"
exit 1
fi
popd
fi
# Test Hubble
echo "Testing HugeGraph Hubble..."
HUBBLE_DIR=$(find . -maxdepth 1 -type d -name "*hubble*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$HUBBLE_DIR" ]]; then
pushd "$HUBBLE_DIR"
if bin/start-hubble.sh; then
echo " ✓ Hubble started"
sleep 2
bin/stop-hubble.sh
echo " ✓ Hubble stopped"
else
echo "Error: Hubble test failed"
exit 1
fi
popd
fi
popd
fi
popd
fi
# Stop server after toolchain tests
SERVER_DIR=$(find . -maxdepth 3 -type d -path "*hugegraph-incubating*src/hugegraph-server/*hugegraph*${{ env.RELEASE_VERSION }}" 2>/dev/null | head -n1)
if [[ -n "$SERVER_DIR" ]]; then
echo "Stopping server..."
pushd "$SERVER_DIR"
bin/stop-hugegraph.sh
echo " ✓ Server stopped"
popd
fi
- name: Step 8 - Validate Binary Packages
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [8/9]: Validate Binary Packages"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
BIN_PACKAGES=()
for pkg in *.tar.gz; do
if [[ "$pkg" != *-src.tar.gz ]] && [[ -f "$pkg" ]]; then
BIN_PACKAGES+=("$pkg")
fi
done
echo "Found ${#BIN_PACKAGES[@]} binary package(s)"
for bin_pkg in "${BIN_PACKAGES[@]}"; do
echo ""
echo "Validating binary package: $bin_pkg"
# Extract package
PACKAGE_DIR=$(basename "$bin_pkg" .tar.gz)
rm -rf "$PACKAGE_DIR"
tar -xzf "$bin_pkg"
if [[ ! -d "$PACKAGE_DIR" ]]; then
echo "Error: Failed to extract package: $bin_pkg"
exit 1
fi
pushd "$PACKAGE_DIR"
# 8.1: Check incubating name
if [[ ! "$bin_pkg" =~ "incubating" ]]; then
echo "Error: Package name '$bin_pkg' should include 'incubating'"
exit 1
fi
echo " ✓ Package name includes 'incubating'"
# 8.2: Check required files
if [[ ! -f "LICENSE" ]]; then
echo "Error: Package '$bin_pkg' missing LICENSE file"
exit 1
fi
echo " ✓ LICENSE file exists"
if [[ ! -f "NOTICE" ]]; then
echo "Error: Package '$bin_pkg' missing NOTICE file"
exit 1
fi
echo " ✓ NOTICE file exists"
if [[ ! -f "DISCLAIMER" ]]; then
echo "Error: Package '$bin_pkg' missing DISCLAIMER file"
exit 1
fi
echo " ✓ DISCLAIMER file exists"
# 8.3: Check licenses directory
if [[ ! -d "licenses" ]]; then
echo "Error: Package '$bin_pkg' missing licenses directory"
exit 1
fi
echo " ✓ licenses directory exists"
# 8.4: Check license categories (Category X - Prohibited)
CAT_X_MATCHES=$(grep -r -E "${{ env.CATEGORY_X }}" LICENSE NOTICE licenses 2>/dev/null || true)
CAT_X_COUNT=$(echo "$CAT_X_MATCHES" | grep -v '^$' | wc -l | tr -d ' ')
if [[ $CAT_X_COUNT -ne 0 ]]; then
echo "Error: Package '$bin_pkg' contains $CAT_X_COUNT prohibited ASF Category X license(s):"
echo "$CAT_X_MATCHES"
exit 1
fi
echo " ✓ No Category X licenses found"
# 8.5: Check license categories (Category B - Warning)
CAT_B_COUNT=$(grep -r -E "${{ env.CATEGORY_B }}" LICENSE NOTICE licenses 2>/dev/null | wc -l | tr -d ' ' || echo "0")
if [[ $CAT_B_COUNT -ne 0 ]]; then
echo " ⚠ Warning: Package '$bin_pkg' contains $CAT_B_COUNT ASF Category B license(s) - please verify documentation"
else
echo " ✓ No Category B licenses found"
fi
# 8.6: Check empty files and directories
EMPTY_DIRS=$(find . -type d -empty 2>/dev/null || true)
EMPTY_FILES=$(find . -type f -empty 2>/dev/null || true)
if [[ -n "$EMPTY_DIRS" ]]; then
echo "Error: Package '$bin_pkg' contains empty director(y/ies):"
echo "$EMPTY_DIRS"
exit 1
fi
if [[ -n "$EMPTY_FILES" ]]; then
echo "Error: Package '$bin_pkg' contains empty file(s):"
echo "$EMPTY_FILES"
exit 1
fi
echo " ✓ No empty files or directories"
popd
echo "✓ Finished validating binary package: $bin_pkg"
done
- name: Step 9 - Test Binary Server & Toolchain
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Step [9/9]: Test Binary Server & Toolchain"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd dist/${{ env.RELEASE_VERSION }}
# Test binary server
BIN_SERVER_DIR=$(find . -maxdepth 3 -type d -path "*hugegraph-incubating*${{ env.RELEASE_VERSION }}/*hugegraph-server-incubating*${{ env.RELEASE_VERSION }}" 2>/dev/null | head -n1)
if [[ -n "$BIN_SERVER_DIR" ]]; then
echo "Testing binary server package..."
pushd "$BIN_SERVER_DIR"
if bin/init-store.sh && sleep ${{ env.SERVER_START_DELAY }} && bin/start-hugegraph.sh; then
echo " ✓ Binary server started"
else
echo "Error: Failed to start binary server"
exit 1
fi
popd
fi
# Test binary toolchain
BIN_TOOLCHAIN=$(find . -maxdepth 3 -type d -path "*toolchain*${{ env.RELEASE_VERSION }}" 2>/dev/null | head -n1)
if [[ -n "$BIN_TOOLCHAIN" ]]; then
pushd "$BIN_TOOLCHAIN"
# Test binary loader
BIN_LOADER=$(find . -maxdepth 1 -type d -name "*loader*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$BIN_LOADER" ]]; then
pushd "$BIN_LOADER"
if bin/hugegraph-loader.sh -f ./example/file/struct.json -s ./example/file/schema.groovy -g hugegraph; then
echo " ✓ Binary loader test passed"
else
echo "Error: Binary loader test failed"
exit 1
fi
popd
fi
# Test binary tool
BIN_TOOL=$(find . -maxdepth 1 -type d -name "*tool*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$BIN_TOOL" ]]; then
pushd "$BIN_TOOL"
if bin/hugegraph gremlin-execute --script 'g.V().count()' && \
bin/hugegraph task-list && \
bin/hugegraph backup -t all --directory ./backup-test; then
echo " ✓ Binary tool test passed"
else
echo "Error: Binary tool test failed"
exit 1
fi
popd
fi
# Test binary hubble
BIN_HUBBLE=$(find . -maxdepth 1 -type d -name "*hubble*${{ env.RELEASE_VERSION }}" | head -n1)
if [[ -n "$BIN_HUBBLE" ]]; then
pushd "$BIN_HUBBLE"
if bin/start-hubble.sh; then
echo " ✓ Binary hubble started"
sleep 2
bin/stop-hubble.sh
echo " ✓ Binary hubble stopped"
else
echo "Error: Binary hubble test failed"
exit 1
fi
popd
fi
popd
fi
# Stop binary server
if [[ -n "$BIN_SERVER_DIR" ]]; then
pushd "$BIN_SERVER_DIR"
bin/stop-hugegraph.sh
echo " ✓ Binary server stopped"
popd
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " VALIDATION SUMMARY "
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "✓ VALIDATION PASSED"
echo ""
echo "Please review the validation results and provide feedback in the"
echo "release voting thread on the mailing list."
strategy:
fail-fast: false
matrix:
java_version: ['11']
os: [ubuntu-latest, macos-latest]