Skip to content

Commit 3e63380

Browse files
committed
fix(ci+testing): fail-closed nojobs fallback in dedup gate; TLS-aware redis defaults mock
- the dedup gate no longer infers coverage from overall run conclusion when no 'Test and Build /' jobs match — a renamed or skipped test job now runs the tests instead of skipping them - the shared getRedisConnectionDefaults mock mirrors the real TLS resolution (rediss:// to a raw IP requires REDIS_TLS_SERVERNAME and yields tls.servername)
1 parent 142d708 commit 3e63380

2 files changed

Lines changed: 38 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,12 @@ jobs:
116116
elif any($t[]; .conclusion != null and .conclusion != "success") then "failed"
117117
else "pending" end' 2>/dev/null || echo pending)"
118118
if [ "$STATE" = "nojobs" ]; then
119-
RUN_STATE="$(printf '%s' "$RUN_JSON" | jq -r '.workflow_runs[0] | if .status == "completed" then .conclusion else "pending" end' 2>/dev/null || echo pending)"
120-
if [ "$RUN_STATE" = "success" ]; then
121-
STATE="success"
122-
elif [ "$RUN_STATE" != "pending" ]; then
123-
STATE="failed"
124-
else
125-
STATE="pending"
126-
fi
119+
# Fail closed: no jobs matching the "Test and Build /" prefix
120+
# means the reusable-workflow job name changed (or tests were
121+
# skipped) — never infer coverage from the overall run
122+
# conclusion. Update the prefix here if test-build is renamed.
123+
echo "Push run ${RUN_ID} has no 'Test and Build /' jobs — running tests in this PR run (update the prefix if the job was renamed)."
124+
break
127125
fi
128126
if [ "$STATE" = "success" ]; then
129127
# (3) Re-verify merge-tree equivalence against the LIVE base

packages/testing/src/mocks/redis-config.mock.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
11
import { vi } from 'vitest'
2+
import { envMockFns } from './env.mock'
23

3-
function getRedisConnectionDefaultsImpl(_url?: string): {
4+
/**
5+
* Mirrors the real `resolveRedisTlsOptions`: `rediss://` URLs targeting a raw
6+
* IPv4 host require `REDIS_TLS_SERVERNAME` (cert hostname verification cannot
7+
* match an IP) and yield a `tls.servername`; DNS hosts and plain `redis://`
8+
* URLs add no TLS options.
9+
*/
10+
function resolveTlsOptionsImpl(url: string | undefined): { servername: string } | undefined {
11+
if (!url) return undefined
12+
let parsed: URL
13+
try {
14+
parsed = new URL(url)
15+
} catch {
16+
return undefined
17+
}
18+
if (parsed.protocol !== 'rediss:') return undefined
19+
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(parsed.hostname)) return undefined
20+
const servername = envMockFns.getEnv('REDIS_TLS_SERVERNAME')
21+
if (!servername) {
22+
throw new Error(
23+
'REDIS_TLS_SERVERNAME must be set when REDIS_URL targets an IP over rediss://. ' +
24+
'TLS cert hostname verification cannot match an IP — set REDIS_TLS_SERVERNAME ' +
25+
'to the DNS name the cert was issued for (the ElastiCache primary endpoint).'
26+
)
27+
}
28+
return { servername }
29+
}
30+
31+
function getRedisConnectionDefaultsImpl(url?: string): {
432
keepAlive: number
533
connectTimeout: number
634
enableOfflineQueue: boolean
35+
tls?: { servername: string }
736
} {
37+
const tls = resolveTlsOptionsImpl(url)
838
return {
939
keepAlive: 1000,
1040
connectTimeout: 10000,
1141
enableOfflineQueue: true,
42+
...(tls ? { tls } : {}),
1243
}
1344
}
1445

0 commit comments

Comments
 (0)