Skip to content

Commit e12a4c1

Browse files
authored
Merge pull request #89 from beehive-lab/ci/quarkus-langchain4j-IT
AddCI Actions for Quarkus-LangChain4j integration
2 parents 87624de + 3073c7d commit e12a4c1

File tree

1 file changed

+260
-0
lines changed

1 file changed

+260
-0
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
name: Integration Quarkus-LangChain4j
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
types: [opened, synchronize, reopened]
9+
schedule:
10+
# Run every Saturday at 02:30 UTC to catch dependency breakages
11+
- cron: '30 2 * * 6'
12+
workflow_dispatch:
13+
inputs:
14+
quarkus_langchain4j_version:
15+
description: 'Quarkus LangChain4j version to test against'
16+
required: false
17+
type: string
18+
quarkus_version:
19+
description: 'Quarkus platform version to test against'
20+
required: false
21+
type: string
22+
23+
env:
24+
JAVA_HOME: /opt/jenkins/jdks/graal-23.1.0/jdk-21.0.3
25+
TORNADO_ROOT: ${{ github.workspace }}/GPULlama3.java/external/tornadovm
26+
GRAAL_JARS: /opt/graalJars
27+
QUARKUS_PORT: 8081
28+
29+
jobs:
30+
quarkus-integration-test:
31+
if: github.repository == 'beehive-lab/GPULlama3.java'
32+
runs-on: [self-hosted]
33+
timeout-minutes: 30
34+
strategy:
35+
fail-fast: true
36+
matrix:
37+
backend:
38+
- name: opencl
39+
- name: ptx
40+
41+
steps:
42+
- name: Checkout GPULlama3
43+
uses: actions/checkout@v4
44+
45+
# Step 1: Clone and build TornadoVM
46+
- name: Clone TornadoVM master
47+
run: |
48+
git clone --depth 1 --branch master \
49+
https://github.com/beehive-lab/TornadoVM.git \
50+
$TORNADO_ROOT
51+
- name: Set up Python venv for TornadoVM
52+
run: |
53+
python3 -m venv $TORNADO_ROOT/venv
54+
source $TORNADO_ROOT/venv/bin/activate
55+
python --version
56+
- name: Build TornadoVM
57+
run: |
58+
cd $TORNADO_ROOT
59+
mkdir -p graalJars && cp $GRAAL_JARS/* graalJars/
60+
source venv/bin/activate
61+
echo "=== Building TornadoVM ==="
62+
63+
make BACKEND=${{ matrix.backend.name }}
64+
65+
echo "=== Searching for TornadoVM SDK directory ==="
66+
SDK_DIR=$(find dist -type d -maxdepth 3 -path "*/tornadovm-*-${{ matrix.backend.name }}" | head -n 1)
67+
if [ -z "$SDK_DIR" ]; then
68+
echo "::error::Could not locate TornadoVM SDK directory!"
69+
find dist -maxdepth 5 -type d
70+
exit 1
71+
fi
72+
FULL_SDK="${PWD}/${SDK_DIR}"
73+
echo "Detected TornadoVM SDK: $FULL_SDK"
74+
75+
# Export for current shell session
76+
export TORNADOVM_HOME="$FULL_SDK"
77+
export PATH="$FULL_SDK/bin:$JAVA_HOME/bin:$PATH"
78+
79+
# Save for subsequent steps
80+
echo "TORNADOVM_HOME=$FULL_SDK" >> $GITHUB_ENV
81+
echo "PATH=$PATH" >> $GITHUB_ENV
82+
83+
echo "=== Checking tornado CLI ==="
84+
which tornado || { echo "::error::tornado not in PATH"; exit 1; }
85+
tornado --devices
86+
87+
# Step 2: Build GPULlama3.java
88+
- name: Build GPULlama3.java
89+
run: |
90+
cd ${{ github.workspace }}
91+
echo "Using TORNADOVM_HOME=$TORNADOVM_HOME"
92+
export PATH="$TORNADOVM_HOME/bin:$JAVA_HOME/bin:$PATH"
93+
tornado --version
94+
95+
# Append SNAPSHOT to GPULlama3 version
96+
GPULLAMA3_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
97+
GPULLAMA3_VERSION="${GPULLAMA3_VERSION}-SNAPSHOT"
98+
echo "GPULlama3 version: $GPULLAMA3_VERSION"
99+
./mvnw versions:set -DnewVersion=$GPULLAMA3_VERSION
100+
101+
# Build
102+
./mvnw clean install -DskipTests
103+
104+
# Save GPULlama3.java version for subsequent steps
105+
echo "GPULLAMA3_VERSION=$GPULLAMA3_VERSION" >> $GITHUB_ENV
106+
107+
# Step 3: Clone Quarkus LangChain4j
108+
- name: Clone Quarkus LangChain4j
109+
run: |
110+
cd ${{ github.workspace }}
111+
git clone https://github.com/quarkiverse/quarkus-langchain4j.git
112+
113+
# Step 4: Build Quarkus LangChain4j with current GPULlama3.java
114+
- name: Build Quarkus LangChain4j
115+
run: |
116+
cd ${{ github.workspace }}/quarkus-langchain4j
117+
export PATH="$TORNADOVM_HOME/bin:$JAVA_HOME/bin:$PATH"
118+
119+
# Update the GPULlama3 version used by quarkus-langchain4j
120+
POM="pom.xml"
121+
sed -i 's/<gpu-llama3\.version>.*<\/gpu-llama3\.version>/<gpu-llama3.version>'$GPULLAMA3_VERSION'<\/gpu-llama3.version>/' "$POM"
122+
123+
# Use reactor to build *only *GPULlama3 integration test + dependencies
124+
# This recompiles everything with the same Java version, avoiding compatibility issues
125+
# The -Dtornado flag activates the TornadoVM profile which includes gpu-llama3 module
126+
mvn clean install -pl integration-tests/gpu-llama3 -am -DskipTests -Dtornado
127+
128+
# Step 4.5: Verify GPULlama3 JAR
129+
- name: Verify GPULlama3 Dependency
130+
run: |
131+
cd ${{ github.workspace }}/quarkus-langchain4j/integration-tests/gpu-llama3
132+
echo "GPULlama3 dependency used by Quarkus-LangChain4j:"
133+
mvn dependency:tree | grep "io.github.beehive-lab:gpu-llama3"
134+
135+
# Step 5: Start Quarkus Application and Wait for Startup
136+
- name: Start Quarkus Application and Wait for Startup
137+
run: |
138+
cd ${{ github.workspace }}/quarkus-langchain4j/integration-tests/gpu-llama3
139+
export PATH="$TORNADOVM_HOME/bin:$JAVA_HOME/bin:$PATH"
140+
141+
echo "Starting Quarkus application on port $QUARKUS_PORT..."
142+
143+
# Start the Quarkus application in the background
144+
java @"$TORNADOVM_HOME/tornado-argfile" \
145+
-Dtornado.device.memory=8GB \
146+
-Dquarkus.http.port=$QUARKUS_PORT \
147+
-jar target/quarkus-app/quarkus-run.jar &
148+
APP_PID=$!
149+
150+
if [ -z "$APP_PID" ]; then
151+
echo "ERROR: Failed to start Quarkus application"
152+
exit 1
153+
fi
154+
155+
echo "Waiting for Quarkus application to start..."
156+
157+
# Wait for application to be ready
158+
for i in {1..30}; do
159+
if curl -s http://localhost:$QUARKUS_PORT/q/health > /dev/null 2>&1; then
160+
echo "Application ready after ${i} seconds"
161+
echo "Health endpoint: http://localhost:$QUARKUS_PORT/q/health"
162+
break
163+
elif [ $i -eq 30 ]; then
164+
echo "ERROR: Application failed to start within 30 seconds"
165+
echo "Debugging info:"
166+
echo "- Port: $QUARKUS_PORT"
167+
echo "- Process ID: $APP_PID"
168+
echo "- Health URL: http://localhost:$QUARKUS_PORT/q/health"
169+
kill $APP_PID || true
170+
exit 1
171+
else
172+
[ $((i % 5)) -eq 0 ] && echo "Still waiting... (${i}s)"
173+
sleep 1
174+
fi
175+
done
176+
177+
# Step 6: Run test 1
178+
- name: Trigger Blocking Endpoint
179+
run: |
180+
MAX_ATTEMPTS=3
181+
ATTEMPT=1
182+
SUCCESS=false
183+
184+
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
185+
echo "Attempt $ATTEMPT of $MAX_ATTEMPTS for blocking endpoint..."
186+
187+
# Trigger endpoint
188+
HTTP_RESPONSE=$(curl -s -w "%{http_code}" http://localhost:$QUARKUS_PORT/chat/blocking)
189+
HTTP_RESPONSE_CODE="${HTTP_RESPONSE: -3}"
190+
HTTP_RESPONSE_BODY="${HTTP_RESPONSE%???}"
191+
192+
# Check response code
193+
if [ "$HTTP_RESPONSE_CODE" = "200" ]; then
194+
echo "SUCCESS: Blocking endpoint returned HTTP code: $HTTP_RESPONSE_CODE"
195+
echo "HTTP Response body: $HTTP_RESPONSE_BODY"
196+
SUCCESS=true
197+
break
198+
else
199+
echo "Attempt $ATTEMPT failed: Blocking endpoint returned HTTP code $HTTP_RESPONSE_CODE"
200+
echo "Response body: $HTTP_RESPONSE_BODY"
201+
202+
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
203+
echo "Retrying in 2 seconds..."
204+
sleep 2
205+
fi
206+
fi
207+
208+
ATTEMPT=$((ATTEMPT + 1))
209+
done
210+
211+
if [ "$SUCCESS" = false ]; then
212+
echo "ERROR: Blocking endpoint failed after $MAX_ATTEMPTS attempts"
213+
exit 1
214+
fi
215+
216+
# Step 7: Run test 2
217+
- name: Trigger Streaming Endpoint
218+
run: |
219+
MAX_ATTEMPTS=3
220+
ATTEMPT=1
221+
SUCCESS=false
222+
223+
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
224+
echo "Attempt $ATTEMPT of $MAX_ATTEMPTS for streaming endpoint..."
225+
226+
# Trigger endpoint
227+
HTTP_RESPONSE=$(timeout 10s curl -s -w "%{http_code}" http://localhost:$QUARKUS_PORT/chat/streaming)
228+
HTTP_RESPONSE_CODE="${HTTP_RESPONSE: -3}"
229+
#HTTP_RESPONSE_BODY="$HTTP_RESPONSE%???}"
230+
231+
# Check response code
232+
if [ "$HTTP_RESPONSE_CODE" == "200" ]; then
233+
echo "SUCCESS: Streaming endpoint returned HTTP code: ${HTTP_RESPONSE: -3}"
234+
# do not show ugly streaming response body
235+
#echo "HTTP Response body: $HTTP_RESPONSE_BODY"
236+
SUCCESS=true
237+
break
238+
else
239+
echo "Attempt $ATTEMPT failed: Streaming endpoint returned HTTP code $HTTP_RESPONSE_CODE"
240+
241+
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
242+
echo "Retrying in 2 seconds..."
243+
sleep 2
244+
fi
245+
fi
246+
247+
ATTEMPT=$((ATTEMPT + 1))
248+
done
249+
250+
if [ "$SUCCESS" = false ]; then
251+
echo "ERROR: Streaming endpoint failed after $MAX_ATTEMPTS attempts"
252+
exit 1
253+
fi
254+
255+
# Step 8: Cleanup & Shutdown
256+
- name: Cleanup & Shutdown
257+
run: |
258+
# Clean shutdown
259+
kill $APP_PID || true
260+
wait $APP_PID 2>/dev/null || true

0 commit comments

Comments
 (0)