github CodesWhat/drydock v1.5.0-rc.22

pre-release4 hours ago

v1.5.0-rc.22

[1.5.0-rc.22] — 2026-05-15

Added

  • All 16 non-English locales now have full key parity with the English source (commits 5e463631, 012dcb83). Two complementary passes bring every translation up to date. The first pass (5e463631) filled gaps in the ten locales that were already mostly translated (de, es, fr, it, nl, pl, pt-BR, tr, zh-CN, zh-TW) — each was missing notificationOutboxView.json entirely and had drifted behind recent string extractions in listViews.json, containerComponents.json, containersView.json, and dashboardView.json (new keys: digestLabel, blockedTag variants, manualUpdateOnly variants, narrowViewportSuffix, autoHiddenBadgeTooltip, queued-update toast variants, recentUpdates.widgetAria). A JSON-breaking typo in de/dashboardView.json (straight quote instead of closing curly quote) was also corrected. The second pass (012dcb83) gave the six stub locales (ar, ja, ko, ru, uk, vi) — which had been scaffolded with English placeholders since rc.20 — a full translation pass across all 13 namespace files plus the new notificationOutboxView.json. Brand names, acronyms, and interpolation placeholders are preserved verbatim; DevOps terminology follows each language's established conventions.

Changed

  • Playwright E2E tests moved to a dedicated workflow file (e2e-playwright.yml) (commit f0989301). OSSF Scorecard's CI-Tests check scores from the github-actions Check Suite conclusion, not individual check-run conclusions. Because every job in ci-verify.yml rolled into a single suite, one failing Playwright assertion would flip the entire suite to failure and cause Scorecard to mark merged PRs as untested — even when all other jobs were green (manifesting as code-scanning alert #43, CI-Tests score 9/10). Each workflow file gets its own Check Suite per commit; isolating Playwright into e2e-playwright.yml means a Playwright failure no longer drags the ci-verify suite down for Scorecard's purposes. Branch protection continues to gate on the "🎭 E2E: Playwright" status check (matched by job name, not workflow file), and release-cut.yml now polls both workflows on the target SHA so releases still require Playwright success.

Fixed

  • #368 — OIDC custom-dispatcher paths (cafile / DD_AUTH_OIDC_*_INSECURE=true) no longer fail with an opaque TypeError: fetch failed on Node 24. Node 24 ships built-in undici 7.21.0 (v1 dispatcher interface) while the app's userland undici@8 (bumped in rc.20) exposes an Agent with the v2 dispatcher interface. The OIDC custom fetch was constructing the v2 Agent from userland undici and passing it as dispatcher to Node's global fetch, which is bound to the built-in undici 7. The v2 Agent's handlers don't satisfy the v1 contract, so the request silently fails — the surface symptom reported by a user upgrading rc.19 → rc.21 against self-signed Authentik with DD_AUTH_OIDC_AUTHENTIK_INSECURE=true. The undici project's Dispatcher1Wrapper bridge (nodejs/undici#4827) covers this mismatch on Node 22 but is absent on Node 24. The fix imports fetch from undici and uses it whenever a custom dispatcher is required (cafile or insecure path) so both halves share the same dispatcher version. The non-insecure code path is unchanged — openid-client continues to use its default fetch when no custom dispatcher is needed. A strict-tsc type error introduced in the same fix (undici's nominal RequestInfo/Response types differ from the lib.dom types that openid-client's CustomFetch is typed against) was resolved by casting through unknown at the boundary using Parameters<typeof undiciFetch> and ReturnType<openidClientLibrary.CustomFetch>; there is no runtime behavior change.

  • OIDC warn logs now surface the full error.cause chain, making TLS and DNS failures actionable (commit 720d99a3). undici's fetch surfaces failures as a generic TypeError: fetch failed; the actionable diagnostic (ENOTFOUND, ECONNREFUSED, UNABLE_TO_VERIFY_LEAF_SIGNATURE, etc.) lives on error.cause, sometimes nested. The previous error sanitizer logged only the top-level message, so issue #368 reached us with only "Unable to initialize OIDC session (fetch failed)" — no indication whether DNS, TLS, or routing was at fault. A new getErrorChainMessage helper walks error.cause up to depth 5, joining parts with and appending [code] when a code property is present; a WeakSet guards against cyclic cause chains. sanitizeOidcErrorMessage now uses it so all OIDC warn logs include the cause chain (still passed through the existing URL and token redaction). This is a forward-only diagnostic improvement with no runtime behavior change for healthy OIDC paths.

  • #362 — SSE reconnect exponential backoff no longer collapses to a flat 1 s loop when the agent is struggling. AgentClient.startSse() previously called this.reconnectAttempts = 0 the instant the axios response headers arrived — before the stream had proven it could stay open. A crash-looping agent, a reverse-proxy with a short upstream idle timeout, or any situation where the SSE stream returned HTTP 200 and then ended almost immediately would cycle as: connect → 200 → reconnectAttempts = 0 → stream ends → scheduleReconnect() (delay = 1 000 ms, attempts → 1) → 1 s later connect → 200 → reconnectAttempts = 0 again — and so on forever. The user who filed #362 saw SSE stream ended. Reconnecting... in their controller logs every ~1.00 s indefinitely, with no escalation. The backoff now only resets after the stream has stayed open for SSE_STABLE_CONNECTION_MS (30 s). A setTimeout is armed when the response arrives and cancelled by scheduleReconnect() if the stream ends or errors before the window expires; streams that end early therefore keep their accumulated reconnectAttempts and the delay continues to double up to the 60 s cap as intended.

Don't miss a new drydock release

NewReleases is sending notifications on new releases.