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
405 lines
19 KiB
YAML
405 lines
19 KiB
YAML
name: "Setup Bun Workspace"
|
|
description: "Install Bun workspace dependencies and required native deps for eliza CI jobs."
|
|
|
|
inputs:
|
|
bun-version:
|
|
description: "Bun version to install"
|
|
required: false
|
|
default: "canary"
|
|
python-version:
|
|
description: "Python version for node-gyp fallbacks"
|
|
required: false
|
|
default: "3.12"
|
|
setup-python:
|
|
description: "Whether to set up Python for node-gyp fallbacks"
|
|
required: false
|
|
default: "true"
|
|
install-protoc:
|
|
description: "Whether to install protoc for Rust plugin builds"
|
|
required: false
|
|
default: "true"
|
|
force-protoc-github-fallback:
|
|
description: "Force the pinned GitHub protoc fallback path for setup action self-tests"
|
|
required: false
|
|
default: "false"
|
|
install-command:
|
|
description: "Dependency install command"
|
|
required: false
|
|
default: "bun install --frozen-lockfile --ignore-scripts"
|
|
install-native-deps:
|
|
description: "Whether to install native apt dependencies"
|
|
required: false
|
|
default: "true"
|
|
run-postinstall:
|
|
description: "Whether to run the repo postinstall step explicitly"
|
|
required: false
|
|
default: "true"
|
|
skip-avatar-clone:
|
|
description: "Set SKIP_AVATAR_CLONE=1 for postinstall"
|
|
required: false
|
|
default: "false"
|
|
no-vision-deps:
|
|
description: "Set ELIZA_NO_VISION_DEPS=1 for postinstall"
|
|
required: false
|
|
default: "false"
|
|
init-submodules:
|
|
description: "Run `git submodule update --init --recursive` before install"
|
|
required: false
|
|
default: "false"
|
|
setup-node:
|
|
description: >-
|
|
Whether to set up Node.js. Self-hosted runners are not guaranteed to have
|
|
`node` on PATH, and this action's very first step (turbo-cache-key) shells
|
|
out to `node`, so leave this on unless the caller already ran
|
|
actions/setup-node in the same job.
|
|
required: false
|
|
default: "true"
|
|
node-version:
|
|
description: "Node.js version to set up when setup-node is true"
|
|
required: false
|
|
default: "24"
|
|
|
|
runs:
|
|
using: "composite"
|
|
steps:
|
|
# Self-hosted (hetzner-robot) runners are not guaranteed to expose `node`
|
|
# on the step PATH, and the very next step (turbo-cache-github ->
|
|
# turbo-cache-key.mjs) invokes `node` directly. Without this, jobs that
|
|
# rely solely on this composite for their toolchain (coverage-gate,
|
|
# feed-env-audit, scenario-matrix, voice-workbench) fail with
|
|
# "node: command not found" on runners missing a system Node. setup-node is
|
|
# idempotent, so callers that already ran it (keyless-harness, the audits)
|
|
# just re-select the same version. Toggle off via setup-node: "false".
|
|
- name: Setup Node.js
|
|
if: ${{ inputs.setup-node == 'true' }}
|
|
# actions/setup-node@v4 (48b55a0)
|
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
|
|
with:
|
|
node-version: ${{ inputs.node-version }}
|
|
|
|
# Persist Turbo's local filesystem cache (.turbo) through the pinned
|
|
# GitHub-native shim (#12341) — the single Turbo cache regime, replacing the
|
|
# Vercel SaaS remote cache. The shim keys on the deterministic
|
|
# turbo-cache-key hash with no github.job fragment, so one entry is shared
|
|
# across every job instead of the ~30-way fragmentation the old per-job key
|
|
# caused; Turbo re-validates task hashes on restore, so a cross-job hit is
|
|
# always safe. This keeps the full 14-way typecheck off the runner on warm
|
|
# caches (cold ran it OOM/SIGTERM). No SaaS, no secrets; a miss is non-fatal.
|
|
- name: Restore Turbo cache (GitHub-native)
|
|
uses: ./.github/actions/turbo-cache-github
|
|
|
|
# actions/setup-python@v6 downloads a CPython build requiring the
|
|
# x86-64-v3 CPU baseline; some [self-hosted, hetzner-robot] runners expose
|
|
# a lower ISA and the download aborts with "CPU ISA level is lower than
|
|
# required" (exit 127), killing the whole step even though Python here is
|
|
# only a best-effort node-gyp fallback (#14188). GitHub-hosted runners are
|
|
# never affected, so this probe (and the fallback it enables) only runs on
|
|
# self-hosted runners via runner.environment — hosted CI takes the
|
|
# untouched actions/setup-python@v6 path below.
|
|
- name: Detect usable system Python (self-hosted ISA guard)
|
|
id: system-python
|
|
if: ${{ inputs.setup-python == 'true' && runner.environment == 'self-hosted' }}
|
|
shell: bash
|
|
run: |
|
|
if command -v python3 >/dev/null 2>&1 && python3 -c "import sys" >/dev/null 2>&1; then
|
|
echo "python-bin=$(command -v python3)" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Setup Python
|
|
if: ${{ inputs.setup-python == 'true' && steps.system-python.outputs.python-bin == '' }}
|
|
# Skipped outright when the probe above found a usable system Python.
|
|
# If it didn't (a self-hosted runner with no system python3 either),
|
|
# don't let an ISA-incompatible download turn into a hard job failure —
|
|
# hosted runners are never in this branch and keep fail-fast behavior.
|
|
continue-on-error: ${{ runner.environment == 'self-hosted' }}
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: ${{ inputs.python-version }}
|
|
|
|
- name: Install setuptools for distutils (Python 3.12+)
|
|
if: ${{ inputs.setup-python == 'true' }}
|
|
shell: bash
|
|
env:
|
|
RUNNER_ENVIRONMENT: ${{ runner.environment }}
|
|
run: |
|
|
python_bin="${{ steps.system-python.outputs.python-bin }}"
|
|
if [ -z "$python_bin" ]; then
|
|
python_bin="python3"
|
|
fi
|
|
if ! command -v "$python_bin" >/dev/null 2>&1; then
|
|
echo "::warning::No usable python3 found; skipping setuptools install (node-gyp fallback unavailable)"
|
|
exit 0
|
|
fi
|
|
if "$python_bin" -c 'import setuptools' >/dev/null 2>&1; then
|
|
echo "setuptools already present: $("$python_bin" -c 'import setuptools; print(setuptools.__version__)')"
|
|
exit 0
|
|
fi
|
|
if "$python_bin" - <<'PY'
|
|
import sys
|
|
raise SystemExit(0 if sys.version_info < (3, 12) else 1)
|
|
PY
|
|
then
|
|
echo "Python <3.12; setuptools distutils shim is not required"
|
|
exit 0
|
|
fi
|
|
if ! "$python_bin" -m pip --version >/dev/null 2>&1; then
|
|
if [ "$RUNNER_ENVIRONMENT" = "self-hosted" ]; then
|
|
echo "::warning::No usable pip found; skipping setuptools install (node-gyp fallback unavailable)"
|
|
exit 0
|
|
fi
|
|
echo "::error::No usable pip found for setuptools install"
|
|
exit 1
|
|
fi
|
|
"$python_bin" -m pip install setuptools \
|
|
|| "$python_bin" -m pip install --user setuptools \
|
|
|| "$python_bin" -m pip install --break-system-packages setuptools
|
|
|
|
- name: Install protoc
|
|
# protoc is required even when install-native-deps=false because Rust
|
|
# plugins (plugin-{discord,groq,openai,sql,whatsapp}) depend on the
|
|
# crates.io `elizaos` crate whose build script invokes prost-build.
|
|
# Without protoc, `cargo test` fails before any test runs.
|
|
if: ${{ inputs.install-protoc == 'true' && runner.os == 'Linux' }}
|
|
shell: bash
|
|
env:
|
|
FORCE_PROTOC_GITHUB_FALLBACK: ${{ inputs.force-protoc-github-fallback }}
|
|
PROTOC_RUNNER_ARCH: ${{ runner.arch }}
|
|
run: |
|
|
if [ "${FORCE_PROTOC_GITHUB_FALLBACK}" != "true" ] && command -v protoc >/dev/null 2>&1; then
|
|
echo "protoc already installed: $(protoc --version)"
|
|
exit 0
|
|
fi
|
|
apt_ok=""
|
|
if [ "${FORCE_PROTOC_GITHUB_FALLBACK}" = "true" ]; then
|
|
echo "forcing protoc GitHub fallback for setup action self-test"
|
|
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
|
|
# GitHub-hosted Ubuntu images include Microsoft feeds that are unrelated
|
|
# to our protoc install. If those feeds return 403, apt-get update fails
|
|
# before it can use the Ubuntu repositories we actually need.
|
|
while IFS= read -r source_file; do
|
|
if [[ "${source_file}" == *.disabled ]]; then
|
|
echo "Microsoft apt source already disabled: ${source_file}"
|
|
continue
|
|
fi
|
|
echo "Disabling unrelated Microsoft apt source: ${source_file}"
|
|
sudo mv "${source_file}" "${source_file}.disabled"
|
|
done < <(grep -RIl "packages.microsoft.com" /etc/apt/sources.list.d 2>/dev/null || true)
|
|
APT_ARGS=(-o Acquire::ForceIPv4=true -o Acquire::Retries=5 -o Acquire::http::Timeout=30)
|
|
for attempt in 1 2 3; do
|
|
if sudo apt-get "${APT_ARGS[@]}" update && \
|
|
sudo apt-get "${APT_ARGS[@]}" install -y --fix-missing protobuf-compiler; then
|
|
apt_ok=1
|
|
break
|
|
fi
|
|
sleep $((attempt * 10))
|
|
done
|
|
fi
|
|
if [ -z "$apt_ok" ]; then
|
|
# Sudo-free fallback: fetch the pinned protoc release into a user-writable
|
|
# dir and put it on PATH. Works on self-hosted runners without passwordless
|
|
# sudo or when Ubuntu mirrors fail. The checksum keeps the privileged
|
|
# build dependency from trusting an unauthenticated release asset.
|
|
echo "apt unavailable/failed; installing protoc from GitHub release (sudo-free)"
|
|
protoc_version=27.3
|
|
case "${PROTOC_RUNNER_ARCH}" in
|
|
X64)
|
|
protoc_asset_arch=x86_64
|
|
protoc_sha256=6dab2adab83f915126cab53540d48957c40e9e9023969c3e84d44bfb936c7741
|
|
;;
|
|
ARM64)
|
|
protoc_asset_arch=aarch_64
|
|
protoc_sha256=bdad36f3ad7472281d90568c4956ea2e203c216e0de005c6bd486f1920f2751c
|
|
;;
|
|
*)
|
|
echo "unsupported Linux runner architecture for protoc fallback: ${PROTOC_RUNNER_ARCH}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
dest="${RUNNER_TEMP:-/tmp}/protoc"
|
|
rm -rf "$dest"
|
|
mkdir -p "$dest"
|
|
for attempt in 1 2 3; do
|
|
if curl -fsSL --retry 5 --retry-all-errors -o "$dest/protoc.zip" \
|
|
"https://github.com/protocolbuffers/protobuf/releases/download/v${protoc_version}/protoc-${protoc_version}-linux-${protoc_asset_arch}.zip"; then
|
|
break
|
|
fi
|
|
if [ "$attempt" -eq 3 ]; then
|
|
echo "protoc GitHub release download failed after ${attempt} attempts"
|
|
exit 1
|
|
fi
|
|
sleep $((attempt * 10))
|
|
done
|
|
echo "${protoc_sha256} $dest/protoc.zip" | sha256sum -c -
|
|
unzip -o "$dest/protoc.zip" -d "$dest" 'bin/protoc' 'include/*'
|
|
chmod +x "$dest/bin/protoc"
|
|
echo "$dest/bin" >> "$GITHUB_PATH"
|
|
export PATH="$dest/bin:$PATH"
|
|
fi
|
|
protoc --version
|
|
|
|
- name: Install native dependencies
|
|
if: ${{ inputs.install-native-deps == 'true' && runner.os == 'Linux' }}
|
|
shell: bash
|
|
run: |
|
|
if ! command -v sudo >/dev/null 2>&1 || ! sudo -n true 2>/dev/null; then
|
|
echo "::warning::passwordless sudo unavailable; skipping native apt deps (assuming runner image is pre-provisioned)"
|
|
else
|
|
# Some CI runners intermittently fail reaching Ubuntu mirrors over IPv6.
|
|
# Force IPv4 and retry apt commands so CI setup is resilient. Also
|
|
# disable unrelated Microsoft feeds because their 403s make apt-get
|
|
# update fail before Ubuntu packages can install.
|
|
while IFS= read -r source_file; do
|
|
if [[ "${source_file}" == *.disabled ]]; then
|
|
echo "Microsoft apt source already disabled: ${source_file}"
|
|
continue
|
|
fi
|
|
echo "Disabling unrelated Microsoft apt source: ${source_file}"
|
|
sudo mv "${source_file}" "${source_file}.disabled"
|
|
done < <(grep -RIl "packages.microsoft.com" /etc/apt/sources.list.d 2>/dev/null || true)
|
|
APT_ARGS=(-o Acquire::ForceIPv4=true -o Acquire::Retries=5 -o Acquire::http::Timeout=30)
|
|
for attempt in 1 2 3; do
|
|
if sudo apt-get "${APT_ARGS[@]}" update && \
|
|
sudo apt-get "${APT_ARGS[@]}" install -y --fix-missing \
|
|
build-essential libcairo2-dev libpango1.0-dev libjpeg-dev \
|
|
libgif-dev libpixman-1-dev librsvg2-dev; then
|
|
break
|
|
fi
|
|
if [ "$attempt" -eq 3 ]; then
|
|
echo "apt install failed after ${attempt} attempts"
|
|
exit 1
|
|
fi
|
|
sleep $((attempt * 10))
|
|
done
|
|
fi
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ inputs.bun-version }}
|
|
|
|
- name: Cache Bun install
|
|
# Cache the Bun install store on every OS, Linux included (#12338). A miss
|
|
# just means no speedup and a cache write failure is non-fatal, so this is
|
|
# additive: worst case a cold Linux runner behaves exactly as before while
|
|
# warm runners skip re-downloading the dependency tarballs. Pinned by SHA
|
|
# (no floating @v5) to avoid the Bun/cache-action drift #12338 targets.
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
|
|
with:
|
|
path: ~/.bun/install/cache
|
|
key: bun-${{ runner.os }}-${{ inputs.bun-version }}-${{ hashFiles('bun.lock') }}
|
|
restore-keys: |
|
|
bun-${{ runner.os }}-${{ inputs.bun-version }}-
|
|
bun-${{ runner.os }}-
|
|
|
|
- name: Initialize submodules
|
|
if: ${{ inputs.init-submodules == 'true' }}
|
|
shell: bash
|
|
run: git submodule update --init --recursive
|
|
|
|
- name: Install dependencies
|
|
shell: bash
|
|
run: |
|
|
install_command="${{ inputs.install-command }}"
|
|
for attempt in 1 2; do
|
|
install_log="$(mktemp)"
|
|
if bash -lc "$install_command" 2>&1 | tee "$install_log"; then
|
|
rm -f "$install_log"
|
|
exit 0
|
|
fi
|
|
install_status=${PIPESTATUS[0]}
|
|
if grep -q "lockfile had changes, but lockfile is frozen" "$install_log" && \
|
|
[[ "$install_command" == *"--frozen-lockfile"* ]]; then
|
|
fallback_command="${install_command/--frozen-lockfile/--no-frozen-lockfile}"
|
|
echo "::warning::Bun reported frozen lockfile drift; falling back to a non-frozen install."
|
|
if bash -lc "$fallback_command"; then
|
|
# The frozen install above is the canonical lockfile-drift signal.
|
|
# When it fails we fall back to a non-frozen install — but Bun
|
|
# canary (this repo tracks `bun-version: canary`) reserializes
|
|
# bun.lock byte-for-byte between versions even when the resolved
|
|
# dependency graph is identical, so a `git diff` here fails on
|
|
# serialization noise rather than real drift. Restore the committed
|
|
# lockfile after installing; the dedicated lockfile-drift gates
|
|
# (cloud-gateway-*, cache-key-stability) still catch genuine drift.
|
|
if ! git diff --quiet -- bun.lock; then
|
|
echo "::warning::bun.lock changed during install (bun-canary reserialization); restoring the committed lockfile."
|
|
git checkout -- bun.lock
|
|
fi
|
|
rm -f "$install_log"
|
|
exit 0
|
|
fi
|
|
fi
|
|
rm -f "$install_log"
|
|
if [ "$attempt" -eq 2 ]; then
|
|
exit "$install_status"
|
|
fi
|
|
echo "Dependency install failed; retrying once after cleaning Bun's install cache."
|
|
node packages/scripts/rm-path-recursive.mjs ~/.bun/install/cache
|
|
sleep 5
|
|
done
|
|
env:
|
|
# When the system-Python guard above found a usable interpreter,
|
|
# `pythonLocation` is never set (actions/setup-python@v6 was skipped),
|
|
# so prefer the probed binary and only fall back to the downloaded
|
|
# toolcache path.
|
|
npm_config_python: ${{ steps.system-python.outputs.python-bin || format('{0}/bin/python3', env.pythonLocation) }}
|
|
|
|
- name: Materialize bun npm package binary
|
|
if: ${{ runner.os != 'Windows' }}
|
|
# The default install command uses --ignore-scripts so trustedDependencies
|
|
# postinstalls don't run silently. The `bun` npm package ships a placeholder
|
|
# binary that errors with "Bun's postinstall script was not run" until its
|
|
# own install.js downloads the real binary; run it explicitly so any
|
|
# subsequent `bun ...` invocation (including the repo postinstall) works.
|
|
#
|
|
# Bun's hoisted install layout puts the package at
|
|
# node_modules/.bun/bun@<ver>/node_modules/bun/install.js rather
|
|
# than the legacy node_modules/bun/install.js, so check the
|
|
# hoisted path too. Recent bun versions nest deeper (the cache
|
|
# uses content-addressable hash dirs); raised maxdepth from 4 to
|
|
# 8 and added a final unbounded fallback so every layout we've
|
|
# seen in the wild gets caught.
|
|
shell: bash
|
|
run: |
|
|
install_js=""
|
|
if [ -f node_modules/bun/install.js ]; then
|
|
install_js="node_modules/bun/install.js"
|
|
elif [ -d node_modules/.bun ]; then
|
|
install_js="$(find node_modules/.bun -maxdepth 8 -path '*/bun@*/node_modules/bun/install.js' -print -quit 2>/dev/null)"
|
|
fi
|
|
# Final fallback: scan the whole node_modules tree (slower but
|
|
# exhaustive). Skip if we already found one above.
|
|
if { [ -z "$install_js" ] || [ ! -f "$install_js" ]; } && [ -d node_modules ]; then
|
|
install_js="$(find node_modules -path '*/bun/install.js' -print -quit 2>/dev/null)"
|
|
fi
|
|
if [ -n "$install_js" ] && [ -f "$install_js" ]; then
|
|
echo "Running bun postinstall: $install_js"
|
|
(cd "$(dirname "$install_js")" && node install.js)
|
|
else
|
|
echo "::warning::No bun/install.js found; downstream bun run calls may fail"
|
|
fi
|
|
|
|
- name: Run repository postinstall
|
|
if: ${{ inputs.run-postinstall == 'true' }}
|
|
shell: bash
|
|
run: bun run postinstall
|
|
env:
|
|
SKIP_AVATAR_CLONE: ${{ inputs.skip-avatar-clone == 'true' && '1' || '' }}
|
|
ELIZA_NO_VISION_DEPS: ${{ inputs.no-vision-deps == 'true' && '1' || '' }}
|
|
|
|
- name: Ensure workspace + native-plugin symlinks (postinstall safety net)
|
|
# `bun run postinstall` chains `bun scripts/patch-*` steps before
|
|
# `ensure-workspace-symlinks.mjs` / `ensure-native-plugins-linked.mjs`;
|
|
# if a `bun` invocation fails partway (e.g. the placeholder binary),
|
|
# those symlinks never get created and downstream vitest jobs hit
|
|
# "Failed to resolve entry for @elizaos/<workspace-pkg>". Run them
|
|
# explicitly with `node` (always available) so the symlinks exist
|
|
# regardless of how postinstall fared. Both scripts are idempotent.
|
|
shell: bash
|
|
run: |
|
|
node packages/scripts/ensure-workspace-symlinks.mjs || echo "::warning::ensure-workspace-symlinks failed"
|
|
node packages/scripts/ensure-native-plugins-linked.mjs || echo "::warning::ensure-native-plugins-linked failed"
|
|
|
|
- name: Ensure generated shared i18n data
|
|
shell: bash
|
|
run: node packages/app-core/scripts/ensure-shared-i18n-data.mjs
|