Copilot commented on code in PR #8165:
URL: https://github.com/apache/incubator-seata/pull/8165#discussion_r3612988859


##########
script/native/merge_native_image_config.py:
##########
@@ -0,0 +1,298 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+Merge reachability-metadata.json (generated by GraalVM native-image agent)
+into the corresponding native-image config files.
+
+Usage:
+    python3 merge_native_image_config.py --target-dir PATH [--source PATH]
+
+    --target-dir  Directory containing native-image config files
+                  (reflect-config.json, resource-config.json, etc.).
+    --source      Path to reachability-metadata.json (source).
+                  Default: 
target/native-image-config/reachability-metadata.json
+
+The script merges into:
+    reflect-config.json   — "reflection" node
+    resource-config.json  — "resources" node
+
+Additional top-level keys from reachability-metadata.json can be supported
+by extending the KEY_TO_FILE map below.
+
+Rules:
+    - Only ADD new entries; existing entries are never deleted.
+    - Duplicate detection is keyed on the primary identifier:
+        reflection: "type" (source) → "name" (target)
+        resources:  "glob" (source) → "pattern" (target)
+    - If a target file does not exist, a default (empty) structure is created.
+    - Target file format is preserved.
+    - After merging, run: mvn spotless:apply -pl server -am
+"""

Review Comment:
   The docstring claims "Target file format is preserved", but save_json() 
rewrites JSON with a fixed 2-space indent and a trailing newline. This is 
misleading for users who expect formatting to be retained.



##########
pom.xml:
##########
@@ -387,6 +393,74 @@
                 <module>test-suite/test-old-version</module>
             </modules>
         </profile>
+
+        <!-- profile: native -->
+        <profile>
+            <id>test-native</id>
+            <modules>
+                <module>test-suite/test-native</module>
+            </modules>
+        </profile>

Review Comment:
   The new test-native profile references test-suite/test-native, but that 
module is not present in the repository. Activating -Ptest-native will fail the 
build with a missing module error.



##########
script/native/merge_native_image_config.py:
##########
@@ -0,0 +1,298 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+Merge reachability-metadata.json (generated by GraalVM native-image agent)
+into the corresponding native-image config files.
+
+Usage:
+    python3 merge_native_image_config.py --target-dir PATH [--source PATH]
+
+    --target-dir  Directory containing native-image config files
+                  (reflect-config.json, resource-config.json, etc.).
+    --source      Path to reachability-metadata.json (source).
+                  Default: 
target/native-image-config/reachability-metadata.json
+
+The script merges into:
+    reflect-config.json   — "reflection" node
+    resource-config.json  — "resources" node
+
+Additional top-level keys from reachability-metadata.json can be supported
+by extending the KEY_TO_FILE map below.
+
+Rules:
+    - Only ADD new entries; existing entries are never deleted.
+    - Duplicate detection is keyed on the primary identifier:
+        reflection: "type" (source) → "name" (target)
+        resources:  "glob" (source) → "pattern" (target)
+    - If a target file does not exist, a default (empty) structure is created.
+    - Target file format is preserved.
+    - After merging, run: mvn spotless:apply -pl server -am
+"""
+
+import argparse
+import json
+import os
+import sys
+from typing import Any, Dict, List, Optional, Set, Union
+
+# ---------------------------------------------------------------------------
+# Path defaults — relative to this script's location
+# ---------------------------------------------------------------------------
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+SEATA_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "..", ".."))  # script 
is at script/native/
+
+DEFAULT_SOURCE_FILE = os.path.join(
+    SEATA_ROOT, "target", "native-image-config", "reachability-metadata.json"
+)
+
+# ---------------------------------------------------------------------------
+# Mapping: top-level key in source → (target_filename, id_mapping, format_type)
+#
+# id_mapping: (source_key, target_key)
+#   The field used to detect duplicates (and renamed when needed).
+#
+# format_type:
+#   "list"    — target file is a JSON array (e.g. reflect-config.json)
+#   "includes"— target file has {"resources": {"includes": [...]}} (e.g. 
resource-config.json)
+# ---------------------------------------------------------------------------
+KEY_TO_FILE: Dict[str, tuple] = {
+    "reflection": ("reflect-config.json",
+                   ("type", "name"),
+                   "list"),
+    "resources":  ("resource-config.json",
+                   ("glob", "pattern"),
+                   "includes"),
+}
+
+
+def load_json(path: str) -> Any:
+    """Load and return a JSON file."""
+    with open(path, "r", encoding="utf-8") as fh:
+        return json.load(fh)
+
+
+def save_json(path: str, data: Any) -> None:
+    """Save data as JSON with consistent formatting.
+
+    Uses the same indent as the source file (2 spaces) and appends a
+    trailing newline so Spotless can operate cleanly."""
+    with open(path, "w", encoding="utf-8") as fh:
+        json.dump(data, fh, indent=2, ensure_ascii=False)
+        fh.write("\n")
+
+
+# ---------------------------------------------------------------------------
+# Merge workers
+# ---------------------------------------------------------------------------
+
+def merge_list_format(
+    source_entries: List[dict],
+    target_list: List[dict],
+    src_key: str,
+    tgt_key: str,
+) -> int:
+    """Merge source entries into a list-format target (e.g. 
reflect-config.json).
+
+    Returns the number of newly added entries."""
+    # Build existing-id set from target
+    existing_ids: Set[str] = set()
+    for entry in target_list:
+        if isinstance(entry, dict):
+            val = entry.get(tgt_key)
+            if isinstance(val, str):
+                existing_ids.add(val)
+
+    added = 0
+    for src_entry in source_entries:
+        identifier = src_entry.get(src_key)
+        if not isinstance(identifier, str):
+            continue
+        if identifier in existing_ids:
+            continue

Review Comment:
   merge_list_format() skips a source entry entirely when the class identifier 
already exists in the target. This can drop newly discovered reflection details 
(methods/fields/constructors) for an existing class, leading to native-image 
runtime failures even after re-running the agent.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Install dependencies for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 4C clean -B -pl ${{ matrix.module }} install 
-DskipTests -am
+      - name: "Compile native image for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 2C clean -B -pl ${{ matrix.module }} package 
-DskipTests -Pnative spring-boot:process-aot native:compile
+      - name: "Upload binaries for ${{ matrix.module }} in ${{ matrix.os }}"
+        uses: actions/[email protected]
+        with:
+          name: ${{ matrix.module }}-native-${{ runner.os }}-${{ runner.arch }}
+          path: |
+            ${{ matrix.module }}/target/seata-*-*
+            !${{ matrix.module }}/target/*.jar
+          if-no-files-found: error
+      - name: "Verify native binary for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        shell: sh
+        run: |
+          rm -rf ./${{ matrix.module }}/target/*.jar
+          ./${{ matrix.module }}/target/seata-${{ matrix.module }}-* &
+          NATIVE_PID=$!
+          echo "$NATIVE_PID" > ./seata-native-${{ matrix.module }}.pid
+          echo "Native binary started with PID=$NATIVE_PID"
+          sleep 10
+          if kill -0 $NATIVE_PID 2>/dev/null; then
+            echo "Native binary is running normally (PID=$NATIVE_PID)"
+          else
+            echo "ERROR: Native binary failed to start or crashed 
(PID=$NATIVE_PID)"
+            exit 1
+          fi
+      - name: "Check port 8081 for ${{ matrix.module }} in ${{ matrix.os }}"
+        shell: sh
+        if: matrix.module == 'namingserver'
+        run: |
+          NATIVE_PID=$(cat ./seata-native-${{ matrix.module }}.pid)
+          echo "NATIVE_PID=$NATIVE_PID"
+          for i in 1 2 3 4 5 6; do
+            if curl -sSf http://localhost:8081/naming/v1/health >/dev/null 
2>&1; then
+              echo "Port 8081 is responding"
+              exit 0
+            fi
+            echo "Waiting for port 8081... ($i/6)"
+            sleep 5
+          done
+          echo "ERROR: Port 8081 is not responding after 30 seconds"
+          exit 1
+      - name: "Delete snapshots from the Maven local repository"
+        shell: sh
+        run: find ~/.m2/repository -type d -name '*-SNAPSHOT' -print -exec rm 
-r {} +
+      - name: "Save local maven repository cache"
+        uses: actions/cache/[email protected]
+        if: steps.cache-maven-repository.outputs.cache-hit != 'true'
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}

Review Comment:
   The cache save step should use the same arch-scoped key as the restore step; 
otherwise different architectures will overwrite each other’s caches under the 
same key.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Install dependencies for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 4C clean -B -pl ${{ matrix.module }} install 
-DskipTests -am
+      - name: "Compile native image for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 2C clean -B -pl ${{ matrix.module }} package 
-DskipTests -Pnative spring-boot:process-aot native:compile
+      - name: "Upload binaries for ${{ matrix.module }} in ${{ matrix.os }}"
+        uses: actions/[email protected]
+        with:
+          name: ${{ matrix.module }}-native-${{ runner.os }}-${{ runner.arch }}
+          path: |
+            ${{ matrix.module }}/target/seata-*-*
+            !${{ matrix.module }}/target/*.jar
+          if-no-files-found: error
+      - name: "Verify native binary for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        shell: sh

Review Comment:
   This step uses shell: sh, but sh may not be available on windows-latest (and 
it’s inconsistent with the earlier Maven steps). Use shell: bash to ensure a 
consistent POSIX shell across all runners.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Install dependencies for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 4C clean -B -pl ${{ matrix.module }} install 
-DskipTests -am
+      - name: "Compile native image for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 2C clean -B -pl ${{ matrix.module }} package 
-DskipTests -Pnative spring-boot:process-aot native:compile

Review Comment:
   These steps run ./mvnw and assume Unix tooling; on Windows they can fail 
unless executed under bash. Explicitly set shell: bash for the Maven run steps 
to make the matrix portable.



##########
namingserver/src/main/resources/logback-spring.xml:
##########
@@ -31,20 +31,11 @@
     <springProperty name="LOG_BASH_DIR" 
source="spring.config.additional-location" defaultValue="" />

Review Comment:
   LOG_BASH_DIR is still defined as a springProperty, but after removing the 
conditional includes it is no longer used anywhere in this logback-spring.xml. 
Keeping unused properties is confusing and suggests an external override 
mechanism that no longer works.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version

Review Comment:
   On windows-latest the default shell is PowerShell; invoking ./mvnw (a Unix 
shell script) can fail. Use bash for steps that run ./mvnw so the same command 
works across all matrix OSes.



##########
Makefile:
##########
@@ -53,16 +79,41 @@ checkstyle-diff: ## Run Checkstyle code check only on 
changed .java files
                echo "No changed .java files detected, skip checkstyle."; \
                exit 0; \
        fi; \
-       $(MVN) $(MAVEN_ARGS) clean checkstyle:check -Dcheckstyle.skip=false 
-Dcheckstyle.includes="$${CHECKSTYLE_INCLUDES}"
+       $(MVN) $(MAVEN_ARGS) clean -e checkstyle:check -Dcheckstyle.skip=false 
-Dcheckstyle.includes="$${CHECKSTYLE_INCLUDES}"
 
 license: ## Run license check
-       $(MVN) $(MAVEN_ARGS) clean -Dlicense.skip=false
+       $(MVN) $(MAVEN_ARGS) clean -e -Dlicense.skip=false
 
 test: ## Run unit tests
-       $(MVN) $(MAVEN_ARGS) clean test
+       $(MVN) $(MAVEN_ARGS) clean -e test
 
 package-only: ## Package the project without running tests
-       $(MVN) $(MAVEN_ARGS) clean package -DskipTests
+       $(MVN) $(MAVEN_ARGS) clean -e package -DskipTests
 
 package: ## Package the project
-       $(MVN) $(MAVEN_ARGS) clean package
+       $(MVN) $(MAVEN_ARGS) clean -e package
+
+package-namingserver-native-metadata: ## Build namingserver JAR for GraalVM 
native-image metadata collection
+       $(MVN) $(MAVEN_ARGS) clean -e install -DskipTests -pl namingserver -am
+       $(MVN) $(MAVEN_ARGS) clean -e package -DskipTests -pl namingserver 
-Prelease-seata-jar
+
+run-namingserver-native-metadata: ## Run namingserver with GraalVM 
native-image agent to collect reflection/config metadata
+       ${GRAALVM_HOME}/bin/java 
-agentlib:native-image-agent=config-output-dir=./target/native-image-config 
-jar ./namingserver/target/seata-namingserver.jar --console.user.username=seata 
 --console.user.password=seata
+
+run-test-native-spring-boot: ## Run native test suite via Spring Boot Maven 
plugin
+       $(MVN) $(MAVEN_ARGS) clean -Ptest-native -pl test-suite/test-native 
spring-boot:run
+
+run-test-native: ## Run native test suite via Maven test phase
+       $(MVN) $(MAVEN_ARGS) clean -Ptest-native -pl test-suite/test-native test
+

Review Comment:
   These targets invoke -pl test-suite/test-native, but that module does not 
exist in the repository. As written, make run-test-native* will fail; consider 
removing the targets or guarding them until the module is added.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-

Review Comment:
   The Maven cache key is only scoped by runner.os, so Linux amd64 and Linux 
arm64 (and other arches) will share the same cache key. This can cause 
non-portable artifacts in ~/.m2 (e.g., native libs) to break builds on other 
architectures; include runner.arch in the cache key.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Install dependencies for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 4C clean -B -pl ${{ matrix.module }} install 
-DskipTests -am
+      - name: "Compile native image for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 2C clean -B -pl ${{ matrix.module }} package 
-DskipTests -Pnative spring-boot:process-aot native:compile
+      - name: "Upload binaries for ${{ matrix.module }} in ${{ matrix.os }}"
+        uses: actions/[email protected]
+        with:
+          name: ${{ matrix.module }}-native-${{ runner.os }}-${{ runner.arch }}
+          path: |
+            ${{ matrix.module }}/target/seata-*-*
+            !${{ matrix.module }}/target/*.jar
+          if-no-files-found: error
+      - name: "Verify native binary for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        shell: sh
+        run: |
+          rm -rf ./${{ matrix.module }}/target/*.jar
+          ./${{ matrix.module }}/target/seata-${{ matrix.module }}-* &
+          NATIVE_PID=$!
+          echo "$NATIVE_PID" > ./seata-native-${{ matrix.module }}.pid
+          echo "Native binary started with PID=$NATIVE_PID"
+          sleep 10
+          if kill -0 $NATIVE_PID 2>/dev/null; then
+            echo "Native binary is running normally (PID=$NATIVE_PID)"
+          else
+            echo "ERROR: Native binary failed to start or crashed 
(PID=$NATIVE_PID)"
+            exit 1
+          fi
+      - name: "Check port 8081 for ${{ matrix.module }} in ${{ matrix.os }}"
+        shell: sh

Review Comment:
   This step uses shell: sh and relies on POSIX utilities (curl, kill, sleep). 
Use shell: bash for better cross-platform support on Windows runners.



##########
.github/workflows/native.yml:
##########
@@ -0,0 +1,110 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Native Build
+
+on:
+  push:
+    branches: [ 2.x, develop, master ]
+  pull_request:
+    branches: [ 2.x, develop, master ]
+    types: [ opened, reopened, synchronize ]
+    paths-ignore:
+      - '**.md'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || 
github.ref }}
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+  build:
+    name: build
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ ubuntu-24.04, ubuntu-24.04-arm, macos-26-intel, macos-26, 
windows-latest ]
+        module: [ namingserver ]
+    steps:
+      - name: "Checkout"
+        uses: actions/[email protected]
+      - name: "Set up Java JDK"
+        uses: actions/[email protected]
+        with:
+          distribution: 'graalvm'
+          java-version: 25
+      - name: "Print maven version"
+        run: ./mvnw -version
+      - name: "Restore local maven repository cache"
+        uses: actions/cache/[email protected]
+        id: cache-maven-repository
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Install dependencies for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 4C clean -B -pl ${{ matrix.module }} install 
-DskipTests -am
+      - name: "Compile native image for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        run: ./mvnw -T 2C clean -B -pl ${{ matrix.module }} package 
-DskipTests -Pnative spring-boot:process-aot native:compile
+      - name: "Upload binaries for ${{ matrix.module }} in ${{ matrix.os }}"
+        uses: actions/[email protected]
+        with:
+          name: ${{ matrix.module }}-native-${{ runner.os }}-${{ runner.arch }}
+          path: |
+            ${{ matrix.module }}/target/seata-*-*
+            !${{ matrix.module }}/target/*.jar
+          if-no-files-found: error
+      - name: "Verify native binary for ${{ matrix.module }} in ${{ matrix.os 
}}"
+        shell: sh
+        run: |
+          rm -rf ./${{ matrix.module }}/target/*.jar
+          ./${{ matrix.module }}/target/seata-${{ matrix.module }}-* &
+          NATIVE_PID=$!
+          echo "$NATIVE_PID" > ./seata-native-${{ matrix.module }}.pid
+          echo "Native binary started with PID=$NATIVE_PID"
+          sleep 10
+          if kill -0 $NATIVE_PID 2>/dev/null; then
+            echo "Native binary is running normally (PID=$NATIVE_PID)"
+          else
+            echo "ERROR: Native binary failed to start or crashed 
(PID=$NATIVE_PID)"
+            exit 1
+          fi
+      - name: "Check port 8081 for ${{ matrix.module }} in ${{ matrix.os }}"
+        shell: sh
+        if: matrix.module == 'namingserver'
+        run: |
+          NATIVE_PID=$(cat ./seata-native-${{ matrix.module }}.pid)
+          echo "NATIVE_PID=$NATIVE_PID"
+          for i in 1 2 3 4 5 6; do
+            if curl -sSf http://localhost:8081/naming/v1/health >/dev/null 
2>&1; then
+              echo "Port 8081 is responding"
+              exit 0
+            fi
+            echo "Waiting for port 8081... ($i/6)"
+            sleep 5
+          done
+          echo "ERROR: Port 8081 is not responding after 30 seconds"
+          exit 1
+      - name: "Delete snapshots from the Maven local repository"
+        shell: sh
+        run: find ~/.m2/repository -type d -name '*-SNAPSHOT' -print -exec rm 
-r {} +

Review Comment:
   This step uses shell: sh and runs find/rm; on Windows this can fail unless a 
POSIX shell is guaranteed. Use bash here as well to keep the Windows job 
working.



-- 
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