v0.66.0 — E2E results in Gitea job summary (#141) #142

Merged
kamilkrzywda merged 1 commits from ci/e2e-job-summary into master 2026-09-23 19:29:55 +02:00
3 changed files with 52 additions and 3 deletions
Showing only changes of commit d278c8ba9c - Show all commits
+48 -2
View File
@@ -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).
+3
View File
@@ -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
View File
@@ -1,6 +1,6 @@
{
"name": "flight-ops",
"version": "0.65.0",
"version": "0.66.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000",