66name : Java Server CI
77
88on :
9- push :
10- branches : [main]
11- paths :
12- - " java-server/**"
13- - " .github/workflows/java-server-ci.yml"
149 pull_request :
15- branches : [main]
16- paths :
17- - " java-server/**"
18- - " .github/workflows/java-server-ci.yml"
1910 workflow_dispatch :
2011
2112concurrency :
8475 DITTO_AUTH_URL : ${{ secrets.DITTO_AUTH_URL }}
8576 DITTO_WEBSOCKET_URL : ${{ secrets.DITTO_WEBSOCKET_URL }}
8677 DITTO_ENABLE_CLOUD_SYNC : true
87- run : ./gradlew bootJar
78+ run : ./gradlew bootJar -x test
8879
8980 - name : Upload JAR artifacts
9081 uses : actions/upload-artifact@v4
@@ -98,19 +89,13 @@ jobs:
9889 runs-on : macos-latest
9990 needs : [build]
10091 if : github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
101- timeout-minutes : 45
92+ timeout-minutes : 150
93+ outputs :
94+ build_id : ${{ steps.test.outputs.build_id }}
10295
10396 steps :
10497 - uses : actions/checkout@v4
10598
106- - name : Seed test task to Ditto Cloud
107- id : seed_task
108- uses : ./.github/actions/seed-ditto-document
109- with :
110- ditto-api-key : ${{ secrets.DITTO_API_KEY }}
111- ditto-api-url : ${{ secrets.DITTO_API_URL }}
112- app-name : " java-server"
113-
11499 - name : Download JAR artifacts
115100 uses : actions/download-artifact@v4
116101 with :
@@ -167,19 +152,27 @@ jobs:
167152 [ -f browserstack-local.log ] && cat browserstack-local.log
168153 exit 1
169154
155+ - name : Get BrowserStack build info
156+ id : build-info
157+ uses : ./.github/actions/generate-browserstack-names
158+ with :
159+ platform-suffix : " (Java)"
160+ title-max-length : " 90"
161+ commit-max-length : " 130"
162+
170163 - name : Create BrowserStack config
171164 working-directory : java-server
172165 run : |
166+ # Load platforms from centralized config and convert to YAML format
167+ PLATFORMS=$(yq eval '.["java-spring"].platforms[] | " - os: \(.os)\n osVersion: \"\(.osVersion)\"\n browserName: \(.browserName)\n browserVersion: \(.browserVersion)"' ../.github/browserstack-devices.yml)
168+
173169 cat > browserstack.yml << EOF
174170 userName: ${{ secrets.BROWSERSTACK_USERNAME }}
175171 accessKey: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
176- projectName: Ditto Java Server Tasks
177- buildName: Java Server Selenium Tests # ${{ github.run_number }}
172+ projectName: ${{ steps.build-info.outputs.project-name }}
173+ buildName: ${{ steps.build-info.outputs.build-name }}
178174 platforms:
179- - os: Windows
180- osVersion: 11
181- browserName: Chrome
182- browserVersion: latest
175+ $PLATFORMS
183176 browserstackLocal: true
184177 debug: true
185178 video: true
@@ -210,19 +203,77 @@ jobs:
210203 sleep 2
211204 done
212205
213- - name : Execute Selenium tests on BrowserStack cloud browsers
214- working-directory : java-server
206+ - name : Seed and execute Selenium tests on BrowserStack cloud browsers
207+ # working-directory: java-server
208+ id : test
209+ uses : nick-fields/retry@v3
215210 env :
216211 BROWSERSTACK_ACCESS_KEY : ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
217212 BROWSERSTACK_BUILD_NAME : " Java Spring Selenium Tests #${{ github.run_number }}"
218213 BROWSERSTACK_USERNAME : ${{ secrets.BROWSERSTACK_USERNAME }}
219214 BROWSERSTACK_LOCAL : true
220- DITTO_CLOUD_TASK_TITLE : " ${{ steps.seed_task.outputs.document-title }}"
221- run : |
222- # Run only the BrowserStack test method, not all test methods
223- ./gradlew test \
224- --tests "*TaskVisibilityIntegrationTest.shouldPassWithExistingTask" \
225- --info
215+ with :
216+ max_attempts : 5
217+ timeout_minutes : 20
218+ retry_wait_seconds : 900
219+ command : |
220+ # Seed test task to Ditto Cloud
221+ echo "Seeding test task to Ditto Cloud..."
222+ TIMESTAMP=$(date +%s)
223+ INVERTED_TIMESTAMP=$((9999999999 - TIMESTAMP))
224+ SEED_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
225+ -H 'Content-type: application/json' \
226+ -H "Authorization: Bearer ${{ secrets.DITTO_API_KEY }}" \
227+ -d "{
228+ \"statement\": \"INSERT INTO tasks DOCUMENTS (:newTask) ON ID CONFLICT DO UPDATE\",
229+ \"args\": {
230+ \"newTask\": {
231+ \"_id\": \"${INVERTED_TIMESTAMP}_java-spring_ci_test_${{ github.run_id }}_${{ github.run_number }}\",
232+ \"title\": \"${INVERTED_TIMESTAMP}_java-spring_ci_test_${{ github.run_id }}_${{ github.run_number }}\",
233+ \"done\": false,
234+ \"deleted\": false
235+ }
236+ }
237+ }" \
238+ "https://${{ secrets.DITTO_API_URL }}/api/v4/store/execute")
239+
240+ HTTP_CODE=$(echo "$SEED_RESPONSE" | tail -n1)
241+ BODY=$(echo "$SEED_RESPONSE" | sed '$d')
242+
243+ if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 201 ]; then
244+ TASK_TITLE="${INVERTED_TIMESTAMP}_java-spring_ci_test_${{ github.run_id }}_${{ github.run_number }}"
245+ echo "Seeded task: $TASK_TITLE"
246+ else
247+ echo "Error: Failed to seed task. HTTP Status: $HTTP_CODE"
248+ echo "Response: $BODY"
249+ exit 1
250+ fi
251+
252+ # Export as environment variable (for System.getenv())
253+ export DITTO_CLOUD_TASK_TITLE="$TASK_TITLE"
254+
255+ # Run BrowserStack Selenium tests
256+ cd java-spring
257+ ./gradlew test --tests "*TaskVisibilityIntegrationTest.shouldPassWithExistingTask" \
258+ -DBROWSERSTACK_USERNAME="${{ secrets.BROWSERSTACK_USERNAME }}" \
259+ -DBROWSERSTACK_ACCESS_KEY="${{ secrets.BROWSERSTACK_ACCESS_KEY }}" \
260+ -DBROWSERSTACK_LOCAL=true \
261+ -DDITTO_CLOUD_TASK_TITLE="$TASK_TITLE" \
262+ --info
263+
264+ # Query BrowserStack API to get the build ID
265+ echo "Fetching build ID from BrowserStack..."
266+ BUILDS_RESPONSE=$(curl -s -u "${{ secrets.BROWSERSTACK_USERNAME }}:${{ secrets.BROWSERSTACK_ACCESS_KEY }}" \
267+ "https://api.browserstack.com/automate/builds.json?limit=1")
268+
269+ BUILD_ID=$(echo "$BUILDS_RESPONSE" | yq eval '.[0].hashed_id' -)
270+
271+ if [ "$BUILD_ID" != "null" ] && [ -n "$BUILD_ID" ]; then
272+ echo "build_id=$BUILD_ID" >> $GITHUB_OUTPUT
273+ echo "✅ Build ID: $BUILD_ID"
274+ else
275+ echo "⚠️ Could not retrieve build ID from BrowserStack API"
276+ fi
226277
227278 - name : Stop Spring Boot app
228279 if : always()
@@ -258,7 +309,7 @@ jobs:
258309 summary :
259310 name : CI Report
260311 runs-on : ubuntu-latest
261- needs : [browserstack-test]
312+ needs : [lint, build, browserstack-test]
262313 if : always()
263314
264315 steps :
@@ -285,10 +336,10 @@ jobs:
285336 echo "" >> $GITHUB_STEP_SUMMARY
286337
287338 # BrowserStack link
288- if [[ "${{ needs.browserstack-test.result }}" != "skipped" ]]; then
339+ if [[ "${{ needs.browserstack-test.result }}" != "skipped" ]] && [ -n "${{ needs.browserstack-test.outputs.build_id }}" ] ; then
289340 echo "### BrowserStack Session" >> $GITHUB_STEP_SUMMARY
290341 echo "" >> $GITHUB_STEP_SUMMARY
291- echo "🔗 [View Test Results](https://automate.browserstack.com/builds?project=Ditto+Java+Spring+Tasks&build=Java+Spring+Selenium+Tests+%23 ${{ github.run_number }})" >> $GITHUB_STEP_SUMMARY
342+ echo "🔗 [View Test Results](https://automate.browserstack.com/dashboard/v2/ builds/ ${{ needs.browserstack-test.outputs.build_id }}/ )" >> $GITHUB_STEP_SUMMARY
292343 echo "" >> $GITHUB_STEP_SUMMARY
293344 echo "**Tested Browser:**" >> $GITHUB_STEP_SUMMARY
294345 echo "- Chrome Latest (Windows 11)" >> $GITHUB_STEP_SUMMARY
0 commit comments