Skip to content

chore(deps): take the Renovate dashboard upgrades - #85

Merged
fylorn merged 1 commit into
devfrom
chore/deps-2026-10
Oct 6, 2026
Merged

fylorn merged 1 commit into
devfrom
chore/deps-2026-10

Conversation

@fylorn

@fylorn fylorn commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Works through the Renovate dependency dashboard (#79): every pending upgrade that could be taken safely, in one PR to spend one CI run.

Rust

Crypto (= pins moved deliberately): jsonwebtoken 10.3.0 → 11.1.0, argon2 0.5.3 → 0.6.0, aes-gcm 0.10.3 → 0.11.1, p256 0.13.2 → 0.14.0, ecdsa 0.16.9 → 0.17.0, and totp-rs 5 → 6.

Data written by the old versions must keep verifying, so this PR first adds known-answer tests. Their vectors were produced with the old crates, and every test passes before and after the bump:

  • an Argon2id PHC string from argon2 0.5.3 still verifies, and new hashes still use m=19456, t=2, p=1
  • an AES-256-GCM envelope from aes-gcm 0.10.3 still decrypts, and a tampered tag is rejected
  • an HS256 token from jsonwebtoken 10.3.0 still verifies; HS512, alg: none and forged signatures are still rejected (the Validation defaults are unchanged)
  • RFC 6238 SHA-1 vectors for TOTP, with exactly ±1 step of skew
  • P-256 signatures from p256 0.13.2 verify, including a high-S signature, which Web Crypto produces about half the time. In ecdsa 0.17 the low-S check only applies to curves with NORMALIZE_S, and that is false for P-256

Code changes:

  • elliptic-curve 0.14 dropped JWK support (it moved to jose-jwk), so P-256 JWK parsing and serialisation are now done by hand in verify_signature.rs: kty/crv are checked, x/y must be unpadded base64url of exactly 32 bytes each, and the point must lie on the curve. Tests cover the round trip and malformed keys.
  • ecdsa's verifying feature is now called algorithm.
  • totp-rs 6 uses the Builder API with default features off, so the migration shims are not compiled in.

Other majors:

  • utoipa 6 / utoipa-swagger-ui 10. I diffed the generated spec against v5: the only change is the order of oneOf members for nullable refs.
  • sqlx 0.9. Dynamic SQL now has to be wrapped in AssertSqlSafe. I audited all 18 sites, and each one interpolates only &'static str fragments or generated identifiers.
  • clickhouse 0.13 → 0.15. insert() is now async. Row validation is a new default; this PR turns it off, which gives the same RowBinary behaviour as 0.13 (see below).
  • tower-http 0.7, rustls-platform-verifier 0.7, metrics-exporter-prometheus 0.18 (the /metrics output is the same apart from line order), and tokio-tungstenite 0.30 (tests only).
  • cargo update for everything else. The tw-* core crates stay on v0.62.0.

The new dependencies need rustc ≥ 1.94.1, so rust-version now says that, and Dockerfile.server moves from rust:1.93 to rust:1.99. 1.93 can no longer build the workspace.

Bugs found on the way

  • ClickHouse ≥ 26.9 breaks every read. 26.9 changed the default network_compression_method from LZ4 to ZSTD. The clickhouse crate (0.13 and 0.15 alike) asks for compress=1 and only decodes LZ4, so every query fails with "incorrect magic number". The client now names LZ4 on every query, which works on every server version. The test harness does the same.
  • SLO percentiles were garbage. quantileExact over Nullable(Int64) returns Int64, and that was decoded into Option<f64>, so p50/p95/p99 came out as denormals next to zero. The 0.15 row validation caught it. The query now uses toFloat64(...), and the integration test asserts the percentiles are whole milliseconds.

Frontend

  • Minor and patch updates for everything on the dashboard list.
  • Majors: vitest 5, jsdom 30, @testing-library/jest-dom 7, react-day-picker 10. react-day-picker 10 needed initialFocus → autoFocus.
  • pnpm 11.0.0 → 11.28.4, in package.json, CI and Dockerfile.web.
  • Not taken:
    • TypeScript 7: typescript-eslint 8.71 supports only versions below 6.1, and openapi-typescript wants ^5.
    • pnpm 12: a six-week-old native rewrite that adds per-platform binary entries to the lockfile.

Images and actions

  • nginx 1.29 → 1.31: the built web image passes nginx -t and serves the app.
  • node → 24.21.0-alpine.
  • zitadel → v4.19.4 (dev compose only).
  • ClickHouse 26.3 → 26.8, the newer LTS, in compose, Helm and CI. A Renovate rule now keeps ClickHouse on LTS releases (YY.3 / YY.8).
  • All actions are pinned to commit SHAs and moved to their current majors. I checked every input the workflows use against each new action.yml. CI service images are pinned by digest.

Renovate config

  • The config migration (baseBranches → baseBranchPatterns) is applied. renovate-config-validator --strict passes; it flagged the old file as needing migration.
  • New rule: Renovate leaves the tw-* core crates alone, because they are pinned by hand.

Supply chain

  • 286 crate versions changed. Every lockfile checksum matches crates.io, and none is yanked. Where the publisher changed, it moved to GitHub trusted publishing from the project's own repo, or to a listed co-owner.
  • I reviewed every build script that is new or changed.
  • npm: every lockfile integrity hash matches the registry, and no new install scripts were added.

Checks run locally

  • cargo fmt --check, clippy --all-targets -D warnings, and 755 unit tests.
  • The full integration suite (409 tests) on ClickHouse 26.8, and on 26.9 with the compression fix.
  • Frontend: lint, test, build, and the web Docker image.
  • The server Docker image.

🤖 Generated with Claude Code

Rust: jsonwebtoken 11, argon2 0.6, aes-gcm 0.11, p256 0.14, ecdsa 0.17
and totp-rs 6, behind known-answer tests whose vectors come from the old
crates (stored Argon2 hashes, AES-GCM envelopes, HS256 tokens, high-S
P-256 signatures and RFC 6238 codes keep verifying). P-256 JWK parsing
moves in-house: elliptic-curve 0.14 dropped it. utoipa 6,
utoipa-swagger-ui 10, sqlx 0.9 (dynamic SQL audited and wrapped in
AssertSqlSafe), clickhouse 0.15, tower-http 0.7, rustls-platform-verifier
0.7, metrics-exporter-prometheus 0.18, tokio-tungstenite 0.30, and a
lock refresh. MSRV is now 1.94.1; the server image builds on rust 1.99.

Found on the way: ClickHouse 26.9 answers compress=1 with ZSTD, which
the crate cannot read, so the client names LZ4; SLO percentiles decoded
Int64 as f64 and came out as denormals.

Frontend: minor/patch updates, vitest 5, jsdom 30, jest-dom 7,
react-day-picker 10, pnpm 11.28.4. Images: nginx 1.31, node 24.21.0,
ClickHouse 26.8 LTS, zitadel 4.19.4. Actions pinned to SHAs on their
current majors. Renovate config migrated (baseBranchPatterns), core
crates left to hand pinning, ClickHouse kept on LTS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fylorn
fylorn merged commit 1fbe7bd into dev Oct 6, 2026
6 checks passed
@fylorn
fylorn deleted the chore/deps-2026-10 branch October 6, 2026 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant