Release v1.5.0-rc.22 prep#369
Merged
Merged
Conversation
These six locales were scaffolded with English placeholders and never
received a translation pass. All 13 existing files now contain real
translations and the missing notificationOutboxView.json has been added
to each, bringing them to full key parity with the English source.
Conventions:
- Brand/proper nouns kept in Latin (Drydock, Docker, Slack, Discord, etc.)
- Acronyms kept in English (API, URL, HTTP, JSON, YAML, TLS, etc.)
- DevOps terminology uses each language's established conventions
- All interpolation placeholders ({name}, {count}) and ICU plurals preserved
…/zh-CN/zh-TW) These ten locales were already mostly translated but had drifted behind recent string extractions and were missing notificationOutboxView.json entirely. Filled across the affected files: - notificationOutboxView.json — new file in every locale (heading, tabs, columns, actions, status, empty states, toast messages). - listViews.json — notificationsView.rules (6 rule name/description pairs), securityView.deltaTooltips, updateOneOfButton, updateThisContainerButton, registriesView.status, serversView.status. - containerComponents.json — digestLabel, blockedTag variants, manualUpdateOnly variants, narrowViewportSuffix, autoHiddenBadgeTooltip, clearContainerIdFilter, suggestedTag.tooltipWithTag. - containersView.json — updateStarted, forceUpdateStarted, alreadyUpToDate, queuedUpdate* and countAlreadyUpToDate* toast variants. - dashboardView.json — recentUpdates.widgetAria. Also fixes a typo in de/dashboardView.json where the closing curly quote was rendered as a straight quote, breaking JSON parsing. All 16 non-English locales now have zero missing keys versus en/.
Scorecard's CI-Tests check derives its score from the github-actions Check Suite conclusion (via GraphQL), not individual check-run conclusions. Because every job in ci-verify.yml rolled into a single github-actions suite, one failing Playwright assertion (e.g. the "No pending entries" casing bug on PR #366) was flipping the entire suite to "failure" and making Scorecard mark the merged PR as untested — even though 9+ other jobs in the same suite were green. That manifested as code-scanning alert #43 (CI-Tests score 9/10). Each workflow file gets its own Check Suite per commit. Moving Playwright into e2e-playwright.yml isolates its failures into a separate suite, so a Playwright bug no longer drags ci-verify's suite down for Scorecard's purposes. Branch protection still gates 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 continue to require Playwright success. Notes: - The new workflow builds its own QA image inline rather than consuming the qa-image artifact, since artifacts are scoped to a single workflow run. Both workflows share the `drydock` GHA cache scope, so whichever runs second hits a warm cache. - ci-verify still owns the qa-image artifact upload because dast-zap-baseline, dast-nuclei, and load-test-ci consume it inside the same workflow run.
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 sanitizer only logged the top-level message, so issue #368 (Authentik SSO regression on rc.21) reached us with only 'Unable to initialize OIDC session (fetch failed)' — no way to tell whether DNS, TLS, or routing was at fault. - New getErrorChainMessage(error, fallback?) walks error.cause up to depth 5, joins parts with ' ← ', appends '[code]' when present, and handles cycles via WeakSet. - sanitizeOidcErrorMessage now uses it, so all OIDC warn logs include the cause chain (still passed through the existing URL + token redaction). - Tests cover plain Error, multi-level chains, cyclic cause, depth-5 truncation, missing message + custom fallback, and an end-to-end OIDC discovery rejection that asserts the cause's ENOTFOUND code reaches log.warn. Forward-only diagnostic improvement — no runtime behavior changes for healthy OIDC paths.
…k SSO regression Fixes #368. Node 24 ships built-in undici 7.21.0 (v1 dispatcher interface) while the app's userland undici@8.2.0 (bumped on May 12 in commit e763e09, shipped in rc.20) exposes an Agent with the v2 dispatcher interface. The OIDC custom fetch was constructing the Agent from userland undici@8 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 fails with the opaque `TypeError: fetch failed` — the same surface symptom @begunfx reported after upgrading rc.19 → rc.21 with `DD_AUTH_OIDC_AUTHENTIK_INSECURE=true` against self-signed Authentik. undici PR nodejs/undici#4827 covers this exact cross-version mismatch and adds a Dispatcher1Wrapper bridge — but only on Node 22. Node 24 has no such bridge, so the global-fetch + userland-undici-Agent combination silently fails. Fix: import `fetch` from `undici` and use it whenever a custom dispatcher is required (cafile or insecure path). Both halves now share the same dispatcher version. The non-insecure code path is unchanged — openid-client still uses its default fetch when no custom dispatcher is needed. Tests updated to mock `undici`'s `fetch` instead of spying on `globalThis.fetch`. All 8085+ app tests pass; coverage stays at 100%.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…nt types The undici-fetch fix in 03ed0f4 passed `npm test` (vitest is lenient on type-only mismatches) but failed the Docker app-build stage where strict `tsc` runs: Oidc.ts(471): TS2322: Promise<undici.Response> not assignable to Promise<Response> Oidc.ts(472): TS2345: 'URL | RequestInfo' not assignable to undici's RequestInfo undici's RequestInfo / RequestInit / Response are nominally distinct from the lib.dom types openid-client's CustomFetch is typed against. At runtime they're the same shape (Node 24's global fetch is undici under the hood). Cast through `unknown` at the boundary using `Parameters<typeof undiciFetch>` for the inputs and `ReturnType<openidClientLibrary.CustomFetch>` for the return — the latter sidesteps the fact that `Response` already resolves to Express's response type from the top-of-file import. No runtime behavior change. Build, lint, and full app suite (8084 tests, 100% coverage) all pass.
AgentClient.startSse() reset reconnectAttempts to 0 the instant the axios response headers arrived, before the SSE stream proved it could stay open. A stream that returned HTTP 200 then ended immediately — crash-looping agent, reverse-proxy idle timeout — reset the backoff on every cycle, collapsing exponential backoff into a flat 1s reconnect loop that hammered the struggling agent. This is the symptom in the #362 reporter's controller logs: "SSE stream ended. Reconnecting..." every ~1.00s with no escalation. The backoff now resets only after the stream stays open for SSE_STABLE_CONNECTION_MS (30s). A stability timer is armed when the response arrives and cancelled by scheduleReconnect() if the stream ends or errors early, so transient connections keep their accumulated attempt count and the delay escalates to the 60s cap as intended.
biggest-littlest
approved these changes
May 15, 2026
ALARGECOMPANY
approved these changes
May 15, 2026
ALARGECOMPANY
left a comment
Member
There was a problem hiding this comment.
rc.22 release prep — second code-owner approval. Changes reviewed, app suite green at 100% coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cutting v1.5.0-rc.22. Two user-facing bug fixes (a remote-agent SSE reconnect storm and the rc.20 Authentik SSO regression), one diagnostic improvement on the OIDC code path, one CI architecture fix that prevents an OSSF Scorecard alert pattern from recurring, and a 16-locale i18n top-up.
Fixes
SSE stream ended. Reconnecting...every ~1.00 s indefinitely.AgentClient.startSse()resetreconnectAttemptsto 0 the instant the axios response headers arrived — before the SSE stream proved it could stay open. A stream that returned HTTP 200 then ended immediately (crash-looping agent, reverse-proxy idle timeout) reset the backoff on every cycle, so exponential backoff never engaged and the controller hammered the agent at 1 req/s. The reset is now deferred — a stability timer armed on response is cancelled byscheduleReconnect()if the stream ends early, soreconnectAttemptsclears only after the stream stays open forSSE_STABLE_CONNECTION_MS(30 s) and the delay escalates to the 60 s cap as intended. (The core "0 running containers" snapshot-wipe was fixed in rc.20 via4cd6b8be; this closes the remaining reconnect-storm symptom from the same thread.)undici7.24.6 → 8.2.0 (e763e09f). Node 24 ships built-inundici@7.21.0(v1 dispatcher interface); the userlandundici@8Agentexposes the v2 interface. The OIDC custom-fetch path constructed theAgentfrom userland undici and passed it asdispatcherto Node's globalfetch, which is bound to the built-in undici 7. The v2 Agent's handlers don't satisfy the v1 contract, so the request fails with the opaqueTypeError: fetch failed. (nodejs/undici#4827 describes this exact mismatch — the Node 22Dispatcher1Wrapperbridge isn't on Node 24.) Fix importsfetchfromundiciand uses it in the custom-dispatcher branch so both halves stay on the same dispatcher version. Default fetch path (noCAFILE/INSECURE) is unchanged.Diagnostics
error.causechain. Previously OIDC failures logged onlyUnable to initialize OIDC session (fetch failed)— undici's surface message hides the actionable detail. NewgetErrorChainMessagehelper walkserror.causeup to depth 5, joins with←, appends[code]from each Error-like node, handles cycles. Future failures now log e.g.fetch failed ← getaddrinfo ENOTFOUND host.tld [ENOTFOUND]orfetch failed ← self signed certificate in certificate chain [UNABLE_TO_VERIFY_LEAF_SIGNATURE], after the existing URL/token redaction.CI hygiene
e2e-playwright.yml). OSSF Scorecard's CI-Tests check derives its score from the github-actions Check Suite conclusion (via GraphQL), not individual check-run conclusions. Because every job inci-verify.ymlrolled into one suite, a single failing Playwright assertion (e.g. the "No pending entries" casing bug on PR Release v1.5.0-rc.21 tail: i18n + Dockerfile arch-drift fix #366) flipped the entire suite tofailureand made Scorecard mark the merged PR as untested — that's alert #43. Each workflow file gets its own Check Suite per commit, so isolating Playwright keepsci-verify's suite reliably green for Scorecard. Branch protection still gates on the🎭 E2E: Playwrightstatus check (matched by job name, not workflow file), andrelease-cut.ymlnow polls both workflows on the target SHA so releases continue to require Playwright success. Both workflows share thedrydockGHA cache scope, so whichever runs second hits a warm cache.Translations
notificationOutboxView.jsonin every locale; backfillednotificationsView.rules,securityView.deltaTooltips,registriesView.status,serversView.status, and the recentcontainerComponents/containersView/dashboardViewkeys. All 16 non-English locales now have zero missing keys versusen/.Test plan
tscbuild + biome lint cleanDD_AUTH_OIDC_AUTHENTIK_INSECURE=trueagainst self-signed cert) on the rc.22 image and confirm SSO login succeeds; if it still fails, the newerror.causechain will surface the actual reason (DNS / cert / connect)jaand walk Dashboard → Containers → Settings) to confirm no key collisions or layout regressionsrelease-cut.ymlfrom main withrelease_tag=v1.5.0-rc.22