@@ -89,86 +89,146 @@ jobs:
8989 - name : Install Playwright (chromium only)
9090 run : task frontend:test:e2e:install -- chromium
9191
92+ # Helper function used by all phases — boots `:stirling-pdf:bootRun`
93+ # with the React frontend baked in (-PbuildWithFrontend=true) so the
94+ # SPA serves on :8080 and OAuth/SAML callbacks land on the same host
95+ # that the browser is interacting with.
96+ - name : Define helpers
97+ run : |
98+ {
99+ echo 'wait_for_backend() {'
100+ echo ' start=$SECONDS'
101+ echo ' for i in $(seq 1 300); do'
102+ echo ' if curl -fsS http://localhost:8080/api/v1/info/status >/dev/null 2>&1; then'
103+ echo ' echo "Backend up after $((SECONDS - start))s"; return 0'
104+ echo ' fi; sleep 2'
105+ echo ' done'
106+ echo ' tail -200 /tmp/backend.log || true; return 1'
107+ echo '}'
108+ echo 'stop_backend() {'
109+ echo ' if [ -f /tmp/backend.pid ]; then'
110+ echo ' kill "$(cat /tmp/backend.pid)" 2>/dev/null || true'
111+ echo ' rm -f /tmp/backend.pid'
112+ echo ' fi'
113+ echo ' pkill -f "gradlew :stirling-pdf:bootRun" 2>/dev/null || true'
114+ echo ' for i in $(seq 1 30); do'
115+ echo ' curl -fsS http://localhost:8080/api/v1/info/status >/dev/null 2>&1 || return 0'
116+ echo ' sleep 1'
117+ echo ' done'
118+ echo '}'
119+ } > /tmp/helpers.sh
120+ chmod +x /tmp/helpers.sh
121+
92122 # ───────── OAuth round-trip ─────────
93- - name : Bring up Keycloak + Stirling-PDF (OAuth)
123+ - name : Bring up Keycloak (OAuth realm )
94124 working-directory : testing/compose
95- run : docker compose -f docker-compose-keycloak-oauth.yml up -d --build
96- - name : Wait for OAuth stack ready
125+ run : docker compose -f docker-compose-keycloak-oauth.yml up -d --no-deps keycloak-oauth-db keycloak-oauth
126+ - name : Wait for Keycloak (OAuth) ready
97127 working-directory : testing/compose
98128 run : |
99129 for i in $(seq 1 60); do
100- if bash validate-oauth-test.sh; then
101- exit 0
102- fi
130+ bash validate-oauth-test.sh 2>/dev/null && exit 0 || true
131+ # validate script also pings stirling on :8080 — accept just the
132+ # keycloak realm as our gate here, stirling boots in the next step
133+ curl -fsS http://localhost:9080/realms/stirling-oauth >/dev/null 2>&1 && exit 0
103134 sleep 5
104135 done
105- docker compose -f docker-compose-keycloak-oauth.yml logs --tail=200
136+ docker compose -f docker-compose-keycloak-oauth.yml logs --tail=200 keycloak-oauth
106137 exit 1
138+ - name : Boot Stirling-PDF (frontend baked in, OAuth env)
139+ env :
140+ SECURITY_ENABLELOGIN : " true"
141+ SECURITY_LOGINMETHOD : " all"
142+ SECURITY_OAUTH2_ENABLED : " true"
143+ SECURITY_OAUTH2_AUTOCREATEUSER : " true"
144+ SECURITY_OAUTH2_CLIENT_KEYCLOAK_ISSUER : " http://localhost:9080/realms/stirling-oauth"
145+ SECURITY_OAUTH2_CLIENT_KEYCLOAK_CLIENTID : " stirling-pdf-client"
146+ SECURITY_OAUTH2_CLIENT_KEYCLOAK_CLIENTSECRET : " test-client-secret-change-in-production"
147+ SECURITY_OAUTH2_CLIENT_KEYCLOAK_USEASUSERNAME : " email"
148+ SECURITY_OAUTH2_CLIENT_KEYCLOAK_SCOPES : " openid,profile,email"
149+ run : |
150+ source /tmp/helpers.sh
151+ nohup ./gradlew :stirling-pdf:bootRun -PbuildWithFrontend=true > /tmp/backend.log 2>&1 &
152+ echo $! > /tmp/backend.pid
153+ wait_for_backend
107154 - name : Run enterprise OAuth Playwright tests
108155 id : oauth-tests
109156 run : task frontend:test:e2e -- --project=enterprise --grep "OAuth"
110- - name : Tear down OAuth stack
157+ - name : Stop backend + tear down OAuth Keycloak
111158 if : always()
112- working-directory : testing/compose
113- run : docker compose -f docker-compose-keycloak-oauth.yml down -v
159+ run : |
160+ source /tmp/helpers.sh
161+ stop_backend
162+ (cd testing/compose && docker compose -f docker-compose-keycloak-oauth.yml down -v)
114163
115164 # ───────── SAML round-trip ─────────
116- - name : Bring up Keycloak + Stirling-PDF (SAML)
165+ - name : Bring up Keycloak (SAML realm )
117166 working-directory : testing/compose
118- run : docker compose -f docker-compose-keycloak-saml.yml up -d --build
119- - name : Wait for SAML stack ready
167+ run : docker compose -f docker-compose-keycloak-saml.yml up -d --no-deps keycloak-saml-db keycloak-saml
168+ - name : Wait for Keycloak (SAML) ready
120169 working-directory : testing/compose
121170 run : |
122171 for i in $(seq 1 60); do
123- if bash validate-saml-test.sh; then
124- exit 0
125- fi
172+ curl -fsS http://localhost:9080/realms/stirling-saml >/dev/null 2>&1 && exit 0
126173 sleep 5
127174 done
128- docker compose -f docker-compose-keycloak-saml.yml logs --tail=200
175+ docker compose -f docker-compose-keycloak-saml.yml logs --tail=200 keycloak-saml
129176 exit 1
177+ - name : Boot Stirling-PDF (frontend baked in, SAML env)
178+ env :
179+ SECURITY_ENABLELOGIN : " true"
180+ SECURITY_LOGINMETHOD : " all"
181+ SECURITY_SAML2_ENABLED : " true"
182+ SECURITY_SAML2_AUTOCREATEUSER : " true"
183+ SECURITY_SAML2_PROVIDER : " keycloak"
184+ SECURITY_SAML2_REGISTRATIONID : " keycloak"
185+ SECURITY_SAML2_IDP_ISSUER : " http://localhost:9080/realms/stirling-saml"
186+ SECURITY_SAML2_IDP_ENTITYID : " http://localhost:9080/realms/stirling-saml"
187+ SECURITY_SAML2_IDP_METADATAURI : " http://localhost:9080/realms/stirling-saml/protocol/saml/descriptor"
188+ SECURITY_SAML2_IDPSINGLELOGINURL : " http://localhost:9080/realms/stirling-saml/protocol/saml"
189+ SECURITY_SAML2_IDPSINGLELOGOUTURL : " http://localhost:9080/realms/stirling-saml/protocol/saml"
190+ SECURITY_SAML2_IDP_CERT : " ${{ github.workspace }}/testing/compose/keycloak-saml-cert.pem"
191+ SECURITY_SAML2_PRIVATEKEY : " ${{ github.workspace }}/testing/compose/saml-private-key.key"
192+ SECURITY_SAML2_SP_CERT : " ${{ github.workspace }}/testing/compose/saml-public-cert.crt"
193+ SECURITY_SAML2_SP_ENTITYID : " http://localhost:8080"
194+ SECURITY_SAML2_SP_ACS : " http://localhost:8080/login/saml2/sso/keycloak"
195+ SECURITY_SAML2_SP_SLS : " http://localhost:8080/logout/saml2/slo"
196+ run : |
197+ source /tmp/helpers.sh
198+ nohup ./gradlew :stirling-pdf:bootRun -PbuildWithFrontend=true > /tmp/backend.log 2>&1 &
199+ echo $! > /tmp/backend.pid
200+ wait_for_backend
130201 - name : Run enterprise SAML Playwright tests
131202 id : saml-tests
132203 run : task frontend:test:e2e -- --project=enterprise --grep "SAML"
133- - name : Tear down SAML stack
204+ - name : Stop backend + tear down SAML Keycloak
134205 if : always()
135- working-directory : testing/compose
136- run : docker compose -f docker-compose-keycloak-saml.yml down -v
206+ run : |
207+ source /tmp/helpers.sh
208+ stop_backend
209+ (cd testing/compose && docker compose -f docker-compose-keycloak-saml.yml down -v)
137210
138211 # ───────── License-gated feature tests (no IdP needed) ─────────
139- - name : Start backend for feature tests (premium-enabled, no SSO)
140- env :
141- SYSTEM_ENABLEANALYTICS : " false"
212+ - name : Boot Stirling-PDF (frontend baked in, premium only)
142213 run : |
143- nohup ./gradlew :stirling-pdf:bootRun > /tmp/backend-ent.log 2>&1 &
144- echo $! > /tmp/backend-ent.pid
145- - name : Wait for backend ready
146- run : |
147- start=$SECONDS
148- for i in $(seq 1 300); do
149- if curl -fsS http://localhost:8080/api/v1/info/status >/dev/null 2>&1; then
150- echo "Backend up after $((SECONDS - start))s"
151- exit 0
152- fi
153- sleep 2
154- done
155- tail -200 /tmp/backend-ent.log || true
156- exit 1
214+ source /tmp/helpers.sh
215+ nohup ./gradlew :stirling-pdf:bootRun -PbuildWithFrontend=true > /tmp/backend.log 2>&1 &
216+ echo $! > /tmp/backend.pid
217+ wait_for_backend
157218 - name : Run enterprise feature Playwright tests
158219 id : feature-tests
159220 run : task frontend:test:e2e -- --project=enterprise --grep "Enterprise license"
160221 - name : Print backend log on failure
161222 if : failure()
162223 run : |
163224 echo "::group::Enterprise backend log"
164- tail -500 /tmp/backend-ent .log || true
225+ tail -500 /tmp/backend.log || true
165226 echo "::endgroup::"
166- - name : Stop backend
227+ - name : Stop backend (final)
167228 if : always()
168229 run : |
169- if [ -f /tmp/backend-ent.pid ]; then
170- kill "$(cat /tmp/backend-ent.pid)" 2>/dev/null || true
171- fi
230+ source /tmp/helpers.sh
231+ stop_backend
172232 - name : Upload Playwright report
173233 if : always()
174234 uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
0 commit comments