@@ -21,7 +21,19 @@ export class AtomicServer {
2121 ignore : [
2222 "**/node_modules" ,
2323 "**/.git" ,
24+ "**/.github" ,
25+ "**/.husky" ,
26+ "**/.vscode" ,
27+ // rust
2428 "**/target" ,
29+ "**/artifact" ,
30+ // browser
31+ "**/.swc" ,
32+ "**/.netlify" ,
33+ // e2e
34+ "**/test-results" ,
35+ "**/template-tests" ,
36+ "**/playwright-report" ,
2537 "**/tmp" ,
2638 "**/.temp" ,
2739 "**/.cargo" ,
@@ -30,7 +42,6 @@ export class AtomicServer {
3042 "**/dist" ,
3143 "**/assets_tmp" ,
3244 "**/build" ,
33- "**/artifact" ,
3445 "**/.env" ,
3546 "**/.envrc" ,
3647 ] ,
@@ -101,20 +112,25 @@ export class AtomicServer {
101112 . stdout ( ) ;
102113 }
103114
115+ /** Extracts the unique deploy URL from netlify output */
116+ private extractDeployUrl ( netlifyOutput : string ) : string {
117+ const match = netlifyOutput . match ( / h t t p s : \/ \/ [ a - f 0 - 9 ] + - - .+ \. n e t l i f y \. a p p / ) ;
118+ return match ? match [ 0 ] : "Deploy URL not found" ;
119+ }
120+
104121 @func ( )
105122 docsFolder ( ) : Directory {
106- const actualDocsDirectory = this . source . directory ( "docs" ) ;
107123 const cargoCache = dag . cacheVolume ( "cargo" ) ;
108124
109- const docsContainer = dag
125+ const mdBookContainer = dag
110126 . container ( )
111127 . from ( RUST_IMAGE )
112- . withExec ( [ "sh" , "-c" , ". $HOME/.cargo/env" ] )
113- . withEnvVariable ( "PATH" , "$HOME/.cargo/bin:$PATH" )
114128 . withMountedCache ( "/usr/local/cargo/registry" , cargoCache )
115129 . withExec ( [ "cargo" , "install" , "mdbook" ] )
116130 . withExec ( [ "cargo" , "install" , "mdbook-linkcheck" ] ) ;
117- return docsContainer
131+
132+ const actualDocsDirectory = this . source . directory ( "docs" ) ;
133+ return mdBookContainer
118134 . withMountedDirectory ( "/docs" , actualDocsDirectory )
119135 . withWorkdir ( "/docs" )
120136 . withExec ( [ "mdbook" , "build" ] )
@@ -187,7 +203,6 @@ export class AtomicServer {
187203 . withExec ( [ "cargo" , "install" , "cargo-nextest" ] )
188204 . withMountedCache ( "/usr/local/cargo/registry" , cargoCache ) ;
189205
190- // Copy source files like in Earthfile, but more selectively
191206 const sourceContainer = rustContainer
192207 . withFile ( "/code/Cargo.toml" , source . file ( "Cargo.toml" ) )
193208 . withFile ( "/code/Cargo.lock" , source . file ( "Cargo.lock" ) )
@@ -258,7 +273,7 @@ export class AtomicServer {
258273 }
259274
260275 @func ( )
261- endToEnd ( @argument ( ) netlifyAuthToken : Secret ) : Promise < string > {
276+ async endToEnd ( @argument ( ) netlifyAuthToken : Secret ) : Promise < string > {
262277 const e2eSource = this . source . directory ( "browser/e2e" ) ;
263278
264279 // Setup Playwright container - debug and fix package manager
@@ -293,6 +308,9 @@ export class AtomicServer {
293308 } )
294309 . withSecretVariable ( "NETLIFY_AUTH_TOKEN" , netlifyAuthToken ) ;
295310
311+ // Test the binary
312+ e2eContainer . withExec ( [ "/atomic-server-bin" , "--version" ] ) ;
313+
296314 // Start atomic-server in background
297315 const serverStarted = e2eContainer
298316 . withExec ( [
@@ -302,24 +320,39 @@ export class AtomicServer {
302320 ] )
303321 . withExec ( [ "sleep" , "3" ] ) ;
304322
305- // Run the tests from the correct directory (always succeed to collect artifacts)
306- const testResult = serverStarted
307- . withExec ( [
308- "/bin/sh" ,
309- "-c" ,
310- "pnpm run test-e2e || echo 'Tests completed with failures, but continuing to collect artifacts'" ,
311- ] )
312- . withExec ( [ "zip" , "-r" , "test.zip" , "playwright-report" ] )
313- . withExec ( [ "unzip" , "-o" , "test.zip" , "-d" , "/artifact" ] ) ;
323+ // Check if atomic-server is running, if its responding with a 200
324+ serverStarted . withExec ( [
325+ "/bin/sh" ,
326+ "-c" ,
327+ "curl -f -s http://localhost:9883/ || (echo 'Server not responding with 200' && exit 1)" ,
328+ ] ) ;
329+
330+ // Run the tests and capture exit code, but continue regardless
331+ const testResult = serverStarted . withExec ( [
332+ "/bin/sh" ,
333+ "-c" ,
334+ "pnpm run test-e2e; echo $? > /test-exit-code" ,
335+ ] ) ;
314336
315337 // Extract the test results directory and upload to Netlify
316- const testReportDirectory = testResult . directory (
317- "/artifact/app/playwright-report"
318- ) ;
319- return this . netlifyDeploy (
338+ const testReportDirectory = testResult . directory ( "playwright-report" ) ;
339+ const deployOutput = await this . netlifyDeploy (
320340 testReportDirectory ,
321341 "atomic-tests" ,
322342 netlifyAuthToken
323343 ) ;
344+
345+ // Extract the deploy URL
346+ const deployUrl = this . extractDeployUrl ( deployOutput ) ;
347+
348+ // Check the test exit code and fail if tests failed
349+ const exitCode = await testResult . file ( "/test-exit-code" ) . contents ( ) ;
350+ if ( exitCode . trim ( ) !== "0" ) {
351+ throw new Error (
352+ `E2E tests failed (exit code: ${ exitCode . trim ( ) } ). Test report deployed to: \n ${ deployUrl } `
353+ ) ;
354+ }
355+
356+ return deployUrl ;
324357 }
325358}
0 commit comments