Skip to content

feat(infra): AWS CDK stack for the imaging S3 bucket + CloudFront, an… #138

feat(infra): AWS CDK stack for the imaging S3 bucket + CloudFront, an…

feat(infra): AWS CDK stack for the imaging S3 bucket + CloudFront, an… #138

Triggered via push August 31, 2026 10:18
Status Failure
Total duration 4m 24s
Artifacts 1

ci.yml

on: push
Matrix: rust
Fit to window
Zoom out
Zoom in

Annotations

10 errors, 10 warnings, and 1 notice
sbom
Process completed with exit code 254.
server
Process completed with exit code 1.
src/store/postgres-compute-control-store.test.ts > PostgresComputeControlStore (integration — requires DATABASE_URL) > the SECURITY DEFINER maintenance functions actually run: stale nodes go offline, expired leases requeue their request: server/src/store/postgres-compute-control-store.ts#L153
ZodError: [ { "origin": "string", "code": "invalid_format", "format": "datetime", "pattern": "/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$/", "path": [ "updatedAt" ], "message": "Invalid ISO datetime" } ] ❯ src/store/postgres-compute-control-store.ts:153:341 ❯ PostgresComputeControlStore.tenantTx src/store/postgres-compute-control-store.ts:39:27 ❯ src/store/postgres-compute-control-store.test.ts:133:17 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { _zod: { def: [ { origin: 'string', code: 'invalid_format', format: 'datetime', pattern: '/^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$/', path: [ 'updatedAt' ], message: 'Invalid ISO datetime' } ], constr: 'Function<ZodError>', traits: { constructor: 'Function<Set>', has: 'Function<has>', add: 'Function<add>', delete: 'Function<delete>', clear: 'Function<clear>', entries: 'Function<entries>', forEach: 'Function<forEach>', size: 2, values: 'Function<values>', keys: 'Function<values>', union: 'Function<union>', intersection: 'Function<intersection>', difference: 'Function<difference>', symmetricDifference: 'Function<symmetricDifference>', isSubsetOf: 'Function<isSubsetOf>', isSupersetOf: 'Function<isSupersetOf>', isDisjointFrom: 'Function<isDisjointFrom>' }, deferred: [] }, issues: [ { origin: 'string', code: 'invalid_format', format: 'datetime', pattern: '/^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$/', path: [ 'updatedAt' ], message: 'Invalid ISO datetime' } ], format: 'Function<value>', flatten: 'Function<value>', addIssue: 'Function<value>', addIssues: 'Function<value>', isEmpty: false }
e2e
Process completed with exit code 1.
tests/audit-sqlite-custom-directory.spec.ts:21:5 › pointing the SQLite audit backend at a custom folder migrates existing events there: e2e/tests/audit-sqlite-custom-directory.spec.ts#L33
3) tests/audit-sqlite-custom-directory.spec.ts:21:5 › pointing the SQLite audit backend at a custom folder migrates existing events there Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 31 | await instance.window.getByRole("button", { name: "Audit & Privacy" }).click(); 32 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 33 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 34 | await toggle.click(); 35 | await expect(instance.window.getByText("SQLite", { exact: true })).toBeVisible(); 36 | at /home/runner/work/modelforge/modelforge/e2e/tests/audit-sqlite-custom-directory.spec.ts:33:26
tests/audit-sqlite-custom-directory.spec.ts:21:5 › pointing the SQLite audit backend at a custom folder migrates existing events there: e2e/tests/audit-sqlite-custom-directory.spec.ts#L33
3) tests/audit-sqlite-custom-directory.spec.ts:21:5 › pointing the SQLite audit backend at a custom folder migrates existing events there Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 31 | await instance.window.getByRole("button", { name: "Audit & Privacy" }).click(); 32 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 33 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 34 | await toggle.click(); 35 | await expect(instance.window.getByText("SQLite", { exact: true })).toBeVisible(); 36 | at /home/runner/work/modelforge/modelforge/e2e/tests/audit-sqlite-custom-directory.spec.ts:33:26
tests/audit-sqlite-backend-toggle.spec.ts:19:5 › switching the audit log storage backend migrates existing events and back again: e2e/tests/audit-sqlite-backend-toggle.spec.ts#L33
2) tests/audit-sqlite-backend-toggle.spec.ts:19:5 › switching the audit log storage backend migrates existing events and back again Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 31 | 32 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 33 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 34 | await toggle.click(); 35 | 36 | await expect(instance.window.getByText("SQLite", { exact: true })).toBeVisible(); at /home/runner/work/modelforge/modelforge/e2e/tests/audit-sqlite-backend-toggle.spec.ts:33:26
tests/audit-sqlite-backend-toggle.spec.ts:19:5 › switching the audit log storage backend migrates existing events and back again: e2e/tests/audit-sqlite-backend-toggle.spec.ts#L33
2) tests/audit-sqlite-backend-toggle.spec.ts:19:5 › switching the audit log storage backend migrates existing events and back again Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 31 | 32 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 33 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 34 | await toggle.click(); 35 | 36 | await expect(instance.window.getByText("SQLite", { exact: true })).toBeVisible(); at /home/runner/work/modelforge/modelforge/e2e/tests/audit-sqlite-backend-toggle.spec.ts:33:26
tests/audit-backend-toggle-failure.spec.ts:19:5 › a failure loading the audit log after switching backends surfaces an error instead of failing silently: e2e/tests/audit-backend-toggle-failure.spec.ts#L41
1) tests/audit-backend-toggle-failure.spec.ts:19:5 › a failure loading the audit log after switching backends surfaces an error instead of failing silently Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 39 | 40 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 41 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 42 | await toggle.click(); 43 | 44 | await expect(instance.window.getByText("Couldn't load the audit log")).toBeVisible(); at /home/runner/work/modelforge/modelforge/e2e/tests/audit-backend-toggle-failure.spec.ts:41:26
tests/audit-backend-toggle-failure.spec.ts:19:5 › a failure loading the audit log after switching backends surfaces an error instead of failing silently: e2e/tests/audit-backend-toggle-failure.spec.ts#L41
1) tests/audit-backend-toggle-failure.spec.ts:19:5 › a failure loading the audit log after switching backends surfaces an error instead of failing silently Error: expect(locator).toBeEnabled() failed Locator: getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) Expected: enabled Received: disabled Timeout: 10000ms Call log: - Expect "toBeEnabled" with timeout 10000ms - waiting for getByRole('button', { name: /Switch to experimental SQLite backend|Switch back to JSON/ }) 24 × locator resolved to <button disabled tabindex="0" type="button" data-disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-150 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive…>Switch to experimental SQLite backend</button> - unexpected value "disabled" 39 | 40 | const toggle = instance.window.getByRole("button", { name: /Switch to experimental SQLite backend|Switch back to JSON/ }); > 41 | await expect(toggle).toBeEnabled({ timeout: 10_000 }); | ^ 42 | await toggle.click(); 43 | 44 | await expect(instance.window.getByText("Couldn't load the audit log")).toBeVisible(); at /home/runner/work/modelforge/modelforge/e2e/tests/audit-backend-toggle-failure.spec.ts:41:26
admin-console
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
sbom
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
python-recommender
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
rust (ubuntu-latest)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830, actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
security
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
server
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
rust (macos-latest)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830, actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
rust (windows-latest)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830, actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
test
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
e2e
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@11d5960a326750d5838078e36cf38b85af677262, actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020, actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
🎭 Playwright Run Summary
3 failed tests/audit-backend-toggle-failure.spec.ts:19:5 › a failure loading the audit log after switching backends surfaces an error instead of failing silently tests/audit-sqlite-backend-toggle.spec.ts:19:5 › switching the audit log storage backend migrates existing events and back again tests/audit-sqlite-custom-directory.spec.ts:21:5 › pointing the SQLite audit backend at a custom folder migrates existing events there 22 passed (2.7m)

Artifacts

Produced during runtime
Name Size Digest
playwright-report Expired
1.76 MB
sha256:72d3735b7cf9b6a53b14d3eb65770f72c0fe0d12d6c3211c901d56ed0bebcbf9