mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
ci: use Blacksmith for default fork lint checks (#163789)
Route current canonical first-attempt core lint stripes to the existing 16-class with an unset or blacksmith backend, and retain that class for hybrid fork rows. Preserve stripe coverage, cache authority, and hosted fallbacks. OPENCLAW_CI_RUNNER_BACKEND=github remains the override; unset uses the fast path without changing repository settings. The same SDK-miss stripe-5 selection measured 157s on Linux versus 250-266s hosted. Workflow planning, preflight checkout shapes, changed static checks, and P2 review passed.
This commit is contained in:
parent
8867d073bd
commit
b73ec60928
4 changed files with 17 additions and 4 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -3943,7 +3943,7 @@ jobs:
|
|||
name: check-lint-core-${{ matrix.stripe }}
|
||||
needs: [preflight, check-plan]
|
||||
if: ${{ !cancelled() && !failure() && (needs.preflight.outputs.run_check_plan != 'true' || needs.check-plan.result == 'success') && (needs.preflight.outputs.run_check == 'true' && (needs.preflight.outputs.run_check_plan == 'true' && needs.check-plan.outputs.run_lint_core || needs.preflight.outputs.run_lint_core) == 'true' && (needs.preflight.outputs.runner_profile == 'github' || needs.preflight.outputs.runner_profile == 'hybrid') && (needs.preflight.outputs.frozen_target != 'true' || needs.preflight.outputs.hosted_runner_profile_contract == 'true')) }}
|
||||
runs-on: ${{ (github.event_name == 'workflow_dispatch' && startsWith(inputs.dispatch_id, 'full-release-validation-') && vars.OPENCLAW_RELEASE_RUNNER_GROUP || '') != '' && fromJSON(format('{{"group":{0},"labels":{1}}}', toJSON((github.event_name == 'workflow_dispatch' && startsWith(inputs.dispatch_id, 'full-release-validation-') && vars.OPENCLAW_RELEASE_RUNNER_GROUP || '')), toJSON(contains(fromJSON('["hybrid","runson"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) && github.run_attempt == 1 && github.repository == 'openclaw/openclaw' && (github.event_name != 'workflow_dispatch' || needs.preflight.outputs.ci_qualification == 'true' || needs.preflight.outputs.node_runner_backend == 'runson') && needs.preflight.outputs.frozen_target != 'true' && (needs.preflight.outputs.runner_profile == 'hybrid' && (matrix.stripe == 1 || (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND) == 'hybrid') && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04'))) || (contains(fromJSON('["hybrid","runson"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) && github.run_attempt == 1 && github.repository == 'openclaw/openclaw' && (github.event_name != 'workflow_dispatch' || needs.preflight.outputs.ci_qualification == 'true' || needs.preflight.outputs.node_runner_backend == 'runson') && needs.preflight.outputs.frozen_target != 'true' && (needs.preflight.outputs.runner_profile == 'hybrid' && (matrix.stripe == 1 || (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND) == 'hybrid') && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
|
||||
runs-on: ${{ (github.event_name == 'workflow_dispatch' && startsWith(inputs.dispatch_id, 'full-release-validation-') && vars.OPENCLAW_RELEASE_RUNNER_GROUP || '') != '' && fromJSON(format('{{"group":{0},"labels":{1}}}', toJSON((github.event_name == 'workflow_dispatch' && startsWith(inputs.dispatch_id, 'full-release-validation-') && vars.OPENCLAW_RELEASE_RUNNER_GROUP || '')), toJSON((contains(fromJSON('["hybrid","runson"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) || (contains(fromJSON('["","blacksmith"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) && github.event_name != 'workflow_dispatch')) && github.run_attempt == 1 && github.repository == 'openclaw/openclaw' && (github.event_name != 'workflow_dispatch' || needs.preflight.outputs.ci_qualification == 'true' || needs.preflight.outputs.node_runner_backend == 'runson') && needs.preflight.outputs.frozen_target != 'true' && (((needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND) != 'runson' || (needs.preflight.outputs.runner_profile == 'hybrid' && matrix.stripe == 1)) && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04'))) || ((contains(fromJSON('["hybrid","runson"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) || (contains(fromJSON('["","blacksmith"]'), (needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND)) && github.event_name != 'workflow_dispatch')) && github.run_attempt == 1 && github.repository == 'openclaw/openclaw' && (github.event_name != 'workflow_dispatch' || needs.preflight.outputs.ci_qualification == 'true' || needs.preflight.outputs.node_runner_backend == 'runson') && needs.preflight.outputs.frozen_target != 'true' && (((needs.preflight.outputs.ci_qualification == 'true' && needs.preflight.outputs.qualification_runner_backend || vars.OPENCLAW_CI_RUNNER_BACKEND) != 'runson' || (needs.preflight.outputs.runner_profile == 'hybrid' && matrix.stripe == 1)) && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ job. Open the page that matches your task.
|
|||
|
||||
Full hybrid extension lint packs the same canonical chunks into three existing rows, sharing setup and SDK preparation within each row. Targeted plans and frozen routes retain their existing layout; see [runner profiles](/ci/runners#runner-backend-modes).
|
||||
|
||||
Default fork first attempts run their existing core lint stripes on Blacksmith16, retaining the same core and extension chunk assignments and restore-only caches. Retries and the GitHub override remain hosted; see [runner placement](/ci/runners#runners).
|
||||
|
||||
[Automation admission](/ci/scheduled-workflows#comment-automation) filters known
|
||||
no-op events before runner allocation and concurrency, keeping automation on
|
||||
GitHub-hosted runners.
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ selection, and self-hosted setup retains its existing range and toolchain-cache
|
|||
policy. A restored cache key is not runtime proof: record the selected binary and
|
||||
`node -v` when comparing runner backends.
|
||||
|
||||
Runner choice does not depend on the pull request author. Same-repository PRs use the configured backend. Fork first attempts, including first-time contributors, use the default Blacksmith routes when repository variables are unavailable; their Node planner uses Blacksmith timings and the same capacity promotion. Fork check jobs keep the hosted lint and type stripes because forks cannot mount the trusted caches that size the all-in-one jobs. The maintainers accepted the added Blacksmith spend. Fork retries route to GitHub-hosted runners. The repository backend override cannot reroute fork first attempts when the variable is unavailable. Pushes and manual dispatches are unaffected. Cache trust is a separate, stricter boundary: exact dependency restores require a pull request from `openclaw/openclaw`, and ordinary CI never publishes the shared archives. The separate trusted warmer owns publication.
|
||||
Runner choice does not depend on the pull request author. Same-repository PRs use the configured backend. Fork first attempts, including first-time contributors, use the default Blacksmith routes when repository variables are unavailable; their Node planner uses Blacksmith timings and the same capacity promotion. Fork check jobs keep the logical GitHub stripe layout because forks cannot mount the trusted caches that size the all-in-one jobs. Runner placement is separate from that layout and cache authority. The maintainers accepted the added Blacksmith spend. Fork retries route to GitHub-hosted runners. The repository backend override cannot reroute fork first attempts when the variable is unavailable. Pushes and manual dispatches are unaffected. Cache trust is a separate, stricter boundary: exact dependency restores require a pull request from `openclaw/openclaw`, and ordinary CI never publishes the shared archives. The separate trusted warmer owns publication.
|
||||
|
||||
| Runner | Jobs |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
|
|
@ -118,6 +118,8 @@ The table lists default placement. On eligible hybrid first attempts, the [hoste
|
|||
|
||||
Baseline ratchets and Node shards start independently after preflight; the final gate still requires the selected ratchets to pass. Standalone ratchets use the Blacksmith 4-class on same-repository hybrid first attempts, automatic main runs, and admitted qualification dispatches. `check-plan` uses the 16-class for shared compiler snapshot memory on canonical first attempts with an unset, `blacksmith`, or `hybrid` backend, including fork PRs. The GitHub override, retries, ordinary manual and frozen targets, RunsOn planners, and noncanonical contexts retain hosted planning. Fork core type stripes with an unset or `blacksmith` backend also use the 16-class on current automatic first attempts. Their logical GitHub profile, five-stripe coverage, and restore-only cache authority remain unchanged; hybrid health admission retains its existing placement rules. Compiler and lint rows still wait for their complete plan; eligible guards and dependency rows start after preflight. See [admission measurements and cost](/ci/routing-costs#ratchet-admission-and-node-tests).
|
||||
|
||||
Current canonical core lint stripes use the 16-class on automatic first attempts with an unset, `blacksmith`, or `hybrid` backend, including fork PRs. The same five fork rows still own their core and extension lint chunks; the remaining extension chunk stays in the combined `check-lint` row, which already uses the 16-class. Standalone `check-lint-extensions-*` rows are hybrid-only and retain their existing route. PR caches stay restore-only. Retries, ordinary dispatches, frozen targets, noncanonical repositories, and `OPENCLAW_CI_RUNNER_BACKEND=github` keep hosted core lint; existing RunsOn and qualification routes are unchanged.
|
||||
|
||||
RunsOn retains its hosted placement for standalone ratchets and check planning, including qualification dispatches.
|
||||
|
||||
Healthy eligible main pushes and Windows-selected PRs can additionally offload seven check rows under the [assignment guard](#hybrid-hosted-assignment-guard). Main alone can then offload lint and central test types. Each decision consumes remaining capacity within the same 45-row limit; the original runner remains the fallback. Artifact builds retain the 16-class: their hosted maximum reached 898 seconds before preflight and gate overhead. See the [routing measurements and qualification gaps](/ci/routing-costs).
|
||||
|
|
@ -311,7 +313,7 @@ The repository variable `OPENCLAW_CI_RUNNER_BACKEND` controls the runner backend
|
|||
| `hybrid` | Eligible preflight and other critical-path jobs use Blacksmith on attempt 1 | Blacksmith on attempt 1; GitHub-hosted on `github.run_attempt > 1` | Rerunning a failed or stuck Blacksmith job automatically moves it to hosted capacity |
|
||||
| `runson` | Hybrid baseline | Hybrid baseline, with pure cron child rows on RunsOn for eligible first attempts | Automatic Spot-interruption retries disabled; other reruns retain the hybrid fallback |
|
||||
|
||||
Configurable heavy lanes are `build-artifacts` and `android`. The macOS Swift and iOS build jobs use GitHub-hosted `xcode-27` with Xcode 27; screenshot shards use `xcode-27-xlarge`. The focused `macos-node` lane uses the existing GitHub-hosted `macos-15` image in hybrid mode, with the same test inventory and two-worker limit. `openclaw/ci-gate` always uses `ubuntu-24.04`: its Bash-only result aggregation needs no checkout or dependency setup. This removes one Blacksmith registration from previously eligible runs without adding jobs or changing the required check. Hosted runner assignment can still delay completion. Trusted automatic hybrid first-attempt `preflight` requests the existing 16-class after three nearby hosted preflights remained unassigned while their Blacksmith security jobs completed. Hybrid retries, manual dispatches, noncanonical contexts, and the `github` override stay hosted. Unset or `blacksmith` keeps the existing 4-class route. Logical planner profile, cache trust, steps and the 20-minute deadline remain unchanged; actual assignment and completion still require CI proof. `security-fast` uses Blacksmith only on eligible hybrid first attempts when the [hosted budget](/ci/capacity#bounded-hybrid-hosted-offload) cannot admit optional work, and stays hosted outside `hybrid`. It waits for preflight to count the selected hosted rows, and still executes after a preflight failure unless the workflow is canceled. Security hooks use pinned installed packages and local hook definitions, so they no longer initialize remote Git repositories. Budget two control-job registrations per eligible hybrid first attempt when optional hosted admission is closed, one when admitted, and one per normal Blacksmith run; both jobs are already reserved in the conservative registration ceiling. The `github` override remains unchanged. Hybrid sends the compact Node matrix, up to 80 compact rows plus separately appended plugin fallback rows, thirteen-row `checks-ui-e2e` matrix for targets with the named-project contract, the `checks-ui-e2e-real-gateway` lane that shares its serial Chromium workload, four-row QA Smoke matrix on canonical automatic runs (six rows for manual dispatches), the two-part Windows matrix, `checks-ui`, `check-lint`, `check-test-types`, the five `check-test-types-core-*` rows, `check-dependencies`, `check-additional-extension-package-boundary`, `check-additional-runtime-topology-architecture`, and `report-plugin-sdk-api-diff` to Blacksmith on attempt 1. Eligible two-child ordinary compact rows request `blacksmith-32vcpu-ubuntu-2404`; bins containing the full `agentic-cli` group request `blacksmith-32vcpu-ubuntu-2404` after planning. Other compact-small rows retain `blacksmith-4vcpu-ubuntu-2404`, compact-large rows retain `blacksmith-8vcpu-ubuntu-2404`, and the planner's measured small queue-tail promotions retain their 8-vCPU labels. Within that set, `checks-ui` and only the browser-extension E2E row move to hosted Ubuntu when preflight admits at most five optional rows below the 45-row hosted limit. Every other configurable `ci.yml` lane stays hosted in hybrid, including the core-lint jobs, the remaining lint/check rows, docs, and Python skills. Separate Opengrep workflows remain GitHub-hosted.
|
||||
Configurable heavy lanes are `build-artifacts` and `android`. The macOS Swift and iOS build jobs use GitHub-hosted `xcode-27` with Xcode 27; screenshot shards use `xcode-27-xlarge`. The focused `macos-node` lane uses the existing GitHub-hosted `macos-15` image in hybrid mode, with the same test inventory and two-worker limit. `openclaw/ci-gate` always uses `ubuntu-24.04`: its Bash-only result aggregation needs no checkout or dependency setup. This removes one Blacksmith registration from previously eligible runs without adding jobs or changing the required check. Hosted runner assignment can still delay completion. Trusted automatic hybrid first-attempt `preflight` requests the existing 16-class after three nearby hosted preflights remained unassigned while their Blacksmith security jobs completed. Hybrid retries, manual dispatches, noncanonical contexts, and the `github` override stay hosted. Unset or `blacksmith` keeps the existing 4-class route. Logical planner profile, cache trust, steps and the 20-minute deadline remain unchanged; actual assignment and completion still require CI proof. `security-fast` uses Blacksmith only on eligible hybrid first attempts when the [hosted budget](/ci/capacity#bounded-hybrid-hosted-offload) cannot admit optional work, and stays hosted outside `hybrid`. It waits for preflight to count the selected hosted rows, and still executes after a preflight failure unless the workflow is canceled. Security hooks use pinned installed packages and local hook definitions, so they no longer initialize remote Git repositories. Budget two control-job registrations per eligible hybrid first attempt when optional hosted admission is closed, one when admitted, and one per normal Blacksmith run; both jobs are already reserved in the conservative registration ceiling. The `github` override remains unchanged. Hybrid sends the compact Node matrix, up to 80 compact rows plus separately appended plugin fallback rows, thirteen-row `checks-ui-e2e` matrix for targets with the named-project contract, the `checks-ui-e2e-real-gateway` lane that shares its serial Chromium workload, four-row QA Smoke matrix on canonical automatic runs (six rows for manual dispatches), the two-part Windows matrix, `checks-ui`, `check-lint`, `check-test-types`, the five `check-test-types-core-*` rows, `check-dependencies`, `check-additional-extension-package-boundary`, `check-additional-runtime-topology-architecture`, and `report-plugin-sdk-api-diff` to Blacksmith on attempt 1. Eligible two-child ordinary compact rows request `blacksmith-32vcpu-ubuntu-2404`; bins containing the full `agentic-cli` group request `blacksmith-32vcpu-ubuntu-2404` after planning. Other compact-small rows retain `blacksmith-4vcpu-ubuntu-2404`, compact-large rows retain `blacksmith-8vcpu-ubuntu-2404`, and the planner's measured small queue-tail promotions retain their 8-vCPU labels. Within that set, `checks-ui` and only the browser-extension E2E row move to hosted Ubuntu when preflight admits at most five optional rows below the 45-row hosted limit. Every other configurable `ci.yml` lane stays hosted in hybrid, including the remaining lint/check rows, docs, and Python skills. Separate Opengrep workflows remain GitHub-hosted.
|
||||
|
||||
### RunsOn qualification
|
||||
|
||||
|
|
|
|||
|
|
@ -5608,6 +5608,7 @@ describe("ci workflow guards", () => {
|
|||
);
|
||||
}
|
||||
const typeRunner = workflow.jobs["check-test-types-hosted-core-shard"]["runs-on"];
|
||||
const lintRunner = workflow.jobs["check-lint-hosted-core-shard"]["runs-on"];
|
||||
for (const runnerBackend of ["", "blacksmith", "hybrid"] as const) {
|
||||
for (const authorAssociation of ["NONE", "CONTRIBUTOR", "OWNER"]) {
|
||||
const fork = {
|
||||
|
|
@ -5617,7 +5618,7 @@ describe("ci workflow guards", () => {
|
|||
headRepository: "contributor/openclaw",
|
||||
authorAssociation,
|
||||
};
|
||||
for (const runner of [plannerRunner, typeRunner]) {
|
||||
for (const runner of [plannerRunner, typeRunner, lintRunner]) {
|
||||
expect(evaluateWorkflowExpression(runner, fork)).toBe("blacksmith-16vcpu-ubuntu-2404");
|
||||
for (const override of [
|
||||
{ runnerBackend: "github" },
|
||||
|
|
@ -5636,6 +5637,14 @@ describe("ci workflow guards", () => {
|
|||
"ubuntu-24.04",
|
||||
);
|
||||
}
|
||||
expect(evaluateWorkflowExpression(lintRunner, { ...fork, frozenTarget: true })).toBe(
|
||||
"ubuntu-24.04",
|
||||
);
|
||||
for (const stripe of [1, 2, 3, 4, 5]) {
|
||||
expect(evaluateWorkflowExpression(lintRunner, { ...fork, matrix: { stripe } })).toBe(
|
||||
"blacksmith-16vcpu-ubuntu-2404",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const qualification = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue