Files
wehub-resource-sync 426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00
..

CI/CD Workflows

This directory contains GitHub Actions workflows for the elizaOS project (v2.0.0).

Workflow Overview

Workflow Trigger Purpose
ci.yaml Push/PR to main Main-specific CI - typecheck, tests, lint, build, dev startup
test.yml Push/PR to develop, manual, schedule Broader develop tests plus required zero-key deterministic E2E; live jobs are separate
quality.yml Push/PR to main/develop, manual Develop/main quality gates: format, type-safety ratchet, prompt-secret scan, UI determinism, lint
scenario-pr.yml PR to main/develop, manual Secret-free deterministic scenario/browser E2E gate
scenario-matrix.yml Develop/manual opt-in Real-service scenario matrix; not a PR gate
pr.yaml PR opened/edited PR title validation
release.yaml Push to main, Release NPM beta/production package releases
claude.yml @claude mentions Interactive Claude assistance
claude-code-review.yml PR opened Automated code review
claude-security-review.yml PR opened Security-focused review
codeql.yml Push/PR to main, Weekly Static security analysis
docs-ci.yml PR (docs paths), Manual Documentation quality checks
build-agent-image.yml Push develop/main, Release, Manual Docker image builds (:develop, :stable, :latest, release tags)
tee-build-deploy.yml Push to main, Manual TEE deployment to Phala Cloud
weekly-maintenance.yml Weekly, Manual Dependency/security audits
jsdoc-automation.yml Manual JSDoc generation

Release Workflows

Alpha Tags

Alpha version tags are tags only. They do not publish NPM packages, run packaging CI, or create GitHub Release entries.

NPM Beta/Production Packages (release.yaml)

Publishes TypeScript/JavaScript packages to NPM.

Triggers:

  • Push to main → Beta release (@beta tag)
  • GitHub Release created → Production release (@latest tag)

Packages: All @elizaos/* packages in the monorepo

Test Workflows

Linux Runner Policy

The heavy develop test lanes in test.yml run on the self-hosted self-hosted, hetzner-robot pool (GitHub-hosted minutes are billing-frozen for this org, #13481). Everything the merge gate depends on to reach a conclusion stays GitHub-hosted so a drained fleet can never wedge develop:

  • Path classifiers (Classify changed paths) across test.yml, scenario-pr.yml, dev-smoke.yml, docker-ci-smoke.yml, mobile-build-smoke.yml, windows-dev-smoke.yml, and windows-desktop-preload-smoke.yml run on ubuntu-24.04. They are git-diff + node scripts with no self-hosted needs; pinning them to the fleet (#8501) once left every downstream job queued indefinitely and gridlocked develop.
  • ci-ok (the merge queue's sole required context), its plugin-tests-status roll-up, and the hosted merge-quality-gate all run on ubuntu-24.04.

Two SPOF guards, enforced by packages/scripts/ci-merge-gate-contract.mjs (run in the changes job, #13617):

  1. Fleet-drain toggle. Every self-hosted lane in test.yml reads runs-on: ${{ fromJSON(vars.HETZNER_FLEET_ONLINE == 'false' && '["ubuntu-24.04"]' || '["self-hosted","hetzner-robot"]') }}. Unset/anything-but-false keeps the current self-hosted placement; there is no way to probe fleet health from a runs-on: expression, so during an outage an admin sets repo variable HETZNER_FLEET_ONLINE=false once and the whole workflow falls back to hosted — one flip unblocks the entire queue instead of per-PR admin-bypass. Keep the runner-agnostic step hardening (no sudo-only install/cleanup) so lanes run on either runner type.
  2. Hosted quality parity. merge-quality-gate runs the same lint / format:check / repo-wide typecheck / gitleaks secret scan that guard main, and ci-ok needs it — so a lint, type, format, or committed-secret regression is refused by the merge queue on develop, not just on main. It runs on merge_group + develop push. The lightweight develop-pr.yml lint job also runs format:check, so formatting fails on the PR even when a busy push wave supersedes post-merge quality runs (#15959).

CodeQL is a separate exception: trusted push, scheduled, and manual CodeQL runs use self-hosted, Linux, X64, hetzner-robot because full JavaScript analysis is disk-bound and has exhausted GitHub-hosted runners during the PolynomialReDoS dataflow query. Pull-request CodeQL remains GitHub-hosted so forked code never executes on self-hosted machines. Keep the full CodeQL query surface intact; move capacity around rather than weakening security coverage. The CodeQL config may ignore deliberately invalid negative-test fixtures, but not real source files; those fixtures should stay covered by their owning tests.

GPU / KVM / macOS jobs (labels gpu-cuda-12.6, kvm, eliza-e2e-macos) are a separate purpose-built fleet and are unaffected by this policy.

PR Path Gates

PR workflows use packages/scripts/ci-path-gate.mjs to keep expensive lanes targeted. Each classifier job writes a GitHub step summary showing:

  • which files changed
  • which lanes will run
  • which path or label caused each lane to run

Maintainers can force specific lanes with labels:

Label Effect
ci:full Run every path-gated lane in workflows that honor the shared gate
ci:e2e / ci:zero-key Run deterministic zero-key E2E lanes
ci:scenario Run scenario-pr.yml deterministic scenario/browser E2E
ci:server Run server tests
ci:client Run client tests
ci:plugins Run plugin tests
ci:cloud Run cloud live E2E where secrets are configured
ci:docker Run Docker CI smoke
ci:mobile / ci:ios / ci:android Run mobile smoke, or one mobile platform
ci:desktop / ci:windows Run desktop and Windows smoke lanes
ci:dev-smoke Run the bun run dev onboarding smoke

Push, scheduled, and manual runs keep their broader/default behavior; the path gate mainly keeps PR feedback fast and explainable.

Why this exists:

  • OSS contributors should get useful feedback quickly without waiting on unrelated mobile, Docker, desktop, Windows, or browser-heavy lanes.
  • Maintainers should be able to see why a lane ran or skipped from the job summary, without reverse-engineering shell conditionals.
  • The quality gate should stay equivalent for affected code. Path gates decide which surface is relevant; they do not replace the tests for that surface.
  • Push, scheduled, and manual runs remain broad because they protect branch health, release readiness, and nightly confidence rather than one PR diff.

Quality contract:

  • Any path-gated lane must be forced by ci:full.
  • Every expensive lane needs a matching force label so maintainers can request coverage without pushing a no-op commit.
  • Workflow, shared setup, toolchain, lockfile, and classifier changes should run the affected expensive lanes because they can change CI behavior even when product code did not move.
  • The Tests workflow runs the classifier self-test before consuming classifier outputs. That self-test covers representative path matches and label forcing so a future edit cannot silently weaken the broadest PR test gate.
  • When splitting a long lane, keep the same substantive commands unless the PR explicitly documents the safety reason for removing one.

Long deterministic E2E gates are split into named parallel slices for unit/UI coverage, browser coverage, diagnostics, and scenario execution. The visible Zero-Key Deterministic E2E check is an aggregate status over those slices, so reviewers can see the failing surface without opening one giant serial log.

Plugin tests are also split across TEST_SHARD=1/4 through 4/4 in the Tests workflow. The root test:plugins script uses the cross-package runner so shard membership is deterministic by package path, while the visible Plugin Tests check remains an aggregate over the shard matrix.

Why the aggregate stays:

  • Branch protection and reviewer muscle memory can keep using one stable check.
  • The underlying slices can run in parallel and fail with precise names.
  • Manual review becomes easier because a browser failure, diagnostics failure, or scenario-runner failure points at the relevant log immediately.

Related CI docs:

  • CHANGELOG.md records workflow policy changes and the reason they happened.
  • ROADMAP.md tracks future CI performance work that should preserve gate quality.

Main CI (ci.yaml)

Runs on PRs and pushes to main:

  • Typecheck + core/plugin tests
  • Linting and formatting checks
  • Build verification
  • Dev startup + HMR propagation
  • Interop TypeScript tests (packages/interop)

The broader test.yml orchestrator runs automatically on develop only to avoid duplicating the main-branch CI gate. Secret-free deterministic zero-key coverage for PRs to either protected branch is handled by scenario-pr.yml; test.yml keeps the broader develop push/PR, manual, and scheduled coverage.

Live E2E

PR E2E does not require CEREBRAS_API_KEY, OPENAI_API_KEY, or any other paid provider key. Live/provider-key coverage belongs to the dedicated live jobs and workflows (cloud-live-e2e, provider-live-e2e, live-scenarios.yml, scenario-matrix.yml) where missing-key behavior is documented per lane.

Code Review Workflows

Claude Code Review (claude-code-review.yml)

Automated PR review using Claude. Checks for:

  • Security issues (hardcoded keys, SQL injection, XSS)
  • Test coverage
  • TypeScript types (no any)
  • Correct tooling (bun, vitest)

Claude Security Review (claude-security-review.yml)

Dedicated security-focused review for code changes.

Claude Interactive (claude.yml)

Responds to @claude mentions in issues and PRs.

Documentation Workflows

Docs CI (docs-ci.yml)

Documentation quality workflow:

  • Dead Link Checking: Scans for broken internal/external links
  • Quality Checks: Double headers, missing frontmatter, heading hierarchy

Automatically creates PRs with fixes when issues are found.

JSDoc Automation (jsdoc-automation.yml)

Manual workflow for generating JSDoc documentation.

Manual Release Process

1. Create a GitHub Release

  1. Go to Releases → Create new release
  2. Create a new tag: v2.0.0 (follows semver)
  3. Add release notes
  4. Publish release

2. Automated Publishing

The release will trigger:

  • release.yaml → NPM packages

3. Manual publishing

Use bunx lerna publish from the repo root when automation is not sufficient (see release.yaml).

Setting Up Secrets

Required Secrets

Secret Purpose How to Get
NPM_TOKEN NPM publishing npmjs.com/settings/~/tokens
ANTHROPIC_API_KEY Claude workflows console.anthropic.com
OPENAI_API_KEY Opt-in live/provider-key lanes platform.openai.com

Optional Secrets

Secret Purpose
PHALA_CLOUD_API_KEY TEE deployment
GH_PAT Cross-repo operations

Turbo caching is GitHub-native (.github/actions/turbo-cache-github via setup-bun-workspace) — no Vercel SaaS remote cache, so TURBO_TOKEN / TURBO_TEAM are no longer used and are banned by ci-workflow-dedup-contract.mjs (#12341).

Package dependencies

NPM packages are ordered by the monorepo graph; release.yaml / Lerna handle publish ordering for @elizaos/* packages.

Troubleshooting

CI Failures

  1. Check if tests pass locally: bun run test
  2. Check formatting: bun run format:check
  3. Check linting: bun run lint

Release Failures

  1. Verify secrets are configured
  2. Check workflow logs for specific errors
  3. For NPM: ensure package versions are unique

Claude Workflow Issues

  1. Verify ANTHROPIC_API_KEY is set
  2. Check rate limits on Anthropic API
  3. Review Claude's output in workflow logs