From 0fc9fa457276007ae376f83f9bcd85fc13379006 Mon Sep 17 00:00:00 2001 From: Feng Qian Date: Mon, 28 Sep 2026 18:40:03 -0700 Subject: [PATCH] fix(ci): run the SDK examples gate 2-wide, not 4-wide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gate failed 2 of 3 runs on ubuntu-latest, always on the same example and always the same way: [basic] page.screenshot: Protocol error (Page.captureScreenshot): Unable to capture screenshot - waiting for fonts to load... - fonts loaded The page had loaded and Chromium then failed to capture it, so this is a capture-time resource failure rather than a test failure. 7 of 8 examples passed every time. The width was 4 on the 8-vCPU self-hosted runner, and I kept it at 4 when moving to ubuntu-latest, reasoning that these block on live-AI calls rather than CPU. That reasoning was incomplete: four concurrent headed Chromium instances also contend for memory and display surfaces, neither of which is a core count. The review on #12 flagged the width as unverified on this runner class, and the one dry run that passed gave false confidence. Halving the width trades wall time on that step for a gate that holds. What this does not do is identify the exact constraint — there was no OOM in the logs, so memory, /dev/shm and display surfaces are all still candidates. If 2-wide proves stable, the diagnosis is contention; if it does not, the explanation is wrong and worth reopening. The guard in publish-sdk-workflow.test.ts pinned -P 4 and carried the disproven claim in a comment; both are corrected, and it fails against the 4-wide workflow. --- .github/workflows/publish-sdk.yml | 18 +++++++++++++----- scripts/__tests__/publish-sdk-workflow.test.ts | 9 +++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish-sdk.yml b/.github/workflows/publish-sdk.yml index 5e3e053..32fd211 100644 --- a/.github/workflows/publish-sdk.yml +++ b/.github/workflows/publish-sdk.yml @@ -219,14 +219,22 @@ jobs: } export -f run_sdk_example - # 4-wide. Each example drives its own Chromium on its own xvfb display - # (`xvfb-run -a` picks a free one). The width is set by how long these - # block on live-AI calls, not by the runner's core count, which is why - # it survived the move off the 8-vCPU self-hosted runner. + # 2-wide. Each example drives its own Chromium on its own xvfb display + # (`xvfb-run -a` picks a free one). + # + # This was 4-wide on the 8-vCPU self-hosted runner, and stayed 4-wide + # across the move to ubuntu-latest on the reasoning that these block on + # live-AI calls rather than CPU. That reasoning was incomplete: + # concurrent headed Chromium instances also contend for memory and + # display surfaces. 4-wide here failed 2 of 3 runs, always on `basic`, + # always as `Page.captureScreenshot: Unable to capture screenshot` after + # the page had loaded — a capture-time resource failure, not a test + # failure. Halving the width trades wall time for a gate that holds. + # # xargs exits nonzero when any worker does, so one failing example # still fails the gate. printf '%s\n' "${EXAMPLES[@]}" \ - | xargs -P 4 -I{} bash -c 'run_sdk_example "$@"' _ {} + | xargs -P 2 -I{} bash -c 'run_sdk_example "$@"' _ {} - name: Download baseline tarball (@shiplightai/sdk@OLD) run: | diff --git a/scripts/__tests__/publish-sdk-workflow.test.ts b/scripts/__tests__/publish-sdk-workflow.test.ts index f1fda3f..1d213cc 100644 --- a/scripts/__tests__/publish-sdk-workflow.test.ts +++ b/scripts/__tests__/publish-sdk-workflow.test.ts @@ -81,8 +81,7 @@ test('SDK publish workflow runs every public SDK example against the candidate t // GitHub-hosted: the shiplight-* self-hosted runners are being decommissioned, // and npm refuses a provenance publish from one (422, "Unsupported GitHub - // Actions runner environment: self-hosted"). The examples gate still runs - // 4-wide — it blocks on live-AI calls, not on cores. + // Actions runner environment: self-hosted"). // github-actions-runner-labels.test.ts holds this for every workflow. assert.equal(publishJob['runs-on'], 'ubuntu-latest'); @@ -123,8 +122,10 @@ test('SDK publish workflow runs every public SDK example against the candidate t 'EXPECTED_SCRIPTS must be derived from the EXAMPLES array, not restated as a literal', ); - // Examples run 4-wide; a failure in any worker must still fail the gate. - assert.match(examples.run, /xargs -P 4 -I\{\} bash -c 'run_sdk_example "\$@"' _ \{\}/); + // Examples run 2-wide; a failure in any worker must still fail the gate. + // Not 4: concurrent headed Chromium contends for memory and display surfaces, + // and 4-wide failed 2 of 3 runs on ubuntu-latest inside Page.captureScreenshot. + assert.match(examples.run, /xargs -P 2 -I\{\} bash -c 'run_sdk_example "\$@"' _ \{\}/); assert.match(examples.run, /export -f run_sdk_example/); assert.ok(stepIndex('Pack candidate tarball') < stepIndex(checkout.name));