diff --git a/.claude/skills/cf-temp-mail-upgrade-dependencies/SKILL.md b/.claude/skills/cf-temp-mail-upgrade-dependencies/SKILL.md index 80327e95..0f671544 100644 --- a/.claude/skills/cf-temp-mail-upgrade-dependencies/SKILL.md +++ b/.claude/skills/cf-temp-mail-upgrade-dependencies/SKILL.md @@ -1,6 +1,6 @@ --- name: cf-temp-mail-upgrade-dependencies -description: Upgrade npm dependencies across all sub-packages of the project. Use when the user asks to upgrade/update dependencies, bump deps, refresh lockfiles, or update wrangler. Runs pnpm upgrades on frontend/, worker/, pages/, and vitepress-docs/. +description: Upgrade npm dependencies across all sub-packages of the project. Use when the user asks to upgrade/update dependencies, bump deps, refresh lockfiles, or update wrangler. Runs pnpm upgrades on frontend/, worker/, pages/, and vitepress-docs/, plus npm upgrades on e2e/. --- # Upgrade Dependencies @@ -23,18 +23,21 @@ The script runs the following in order: | `worker/` | `pnpm up` + `pnpm add -D wrangler@latest` | | `pages/` | `pnpm up` + `pnpm add -D wrangler@latest` | | `vitepress-docs/` | `pnpm up --latest` + `pnpm add -D wrangler@latest` | +| `e2e/` | `npx --yes npm-check-updates@23.0.0 --upgrade` + `npm install` + Playwright image validation | -Note: `vitepress-docs/` uses `--latest` (crosses semver ranges); other packages upgrade within ranges only. +Note: `vitepress-docs/` and `e2e/` upgrade to the latest versions and may cross semver ranges; other packages upgrade within ranges only. `e2e/` uses npm because it has a `package-lock.json`. ## Post-upgrade checklist -1. Inspect `git diff` on `package.json` / `pnpm-lock.yaml` files for reasonable changes. +1. Inspect `git diff` on `package.json`, `pnpm-lock.yaml`, and `package-lock.json` files for reasonable changes. 2. Verify builds in each sub-package: - `cd frontend && pnpm build` - `cd worker && pnpm build && pnpm lint` - `cd vitepress-docs && pnpm build` -3. If wrangler had a major version bump, check `worker/wrangler.toml` for any required syntax changes. -4. Commit with Conventional Commits format, e.g. `chore: upgrade dependencies`. + - `cd e2e && npm test` +3. If Playwright changed, keep `e2e/Dockerfile.e2e` on the matching Playwright image version. +4. If wrangler had a major version bump, check `worker/wrangler.toml` for any required syntax changes. +5. Commit with Conventional Commits format, e.g. `chore: upgrade dependencies`. ## Do NOT diff --git a/e2e/Dockerfile.e2e b/e2e/Dockerfile.e2e index e559d1a3..ed900f14 100644 --- a/e2e/Dockerfile.e2e +++ b/e2e/Dockerfile.e2e @@ -1,5 +1,5 @@ # Keep this version in sync with @playwright/test in package.json -FROM mcr.microsoft.com/playwright:v1.58.2-noble +FROM mcr.microsoft.com/playwright:v1.62.1-noble RUN apt-get update && apt-get install -y curl netcat-openbsd && rm -rf /var/lib/apt/lists/* diff --git a/e2e/package-lock.json b/e2e/package-lock.json index 5cd570bf..63f156a7 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -6,14 +6,14 @@ "": { "name": "cloudflare-temp-email-e2e", "dependencies": { - "imapflow": "^1.4.2", - "nodemailer": "^9.0.1" + "imapflow": "^1.6.5", + "nodemailer": "^9.0.3" }, "devDependencies": { - "@playwright/test": "1.58.2", - "@types/nodemailer": "^7.0.11", - "@types/ws": "^8.5.0", - "ws": "^8.18.0" + "@playwright/test": "1.62.1", + "@types/nodemailer": "^8.0.1", + "@types/ws": "^8.18.1", + "ws": "^8.21.1" } }, "node_modules/@pinojs/redact": { @@ -23,35 +23,35 @@ "license": "MIT" }, "node_modules/@playwright/test": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", - "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "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.58.2" + "playwright": "1.62.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@types/node": { - "version": "25.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "version": "26.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz", + "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.18.0" + "undici-types": "~8.3.0" } }, "node_modules/@types/nodemailer": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.11.tgz", - "integrity": "sha512-E+U4RzR2dKrx+u3N4DlsmLaDC6mMZOM/TPROxA0UAPiTgI0y4CEFBmZE+coGWTjakDriRsXG368lNk1u9Q0a2g==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz", + "integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==", "dev": true, "license": "MIT", "dependencies": { @@ -69,13 +69,13 @@ } }, "node_modules/@zone-eu/mailsplit": { - "version": "5.4.12", - "resolved": "https://registry.npmjs.org/@zone-eu/mailsplit/-/mailsplit-5.4.12.tgz", - "integrity": "sha512-w7Gy+NvjZ0MiXm8F6zfjImAqcTONKDImgWVBjDKQVFUXWuz3VFM5levNArkL2M877ajql5+bkS2pDV56injlmg==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/@zone-eu/mailsplit/-/mailsplit-5.4.14.tgz", + "integrity": "sha512-rz0FQOhN3Vq1XrSeSSa9+dPcaFbBxmQPjiZm6zS9oxdVHV7rOWIAYX3yP2YAUf0qBncY8CI+NogzPCmMVrMXcw==", "license": "(MIT OR EUPL-1.1+)", "dependencies": { "libbase64": "1.3.0", - "libmime": "5.3.8", + "libmime": "5.4.1", "libqp": "2.1.1" } }, @@ -113,9 +113,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -129,26 +129,25 @@ } }, "node_modules/imapflow": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/imapflow/-/imapflow-1.4.2.tgz", - "integrity": "sha512-73CGfb5+W0FkZ5CY4GfSdsoXyQ+17wdKkpMN2vwJHdLtOOFQWxv0ilG7KYY79XHBYg5njjqxXYB2FPw5Tl81zQ==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/imapflow/-/imapflow-1.6.5.tgz", + "integrity": "sha512-5XgLcfl6blDju2SP7TgTv4WIlTt7zxXYcfjznJFmfFrogHR2XzHGlS9s2wdqxv9ZJ5CPaRnig7KaK7qNoJPmlg==", "license": "MIT", "dependencies": { - "@zone-eu/mailsplit": "5.4.12", + "@zone-eu/mailsplit": "5.4.14", "encoding-japanese": "2.2.0", - "iconv-lite": "0.7.2", + "iconv-lite": "0.7.3", "libbase64": "1.3.0", - "libmime": "5.3.8", + "libmime": "5.4.1", "libqp": "2.1.1", - "nodemailer": "9.0.1", "pino": "10.3.1", "socks": "2.8.9" } }, "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz", + "integrity": "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==", "license": "MIT", "engines": { "node": ">= 12" @@ -161,13 +160,13 @@ "license": "MIT" }, "node_modules/libmime": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.8.tgz", - "integrity": "sha512-ZrCY+Q66mPvasAfjsQ/IgahzoBvfE1VdtGRpo1hwRB1oK3wJKxhKA3GOcd2a6j7AH5eMFccxK9fBoCpRZTf8ng==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.4.1.tgz", + "integrity": "sha512-0wHGhsofo9IdQPenr3BBHXuxcwMq4atFUTsZ9Ogc1OvI5h4rUdDIrBQEN9JHjCXfDMrE59LUMJWsTD82wTYk8A==", "license": "MIT", "dependencies": { "encoding-japanese": "2.2.0", - "iconv-lite": "0.7.2", + "iconv-lite": "0.7.3", "libbase64": "1.3.0", "libqp": "2.1.1" } @@ -179,9 +178,9 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.1.tgz", - "integrity": "sha512-Gwv8SQewT616ZM/URn0H54b8PWo/Wum7md3EW2aWy1lO27+WZCX+Xyak3J+NlmHUjDh5ME+uesJUDRbR3Ye8Bw==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.3.tgz", + "integrity": "sha512-n+YP+NKwR5zRWa60k3GiQ6Q3B4KXCoAw40dAKeCtYn020iNN74aWK2liXIC3ZEATeGql7we3tE3t8QwhY0eskw==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -234,41 +233,41 @@ "license": "MIT" }, "node_modules/playwright": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", - "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "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.58.2" + "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.58.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", - "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "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" } }, "node_modules/process-warning": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", - "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.1.0.tgz", + "integrity": "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==", "funding": [ { "type": "github", @@ -354,28 +353,34 @@ } }, "node_modules/thread-stream": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.0.0.tgz", - "integrity": "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.2.0.tgz", + "integrity": "sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==", "license": "MIT", "dependencies": { - "real-require": "^0.2.0" + "real-require": "^1.0.0" }, "engines": { "node": ">=20" } }, + "node_modules/thread-stream/node_modules/real-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz", + "integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==", + "license": "MIT" + }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "dev": true, "license": "MIT" }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", "dev": true, "license": "MIT", "engines": { diff --git a/e2e/package.json b/e2e/package.json index d837bbe8..be65de64 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -7,13 +7,13 @@ "test:down": "docker compose down -v" }, "devDependencies": { - "@playwright/test": "1.58.2", - "@types/nodemailer": "^7.0.11", - "@types/ws": "^8.5.0", - "ws": "^8.18.0" + "@playwright/test": "1.62.1", + "@types/nodemailer": "^8.0.1", + "@types/ws": "^8.18.1", + "ws": "^8.21.1" }, "dependencies": { - "imapflow": "^1.4.2", - "nodemailer": "^9.0.1" + "imapflow": "^1.6.5", + "nodemailer": "^9.0.3" } } diff --git a/scripts/update-dependencies.sh b/scripts/update-dependencies.sh index 4eae50f4..8750b9d4 100755 --- a/scripts/update-dependencies.sh +++ b/scripts/update-dependencies.sh @@ -1,3 +1,5 @@ +set -euo pipefail + cd frontend/ pnpm up pnpm add -D wrangler@latest @@ -17,3 +19,18 @@ cd vitepress-docs/ pnpm up --latest pnpm add -D wrangler@latest cd .. + +cd e2e/ || exit 1 +npx --yes npm-check-updates@23.0.0 --upgrade +npm install + +PLAYWRIGHT_VERSION="$(node -p "require('./package.json').devDependencies['@playwright/test']")" +EXPECTED_IMAGE="mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble" +if ! awk -v expected="${EXPECTED_IMAGE}" \ + '$1 == "FROM" && $2 == expected { found=1 } END { exit !found }' \ + Dockerfile.e2e; then + echo "Dockerfile.e2e must use Playwright ${PLAYWRIGHT_VERSION}" >&2 + exit 1 +fi + +cd ..