diff --git a/AGENTS.md b/AGENTS.md index 478f878..3ac871b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -89,8 +89,10 @@ them. Revisit only if the stated reason stops holding. - **CI docker logins share the runner host's Docker config.** The act_runner is host-mode, so `docker login`/`logout` in the workflows mutate one shared `~/.docker/config.json`: concurrent jobs can race (one job's logout can 401 another's push — recover by re-running), - and tokens sit in that file between login and logout. Accepted for a single-maintainer - cadence; serialize with a workflow `concurrency` group if it ever bites. + and tokens sit in that file between login and logout. Same class: concurrent runs share the + workspace dir, so ci.sh's web-image build races another run's container creation on the + `-web` tag. Accepted for a single-maintainer cadence; serialize with a workflow + `concurrency` group if it ever bites. ## Docker only — no host tooling diff --git a/ci.sh b/ci.sh index f78f8d2..d82cc16 100755 --- a/ci.sh +++ b/ci.sh @@ -40,6 +40,12 @@ pkg=$(grep -oE '"@playwright/test": "[0-9.]+"' e2e-tests/package.json | grep -oE [ -n "$img" ] && [ "$img" = "$pkg" ] || { echo "Playwright pin mismatch/unreadable: image v$img vs @playwright/test $pkg"; exit 1; } echo "ok ($img)" +# Explicit rebuild: without it a stale web image from a previous branch supplies node_modules +# (the source is bind-mounted but deps are baked in), so a dep bump gets typechecked/tested +# against the OLD packages. Cheap when deps are unchanged (npm ci layer is cache-keyed). +step "Build web image" +docker compose build web + step "Typecheck" docker compose run --rm --no-deps web npm run typecheck diff --git a/e2e-tests/Dockerfile b/e2e-tests/Dockerfile index 14a94f1..40fae2a 100644 --- a/e2e-tests/Dockerfile +++ b/e2e-tests/Dockerfile @@ -1,6 +1,6 @@ # Playwright runner — browsers preinstalled, pinned to match @playwright/test in e2e-tests/. # Built/run via e2e-tests/compose.visual.yml; targets the `web` service over the network. -FROM mcr.microsoft.com/playwright:v1.49.1-noble +FROM mcr.microsoft.com/playwright:v1.62.1-noble WORKDIR /e2e-tests diff --git a/e2e-tests/package-lock.json b/e2e-tests/package-lock.json index 25c4d88..d458f47 100644 --- a/e2e-tests/package-lock.json +++ b/e2e-tests/package-lock.json @@ -8,23 +8,23 @@ "name": "plainpages-e2e", "version": "0.1.0", "devDependencies": { - "@playwright/test": "1.49.1" + "@playwright/test": "1.62.1" } }, "node_modules/@playwright/test": { - "version": "1.49.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", - "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.1.tgz", + "integrity": "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.49.1" + "playwright": "1.62.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/fsevents": { @@ -43,35 +43,35 @@ } }, "node_modules/playwright": { - "version": "1.49.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", - "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.49.1" + "playwright-core": "1.62.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.49.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", - "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz", + "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==", "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } } } diff --git a/e2e-tests/package.json b/e2e-tests/package.json index 344d1de..ea57bb6 100644 --- a/e2e-tests/package.json +++ b/e2e-tests/package.json @@ -8,6 +8,6 @@ "test": "playwright test" }, "devDependencies": { - "@playwright/test": "1.49.1" + "@playwright/test": "1.62.1" } } diff --git a/package-lock.json b/package-lock.json index c8b9062..b497fac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@larvit/log": "2.3.0", "ejs": "3.1.10", - "lucide-static": "1.18.0" + "lucide-static": "1.28.0" }, "devDependencies": { "@types/ejs": "3.1.5", @@ -110,9 +110,9 @@ } }, "node_modules/lucide-static": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-1.18.0.tgz", - "integrity": "sha512-0WRXLQnjbte5SXuzom6yfeGlVSFsEsC9rzxn66DZN0pXows3+N34CQHy3BHI1qA3uH7u/SUzx8LQhjeAnxd8JQ==", + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-1.28.0.tgz", + "integrity": "sha512-dC3VJwRFsjEVX7Iaq4rY88pm7Fi2OmOb8P0WRzXsUMgbt7sCmFX8bLhaDBeNW6JdRjuele+jKqqFaam4yr+Ygg==", "license": "ISC" }, "node_modules/minimatch": { diff --git a/package.json b/package.json index b7fafd4..9b6eef6 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "dependencies": { "@larvit/log": "2.3.0", "ejs": "3.1.10", - "lucide-static": "1.18.0" + "lucide-static": "1.28.0" }, "devDependencies": { "@types/ejs": "3.1.5", diff --git a/views/partials/icons.ejs b/views/partials/icons.ejs index c47c028..a446e21 100644 --- a/views/partials/icons.ejs +++ b/views/partials/icons.ejs @@ -4,7 +4,7 @@ - +