ci: use measured 16-class runners for current artifact builds (#145611)

This commit is contained in:
Peter Steinberger 2026-09-11 23:26:34 -07:00 • committed by GitHub
parent 27e810cf26
commit 1754576c2c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 45 additions and 9 deletions

View file

@ -311,7 +311,12 @@ These are intentionally guarded by `test/scripts/ci-workflow-guards.test.ts`:
routing, deadlines and all caps unchanged. This adds zero jobs or registrations.
Compiler-only AWS evidence does not prove CI timing; validate the complete job
through exact-head native CI before claiming an improvement.
- `build-artifacts` on `blacksmith-32vcpu-ubuntu-2404`.
- Current-target `build-artifacts` uses the existing 16-class after a complete
four-CPU/15.42-GiB compute proof, including the unchanged parallel verifier wave.
The SDK memory owner keeps declarations serial when two heaps do not fit.
Frozen or unclassified targets retain 32-class; hosted fallbacks, job counts,
concurrency and deadlines stay unchanged. Measured compute fit does not prove
queue savings; observe the next exact-head CI cycle.
- Normal canonical hybrid first attempts use the existing four-part QA smoke
plan, removing two repeated checkouts, setups and private runtime builds.
Blacksmith profiles retain four parts; GitHub profiles and fresh hybrid

View file

@ -2126,10 +2126,9 @@ jobs:
contents: read
needs: [preflight]
if: needs.preflight.outputs.run_build_artifacts == 'true'
# 32 vCPU: the dist build sits on the light-run critical path alongside
# check-lint/check-dependencies; tsdown parallelizes across the extra
# cores for roughly the same billed core-minutes.
runs-on: ${{ vars.OPENCLAW_CI_RUNNER_BACKEND == 'github' && 'ubuntu-24.04' || (vars.OPENCLAW_CI_RUNNER_BACKEND == 'hybrid' && github.run_attempt > 1) && 'ubuntu-24.04' || (github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && github.run_attempt > 1)) && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || contains(fromJSON('["OWNER","MEMBER","COLLABORATOR","CONTRIBUTOR"]'), github.event.pull_request.author_association)) && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
# Current targets fit the measured 16-class with serial SDK declarations.
# Keep frozen/unknown targets on their existing class; their compute was not proved.
runs-on: ${{ vars.OPENCLAW_CI_RUNNER_BACKEND == 'github' && 'ubuntu-24.04' || (vars.OPENCLAW_CI_RUNNER_BACKEND == 'hybrid' && github.run_attempt > 1) && 'ubuntu-24.04' || (github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && github.run_attempt > 1)) && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || contains(fromJSON('["OWNER","MEMBER","COLLABORATOR","CONTRIBUTOR"]'), github.event.pull_request.author_association)) && (needs.preflight.outputs.frozen_target == 'false' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-32vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
timeout-minutes: ${{ (vars.OPENCLAW_CI_RUNNER_BACKEND == 'github' || (vars.OPENCLAW_CI_RUNNER_BACKEND == 'hybrid' && github.run_attempt > 1) || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)) && 35 || 20 }}
steps:
- *linux_node_checkout_step

View file

@ -15,8 +15,8 @@ Runner choice follows contributor trust, not whether a pull request came from a
| `ubuntu-24.04` | `openclaw/ci-gate` in every mode, `preflight` in hybrid mode, `check-docs` in every mode (its ClawHub mirror clone is unauthenticated by design), `security-fast` outside hybrid first attempts, manual CI dispatch and non-canonical repository fallbacks, CodeQL security and quality scans, workflow-sanity, labeler, auto-response, the standalone Docs workflow, the whole Install Smoke workflow, all configurable CI jobs in `github` mode, and the remaining light lanes plus rerun Blacksmith lanes in `hybrid` mode. The GitHub/hybrid planner profile expands the Node matrix, QA Smoke to six parts, core oxlint across five Programs (three jobs on ordinary non-frozen hybrid push/PR runs), and type checks across three jobs. Extension/scripts lint plus optional UI and format checks stay in `check-lint`; the last core type batch shares `check-test-types` with the extensions/root/scripts tail. |
| `blacksmith-4vcpu-ubuntu-2404` | `preflight` when the backend is unset or `blacksmith`, hybrid first-attempt `security-fast`, `pnpm-store-warmup`, `native-i18n`, `checks-fast-core` except QA Smoke CI, plugin/channel contract shards, most bundled/lower-weight Linux Node shards, `check-*` lanes except `check-lint`, selected `check-additional-*` shards, and `skills-python` |
| `blacksmith-8vcpu-ubuntu-2404` | Retained heavy Linux Node suites, compact-small queue-tail bins 2, 5, and 8, the `checks-ui-e2e` browser-extension row, boundary/extension-heavy `check-additional-*` shards except runtime topology architecture, and `android` |
| `blacksmith-16vcpu-ubuntu-2404` | Automatic QA Smoke CI shards and eligible compact bins containing the full CLI suite |
| `blacksmith-32vcpu-ubuntu-2404` | Eligible ordinary multi-group compact bins, numbered tooling bins, agent-support, the Docker seed job, `checks-ui-e2e` Control UI rows, eligible `checks-ui-e2e-real-gateway` jobs, `build-artifacts`, `check-lint`, `check-dependencies`, `check-test-types`, the two `check-test-types-core-*` rows, `check-additional-extension-package-boundary`, `check-additional-runtime-topology-architecture`, and npm release preflight; these CPU-heavy lanes need the measured capacity described below |
| `blacksmith-16vcpu-ubuntu-2404` | Current-target `build-artifacts`, automatic QA Smoke CI shards and eligible compact bins containing the full CLI suite |
| `blacksmith-32vcpu-ubuntu-2404` | Eligible ordinary multi-group compact bins, numbered tooling bins, agent-support, the Docker seed job, `checks-ui-e2e` Control UI rows, eligible `checks-ui-e2e-real-gateway` jobs, frozen/unclassified `build-artifacts` targets, `check-lint`, `check-dependencies`, `check-test-types`, the two `check-test-types-core-*` rows, `check-additional-extension-package-boundary`, `check-additional-runtime-topology-architecture`, and npm release preflight; these CPU-heavy lanes need the measured capacity described below |
| `blacksmith-8vcpu-windows-2025` | `checks-windows` |
| `blacksmith-6vcpu-macos-15` | `macos-node` on `openclaw/openclaw` when the backend is unset or `blacksmith`; hybrid and existing fallback routes use `macos-15` |
| `macos-26` | All selected `macos-swift` and iOS build phases, both full-manual screenshot shards, and all four Periphery scans always use GitHub-hosted capacity. |
@ -58,6 +58,8 @@ preserves existing worker limits, explicit budgets, matrix sizes, and
existing jobs adds no runner registrations. Repeat the capacity probe and
reassess sizing after Blacksmith's allocation changes.
Current-target `build-artifacts` uses the existing 16-class. A [controlled Testbox proof](https://github.com/openclaw/openclaw/actions/runs/34669346942) at `3ccc3710bd6` completed all eight job compute steps in 229.3 seconds (252.8 seconds including payload setup) on four CPUs and 15.42 GiB RAM, with a 12.59 GiB cgroup peak and no recorded OOM events. The proof retained the complete parallel verifier wave and passed final source, worker-generation cleanup, and memory-event checks. The existing SDK memory gate keeps declarations serial below the capacity needed for both compiler heaps. Frozen targets and missing target classifications retain the 32-class; hosted fallbacks, job counts, concurrency, and deadlines are unchanged. These measurements establish compute fit, not a guaranteed queue reduction or full Actions duration.
Eligible `checks-ui-e2e-real-gateway` jobs request the 32-class so their private
artifact build can overlap the two canonical SDK cache misses. Each compiler keeps
its 12-GiB heap: overlap requires at least two available CPUs and 25.5 GiB of

View file

@ -5992,7 +5992,7 @@ setImmediate(() => {
...expectedHostedRunners,
"security-fast": "blacksmith-4vcpu-ubuntu-2404",
android: "blacksmith-8vcpu-ubuntu-2404",
"build-artifacts": "blacksmith-32vcpu-ubuntu-2404",
"build-artifacts": "blacksmith-16vcpu-ubuntu-2404",
"checks-node-core-test-nondist-shard": "blacksmith-32vcpu-ubuntu-2404",
"checks-ui-e2e": "blacksmith-8vcpu-ubuntu-2404",
"checks-ui-e2e-real-gateway": "blacksmith-32vcpu-ubuntu-2404",
@ -8276,7 +8276,37 @@ server.listen(0, "127.0.0.1", () => {
const source = readFileSync(".github/workflows/ci.yml", "utf8");
expect(source).toContain("createNodeTestShardBundles");
expect(workflow.jobs["build-artifacts"]["runs-on"]).toContain("blacksmith-32vcpu-ubuntu-2404");
const artifactRunner = workflow.jobs["build-artifacts"]["runs-on"];
for (const [frozenTarget, expected] of [
["false", "blacksmith-16vcpu-ubuntu-2404"],
["true", "blacksmith-32vcpu-ubuntu-2404"],
["", "blacksmith-32vcpu-ubuntu-2404"],
] as const) {
const context = {
eventName: "push",
repository: "openclaw/openclaw",
runAttempt: 1,
preflightOutputs: { frozen_target: frozenTarget },
} as const;
for (const runnerBackend of ["", "blacksmith", "hybrid"] as const) {
for (const eventName of ["push", "pull_request"] as const) {
expect(
evaluateWorkflowExpression(artifactRunner, { ...context, runnerBackend, eventName }),
`build-artifacts: ${runnerBackend || "default"}/${eventName}/frozen=${frozenTarget}`,
).toBe(expected);
}
}
for (const override of [
{ runnerBackend: "github" },
{ runnerBackend: "hybrid", runAttempt: 2 },
{ eventName: "workflow_dispatch" },
{ eventName: "pull_request", authorAssociation: "NONE", headRepository: "fork/openclaw" },
] as const) {
expect(evaluateWorkflowExpression(artifactRunner, { ...context, ...override })).toBe(
"ubuntu-24.04",
);
}
}
expect(workflow.jobs["build-artifacts"]["timeout-minutes"]).toBe(
"${{ (vars.OPENCLAW_CI_RUNNER_BACKEND == 'github' || (vars.OPENCLAW_CI_RUNNER_BACKEND == 'hybrid' && github.run_attempt > 1) || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)) && 35 || 20 }}",
);