@norskvideo/ctl-dev-kit 0.2.23 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -186,7 +186,14 @@ jobs:
|
|
|
186
186
|
for attempt in 1 2 3 4 5; do
|
|
187
187
|
if git push origin HEAD:main; then exit 0; fi
|
|
188
188
|
echo "push rejected (attempt $attempt) - rebasing onto latest origin/main"
|
|
189
|
-
|
|
189
|
+
# --unshallow, not a plain fetch: these runners keep their .git
|
|
190
|
+
# between jobs, and a commit an earlier job fetched at depth 1 stays
|
|
191
|
+
# recorded as parentless. A plain fetch does not re-fetch an object it
|
|
192
|
+
# already holds, so main's tip can look like an unrelated root and the
|
|
193
|
+
# rebase replays our base commit over it -- add/add conflicts on every
|
|
194
|
+
# file it touches (playout + studio, 2026-10-03). The fallback covers
|
|
195
|
+
# a repo that is already complete, where --unshallow is refused.
|
|
196
|
+
git fetch --unshallow origin main 2>/dev/null || git fetch origin main
|
|
190
197
|
git rebase origin/main || { git rebase --abort; echo "rebase hit a real conflict; aborting"; exit 1; }
|
|
191
198
|
done
|
|
192
199
|
echo "push still failing after 5 rebase attempts"; exit 1
|
|
@@ -318,7 +318,14 @@ jobs:
|
|
|
318
318
|
for attempt in 1 2 3 4 5; do
|
|
319
319
|
if git push origin HEAD:main; then exit 0; fi
|
|
320
320
|
echo "push rejected (attempt $attempt) - rebasing onto latest origin/main"
|
|
321
|
-
|
|
321
|
+
# --unshallow, not a plain fetch: these runners keep their .git
|
|
322
|
+
# between jobs, and a commit an earlier job fetched at depth 1 stays
|
|
323
|
+
# recorded as parentless. A plain fetch does not re-fetch an object it
|
|
324
|
+
# already holds, so main's tip can look like an unrelated root and the
|
|
325
|
+
# rebase replays our base commit over it -- add/add conflicts on every
|
|
326
|
+
# file it touches (playout + studio, 2026-10-03). The fallback covers
|
|
327
|
+
# a repo that is already complete, where --unshallow is refused.
|
|
328
|
+
git fetch --unshallow origin main 2>/dev/null || git fetch origin main
|
|
322
329
|
git rebase origin/main || { git rebase --abort; echo "rebase hit a real conflict; aborting"; exit 1; }
|
|
323
330
|
done
|
|
324
331
|
echo "push still failing after 5 rebase attempts"; exit 1
|
|
@@ -265,6 +265,28 @@ export function lockfileRefreshCanFail(yaml: string): number[] {
|
|
|
265
265
|
return out;
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
/** `- name:` lines of steps that rebase onto a fetched branch without first
|
|
269
|
+
* unshallowing.
|
|
270
|
+
*
|
|
271
|
+
* The self-hosted runners keep each repo's .git between jobs, and
|
|
272
|
+
* actions/checkout fetches at depth 1, so a commit an earlier job fetched is
|
|
273
|
+
* left recorded as parentless. A plain `git fetch` will not re-fetch an object
|
|
274
|
+
* it already holds, so when that commit is main's tip the rebase sees two
|
|
275
|
+
* unrelated roots and replays our base commit over it: add/add conflicts on
|
|
276
|
+
* every file, read as "a real conflict". It failed playout's sync-dev-kit and
|
|
277
|
+
* studio's upgrade-latest that way on 2026-10-03. `--unshallow` re-fetches the
|
|
278
|
+
* parents and clears the stale boundary. */
|
|
279
|
+
export function rebaseWithoutUnshallow(yaml: string): number[] {
|
|
280
|
+
const lines = yaml.split("\n");
|
|
281
|
+
const out: number[] = [];
|
|
282
|
+
lines.forEach((text, i) => {
|
|
283
|
+
if (!/^\s+- name:/.test(text)) return;
|
|
284
|
+
const body = stepBody(lines, i);
|
|
285
|
+
if (/\bgit rebase\b/.test(body) && !/git fetch --unshallow\b/.test(body)) out.push(i + 1);
|
|
286
|
+
});
|
|
287
|
+
return out;
|
|
288
|
+
}
|
|
289
|
+
|
|
268
290
|
/** A `ctl-candidate` validation that another candidate, or its own retry, can
|
|
269
291
|
* cancel.
|
|
270
292
|
*
|
package/doc-guide/doc-guide.d.ts
CHANGED
|
@@ -62,6 +62,19 @@ export declare function livePictureFailure(selector: string, phase: string | nul
|
|
|
62
62
|
export declare function awaitLivePicture(page: Page, selector: string, opts?: {
|
|
63
63
|
timeoutMs?: number;
|
|
64
64
|
}): Promise<void>;
|
|
65
|
+
/** How long a capture waits for web fonts before shooting anyway. */
|
|
66
|
+
export declare const FONTS_READY_TIMEOUT_MS = 10000;
|
|
67
|
+
/** `document.fonts.ready`, bounded. True when the fonts settled in time.
|
|
68
|
+
*
|
|
69
|
+
* Unbounded, this hung commentary's composition guide for its whole 360s test
|
|
70
|
+
* budget on 2026-10-03 (CI only, after the Take, with the page about to render
|
|
71
|
+
* the advanced compositor): `fonts.ready` resolves only once every pending font
|
|
72
|
+
* load has finished, a request that never answers never finishes, and
|
|
73
|
+
* `page.evaluate` has no timeout of its own. The test then timed out, its
|
|
74
|
+
* teardown with it, and the instance ran on for hours. A capture in a fallback
|
|
75
|
+
* font is a far smaller failure than that, so bound the wait inside the page
|
|
76
|
+
* AND around the call -- a wedged renderer never answers the call at all. */
|
|
77
|
+
export declare function awaitFontsReady(page: Pick<Page, "evaluate">, timeoutMs?: number): Promise<boolean>;
|
|
65
78
|
/** Produce the screenshot bytes for a capture, applying its treatment. Split out
|
|
66
79
|
* from `DocGuide.capture` (which also gates on DOCS_GENERATE and writes the file)
|
|
67
80
|
* so the treatment geometry is testable on its own. */
|
package/doc-guide/doc-guide.js
CHANGED
|
@@ -79,14 +79,47 @@ async function spotlightOn(page, selector, pad) {
|
|
|
79
79
|
async function spotlightOff(page) {
|
|
80
80
|
await page.evaluate((id) => document.getElementById(id)?.remove(), SPOTLIGHT_ID);
|
|
81
81
|
}
|
|
82
|
+
/** How long a capture waits for web fonts before shooting anyway. */
|
|
83
|
+
export const FONTS_READY_TIMEOUT_MS = 10_000;
|
|
84
|
+
/** `document.fonts.ready`, bounded. True when the fonts settled in time.
|
|
85
|
+
*
|
|
86
|
+
* Unbounded, this hung commentary's composition guide for its whole 360s test
|
|
87
|
+
* budget on 2026-10-03 (CI only, after the Take, with the page about to render
|
|
88
|
+
* the advanced compositor): `fonts.ready` resolves only once every pending font
|
|
89
|
+
* load has finished, a request that never answers never finishes, and
|
|
90
|
+
* `page.evaluate` has no timeout of its own. The test then timed out, its
|
|
91
|
+
* teardown with it, and the instance ran on for hours. A capture in a fallback
|
|
92
|
+
* font is a far smaller failure than that, so bound the wait inside the page
|
|
93
|
+
* AND around the call -- a wedged renderer never answers the call at all. */
|
|
94
|
+
export async function awaitFontsReady(page, timeoutMs = FONTS_READY_TIMEOUT_MS) {
|
|
95
|
+
let timer;
|
|
96
|
+
const late = new Promise((resolve) => {
|
|
97
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
98
|
+
});
|
|
99
|
+
const ready = page
|
|
100
|
+
.evaluate((ms) => Promise.race([
|
|
101
|
+
document.fonts.ready.then(() => true),
|
|
102
|
+
new Promise((resolve) => setTimeout(() => resolve(false), ms)),
|
|
103
|
+
]), timeoutMs)
|
|
104
|
+
.catch(() => false);
|
|
105
|
+
try {
|
|
106
|
+
return await Promise.race([ready, late]);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
82
112
|
/** Produce the screenshot bytes for a capture, applying its treatment. Split out
|
|
83
113
|
* from `DocGuide.capture` (which also gates on DOCS_GENERATE and writes the file)
|
|
84
114
|
* so the treatment geometry is testable on its own. */
|
|
85
115
|
export async function screenshotFor(page, treat) {
|
|
86
116
|
if (treat?.livePicture)
|
|
87
117
|
await awaitLivePicture(page, treat.livePicture, { timeoutMs: treat.livePictureTimeoutMs });
|
|
88
|
-
// Wait for web fonts, else the snapshot catches a fallback font mid-swap
|
|
89
|
-
|
|
118
|
+
// Wait for web fonts, else the snapshot catches a fallback font mid-swap --
|
|
119
|
+
// but not forever (see awaitFontsReady).
|
|
120
|
+
if (!(await awaitFontsReady(page))) {
|
|
121
|
+
console.warn(`[doc-guide] web fonts not ready after ${FONTS_READY_TIMEOUT_MS}ms; capturing with what has loaded`);
|
|
122
|
+
}
|
|
90
123
|
if (treat?.crop)
|
|
91
124
|
return page.locator(treat.crop).first().screenshot();
|
|
92
125
|
if (treat?.spotlight) {
|