imbajin commented on code in PR #464:
URL: https://github.com/apache/hugegraph-doc/pull/464#discussion_r3732282910


##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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'

Review Comment:
   ‼️ critical — The Category X pattern uses `\b`, but the workflow runs on 
`macos-latest` where BSD grep does not treat `\b` as a word boundary (`printf 
'GPL\n' | grep -E '\\bGPL'` returns no match). Prohibited licenses can 
therefore pass on macOS while the Linux job rejects them. Use portable POSIX 
boundaries or a portable matcher and add a macOS regression check.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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

Review Comment:
   ⚠️ important — `shasum --check "${pkg}.sha512"` accepts the filenames 
embedded in the sidecar and never asserts that the sidecar contains exactly 
`$pkg`. A sidecar entry for another existing file can make this package pass 
without its own digest being checked. Parse one exact digest for `$pkg` and 
reject missing, duplicate, malformed, or extra records.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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') }}

Review Comment:
   ⚠️ important — `hashFiles('**/pom.xml')` is evaluated before the workflow 
checks out/downloads the release source, and this documentation repository has 
no Maven POMs. The broad `restore-keys` can therefore restore an unrelated 
Maven cache for the later build. Remove the broad cache or key an isolated 
repository from the extracted release and version.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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 
' ')

Review Comment:
   ‼️ critical — When `CAT_X_MATCHES` is empty, `grep -v '^$'` exits 1; under 
GitHub Actions' default `bash -eo pipefail`, this assignment exits the step 
before the package check. I reproduced the non-zero status with `bash -eo 
pipefail`; the same pattern appears again at line 665. Count matches with an 
error-safe tool such as `awk` and keep read errors fail-closed.



##########
content/cn/docs/quickstart/toolchain/hugegraph-seatunnel-connector.md:
##########
@@ -0,0 +1,79 @@
+---
+title: "HugeGraph-SeaTunnel Connector Quick Start"
+linkTitle: "使用 SeaTunnel Connector 同步数据"
+weight: 5
+---
+
+### 1 HugeGraph-SeaTunnel Connector 概述
+
+[Apache SeaTunnel](https://seatunnel.apache.org/) 
是一个高性能、分布式的数据集成平台,支持海量数据的实时同步与批处理。
+HugeGraph 为 Apache SeaTunnel 提供了 Connector-V2 支持,用户可以通过 SeaTunnel 方便地在 
HugeGraph
+与外部数据系统之间进行数据同步。
+
+> **注意**:SeaTunnel Connector 由 HugeGraph 社区贡献至 Apache SeaTunnel 项目,具体使用方式请参考
+> [Apache SeaTunnel 官方文档](https://seatunnel.apache.org/docs/)。
+
+### 2 功能特性
+
+HugeGraph-SeaTunnel Connector 提供以下能力:
+
+- **HugeGraph Source Connector**:从 HugeGraph 读取图数据,支持顶点和边的批量读取
+- **HugeGraph Sink Connector**:将外部数据写入 HugeGraph,支持顶点和边的批量写入
+- **顶点同步**:支持全量或增量同步顶点数据
+- **边同步**:支持全量或增量同步边数据
+- **Schema 映射**:自动映射 HugeGraph Schema(PropertyKey、VertexLabel、EdgeLabel)与外部数据字段
+- **数据迁移**:支持在不同 HugeGraph 实例之间进行数据迁移,或从其他数据源导入图数据
+
+### 3 环境要求
+
+- Java 8+

Review Comment:
   ⚠️ important — The page claims `Java 8+` and `HugeGraph Server 1.0.0+`, but 
the released SeaTunnel 2.3.13 connector depends on HugeGraph client/common 
1.5.0, and HugeGraph 1.5.0+ requires Java 11. Publish a verified 
SeaTunnel/HugeGraph version matrix and do not advertise an unsupported Java 8 
or Server 1.0.x combination.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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"

Review Comment:
   ⚠️ important — The workflow extracts downloaded release archives directly 
with `tar -xzf` before compiling and executing their contents. It does not 
reject absolute, `..`, symlink, or hardlink members, so a crafted archive can 
escape the staging directory or redirect later validation commands. Validate 
members first and extract into a fresh isolated directory with resolved-path 
checks. Apply the same fix to the binary extraction at line 621.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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

Review Comment:
   ⚠️ important — Source validation runs `mvn clean package -DskipTests 
-Dcheckstyle.skip=true` without the `apache-release` profile used by the 
repository's release workflow. Profile-specific packaging and release checks 
are consequently never exercised. Build with the release profile or explicitly 
run the omitted checks before declaring validation passed.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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

Review Comment:
   ⚠️ important — The version check stops at the first POM containing 
`<revision>` and skips validation entirely if none is found. A child module can 
therefore carry a mismatched version while the workflow reports success. 
Validate all relevant parent/child POM versions against the release version and 
fail when the expected version metadata is absent.



##########
content/cn/docs/quickstart/toolchain/hugegraph-seatunnel-connector.md:
##########
@@ -0,0 +1,79 @@
+---
+title: "HugeGraph-SeaTunnel Connector Quick Start"
+linkTitle: "使用 SeaTunnel Connector 同步数据"
+weight: 5
+---
+
+### 1 HugeGraph-SeaTunnel Connector 概述
+
+[Apache SeaTunnel](https://seatunnel.apache.org/) 
是一个高性能、分布式的数据集成平台,支持海量数据的实时同步与批处理。
+HugeGraph 为 Apache SeaTunnel 提供了 Connector-V2 支持,用户可以通过 SeaTunnel 方便地在 
HugeGraph
+与外部数据系统之间进行数据同步。
+
+> **注意**:SeaTunnel Connector 由 HugeGraph 社区贡献至 Apache SeaTunnel 项目,具体使用方式请参考
+> [Apache SeaTunnel 官方文档](https://seatunnel.apache.org/docs/)。
+
+### 2 功能特性
+
+HugeGraph-SeaTunnel Connector 提供以下能力:
+
+- **HugeGraph Source Connector**:从 HugeGraph 读取图数据,支持顶点和边的批量读取
+- **HugeGraph Sink Connector**:将外部数据写入 HugeGraph,支持顶点和边的批量写入
+- **顶点同步**:支持全量或增量同步顶点数据
+- **边同步**:支持全量或增量同步边数据
+- **Schema 映射**:自动映射 HugeGraph Schema(PropertyKey、VertexLabel、EdgeLabel)与外部数据字段
+- **数据迁移**:支持在不同 HugeGraph 实例之间进行数据迁移,或从其他数据源导入图数据
+
+### 3 环境要求
+
+- Java 8+
+- Apache SeaTunnel 2.3.x+
+- HugeGraph Server 1.0.0+
+
+### 4 快速开始
+
+#### 4.1 安装 SeaTunnel
+
+请参考 [Apache SeaTunnel 安装指南](https://seatunnel.apache.org/docs/start-v2/) 完成 
SeaTunnel 的部署。
+
+#### 4.2 使用 HugeGraph Connector
+
+HugeGraph Connector 已包含在 SeaTunnel 的 Connector-V2 生态中。在 SeaTunnel 配置文件中直接引用即可:
+
+**从 HugeGraph 读取数据(Source)示例:**
+
+```hocon
+source {
+  HugeGraph {
+    url = "http://127.0.0.1:8080";
+    graph = "hugegraph"
+    label = "person"
+    # 更多配置请参考 SeaTunnel 官方文档
+  }
+}
+```
+
+**向 HugeGraph 写入数据(Sink)示例:**
+
+```hocon
+sink {
+  HugeGraph {
+    url = "http://127.0.0.1:8080";
+    graph = "hugegraph"
+    # 更多配置请参考 SeaTunnel 官方文档
+  }
+}
+```
+
+> 完整配置参数和详细用法请参考 [Apache SeaTunnel Connector-V2 
文档](https://seatunnel.apache.org/docs/connector-v2/)。

Review Comment:
   ⚠️ important — The "complete configuration" link points to the generic 
`/docs/connector-v2/` index rather than the concrete HugeGraph connector 
reference, so users cannot find the options used by this page. Link to the 
versioned/current [HugeGraph Sink Connector 
documentation](https://seatunnel.apache.org/docs/connectors/sink/HugeGraph/) 
and qualify any Source claim separately.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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")

Review Comment:
   ⚠️ important — Category B is labeled "Must be documented", but this branch 
only emits a warning and continues; the parent release workflow rejects these 
matches. Enforce the documented policy (or explicitly verify the license 
documentation) in both the source and binary checks instead of reporting 
success.



##########
.github/workflows/validate-release-new.yml:
##########
@@ -0,0 +1,805 @@
+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 
}})"

Review Comment:
   🧹 minor — `java_version` accepts 11 or 17, but the job name always uses 
`matrix.java_version`, whose matrix contains only 11. A manual Java 17 run will 
execute Java 17 while being labeled `java-11`. Use the effective input in the 
job name or remove the misleading override.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to