1- name : CI
1+ name : Java CI with Maven, Nacos, and Python
22
33on :
44 push :
55 branches : [ "main" ]
66 pull_request :
77 branches : [ "main" ]
88
9- # ───────────────────────────────────────────────────────
10- # Job 1 — 编译 + 单元测试 + Go 编译检查
11- # ───────────────────────────────────────────────────────
129jobs :
13- build-and-test :
10+ unit-tests :
1411 runs-on : ubuntu-latest
15- timeout-minutes : 15
12+ timeout-minutes : 20
1613
1714 steps :
1815 - uses : actions/checkout@v4
1916
20- # ── Java 环境 ──
2117 - name : Set up JDK 17
2218 uses : actions/setup-java@v4
2319 with :
2420 java-version : ' 17'
2521 distribution : ' temurin'
2622 cache : maven
2723
28- - name : Maven Build & Unit Tests
29- run : mvn -B -ntp clean test
24+ - name : Run Maven Tests
25+ run : |
26+ set -euo pipefail
27+ mvn -B -ntp clean test
3028
3129 - name : Upload Surefire Reports
3230 if : always()
@@ -37,60 +35,58 @@ jobs:
3735 **/target/surefire-reports/*.txt
3836 **/target/surefire-reports/*.xml
3937
40- # ── Go 编译检查 ──
38+ go-client-check :
39+ runs-on : ubuntu-latest
40+ timeout-minutes : 10
41+
42+ steps :
43+ - uses : actions/checkout@v4
44+
4145 - name : Set up Go
4246 uses : actions/setup-go@v5
4347 with :
4448 go-version-file : go_client/go.mod
4549 cache-dependency-path : go_client/go.sum
4650
47- - name : Go Client Build Check
51+ - name : Verify Go Client Build
4852 working-directory : go_client
4953 run : |
54+ set -euo pipefail
5055 go mod download
5156 go test ./...
52- go build -o /dev/null main.go
57+ go build -o /tmp/go-rpc-client main.go
5358
54- # ───────────────────────────────────────────────────────
55- # Job 2 — 集成测试 (Nacos + Java Provider + 三端客户端)
56- # ───────────────────────────────────────────────────────
5759 integration-test :
5860 runs-on : ubuntu-latest
59- timeout-minutes : 25
60- needs : build-and-test
61+ timeout-minutes : 30
62+ needs : [unit-tests, go-client-check]
6163
6264 services :
6365 nacos :
64- image : nacos/nacos-server:v2.3.1-slim
66+ image : nacos/nacos-server:v2.2.3
6567 env :
6668 MODE : standalone
67- NACOS_AUTH_ENABLE : " false"
68- JVM_XMS : 256m
69- JVM_XMX : 256m
70- JVM_XMN : 128m
71- # 彻底禁用 Metrics 采集和 Prometheus 导出,规避 JDK 8 在 cgroup v2 环境下的 NPE
72- JAVA_OPT_EXT : " -Dmanagement.metrics.export.prometheus.enabled=false -Dmanagement.endpoint.prometheus.enabled=false -Dmanagement.metrics.binders.processor.enabled=false -Dmanagement.metrics.binders.jvm.enabled=false -Dmanagement.metrics.binders.uptime.enabled=false -Dmanagement.metrics.binders.files.enabled=false"
69+ AUTH_ENABLE : false
7370 ports :
7471 - 8848:8848
7572 - 9848:9848
73+ # Wait for Nacos to be fully ready
7674 options : >-
77- --health-cmd "curl -sf http://localhost:8848/nacos/v1/console/health/readiness || exit 1"
75+ --name nacos-server
76+ --health-cmd "curl -f http://localhost:8848/nacos/v1/console/health/readiness"
7877 --health-interval 10s
7978 --health-timeout 5s
80- --health-retries 20
81- --health-start-period 30s
82-
79+ --health-retries 10
8380 steps :
8481 - uses : actions/checkout@v4
85-
86- # ── 设置工具链 ──
82+
8783 - name : Set up JDK 17
8884 uses : actions/setup-java@v4
8985 with :
9086 java-version : ' 17'
9187 distribution : ' temurin'
9288 cache : maven
93-
89+
9490 - name : Set up Python
9591 uses : actions/setup-python@v5
9692 with :
@@ -102,161 +98,135 @@ jobs:
10298 go-version-file : go_client/go.mod
10399 cache-dependency-path : go_client/go.sum
104100
105- - name : Install Python gRPC Dependencies
106- run : pip install grpcio grpcio-tools protobuf
107-
108- # ── 构建 JAR 包 ──
109- - name : Build Jars (skip tests)
110- run : mvn -B -ntp -DskipTests clean package
111-
112- # ── 确认 Nacos 就绪 ──
113- - name : Wait For Nacos
101+ - name : Install Python Dependencies
114102 run : |
115- echo "=== Nacos 容器状态 ==="
116- docker ps --filter "name=nacos" --format "table {{.ID}}\t{{.Status}}\t{{.Ports}}"
117-
118- echo "等待 HTTP 端口 8848..."
119- timeout 120s bash -c 'until echo > /dev/tcp/localhost/8848; do sleep 1; done'
120-
121- echo "等待 gRPC 端口 9848..."
122- timeout 120s bash -c 'until echo > /dev/tcp/localhost/9848; do sleep 1; done'
103+ set -euo pipefail
104+ python -m pip install --upgrade pip
105+ pip install grpcio grpcio-tools protobuf
123106
124- echo "验证 Nacos Readiness API..."
125- timeout 60s bash -c 'until curl -sf http://localhost:8848/nacos/v1/console/health/readiness > /dev/null; do sleep 2; done'
126-
127- echo "✅ Nacos 已就绪"
128-
129- # ── 启动 RPC Provider ──
130- - name : Start RPC Provider
107+ - name : Build Jars For Integration Test
131108 run : |
132- # 构建 classpath
133- CP="rpc-provider/target/rpc-provider-1.0-SNAPSHOT.jar"
134- CP="$CP:rpc-transport-netty/target/rpc-transport-netty-1.0-SNAPSHOT.jar"
135- CP="$CP:rpc-core/target/rpc-core-1.0-SNAPSHOT.jar"
136- CP="$CP:rpc-common/target/rpc-common-1.0-SNAPSHOT.jar"
137- CP="$CP:rpc-api/target/rpc-api-1.0-SNAPSHOT.jar"
138- CP="$CP:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout -pl rpc-provider -am)"
139-
140- nohup java \
141- -Dlogback.configurationFile=rpc-core/src/main/resources/logback.xml \
142- -Drpc.protocol=grpc \
143- -cp "$CP" \
144- com.xiaoyu.rpc.provider.ProviderApp > server.log 2>&1 &
109+ set -euo pipefail
110+ mvn -B -ntp -DskipTests clean package
145111
146- echo "等待 Provider 端口 8080..."
112+ - name : Wait For Nacos Ports
113+ run : |
114+ set -euo pipefail
115+ echo "Waiting for Nacos HTTP API on 8848..."
116+ timeout 60s bash -c 'until curl -sf http://localhost:8848/nacos/v1/console/health/readiness > /dev/null; do sleep 1; done'
117+ echo "Waiting for Nacos gRPC port on 9848..."
118+ timeout 60s bash -c 'until echo > /dev/tcp/localhost/9848; do sleep 1; done'
119+ echo "Nacos 8848/9848 are both reachable."
120+
121+ - name : Start RPC Provider (Java Server)
122+ run : |
123+ set -euo pipefail
124+ # Build classpath including project jars and dependencies
125+ CLASSPATH="rpc-provider/target/rpc-provider-1.0-SNAPSHOT.jar:rpc-transport-netty/target/rpc-transport-netty-1.0-SNAPSHOT.jar:rpc-core/target/rpc-core-1.0-SNAPSHOT.jar:rpc-common/target/rpc-common-1.0-SNAPSHOT.jar:rpc-api/target/rpc-api-1.0-SNAPSHOT.jar:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout -pl rpc-provider -am)"
126+
127+ echo "Starting Java Server..."
128+ echo "Provider protocol override: rpc.protocol=grpc"
129+ # Run in background with nohup
130+ nohup java -Dlogback.configurationFile=rpc-core/src/main/resources/logback.xml -Drpc.protocol=grpc -cp "$CLASSPATH" com.xiaoyu.rpc.provider.ProviderApp > server.log 2>&1 &
131+
132+ # Wait for server port 8080 to be available
133+ echo "Waiting for Java Server to start on port 8080..."
147134 timeout 60s bash -c 'until echo > /dev/tcp/localhost/8080; do sleep 1; done'
148- echo "✅ Provider 已启动"
149- head -20 server.log
135+
136+ echo "Java Server is running!"
137+ # Optional: Print initial logs
138+ head -n 20 server.log
150139
151- # ── 等待服务注册完成 ──
152- - name : Wait For Service Registration
140+ - name : Wait For Service Registration In Nacos
153141 run : |
154- echo "等待 HelloService 注册到 Nacos..."
142+ set -euo pipefail
143+ echo "Waiting for HelloService registration..."
155144 if timeout 60s bash -c 'until grep -q "Service registered: com.xiaoyu.rpc.api.HelloService" server.log; do sleep 1; done'; then
156- echo "✅ HelloService 注册成功 "
145+ echo "HelloService registration confirmed. "
157146 else
158- echo "❌ 注册超时,最近日志: "
159- tail -100 server.log
147+ echo "Service registration wait timed out. Recent server logs: "
148+ tail -n 120 server.log || true
160149 exit 1
161150 fi
162151
163- # ── 并行运行三端客户端 ──
164- - name : Run Multi-Client Integration Tests
152+ - name : Run Multi-Client Chains In Parallel
165153 run : |
166- mkdir -p .ci-results
154+ set -euo pipefail
155+ mkdir -p .ci-status
167156
168- # --- Java 客户端 ---
169- run_java() {
170- CP="rpc-consumer/target/rpc-consumer-1.0-SNAPSHOT.jar"
171- CP="$CP:rpc-transport-netty/target/rpc-transport-netty-1.0-SNAPSHOT.jar"
172- CP="$CP:rpc-core/target/rpc-core-1.0-SNAPSHOT.jar"
173- CP="$CP:rpc-common/target/rpc-common-1.0-SNAPSHOT.jar"
174- CP="$CP:rpc-api/target/rpc-api-1.0-SNAPSHOT.jar"
175- CP="$CP:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout -pl rpc-consumer -am)"
157+ CLASSPATH="rpc-consumer/target/rpc-consumer-1.0-SNAPSHOT.jar:rpc-transport-netty/target/rpc-transport-netty-1.0-SNAPSHOT.jar:rpc-core/target/rpc-core-1.0-SNAPSHOT.jar:rpc-common/target/rpc-common-1.0-SNAPSHOT.jar:rpc-api/target/rpc-api-1.0-SNAPSHOT.jar:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout -pl rpc-consumer -am)"
176158
177- echo "[Java] 开始运行..."
178- if timeout 120s java \
179- -Dlogback.configurationFile=rpc-core/src/main/resources/logback.xml \
180- -Drpc.protocol=grpc -Drpc.serializer=protobuf \
181- -cp "$CP" com.xiaoyu.rpc.consumer.ConsumerApp | tee java-client.log \
182- && grep -q "Result1:" java-client.log \
183- && grep -q "Result2:" java-client.log; then
184- echo "PASS" > .ci-results/java
159+ run_java() {
160+ echo "Running Java Client (grpc)..."
161+ if timeout 120s java -Dlogback.configurationFile=rpc-core/src/main/resources/logback.xml -Drpc.protocol=grpc -Drpc.serializer=protobuf -cp "$CLASSPATH" com.xiaoyu.rpc.consumer.ConsumerApp | tee java-client.log \
162+ && grep -q "Result1:" java-client.log \
163+ && grep -q "Result2:" java-client.log; then
164+ echo "PASS" > .ci-status/java.status
185165 else
186- echo "[ Java] ❌ 失败 "
187- echo "FAIL" > .ci-results /java
166+ echo "Java client chain failed or timed out. "
167+ echo "FAIL" > .ci-status /java.status
188168 fi
189169 }
190170
191- # --- Python 客户端 ---
192171 run_python() {
193- echo "[ Python] 开始运行 ..."
172+ echo "Running Python Client ..."
194173 if timeout 120s bash -c 'cd python_client && python client.py' | tee python-client.log \
195- && grep -q "Message: Success" python-client.log; then
196- echo "PASS" > .ci-results /python
174+ && grep -q "Message: Success" python-client.log; then
175+ echo "PASS" > .ci-status /python.status
197176 else
198- echo "[ Python] ❌ 失败 "
199- echo "FAIL" > .ci-results /python
177+ echo "Python client chain failed or timed out. "
178+ echo "FAIL" > .ci-status /python.status
200179 fi
201180 }
202181
203- # --- Go 客户端 ---
204182 run_go() {
205- echo "[Go] 开始运行 ..."
183+ echo "Running Go Client ..."
206184 if timeout 120s bash -c 'cd go_client && go run main.go' | tee go-client.log \
207- && grep -q "Message: Success" go-client.log; then
208- echo "PASS" > .ci-results /go
185+ && grep -q "Message: Success" go-client.log; then
186+ echo "PASS" > .ci-status /go.status
209187 else
210- echo "[Go] ❌ 失败 "
211- echo "FAIL" > .ci-results /go
188+ echo "Go client chain failed or timed out. "
189+ echo "FAIL" > .ci-status /go.status
212190 fi
213191 }
214192
215- # 并行启动三个客户端
216193 run_java &
194+ PID_JAVA=$!
217195 run_python &
196+ PID_PY=$!
218197 run_go &
219- wait
220-
221- # ── 聚合结果 ──
222- - name : Check Results
223- run : |
224- JAVA=$(cat .ci-results/java 2>/dev/null || echo "FAIL")
225- PY=$(cat .ci-results/python 2>/dev/null || echo "FAIL")
226- GO=$(cat .ci-results/go 2>/dev/null || echo "FAIL")
198+ PID_GO=$!
227199
228- echo "╔══════════════════════════════════╗"
229- echo "║ 集成测试结果 ║"
230- echo "╠══════════════════════════════════╣"
231- printf "║ Java : %-22s║\n" "$JAVA"
232- printf "║ Python : %-22s║\n" "$PY"
233- printf "║ Go : %-22s║\n" "$GO"
234- echo "╚══════════════════════════════════╝"
200+ wait "${PID_JAVA}" || true
201+ wait "${PID_PY}" || true
202+ wait "${PID_GO}" || true
235203
236- if [[ "$JAVA" != "PASS" || "$PY" != "PASS" || "$GO" != "PASS" ]]; then
237- echo "::error::至少一个客户端测试失败"
204+ - name : Aggregate Multi-Client Results
205+ run : |
206+ set -euo pipefail
207+ JAVA_RESULT=$(cat .ci-status/java.status 2>/dev/null || echo "FAIL")
208+ PY_RESULT=$(cat .ci-status/python.status 2>/dev/null || echo "FAIL")
209+ GO_RESULT=$(cat .ci-status/go.status 2>/dev/null || echo "FAIL")
210+
211+ echo "Multi-client chain summary:"
212+ echo " Java : ${JAVA_RESULT}"
213+ echo " Python : ${PY_RESULT}"
214+ echo " Go : ${GO_RESULT}"
215+
216+ if [[ "${JAVA_RESULT}" != "PASS" || "${PY_RESULT}" != "PASS" || "${GO_RESULT}" != "PASS" ]]; then
217+ echo "At least one client chain failed."
238218 exit 1
239219 fi
240- echo "✅ 全部通过"
241-
242- # ── 失败时输出诊断日志 ──
243- - name : Dump Nacos Logs (on failure)
244- if : failure()
245- run : |
246- echo "=== Nacos 容器日志 (最后 200 行) ==="
247- docker logs "${{ job.services.nacos.id }}" 2>&1 | tail -200 || true
248- echo ""
249- echo "=== Java Provider 日志 ==="
250- cat server.log 2>/dev/null || echo "(无日志文件)"
220+ echo "All three client chains passed."
251221
252222 - name : Upload CI Logs
253223 if : always()
254224 uses : actions/upload-artifact@v4
255225 with :
256- name : integration -logs
226+ name : ci -logs
257227 path : |
258228 server.log
259229 java-client.log
260230 python-client.log
261231 go-client.log
262- .ci-results/*
232+ .ci-status/*.status
0 commit comments