v0.66.0: e2e results in Gitea job summary (#141)
CI / build + unit + e2e (pull_request) Successful in 14m43s
CI / build + unit + e2e (pull_request) Successful in 14m43s
The run page's Job summaries panel showed vitest results (vitest's built-in github-actions reporter auto-appends $GITHUB_STEP_SUMMARY in CI) but nothing about the Playwright suite. The E2E step now also runs the built-in json reporter (--reporter=list,json, output pinned to git-ignored test-results/e2e.json via PLAYWRIGHT_JSON_OUTPUT_FILE), and a new non-fatal 'E2E job summary' step (if: always()) parses it with an inline node script and appends spec-level passed/failed/skipped counts + failed spec names (file > title) to $GITHUB_STEP_SUMMARY. Guarded so a missing/malformed report can never fail or mask the e2e step's real exit code; no test behavior, timeouts, workers or retries changed.
This commit is contained in:
+48
-2
@@ -189,10 +189,56 @@ jobs:
|
||||
# in-network app host out of any proxy path.
|
||||
NO_PROXY: app,localhost,127.0.0.1,.kkhost.pl
|
||||
no_proxy: app,localhost,127.0.0.1,.kkhost.pl
|
||||
# Machine-readable e2e results for the job-summary step below (Playwright's built-in
|
||||
# json reporter; without this env var it would dump to stdout). test-results/ is git-ignored.
|
||||
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/e2e.json
|
||||
# Connectivity diagnostics now run post-deploy in e2e/ci-diagnostics.ts (globalSetup).
|
||||
# --reporter=list prints each test as it completes (name + ✓/× + duration) for progress
|
||||
# visibility in the job log; failure error context/snapshots are unchanged.
|
||||
run: npx playwright test --reporter=list
|
||||
# visibility in the job log; failure error context/snapshots are unchanged. The json
|
||||
# reporter adds a machine-readable report (PLAYWRIGHT_JSON_OUTPUT_FILE above) — no
|
||||
# execution behavior changes, reporters only observe.
|
||||
run: npx playwright test --reporter=list,json
|
||||
|
||||
# Appends e2e results to the job-summary panel — mirrors how unit tests get there
|
||||
# (vitest's built-in github-actions reporter auto-appends $GITHUB_STEP_SUMMARY in CI).
|
||||
# if: always() so a FAILED suite still gets summarized; non-fatal by design — a missing
|
||||
# or malformed report must never mask the real e2e exit code. The script is single-quoted
|
||||
# for bash, so it contains no apostrophes.
|
||||
- name: E2E job summary
|
||||
if: always()
|
||||
run: |
|
||||
node -e '
|
||||
const fs = require("fs");
|
||||
let report;
|
||||
try {
|
||||
report = JSON.parse(fs.readFileSync("test-results/e2e.json", "utf8"));
|
||||
} catch {
|
||||
process.exit(0); // e2e never ran (earlier step failed) or no report — nothing to summarize
|
||||
}
|
||||
let passed = 0, skipped = 0;
|
||||
const failed = [];
|
||||
const walk = (suite) => {
|
||||
for (const spec of suite.specs ?? []) {
|
||||
if (!spec.ok) failed.push(`${suite.title} › ${spec.title}`);
|
||||
else if ((spec.tests ?? []).length && spec.tests.every((t) => t.expectedStatus === "skipped")) skipped++;
|
||||
else passed++;
|
||||
}
|
||||
for (const sub of suite.suites ?? []) walk(sub);
|
||||
};
|
||||
for (const s of report.suites ?? []) walk(s);
|
||||
const lines = [
|
||||
"", "## E2E results", "",
|
||||
`- Passed: ${passed}`,
|
||||
`- Failed: ${failed.length}`,
|
||||
`- Skipped: ${skipped}`,
|
||||
];
|
||||
if (failed.length) {
|
||||
lines.push("", "### Failed specs");
|
||||
for (const f of failed) lines.push(`- \`${f}\``);
|
||||
}
|
||||
const summaryFile = process.env.GITHUB_STEP_SUMMARY;
|
||||
if (summaryFile) fs.appendFileSync(summaryFile, lines.join("\n") + "\n");
|
||||
' || true
|
||||
|
||||
# The daemon is shared with production — never leave our stack or network behind.
|
||||
# -v drops the named DB volume so every run seeds fresh (no schema drift between PRs).
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## v0.66.0 — 2026-09-23 17:06
|
||||
- **E2E results in the Gitea job summary (#141).** The run page's "Job summaries" panel showed vitest results (vitest's built-in `github-actions` reporter auto-appends `$GITHUB_STEP_SUMMARY` when `GITHUB_ACTIONS=true`) but nothing about the Playwright suite, so a failed e2e run required digging into raw logs to see which specs broke. The CI E2E step now also runs Playwright's built-in `json` reporter (`--reporter=list,json`, output pinned to git-ignored `test-results/e2e.json` via `PLAYWRIGHT_JSON_OUTPUT_FILE` — no new dependencies, no config/TS changes), and a new non-fatal "E2E job summary" step (`if: always()`) parses that report with an inline node script and appends spec-level passed/failed/skipped counts plus the file + title of every failed spec to `$GITHUB_STEP_SUMMARY` — mirroring exactly how vitest gets there. The append is guarded (`|| true`, missing/malformed report = silent no-op) so it can never fail or mask the e2e step's real exit code; test behavior, timeouts, workers and retries are untouched.
|
||||
|
||||
## v0.65.0 — 2026-09-23 12:58
|
||||
- **Per-airport job pools with real-time refresh.** The market was a global bag of jobs (top-up to `MARKET_TARGET_OPEN_PACKAGES = 10` + coverage spawn at uncovered grounded airports), so the board showed work you could never take and hid nothing. Now open jobs are generated PER AIRPORT where a plane can actually pick them up — the pool is the set of grounded planes' `locationIcao`, flying planes' `destIcao` and queued-leg ICAOs — queued legs count even while their plane is in the shop (the work will be waiting at its next stop); a fleet fully repairing with empty queues has no pool, and orphaned pools simply expire out. Each pool airport holds exactly `POOL_TARGET_PER_AIRPORT = 10` open jobs in a fixed weight composition (`POOL_BANDS`: 2×[500,4000) + 6×[4000,18000) + 1×[18000,48000] + 1×(48000,80000] kg), so the board always mixes jobs you can take now with heavier ones that are what you buy better planes for. `spawnPoolPackages` in `lib/sim/engine.ts` replaces both old spawners and runs on every tick (including frozen ones) like v0.64.0's top-up; seeded and spawned packages come from the same new `generatePoolPackage` helper in `lib/game/seed.ts`, so they are indistinguishable — `buildSeed` now seeds a full pool at the starter's home hub, and `PACKAGE_COUNT_MIN/MAX` + `MARKET_TARGET_OPEN_PACKAGES` are retired.
|
||||
- **Open jobs live on the wall clock.** New `created_real_ms INTEGER NOT NULL DEFAULT 0` column (guarded ALTER backfilled with `Date.now()` for existing rows): an open job expires `JOB_LIFETIME_MS = 1 h` after creation regardless of time scale or fleet state — checked every tick OUTSIDE the advance gate, so a paused world still refreshes its board. Loaded jobs keep their sim-clock deadline logic unchanged (delivery check, expiry floor, abandon penalty all untouched). Taken slots (loaded OR ignored) stamp `slot_free_at_real_ms` and hold their pool slot for a refill cooldown — `REFILL_DELAY_MS = 15 min`, or `SMALL_REFILL_DELAY_MS = 1 min` for the <4 t band — so the board visibly refreshes instead of instantly refilling; expired/delivered/abandoned never block. ponytail: one shared per-airport cooldown (the max stamp) rather than a per-band table, add when per-band refill timing matters.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "flight-ops",
|
||||
"version": "0.65.0",
|
||||
"version": "0.66.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3000",
|
||||
|
||||
Reference in New Issue
Block a user