ci(frontend): reuse production build in smoke
This commit is contained in:
@@ -190,6 +190,30 @@ jobs:
|
|||||||
echo "Frontend test process crashed with SIGSEGV — retrying the complete suite once..."
|
echo "Frontend test process crashed with SIGSEGV — retrying the complete suite once..."
|
||||||
npm test -- --watchAll=false --runInBand
|
npm test -- --watchAll=false --runInBand
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
working-directory: job-tracker-ui
|
||||||
|
env:
|
||||||
|
CI: 'false'
|
||||||
|
GENERATE_SOURCEMAP: 'false'
|
||||||
|
NODE_OPTIONS: --max-old-space-size=4096
|
||||||
|
# Build once, then make Playwright serve this exact export. A SIGSEGV-only retry preserves
|
||||||
|
# the runner workaround without hiding an ordinary compiler or type-check failure.
|
||||||
|
run: |
|
||||||
|
set +e
|
||||||
|
npm run build
|
||||||
|
build_status=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$build_status" -eq 0 ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [ "$build_status" -ne 139 ]; then
|
||||||
|
exit "$build_status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Frontend build process crashed with SIGSEGV — retrying once..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
- name: Install browser smoke runtime
|
- name: Install browser smoke runtime
|
||||||
working-directory: job-tracker-ui
|
working-directory: job-tracker-ui
|
||||||
env:
|
env:
|
||||||
@@ -206,6 +230,7 @@ jobs:
|
|||||||
# Exercise the deployable frontend and avoid Turbopack's persistence crashes on
|
# Exercise the deployable frontend and avoid Turbopack's persistence crashes on
|
||||||
# this runner's slow Docker volume.
|
# this runner's slow Docker volume.
|
||||||
PLAYWRIGHT_STATIC_EXPORT: 'true'
|
PLAYWRIGHT_STATIC_EXPORT: 'true'
|
||||||
|
PLAYWRIGHT_PREBUILT_EXPORT: 'true'
|
||||||
# The runner occasionally terminates an otherwise healthy Node process with
|
# The runner occasionally terminates an otherwise healthy Node process with
|
||||||
# SIGSEGV/139. Retry only that infrastructure signature. Do not reinstall npm
|
# SIGSEGV/139. Retry only that infrastructure signature. Do not reinstall npm
|
||||||
# or browser payloads here: doing so used to redownload hundreds of megabytes
|
# or browser payloads here: doing so used to redownload hundreds of megabytes
|
||||||
@@ -227,19 +252,6 @@ jobs:
|
|||||||
echo "Browser smoke process crashed with SIGSEGV — retrying the unchanged suite once..."
|
echo "Browser smoke process crashed with SIGSEGV — retrying the unchanged suite once..."
|
||||||
npm run test:e2e
|
npm run test:e2e
|
||||||
|
|
||||||
- name: Build frontend
|
|
||||||
working-directory: job-tracker-ui
|
|
||||||
env:
|
|
||||||
CI: 'false'
|
|
||||||
GENERATE_SOURCEMAP: 'false'
|
|
||||||
NODE_OPTIONS: --max-old-space-size=4096
|
|
||||||
# CRA's build (Terser minify + fork-ts-checker workers) has repeatedly died silently on
|
|
||||||
# this runner with no error output (OOM/SIGSEGV signature — same resource-starved-runner
|
|
||||||
# class as the npm ci and dotnet-install flakes elsewhere in this workflow). Retry once.
|
|
||||||
run: |
|
|
||||||
npm run build \
|
|
||||||
|| ( echo "Frontend build failed ($?) — retrying once..." && npm run build )
|
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
needs: test
|
needs: test
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ Updated: 2026-08-30
|
|||||||
- Hardened deployment replacement semantics: backend/frontend images receive exact commit tags, the prior running core images are retained as the rollback release, and any post-replacement failure automatically restores both previous services while keeping the deployment result failed. Removed the non-actionable blanket `compose pull || true` suppression.
|
- Hardened deployment replacement semantics: backend/frontend images receive exact commit tags, the prior running core images are retained as the rollback release, and any post-replacement failure automatically restores both previous services while keeping the deployment result failed. Removed the non-actionable blanket `compose pull || true` suppression.
|
||||||
- Completed the next lifecycle-controller boundary by moving status changes and deterministic email status suggestions out of the core controller. The applied-date invariant and cleared-date audit event now live in `JobLifecycleEvents`, so full edits and status-only updates cannot drift.
|
- Completed the next lifecycle-controller boundary by moving status changes and deterministic email status suggestions out of the core controller. The applied-date invariant and cleared-date audit event now live in `JobLifecycleEvents`, so full edits and status-only updates cannot drift.
|
||||||
- Added axe-powered WCAG A/AA browser gates for public entry points and the Dashboard, Jobs, Kanban, Career, Settings, and Admin/System workspaces. Fixed the shared violations they exposed: primary-action contrast, dark-surface language-toggle contrast, account-avatar contrast, sidebar list semantics, job-filter accessible names, and the Google sign-in wrapper role.
|
- Added axe-powered WCAG A/AA browser gates for public entry points and the Dashboard, Jobs, Kanban, Career, Settings, and Admin/System workspaces. Fixed the shared violations they exposed: primary-action contrast, dark-surface language-toggle contrast, account-avatar contrast, sidebar list semantics, job-filter accessible names, and the Google sign-in wrapper role.
|
||||||
|
- Removed the duplicate frontend production build from CI: Next now builds once before browser smoke, and Playwright serves that exact static export instead of rebuilding it. Ordinary build failures remain terminal and only the runner's explicit exit-139 signature retries.
|
||||||
- Transferred the independent `UserRuleSettings` table from both provider startup paths to its own provider-aware migration; owner-keyed settings survive adoption, downgrade and retry.
|
- Transferred the independent `UserRuleSettings` table from both provider startup paths to its own provider-aware migration; owner-keyed settings survive adoption, downgrade and retry.
|
||||||
- Moved `GmailReviewDecisions` into a provider-aware migration, preserving existing SQLite decisions and closing the previously missing MariaDB table path.
|
- Moved `GmailReviewDecisions` into a provider-aware migration, preserving existing SQLite decisions and closing the previously missing MariaDB table path.
|
||||||
- Moved recovery codes, trusted devices, and revocable user sessions into one provider-aware authentication-support migration; populated legacy rows and indexes survive adoption, downgrade, and retry.
|
- Moved recovery codes, trusted devices, and revocable user sessions into one provider-aware authentication-support migration; populated legacy rows and indexes survive adoption, downgrade, and retry.
|
||||||
@@ -102,6 +103,7 @@ Updated: 2026-08-30
|
|||||||
- Deployment rollback configuration: Docker Compose configuration validation passed with non-secret fixture values. Runtime rollback rehearsal remains pending because the local Linux Docker daemon is offline.
|
- Deployment rollback configuration: Docker Compose configuration validation passed with non-secret fixture values. Runtime rollback rehearsal remains pending because the local Linux Docker daemon is offline.
|
||||||
- Status lifecycle extraction: Release build passed with 0 warnings/errors and the complete backend suite passed 736/736, including applied-date preservation, status suggestions, and cross-tenant not-found behavior.
|
- Status lifecycle extraction: Release build passed with 0 warnings/errors and the complete backend suite passed 736/736, including applied-date preservation, status suggestions, and cross-tenant not-found behavior.
|
||||||
- Accessibility package: public axe flow passed 1/1 and authenticated axe flow passed 1/1 across six workspaces; ESLint passed with zero warnings; all 60 frontend suites and 260/260 tests passed; optimized Next build and integrated TypeScript passed; npm audit reported zero vulnerabilities after adding `@axe-core/playwright`.
|
- Accessibility package: public axe flow passed 1/1 and authenticated axe flow passed 1/1 across six workspaces; ESLint passed with zero warnings; all 60 frontend suites and 260/260 tests passed; optimized Next build and integrated TypeScript passed; npm audit reported zero vulnerabilities after adding `@axe-core/playwright`.
|
||||||
|
- Prebuilt-export browser path: focused Playwright passed 1/1 while serving the existing optimized export without invoking another Next build.
|
||||||
- Focused frontend: 2 suites, 6 tests passed.
|
- Focused frontend: 2 suites, 6 tests passed.
|
||||||
- Full frontend: 64 suites, 272 tests passed.
|
- Full frontend: 64 suites, 272 tests passed.
|
||||||
- Next production build and TypeScript: passed.
|
- Next production build and TypeScript: passed.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const appUrl = "http://localhost:3300";
|
|||||||
const dataRoot = path.join(os.tmpdir(), `jobtracker-e2e-${process.pid}-${Date.now().toString(36)}`);
|
const dataRoot = path.join(os.tmpdir(), `jobtracker-e2e-${process.pid}-${Date.now().toString(36)}`);
|
||||||
const reuseServers = process.env.PLAYWRIGHT_REUSE_SERVERS === "true";
|
const reuseServers = process.env.PLAYWRIGHT_REUSE_SERVERS === "true";
|
||||||
const useStaticExport = process.env.PLAYWRIGHT_STATIC_EXPORT === "true";
|
const useStaticExport = process.env.PLAYWRIGHT_STATIC_EXPORT === "true";
|
||||||
|
const usePrebuiltExport = process.env.PLAYWRIGHT_PREBUILT_EXPORT === "true";
|
||||||
const quote = (value: string) => `"${value.replaceAll('"', '\\"')}"`;
|
const quote = (value: string) => `"${value.replaceAll('"', '\\"')}"`;
|
||||||
const nodeCommand = quote(process.execPath);
|
const nodeCommand = quote(process.execPath);
|
||||||
const dotnetCommand = quote(process.env.DOTNET_HOST_PATH || "dotnet");
|
const dotnetCommand = quote(process.env.DOTNET_HOST_PATH || "dotnet");
|
||||||
@@ -48,7 +49,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
command: useStaticExport
|
command: useStaticExport
|
||||||
? `${nodeCommand} ${nextCommand} build && ${nodeCommand} ${exportServerCommand}`
|
? `${usePrebuiltExport ? "" : `${nodeCommand} ${nextCommand} build && `}${nodeCommand} ${exportServerCommand}`
|
||||||
: `${nodeCommand} ${nextCommand} dev --webpack --hostname localhost --port 3300`,
|
: `${nodeCommand} ${nextCommand} dev --webpack --hostname localhost --port 3300`,
|
||||||
url: appUrl,
|
url: appUrl,
|
||||||
timeout: 120_000,
|
timeout: 120_000,
|
||||||
|
|||||||
Reference in New Issue
Block a user