Release and CI

Конвеєр CI

OpenClaw CI запускається під час кожного push до main і кожного pull request. Завдання preflight класифікує diff і вимикає дорогі напрямки, коли змінилися лише непов’язані області. Ручні запуски workflow_dispatch навмисно обходять розумне обмеження області й розгортають повний граф для кандидатів релізу та широкої валідації. Напрямки Android залишаються opt-in через include_android. Покриття Plugin лише для релізів міститься в окремому workflow Plugin Prerelease і запускається лише з Full Release Validation або явного ручного dispatch.

Огляд Pipeline

Завдання Призначення Коли запускається
preflight Виявляє зміни лише в документації, змінені області, змінені extensions і будує маніфест CI Завжди для нечернеткових push і PR
security-scm-fast Виявлення приватних ключів і аудит workflow через zizmor Завжди для нечернеткових push і PR
security-dependency-audit Аудит production lockfile без залежностей щодо advisories npm Завжди для нечернеткових push і PR
security-fast Обов’язковий агрегат для швидких завдань безпеки Завжди для нечернеткових push і PR
check-dependencies Production-прохід Knip лише для залежностей плюс guard allowlist невикористаних файлів Зміни, релевантні для Node
build-artifacts Збірка dist/, Control UI, перевірки зібраних артефактів і повторно використовувані downstream-артефакти Зміни, релевантні для Node
checks-fast-core Швидкі Linux-напрямки коректності, як-от bundled/plugin-contract/protocol перевірки Зміни, релевантні для Node
checks-fast-contracts-channels Sharded-перевірки контрактів каналів зі стабільним агрегованим результатом перевірки Зміни, релевантні для Node
checks-node-core-test Shards тестів core Node, без напрямків channel, bundled, contract і extension Зміни, релевантні для Node
check Sharded-еквівалент основного локального gate: production-типи, lint, guards, test types і strict smoke Зміни, релевантні для Node
check-additional Архітектура, sharded boundary/prompt drift, extension guards, package boundary і gateway watch Зміни, релевантні для Node
build-smoke Smoke-тести зібраного CLI і smoke для startup-memory Зміни, релевантні для Node
checks Верифікатор для channel-тестів зібраних артефактів Зміни, релевантні для Node
checks-node-compat-node22 Збірка сумісності Node 22 і smoke-напрямок Ручний dispatch CI для релізів
check-docs Форматування документації, lint і перевірки битих посилань Документацію змінено
skills-python Ruff + pytest для Skills на базі Python Зміни, релевантні для Python Skills
checks-windows Windows-специфічні тести process/path плюс спільні регресії runtime import specifier Зміни, релевантні для Windows
macos-node Напрямок TypeScript-тестів macOS із використанням спільних зібраних артефактів Зміни, релевантні для macOS
macos-swift Swift lint, збірка і тести для застосунку macOS Зміни, релевантні для macOS
android Unit-тести Android для обох flavors плюс одна збірка debug APK Зміни, релевантні для Android
test-performance-agent Щоденна оптимізація повільних тестів Codex після довіреної активності Успіх main CI або ручний dispatch
openclaw-performance Щоденні/на вимогу звіти продуктивності runtime Kova з mock-provider, deep-profile і GPT 5.4 live напрямками Запланований і ручний dispatch

Порядок fail-fast

  1. preflight вирішує, які напрямки взагалі існують. Логіка docs-scope і changed-scope є кроками всередині цього завдання, а не окремими завданнями.
  2. security-scm-fast, security-dependency-audit, security-fast, check, check-additional, check-docs і skills-python швидко падають, не чекаючи важчих artifact і platform matrix завдань.
  3. build-artifacts перекривається зі швидкими Linux-напрямками, щоб downstream-споживачі могли стартувати, щойно спільна збірка готова.
  4. Важчі platform і runtime напрямки розгортаються після цього: checks-fast-core, checks-fast-contracts-channels, checks-node-core-test, checks, checks-windows, macos-node, macos-swift і android.

GitHub може позначати витіснені завдання як cancelled, коли новіший push потрапляє в той самий PR або ref main. Вважайте це шумом CI, якщо найновіший запуск для того самого ref також не падає. Агреговані shard-перевірки використовують !cancelled() && always(), тому вони все ще повідомляють звичайні shard-помилки, але не стають у чергу після того, як увесь workflow уже був витіснений. Автоматичний concurrency key CI версіонований (CI-v7-*), щоб zombie на стороні GitHub у старій queue group не міг безстроково блокувати новіші main-запуски. Ручні запуски повного набору використовують CI-manual-v1-* і не скасовують запуски, що вже виконуються.

Завдання ci-timings-summary завантажує компактний артефакт ci-timings-summary для кожного нечернеткового запуску CI. Він записує wall time, queue time, найповільніші завдання і завдання з помилками для поточного запуску, щоб перевіркам здоров’я CI не потрібно було повторно сканувати повний payload Actions.

Область і маршрутизація

Логіка області міститься в scripts/ci-changed-scope.mjs і покрита unit-тестами в src/scripts/ci-changed-scope.test.ts. Ручний dispatch пропускає виявлення changed-scope і змушує manifest preflight поводитися так, ніби кожна scoped-область змінилася.

  • Редагування workflow CI валідують граф Node CI плюс linting workflow, але самі по собі не примушують Windows, Android або macOS native builds; ці platform-напрямки залишаються обмеженими змінами platform source.
  • Редагування лише маршрутизації CI, вибрані дешеві редагування fixtures core-test і вузькі редагування plugin contract helper/test-routing використовують швидкий шлях Node-only manifest: preflight, security і одне завдання checks-fast-core. Цей шлях пропускає build artifacts, сумісність Node 22, channel contracts, повні core shards, bundled-plugin shards і додаткові guard matrices, коли зміна обмежена routing або helper surfaces, які швидке завдання перевіряє напряму.
  • Перевірки Windows Node обмежені Windows-специфічними process/path wrappers, npm/pnpm/UI runner helpers, package manager config і поверхнями CI workflow, які виконують цей напрямок; непов’язані зміни source, plugin, install-smoke і test-only залишаються на Linux Node напрямках.

Найповільніші родини тестів Node розділені або збалансовані, щоб кожне завдання залишалося малим без надмірного резервування runners: channel contracts запускаються як три weighted shards, core unit fast/support напрямки запускаються окремо, core runtime infra розділено між state, process/config, cron і shared shards, auto-reply запускається як збалансовані workers (із reply subtree, розділеним на shards agent-runner, dispatch і commands/state-routing), а agentic gateway/server configs розділені між chat/auth/model/http-plugin/runtime/startup напрямками замість очікування built artifacts. Broad browser, QA, media і miscellaneous plugin-тести використовують власні спеціальні Vitest configs замість спільного plugin catch-all. Include-pattern shards записують timing entries з використанням імені CI shard, тому .artifacts/vitest-shard-timings.json може відрізняти цілий config від filtered shard. check-additional тримає package-boundary compile/canary роботу разом і відокремлює runtime topology architecture від gateway watch coverage; список boundary guard розподілено смугами на чотири matrix shards, кожен із яких запускає вибрані незалежні guards паралельно й друкує timings для кожної перевірки. Дорога перевірка drift snapshot happy-path prompt Codex запускається лише для ручного CI і для змін, що впливають на prompt, тому звичайні непов’язані зміни Node не чекають за холодною генерацією prompt snapshot, водночас prompt drift усе ще прив’язаний до PR, який його спричинив; той самий прапорець пропускає генерацію prompt snapshot Vitest усередині built-artifact core support-boundary shard. Gateway watch, channel tests і core support-boundary shard запускаються паралельно всередині build-artifacts після того, як dist/ і dist-runtime/ уже зібрані.

Android CI запускає і testPlayDebugUnitTest, і testThirdPartyDebugUnitTest, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test напрямок усе одно компілює flavor із прапорцями BuildConfig для SMS/call-log, уникаючи дублювання debug APK packaging job під час кожного Android-релевантного push.

Shard check-dependencies запускає pnpm deadcode:dependencies (production-прохід Knip лише для залежностей, закріплений за найновішою версією Knip, із вимкненим minimum release age pnpm для встановлення dlx) і pnpm deadcode:unused-files, який порівнює production-висновки Knip про невикористані файли з scripts/deadcode-unused-files.allowlist.mjs. Guard невикористаних файлів падає, коли PR додає новий непереглянутий невикористаний файл або залишає застарілий запис allowlist, водночас зберігаючи навмисні dynamic plugin, generated, build, live-test і package bridge surfaces, які Knip не може статично розв’язати.

Пересилання активності ClawSweeper

.github/workflows/clawsweeper-dispatch.yml є target-side мостом від активності репозиторію OpenClaw до ClawSweeper. Він не виконує checkout і не запускає недовірений код pull request. Workflow створює GitHub App token із CLAWSWEEPER_APP_PRIVATE_KEY, а потім надсилає compact repository_dispatch payloads до openclaw/clawsweeper.

Workflow має чотири напрямки:

  • clawsweeper_item для точних запитів на review issue і pull request;
  • clawsweeper_comment для явних команд ClawSweeper у коментарях issue;
  • clawsweeper_commit_review для запитів commit-level review на push до main;
  • github_activity для загальної активності GitHub, яку агент ClawSweeper може перевіряти.

Напрямок github_activity пересилає лише нормалізовані metadata: event type, action, actor, repository, item number, URL, title, state і короткі excerpts для comments або reviews, якщо вони є. Він навмисно уникає пересилання повного webhook body. Отримувальний workflow у openclaw/clawsweeper.github/workflows/github-activity.yml, який публікує нормалізовану подію в hook OpenClaw Gateway для агента ClawSweeper.

Загальна активність є спостереженням, а не доставкою за замовчуванням. Агент ClawSweeper отримує ціль Discord у своєму prompt і має публікувати в #clawsweeper лише тоді, коли подія є несподіваною, actionable, risky або операційно корисною. Рутинні відкриття, редагування, bot churn, duplicate webhook noise і звичайний review traffic мають завершуватися NO_REPLY.

Treat GitHub titles, comments, bodies, review text, branch names, and commit messages as untrusted data throughout this path. They are input for summarization and triage, not instructions for the workflow or agent runtime.

Manual dispatches

Manual CI dispatches run the same job graph as normal CI but force every non-Android scoped lane on: Linux Node shards, bundled-plugin shards, channel contracts, Node 22 compatibility, check, check-additional, build smoke, docs checks, Python skills, Windows, macOS, and Control UI i18n. Standalone manual CI dispatches run Android only with include_android=true; the full release umbrella enables Android by passing include_android=true. Plugin prerelease static checks, the release-only agentic-plugins shard, the full extension batch sweep, and plugin prerelease Docker lanes are excluded from CI. The Docker prerelease suite runs only when Full Release Validation dispatches the separate Plugin Prerelease workflow with the release-validation gate enabled.

Manual runs use a unique concurrency group so a release-candidate full suite is not cancelled by another push or PR run on the same ref. The optional target_ref input lets a trusted caller run that graph against a branch, tag, or full commit SHA while using the workflow file from the selected dispatch ref.

gh workflow run ci.yml --ref release/YYYY.M.D
gh workflow run ci.yml --ref main -f target_ref=<branch-or-sha> -f include_android=true
gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>

Runners

Runner Jobs
ubuntu-24.04 preflight, fast security jobs and aggregates (security-scm-fast, security-dependency-audit, security-fast), fast protocol/contract/bundled checks, sharded channel contract checks, check shards except lint, check-additional aggregates, Node test aggregate verifiers, docs checks, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight also uses GitHub-hosted Ubuntu so the Blacksmith matrix can queue earlier
blacksmith-4vcpu-ubuntu-2404 CodeQL Critical Quality, lower-weight extension shards, checks-fast-core, checks-node-compat-node22, check-prod-types, and check-test-types
blacksmith-8vcpu-ubuntu-2404 build-artifacts, build-smoke, Linux Node test shards, bundled plugin test shards, check-additional shards, android
blacksmith-16vcpu-ubuntu-2404 check-lint (CPU-sensitive enough that 8 vCPU cost more than they saved); install-smoke Docker builds (32-vCPU queue time cost more than it saved)
blacksmith-16vcpu-windows-2025 checks-windows
blacksmith-6vcpu-macos-latest macos-node on openclaw/openclaw; forks fall back to macos-latest
blacksmith-12vcpu-macos-latest macos-swift on openclaw/openclaw; forks fall back to macos-latest

Canonical-repo CI keeps Blacksmith as the default runner path. During preflight, scripts/ci-runner-labels.mjs checks recent queued and in-progress Actions runs for queued Blacksmith jobs. If a specific Blacksmith label already has queued jobs, downstream jobs that would use that exact label fall back to the matching GitHub-hosted runner (ubuntu-24.04, windows-2025, or macos-latest) for that run only. Other Blacksmith sizes in the same OS family stay on their primary labels. If the API probe fails, no fallback is applied.

Local equivalents

pnpm changed:lanes                            # inspect the local changed-lane classifier for origin/main...HEAD
pnpm check:changed                            # smart local check gate: changed typecheck/lint/guards by boundary lane
pnpm check                                    # fast local gate: prod tsgo + sharded lint + parallel fast guards
pnpm check:test-types
pnpm check:timed                              # same gate with per-stage timings
pnpm build:strict-smoke
pnpm check:architecture
pnpm test:gateway:watch-regression
pnpm test                                     # vitest tests
pnpm test:changed                             # cheap smart changed Vitest targets
pnpm test:channels
pnpm test:contracts:channels
pnpm check:docs                               # docs format + lint + broken links
pnpm build                                    # build dist when CI artifact/build-smoke lanes matter
pnpm ci:timings                               # summarize the latest origin/main push CI run
pnpm ci:timings:recent                        # compare recent successful main CI runs
node scripts/ci-run-timings.mjs <run-id>      # summarize wall time, queue time, and slowest jobs
node scripts/ci-run-timings.mjs --latest-main # ignore issue/comment noise and choose origin/main push CI
node scripts/ci-run-timings.mjs --recent 10   # compare recent successful main CI runs
pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json
pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json
pnpm perf:kova:summary --report .artifacts/kova/reports/mock-provider/report.json --output .artifacts/kova/summary.md

OpenClaw Performance

OpenClaw Performance is the product/runtime performance workflow. It runs daily on main and can be dispatched manually:

gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f repeat=3
gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 -f deep_profile=true -f live_gpt54=true
gh workflow run openclaw-performance.yml --ref main -f target_ref=v2026.5.2 -f profile=diagnostic -f repeat=3

Manual dispatch normally benchmarks the workflow ref. Set target_ref to benchmark a release tag or another branch with the current workflow implementation. Published report paths and latest pointers are keyed by the tested ref, and each index.md records the tested ref/SHA, workflow ref/SHA, Kova ref, profile, lane auth mode, model, repeat count, and scenario filters.

The workflow installs OCM from a pinned release and Kova from openclaw/Kova at the pinned kova_ref input, then runs three lanes:

  • mock-provider: Kova diagnostic scenarios against a local-build runtime with deterministic fake OpenAI-compatible auth.
  • mock-deep-profile: CPU/heap/trace profiling for startup, gateway, and agent-turn hotspots.
  • live-gpt54: a real OpenAI openai/gpt-5.4 agent turn, skipped when OPENAI_API_KEY is unavailable.

The mock-provider lane also runs OpenClaw-native source probes after the Kova pass: gateway boot timing and memory across default, hook, and 50-plugin startup cases; repeated mock-OpenAI channel-chat-baseline hello loops; and CLI startup commands against the booted gateway. The source probe Markdown summary lives at source/index.md in the report bundle, with raw JSON beside it.

Every lane uploads GitHub artifacts. When CLAWGRIT_REPORTS_TOKEN is configured, the workflow also commits report.json, report.md, bundles, index.md, and source-probe artifacts into openclaw/clawgrit-reports under openclaw-performance/<tested-ref>/<run-id>-<attempt>/<lane>/. The current tested-ref pointer is written as openclaw-performance/<tested-ref>/latest-<lane>.json.

Full Release Validation

Full Release Validation is the manual umbrella workflow for "run everything before release." It accepts a branch, tag, or full commit SHA, dispatches the manual CI workflow with that target, dispatches Plugin Prerelease for release-only plugin/package/static/Docker proof, and dispatches OpenClaw Release Checks for install smoke, package acceptance, cross-OS package checks, QA Lab parity, Matrix, and Telegram lanes. Stable/default runs keep exhaustive live/E2E and Docker release-path coverage behind run_release_soak=true; release_profile=full forces that soak coverage on so broad advisory validation remains broad. With rerun_group=all and release_profile=full, it also runs NPM Telegram Beta E2E against the release-package-under-test artifact from release checks. After publishing, pass npm_telegram_package_spec to rerun the same Telegram package lane against the published npm package.

See Full release validation for the stage matrix, exact workflow job names, profile differences, artifacts, and focused rerun handles.

OpenClaw Release Publish is the manual mutating release workflow. Dispatch it from release/YYYY.M.D or main after the release tag exists and after the OpenClaw npm preflight has succeeded. It verifies pnpm plugins:sync:check, dispatches Plugin NPM Release for all publishable plugin packages, dispatches Plugin ClawHub Release for the same release SHA, and only then dispatches OpenClaw NPM Release with the saved preflight_run_id.

gh workflow run openclaw-release-publish.yml \
  --ref release/YYYY.M.D \
  -f tag=vYYYY.M.D-beta.N \
  -f preflight_run_id=<successful-openclaw-npm-preflight-run-id> \
  -f npm_dist_tag=beta

Для доказу закріпленого коміту на гілці, що швидко змінюється, використовуйте помічник замість gh workflow run ... --ref main -f ref=<sha>:

pnpm ci:full-release --sha <full-sha>

Refs для dispatch у GitHub workflow мають бути гілками або тегами, а не сирими SHA комітів. Помічник надсилає тимчасову гілку release-ci/<sha>-... на цільовий SHA, запускає Full Release Validation із цього закріпленого ref, перевіряє, що headSha кожного дочірнього workflow збігається з ціллю, і видаляє тимчасову гілку після завершення запуску. Парасольковий верифікатор також завершується з помилкою, якщо будь-який дочірній workflow запускався на іншому SHA.

release_profile керує шириною live/provider, що передається у release checks. Ручні release workflows за замовчуванням використовують stable; використовуйте full лише тоді, коли навмисно потрібна широка рекомендаційна матриця provider/media. run_release_soak керує тим, чи stable/default release checks запускають вичерпний live/E2E та Docker soak release-path; full примусово вмикає soak.

  • minimum залишає найшвидші критичні для релізу лінії OpenAI/core.
  • stable додає стабільний набір provider/backend.
  • full запускає широку рекомендаційну матрицю provider/media.

Парасолька записує ідентифікатори запущених дочірніх запусків, а фінальне завдання Verify full validation повторно перевіряє поточні висновки дочірніх запусків і додає таблиці найповільніших завдань для кожного дочірнього запуску. Якщо дочірній workflow перезапущено і він став зеленим, перезапустіть лише батьківське завдання верифікатора, щоб оновити результат парасольки та підсумок часу.

Для відновлення Full Release Validation і OpenClaw Release Checks приймають rerun_group. Використовуйте all для release candidate, ci лише для звичайного дочірнього full CI, plugin-prerelease лише для дочірнього plugin prerelease, release-checks для кожного дочірнього release, або вужчу групу: install-smoke, cross-os, live-e2e, package, qa, qa-parity, qa-live чи npm-telegram на парасольці. Це утримує перезапуск невдалого release box у межах після сфокусованого виправлення. Для однієї невдалої cross-OS лінії поєднайте rerun_group=cross-os із cross_os_suite_filter, наприклад windows/packaged-upgrade; довгі cross-OS команди виводять рядки Heartbeat, а підсумки packaged-upgrade містять часи для кожної фази. QA лінії release-check є рекомендаційними, тому помилки лише в QA попереджають, але не блокують верифікатор release-check.

OpenClaw Release Checks використовує довірений workflow ref, щоб один раз розв’язати вибраний ref у tarball release-package-under-test, а потім передає цей артефакт у cross-OS checks і Package Acceptance, а також у live/E2E release-path Docker workflow, коли запускається soak coverage. Це зберігає однакові байти пакета на release boxes і уникає повторного пакування того самого кандидата в кількох дочірніх завданнях.

Дублікати запусків Full Release Validation для ref=main і rerun_group=all заміщують старішу парасольку. Батьківський монітор скасовує будь-який дочірній workflow, який він уже запустив, коли батьківський запуск скасовано, тому новіша валідація main не стоїть за застарілим двогодинним запуском release-check. Валідація release branch/tag і сфокусовані групи перезапуску зберігають cancel-in-progress: false.

Live та E2E shards

Дочірній release live/E2E зберігає широке нативне покриття pnpm test:live, але запускає його як іменовані shards через scripts/test-live-shard.mjs замість одного серійного завдання:

  • native-live-src-agents
  • native-live-src-gateway-core
  • jobs native-live-src-gateway-profiles, відфільтровані за provider
  • native-live-src-gateway-backends
  • native-live-test
  • native-live-extensions-a-k
  • native-live-extensions-l-n
  • native-live-extensions-openai
  • native-live-extensions-o-z-other
  • native-live-extensions-xai
  • розділені media audio/video shards і music shards, відфільтровані за provider

Це зберігає те саме покриття файлів, водночас роблячи повільні live-помилки provider простішими для перезапуску й діагностики. Агреговані назви shards native-live-extensions-o-z, native-live-extensions-media і native-live-extensions-media-music залишаються чинними для ручних одноразових перезапусків.

Нативні live media shards запускаються в ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04, зібраному workflow Live Media Runner Image. Цей image попередньо встановлює ffmpeg і ffprobe; media jobs лише перевіряють binaries перед налаштуванням. Залишайте Docker-backed live suites на звичайних Blacksmith runners — container jobs є неправильним місцем для запуску вкладених Docker tests.

Docker-backed live model/backend shards використовують окремий спільний image ghcr.io/openclaw/openclaw-live-test:<sha> для кожного вибраного коміту. Live release workflow збирає і надсилає цей image один раз, після чого Docker live model, provider-sharded gateway, CLI backend, ACP bind і Codex harness shards запускаються з OPENCLAW_SKIP_DOCKER_BUILD=1. Gateway Docker shards мають явні обмеження timeout на рівні script, нижчі за timeout завдання workflow, щоб завислий container або cleanup path швидко завершувався з помилкою, а не споживав увесь бюджет release-check. Якщо ці shards незалежно перебудовують повну source Docker target, release run налаштовано неправильно, і він витрачатиме час на дубльовані image builds.

Package Acceptance

Використовуйте Package Acceptance, коли питання звучить як «чи працює цей installable пакет OpenClaw як продукт?» Він відрізняється від звичайного CI: звичайний CI перевіряє source tree, тоді як package acceptance перевіряє один tarball через той самий Docker E2E harness, який користувачі виконують після встановлення або оновлення.

Завдання

  1. resolve_package робить checkout workflow_ref, розв’язує одного кандидата пакета, записує .artifacts/docker-e2e-package/openclaw-current.tgz, записує .artifacts/docker-e2e-package/package-candidate.json, завантажує обидва як артефакт package-under-test і друкує source, workflow ref, package ref, version, SHA-256 і profile у GitHub step summary.
  2. docker_acceptance викликає openclaw-live-and-e2e-checks-reusable.yml з ref=workflow_ref і package_artifact_name=package-under-test. Reusable workflow завантажує цей артефакт, перевіряє inventory tarball, готує package-digest Docker images за потреби й запускає вибрані Docker lanes проти цього пакета замість пакування workflow checkout. Коли profile вибирає кілька цільових docker_lanes, reusable workflow готує пакет і спільні images один раз, а потім розгортає ці lanes як паралельні цільові Docker jobs з унікальними артефактами.
  3. package_telegram опційно викликає NPM Telegram Beta E2E. Він запускається, коли telegram_mode не є none, і встановлює той самий артефакт package-under-test, коли Package Acceptance розв’язав один; standalone Telegram dispatch усе ще може встановити опублікований npm spec.
  4. summary завершує workflow з помилкою, якщо package resolution, Docker acceptance або опційна Telegram lane зазнали помилки.

Джерела кандидатів

  • source=npm приймає лише openclaw@beta, openclaw@latest або точну release version OpenClaw, таку як [email protected]. Використовуйте це для published prerelease/stable acceptance.
  • source=ref пакує довірену гілку package_ref, тег або повний SHA коміту. Resolver отримує гілки/теги OpenClaw, перевіряє, що вибраний коміт досяжний з історії гілок репозиторію або release tag, встановлює deps у detached worktree і пакує його через scripts/package-openclaw-for-docker.mjs.
  • source=url завантажує HTTPS .tgz; package_sha256 є обов’язковим.
  • source=artifact завантажує один .tgz з artifact_run_id і artifact_name; package_sha256 є опційним, але його слід надавати для зовнішньо поширених артефактів.

Тримайте workflow_ref і package_ref окремо. workflow_ref — це довірений код workflow/harness, який запускає test. package_ref — це source commit, який пакується, коли source=ref. Це дає змогу поточному test harness перевіряти старіші довірені source commits без запуску старої workflow logic.

Профілі suites

  • smokenpm-onboard-channel-agent, gateway-network, config-reload
  • packagenpm-onboard-channel-agent, doctor-switch, update-channel-switch, upgrade-survivor, published-upgrade-survivor, plugins-offline, plugin-update
  • productpackage плюс mcp-channels, cron-mcp-cleanup, openai-web-search-minimal, openwebui
  • full — повні Docker release-path chunks з OpenWebUI
  • custom — точні docker_lanes; обов’язкові, коли suite_profile=custom

Профіль package використовує offline покриття плагінів, щоб валідація published-package не залежала від live доступності ClawHub. Опційна Telegram lane повторно використовує артефакт package-under-test у NPM Telegram Beta E2E, а шлях published npm spec збережено для standalone dispatches.

Для спеціальної політики тестування оновлень і плагінів, включно з локальними командами, Docker lanes, inputs Package Acceptance, release defaults і triage помилок, див. Testing updates and plugins.

Release checks викликають Package Acceptance з source=artifact, підготовленим release package artifact, suite_profile=custom, docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update' і telegram_mode=mock-openai. Це зберігає докази package migration, update, stale-plugin-dependency cleanup, configured-plugin install repair, offline plugin, plugin-update і Telegram на тому самому розв’язаному package tarball. Установіть package_acceptance_package_spec у Full Release Validation або OpenClaw Release Checks, щоб запустити ту саму матрицю проти shipped npm package замість SHA-built artifact. Cross-OS release checks усе ще покривають OS-specific onboarding, installer і platform behavior; package/update product validation має починатися з Package Acceptance. Docker lane published-upgrade-survivor перевіряє один published package baseline за запуск у blocking release path. У Package Acceptance розв’язаний tarball package-under-test завжди є кандидатом, а published_upgrade_survivor_baseline вибирає fallback published baseline, за замовчуванням openclaw@latest; failed-lane rerun commands зберігають цей baseline. Full Release Validation з run_release_soak=true або release_profile=full встановлює published_upgrade_survivor_baselines='last-stable-4 2026.4.23 2026.5.2 2026.4.15' і published_upgrade_survivor_scenarios=reported-issues, щоб розширити покриття на чотири найновіші stable npm releases плюс закріплені plugin-compatibility boundary releases і issue-shaped fixtures для Feishu config, збережених bootstrap/persona files, configured OpenClaw plugin installs, tilde log paths і stale legacy plugin dependency roots. Multi-baseline published-upgrade survivor selections шардяться за baseline в окремі targeted Docker runner jobs. Окремий workflow Update Migration використовує Docker lane update-migration з all-since-2026.4.23 і plugin-deps-cleanup, коли питанням є вичерпне published update cleanup, а не звичайна ширина Full Release CI. Local aggregate runs можуть передавати точні package specs через OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS, залишати одну lane з OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC, наприклад [email protected], або встановити OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS для scenario matrix. Published lane налаштовує baseline через вбудований рецепт команди openclaw config set, записує кроки рецепта в summary.json і перевіряє /healthz, /readyz, а також RPC status після запуску Gateway. Windows packaged і installer fresh lanes також перевіряють, що встановлений пакет може імпортувати browser-control override із сирого абсолютного Windows path. OpenAI cross-OS agent-turn smoke за замовчуванням використовує OPENCLAW_CROSS_OS_OPENAI_MODEL, якщо встановлено, інакше openai/gpt-5.4, щоб install і gateway proof залишалися на GPT-5 test model, уникаючи GPT-4.x defaults.

Вікна сумісності legacy

Приймання пакета має обмежені вікна сумісності зі застарілими версіями для вже опублікованих пакетів. Пакети до 2026.4.25 включно, зокрема 2026.4.25-beta.*, можуть використовувати шлях сумісності:

  • відомі приватні записи QA в dist/postinstall-inventory.json можуть вказувати на файли, пропущені в tarball;
  • doctor-switch може пропускати підвипадок збереження gateway install --wrapper, коли пакет не надає цей прапорець;
  • update-channel-switch може прибирати відсутні pnpm.patchedDependencies із фіктивного git-фікстура, отриманого з tarball, і може логувати відсутній збережений update.channel;
  • димові перевірки plugin можуть читати застарілі розташування install-record або приймати відсутнє збереження install-record marketplace;
  • plugin-update може дозволяти міграцію метаданих конфігурації, водночас і далі вимагаючи, щоб install record і поведінка без повторного встановлення залишалися незмінними.

Опублікований пакет 2026.4.26 також може попереджати про файли штампів метаданих локальної збірки, які вже були постачені. Пізніші пакети мають відповідати сучасним контрактам; ті самі умови призводять до помилки, а не до попередження чи пропуску.

Приклади

# Validate the current beta package with product-level coverage.
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=npm \
  -f package_spec=openclaw@beta \
  -f suite_profile=product \
  -f telegram_mode=mock-openai

# Pack and validate a release branch with the current harness.
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=ref \
  -f package_ref=release/YYYY.M.D \
  -f suite_profile=package \
  -f telegram_mode=mock-openai

# Validate a tarball URL. SHA-256 is mandatory for source=url.
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=url \
  -f package_url=https://example.com/openclaw-current.tgz \
  -f package_sha256=<64-char-sha256> \
  -f suite_profile=smoke

# Reuse a tarball uploaded by another Actions run.
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=artifact \
  -f artifact_run_id=<run-id> \
  -f artifact_name=package-under-test \
  -f suite_profile=custom \
  -f docker_lanes='install-e2e plugin-update'

Під час налагодження невдалого запуску приймання пакета починайте зі зведення resolve_package, щоб підтвердити джерело пакета, версію та SHA-256. Потім перевірте дочірній запуск docker_acceptance і його Docker-артефакти: .artifacts/docker-tests/**/summary.json, failures.json, логи lane, таймінги фаз і команди повторного запуску. Надавайте перевагу повторному запуску невдалого профілю пакета або точних Docker lanes замість повторного запуску повної валідації релізу.

Димова перевірка встановлення

Окремий workflow Install Smoke повторно використовує той самий scope-скрипт через власну задачу preflight. Він розділяє покриття димових перевірок на run_fast_install_smoke і run_full_install_smoke.

  • Швидкий шлях запускається для pull requests, що торкаються поверхонь Docker/пакета, змін пакетів/маніфестів вбудованих plugin або поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke jobs. Зміни лише у вихідному коді вбудованого plugin, зміни лише тестів і зміни лише документації не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає димову CLI-перевірку agents delete shared-workspace, запускає e2e container gateway-network, перевіряє аргумент збірки bundled extension і запускає обмежений Docker-профіль bundled-plugin із сукупним тайм-аутом команди 240 секунд (кожен Docker-запуск сценарію обмежений окремо).
  • Повний шлях зберігає QR package install і Docker/update-покриття інсталятора для нічних запланованих запусків, ручних dispatches, workflow-call release checks і pull requests, які справді торкаються поверхонь installer/package/Docker. У повному режимі install-smoke готує або повторно використовує один GHCR root Dockerfile smoke image для target-SHA, а потім запускає QR package install, root Dockerfile/gateway smokes, installer/update smokes і швидкий bundled-plugin Docker E2E як окремі jobs, щоб робота інсталятора не чекала за root image smokes.

Пуші в main (зокрема merge commits) не примушують повний шлях; коли логіка changed-scope запитувала б повне покриття під час push, workflow зберігає швидку Docker smoke і залишає повну install smoke для нічної або релізної валідації.

Повільна Bun global install image-provider smoke окремо керується через run_bun_global_install_smoke. Вона запускається за нічним розкладом і з release checks workflow, а ручні dispatches Install Smoke можуть увімкнути її, але pull requests і пуші в main — ні. QR і installer Docker tests зберігають власні Dockerfiles, зосереджені на встановленні.

Локальний Docker E2E

pnpm test:docker:all попередньо збирає один спільний live-test image, один раз пакує OpenClaw як npm tarball і збирає два спільні образи scripts/e2e/Dockerfile:

  • мінімальний Node/Git runner для installer/update/plugin-dependency lanes;
  • функціональний образ, який встановлює той самий tarball у /app для звичайних функціональних lanes.

Визначення Docker lane містяться в scripts/lib/docker-e2e-scenarios.mjs, логіка планувальника — у scripts/lib/docker-e2e-plan.mjs, а runner виконує лише вибраний план. Планувальник вибирає образ для кожної lane за допомогою OPENCLAW_DOCKER_E2E_BARE_IMAGE і OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE, а потім запускає lanes із OPENCLAW_SKIP_DOCKER_BUILD=1.

Налаштування

Змінна Типове значення Призначення
OPENCLAW_DOCKER_ALL_PARALLELISM 10 Кількість слотів основного pool для звичайних lanes.
OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM 10 Кількість слотів tail-pool, чутливого до provider.
OPENCLAW_DOCKER_ALL_LIVE_LIMIT 9 Обмеження одночасних live lane, щоб providers не застосовували throttling.
OPENCLAW_DOCKER_ALL_NPM_LIMIT 10 Обмеження одночасних npm install lane.
OPENCLAW_DOCKER_ALL_SERVICE_LIMIT 7 Обмеження одночасних multi-service lane.
OPENCLAW_DOCKER_ALL_START_STAGGER_MS 2000 Затримка між стартами lane, щоб уникати сплесків створення в Docker daemon; задайте 0, щоб вимкнути затримку.
OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS 7200000 Резервний тайм-аут на lane (120 хвилин); вибрані live/tail lanes використовують жорсткіші обмеження.
OPENCLAW_DOCKER_ALL_DRY_RUN unset 1 друкує план планувальника без запуску lanes.
OPENCLAW_DOCKER_ALL_LANES unset Список точних lanes, розділених комами; пропускає cleanup smoke, щоб agents могли відтворити одну невдалу lane.

Lane, важча за свій ефективний ліміт, все одно може стартувати з порожнього pool, а потім працює сама, доки не звільнить capacity. Локальний aggregate попередньо перевіряє Docker, видаляє застарілі OpenClaw E2E containers, виводить статус active-lane, зберігає таймінги lanes для впорядкування longest-first і за замовчуванням припиняє планувати нові pooled lanes після першої помилки.

Повторно використовуваний live/E2E workflow

Повторно використовуваний live/E2E workflow запитує в scripts/test-docker-all.mjs --plan-json, яке покриття пакета, типу образу, live image, lane і credentials потрібне. Потім scripts/docker-e2e.mjs перетворює цей план на GitHub outputs і summaries. Він або пакує OpenClaw через scripts/package-openclaw-for-docker.mjs, завантажує package artifact поточного запуску, або завантажує package artifact із package_artifact_run_id; перевіряє інвентар tarball; збирає й публікує package-digest-tagged bare/functional GHCR Docker E2E images через Docker layer cache Blacksmith, коли план потребує package-installed lanes; і повторно використовує надані inputs docker_e2e_bare_image/docker_e2e_functional_image або наявні package-digest images замість повторної збірки. Docker image pulls повторюються з обмеженим тайм-аутом 180 секунд на спробу, щоб завислий registry/cache stream швидко повторювався, а не споживав більшу частину критичного шляху CI.

Частини release-path

Release Docker coverage запускає менші chunked jobs із OPENCLAW_SKIP_DOCKER_BUILD=1, щоб кожен chunk завантажував лише потрібний йому тип образу й виконував кілька lanes через той самий зважений планувальник:

  • OPENCLAW_DOCKER_ALL_PROFILE=release-path
  • OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h

Поточні release Docker chunks: core, package-update-openai, package-update-anthropic, package-update-core, plugins-runtime-plugins, plugins-runtime-services і plugins-runtime-install-a до plugins-runtime-install-h. plugins-runtime-core, plugins-runtime і plugins-integrations залишаються aggregate plugin/runtime aliases. Alias lane install-e2e залишається aggregate manual rerun alias для обох provider installer lanes.

OpenWebUI включається в plugins-runtime-services, коли повне release-path coverage запитує його, і зберігає окремий chunk openwebui лише для OpenWebUI-only dispatches. Bundled-channel update lanes повторюються один раз у разі тимчасових npm network failures.

Кожен chunk завантажує .artifacts/docker-tests/ з lane logs, timings, summary.json, failures.json, phase timings, scheduler plan JSON, slow-lane tables і per-lane rerun commands. Input workflow docker_lanes запускає вибрані lanes на підготовлених образах замість chunk jobs, що обмежує налагодження failed-lane одним цільовим Docker job і готує, завантажує або повторно використовує package artifact для цього запуску; якщо вибрана lane є live Docker lane, цільова job локально збирає live-test image для цього rerun. Згенеровані GitHub rerun commands для кожної lane містять package_artifact_run_id, package_artifact_name і inputs підготовлених образів, коли ці значення існують, тож failed lane може повторно використати точний пакет і образи з невдалого запуску.

pnpm test:docker:rerun <run-id>      # download Docker artifacts and print combined/per-lane targeted rerun commands
pnpm test:docker:timings <summary>   # slow-lane and phase critical-path summaries

Запланований live/E2E workflow щодня запускає повний release-path Docker suite.

Попередній реліз Plugin

Plugin Prerelease — дорожче покриття продукту/пакета, тому це окремий workflow, який запускається Full Release Validation або явним оператором. Звичайні pull requests, пуші в main і самостійні ручні CI dispatches тримають цей suite вимкненим. Він балансує bundled plugin tests між вісьмома extension workers; ці extension shard jobs запускають до двох plugin config groups одночасно з одним Vitest worker на group і більшим Node heap, щоб import-heavy plugin batches не створювали додаткових CI jobs. Release-only Docker prerelease path групує цільові Docker lanes у малі groups, щоб не резервувати десятки runners для jobs тривалістю від однієї до трьох хвилин.

QA Lab

QA Lab має виділені CI lanes поза основним smart-scoped workflow. Agentic parity вкладена в broad QA і release harnesses, а не є окремим PR workflow. Використовуйте Full Release Validation з rerun_group=qa-parity, коли parity має виконуватися разом із широким validation run.

  • Workflow QA-Lab - All Lanes запускається щоночі на main і вручну через dispatch; він розгортає mock parity lane, live Matrix lane, а також live Telegram і Discord lanes як паралельні jobs. Live jobs використовують середовище qa-live-shared, а Telegram/Discord використовують Convex leases.

Перевірки релізу запускають live transport-ланки Matrix і Telegram з детермінованим mock-провайдером і mock-кваліфікованими моделями (mock-openai/gpt-5.5 і mock-openai/gpt-5.5-alt), щоб контракт каналу був ізольований від затримки live-моделі та звичайного запуску provider-plugin. Live transport gateway вимикає пошук у пам’яті, оскільки QA parity окремо покриває поведінку пам’яті; підключення провайдерів покривається окремими наборами live model, native provider і Docker provider.

Matrix використовує --profile fast для запланованих і релізних gate, додаючи --fail-fast лише тоді, коли checkout-нутий CLI це підтримує. Значення CLI за замовчуванням і ручний workflow input залишаються all; ручний dispatch matrix_profile=all завжди шардує повне покриття Matrix на завдання transport, media, e2ee-smoke, e2ee-deep і e2ee-cli.

OpenClaw Release Checks також запускає релізно-критичні ланки QA Lab перед схваленням релізу; його QA parity gate запускає candidate і baseline packs як паралельні lane jobs, потім завантажує обидва artifacts у невелике report job для фінального parity comparison.

Для звичайних PR дотримуйтеся scoped CI/check evidence замість того, щоб вважати parity обов’язковим статусом.

CodeQL

Workflow CodeQL навмисно є вузьким security scanner першого проходу, а не повним sweep репозиторію. Щоденні, ручні та guard-запуски для non-draft pull request сканують код Actions workflow плюс найризикованіші поверхні JavaScript/TypeScript за допомогою high-confidence security queries, відфільтрованих до high/critical security-severity.

Pull request guard лишається легким: він стартує лише для змін у .github/actions, .github/codeql, .github/workflows, packages або src, і запускає ту саму high-confidence security matrix, що й scheduled workflow. Android і macOS CodeQL не входять до PR defaults.

Категорії безпеки

Категорія Поверхня
/codeql-security-high/core-auth-secrets Auth, secrets, sandbox, cron і базова лінія gateway
/codeql-security-high/channel-runtime-boundary Контракти реалізації основних каналів плюс runtime channel plugin, gateway, Plugin SDK, secrets, audit touchpoints
/codeql-security-high/network-ssrf-boundary Поверхні core SSRF, IP parsing, network guard, web-fetch і Plugin SDK SSRF policy
/codeql-security-high/mcp-process-tool-boundary MCP servers, process execution helpers, outbound delivery і agent tool-execution gates
/codeql-security-high/plugin-trust-boundary Поверхні довіри Plugin install, loader, manifest, registry, package-manager install, source-loading і Plugin SDK package contract

Platform-specific security shards

  • CodeQL Android Critical Security — scheduled Android security shard. Збирає Android app вручну для CodeQL на найменшому Blacksmith Linux runner, прийнятому workflow sanity. Завантажує під /codeql-critical-security/android.
  • CodeQL macOS Critical Security — щотижневий/ручний macOS security shard. Збирає macOS app вручну для CodeQL на Blacksmith macOS, відфільтровує результати dependency build із завантаженого SARIF і завантажує під /codeql-critical-security/macos. Утримується поза daily defaults, бо macOS build домінує runtime навіть коли він чистий.

Категорії Critical Quality

CodeQL Critical Quality — відповідний non-security shard. Він запускає лише error-severity, non-security JavaScript/TypeScript quality queries на вузьких high-value поверхнях на меншому Blacksmith Linux runner. Його pull request guard навмисно менший за scheduled profile: non-draft PRs запускають лише відповідні шарди agent-runtime-boundary, config-boundary, core-auth-secrets, channel-runtime-boundary, gateway-runtime-boundary, memory-runtime-boundary, mcp-process-runtime-boundary, provider-runtime-boundary, session-diagnostics-boundary, plugin-boundary, plugin-sdk-package-contract і plugin-sdk-reply-runtime для змін у коді agent command/model/tool execution і reply dispatch, config schema/migration/IO code, auth/secrets/sandbox/security code, core channel і bundled channel plugin runtime, gateway protocol/server-method, memory runtime/SDK glue, MCP/process/outbound delivery, provider runtime/model catalog, session diagnostics/delivery queues, plugin loader, Plugin SDK/package-contract або Plugin SDK reply runtime. Зміни CodeQL config і quality workflow запускають усі дванадцять PR quality shards.

Manual dispatch приймає:

profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary

Вузькі profiles — це teaching/iteration hooks для запуску одного quality shard ізольовано.

Категорія Поверхня
/codeql-critical-quality/core-auth-secrets Код межі безпеки auth, secrets, sandbox, cron і gateway
/codeql-critical-quality/config-boundary Контракти config schema, migration, normalization і IO
/codeql-critical-quality/gateway-runtime-boundary Gateway protocol schemas і server method contracts
/codeql-critical-quality/channel-runtime-boundary Контракти реалізації core channel і bundled channel plugin
/codeql-critical-quality/agent-runtime-boundary Command execution, model/provider dispatch, auto-reply dispatch and queues, і ACP control-plane runtime contracts
/codeql-critical-quality/mcp-process-runtime-boundary MCP servers і tool bridges, process supervision helpers, і outbound delivery contracts
/codeql-critical-quality/memory-runtime-boundary Memory host SDK, memory runtime facades, memory Plugin SDK aliases, memory runtime activation glue і memory doctor commands
/codeql-critical-quality/session-diagnostics-boundary Reply queue internals, session delivery queues, outbound session binding/delivery helpers, diagnostic event/log bundle surfaces і session doctor CLI contracts
/codeql-critical-quality/plugin-sdk-reply-runtime Plugin SDK inbound reply dispatch, reply payload/chunking/runtime helpers, channel reply options, delivery queues і session/thread binding helpers
/codeql-critical-quality/provider-runtime-boundary Model catalog normalization, provider auth and discovery, provider runtime registration, provider defaults/catalogs і web/search/fetch/embedding registries
/codeql-critical-quality/ui-control-plane Control UI bootstrap, local persistence, gateway control flows і task control-plane runtime contracts
/codeql-critical-quality/web-media-runtime-boundary Core web fetch/search, media IO, media understanding, image-generation і media-generation runtime contracts
/codeql-critical-quality/plugin-boundary Loader, registry, public-surface і Plugin SDK entrypoint contracts
/codeql-critical-quality/plugin-sdk-package-contract Published package-side Plugin SDK source і plugin package contract helpers

Quality залишається окремо від security, щоб quality findings можна було планувати, вимірювати, вимикати або розширювати без затемнення security signal. Розширення CodeQL для Swift, Python і bundled-plugin слід додавати назад як scoped або sharded follow-up work лише після того, як вузькі profiles матимуть стабільні runtime і signal.

Maintenance workflows

Docs Agent

Workflow Docs Agent — це event-driven Codex maintenance lane для підтримання наявних docs у відповідності з нещодавно landed changes. Він не має pure schedule: успішний non-bot push CI run на main може його запустити, а manual dispatch може запустити його напряму. Workflow-run invocations пропускаються, коли main просунувся далі або коли інший non-skipped Docs Agent run був створений за останню годину. Коли він запускається, він переглядає commit range від попереднього non-skipped Docs Agent source SHA до поточного main, тож один hourly run може покрити всі main changes, накопичені від останнього docs pass.

Test Performance Agent

Workflow Test Performance Agent — це event-driven Codex maintenance lane для повільних тестів. Він не має pure schedule: успішний non-bot push CI run на main може його запустити, але він пропускається, якщо інший workflow-run invocation уже виконувався або виконується цього UTC-дня. Manual dispatch обходить цей daily activity gate. Lane будує full-suite grouped Vitest performance report, дозволяє Codex робити лише невеликі coverage-preserving test performance fixes замість широких refactors, потім повторно запускає full-suite report і відхиляє зміни, які зменшують passing baseline test count. Якщо baseline має failing tests, Codex може виправити лише очевидні failures, а after-agent full-suite report має пройти перед тим, як щось буде committed. Коли main просувається до того, як bot push lands, lane rebases validated patch, повторно запускає pnpm check:changed і retry push; conflicting stale patches пропускаються. Він використовує GitHub-hosted Ubuntu, щоб Codex action міг зберегти ту саму drop-sudo safety posture, що й docs agent.

Duplicate PRs After Merge

Workflow Duplicate PRs After Merge — це ручний maintainer workflow для post-land duplicate cleanup. За замовчуванням це dry-run, і він закриває лише явно перелічені PRs, коли apply=true. Перед зміною GitHub він перевіряє, що landed PR is merged і що кожен duplicate має або спільне referenced issue, або overlapping changed hunks.

gh workflow run duplicate-after-merge.yml \
  -f landed_pr=70532 \
  -f duplicate_prs='70530,70592' \
  -f apply=true

Local check gates and changed routing

Local changed-lane logic живе в scripts/changed-lanes.mjs і виконується scripts/check-changed.mjs. Цей local check gate суворіший щодо architecture boundaries, ніж широкий CI platform scope:

  • зміни production у core запускають typecheck для core prod і core test, а також lint/guards для core;
  • зміни лише в тестах core запускають тільки typecheck для core test і lint для core;
  • зміни production у розширеннях запускають typecheck для extension prod і extension test, а також lint для розширень;
  • зміни лише в тестах розширень запускають typecheck для extension test і lint для розширень;
  • зміни публічного Plugin SDK або контракту Plugin розширюються до typecheck розширень, бо розширення залежать від цих контрактів core (розширені перевірки розширень Vitest залишаються явною тестовою роботою);
  • підняття версії лише в метаданих релізу запускає цільові перевірки версії, конфігурації та кореневих залежностей;
  • невідомі зміни в root/config безпечно спрямовуються на всі check-лінії.

Локальна маршрутизація змінених тестів живе в scripts/test-projects.test-support.mjs і навмисно дешевша за check:changed: прямі зміни тестів запускають самі себе, зміни джерел спершу віддають перевагу явним зіставленням, а потім сусіднім тестам і залежним через граф імпортів. Спільна конфігурація доставки для групових кімнат є одним із явних зіставлень: зміни до конфігурації видимої відповіді в групі, режиму доставки відповіді з джерела або системного промпта message-tool проходять через core-тести відповідей, а також регресії доставки Discord і Slack, щоб зміна спільного стандартного значення впала до першого push PR. Використовуйте OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed лише тоді, коли зміна настільки широка для harness, що дешевий зіставлений набір не є надійним проксі.

Валідація Testbox

Запускайте Testbox з кореня репозиторію і віддавайте перевагу свіжому прогрітому box для широкого доказу. Перед тим як витрачати повільний gate на box, який повторно використали, термін дії якого сплив або який щойно повідомив про неочікувано велику синхронізацію, спершу запустіть pnpm testbox:sanity всередині box.

Sanity-перевірка швидко падає, коли обов'язкові кореневі файли на кшталт pnpm-lock.yaml зникли або коли git status --short показує принаймні 200 відстежуваних видалень. Зазвичай це означає, що стан віддаленої синхронізації не є надійною копією PR; зупиніть цей box і прогрійте свіжий замість налагодження падіння тесту продукту. Для навмисних PR з великою кількістю видалень встановіть OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1 для цього sanity-запуску.

pnpm testbox:run також завершує локальний виклик Blacksmith CLI, який залишається у фазі синхронізації понад п'ять хвилин без виводу після синхронізації. Встановіть OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0, щоб вимкнути цей guard, або використайте більше значення в мілісекундах для незвично великих локальних diff.

Crabbox — це repo-owned обгортка віддаленого box для maintainer-доказу Linux. Використовуйте її, коли перевірка занадто широка для локального циклу редагування, коли важлива парність із CI або коли доказу потрібні secrets, Docker, package-лінії, reusable boxes чи віддалені логи. Звичайний бекенд OpenClaw — blacksmith-testbox; власна місткість AWS/Hetzner є fallback для збоїв Blacksmith, проблем із квотою або явного тестування на власній місткості.

Перед першим запуском перевірте обгортку з кореня репозиторію:

pnpm crabbox:run -- --help | sed -n '1,120p'

Обгортка репозиторію відмовляється від застарілого binary Crabbox, який не рекламує blacksmith-testbox. Передавайте provider явно, навіть якщо .crabbox.yaml має стандартні налаштування owned-cloud.

Changed gate:

pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed"

Сфокусований повторний запуск тесту:

pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm test <path-or-filter>"

Повний набір:

pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm test"

Прочитайте фінальний JSON-підсумок. Корисні поля: provider, leaseId, syncDelegated, exitCode, commandMs і totalMs. Одноразові запуски Crabbox на базі Blacksmith мають автоматично зупиняти Testbox; якщо запуск перервано або cleanup незрозумілий, огляньте live boxes і зупиніть лише ті boxes, які створили ви:

blacksmith testbox list --all
blacksmith testbox status --id <tbx_id>
blacksmith testbox stop --id <tbx_id>

Використовуйте reuse лише тоді, коли вам навмисно потрібні кілька команд на тому самому гідрованому box:

pnpm crabbox:run -- --provider blacksmith-testbox --id <tbx_id> --no-sync --timing-json --shell -- "pnpm test <path-or-filter>"
pnpm crabbox:stop -- <tbx_id>

Якщо зламаним шаром є Crabbox, але сам Blacksmith працює, використовуйте прямий Blacksmith як вузький fallback:

blacksmith testbox warmup ci-check-testbox.yml --ref main --idle-timeout 90
blacksmith testbox run --id <tbx_id> "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed"
blacksmith testbox stop --id <tbx_id>

Якщо blacksmith testbox list --all і blacksmith testbox status працюють, але нові warmups залишаються queued без IP або URL запуску Actions через кілька хвилин, трактуйте це як тиск provider Blacksmith, черги, білінгу або ліміту організації. Зупиніть створені вами queued ids, не запускайте більше Testboxes і перенесіть доказ на шлях власної місткості Crabbox нижче, поки хтось перевіряє dashboard Blacksmith, білінг і ліміти організації.

Переходьте на власну місткість Crabbox лише тоді, коли Blacksmith недоступний, обмежений квотою, не має потрібного середовища або власна місткість є явною метою:

CRABBOX_CAPACITY_REGIONS=eu-west-1,eu-west-2,eu-central-1,us-east-1,us-west-2 \
  pnpm crabbox:warmup -- --provider aws --class standard --market on-demand --idle-timeout 90m
pnpm crabbox:hydrate -- --id <cbx_id-or-slug>
pnpm crabbox:run -- --id <cbx_id-or-slug> --timing-json --shell -- "env NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed"
pnpm crabbox:stop -- <cbx_id-or-slug>

Під тиском AWS уникайте class=beast, якщо завдання справді не потребує CPU класу 48xlarge. Запит beast стартує зі 192 vCPU і є найпростішим способом зачепити регіональну квоту EC2 Spot або On-Demand Standard. Repo-owned .crabbox.yaml за замовчуванням використовує standard, кілька регіонів місткості та capacity.hints: true, тож брокеровані leases AWS друкують вибрані регіон/ринок, тиск квоти, Spot fallback і попередження про клас із високим тиском. Використовуйте fast для важчих широких перевірок, large лише після того, як standard/fast недостатні, і beast лише для виняткових CPU-bound ліній, як-от повний набір або all-plugin Docker matrices, явна release/blocker-валідація чи high-core performance profiling. Не використовуйте beast для pnpm check:changed, сфокусованих тестів, docs-only роботи, звичайного lint/typecheck, малих E2E-відтворень або triage збою Blacksmith. Використовуйте --market on-demand для діагностики місткості, щоб коливання Spot-ринку не змішувалися із сигналом.

.crabbox.yaml володіє стандартними налаштуваннями provider, sync і hydration GitHub Actions для owned-cloud ліній. Він виключає локальний .git, щоб гідрований checkout Actions зберігав власні віддалені Git-метадані замість синхронізації maintainer-local remotes і object stores, і виключає локальні runtime/build artifacts, які ніколи не слід передавати. .github/workflows/crabbox-hydrate.yml володіє checkout, налаштуванням Node/pnpm, fetch origin/main і non-secret handoff середовища для owned-cloud команд crabbox run --id <cbx_id>.

Пов'язане