Files
wehub-resource-sync 9e8f1bbeed
Dashboard / frontend (push) Failing after 0s
Dashboard / api (push) Failing after 0s
Lint PowerShell / powershell-lint (ubuntu-latest) (push) Failing after 1s
Python Lint / Lint Python with Ruff (push) Failing after 1s
ShellCheck / Lint shell scripts (push) Failing after 1s
Matrix Smoke / linux-smoke (push) Failing after 1s
Matrix Smoke / distro: cachyos (push) Failing after 15s
Matrix Smoke / distro: linux-mint-21.3 (push) Failing after 15s
Matrix Smoke / distro: debian-12 (push) Failing after 5m21s
Matrix Smoke / distro: fedora-41 (push) Failing after 4m56s
Matrix Smoke / distro: ubuntu-24.04 (push) Failing after 2m13s
Matrix Smoke / distro: rocky-9 (push) Failing after 10m39s
Matrix Smoke / distro: manjaro (push) Failing after 12m11s
Matrix Smoke / distro: opensuse-tw (push) Failing after 11m53s
Matrix Smoke / distro: archlinux (push) Failing after 20m3s
Matrix Smoke / distro: ubuntu-22.04 (push) Failing after 13m49s
Validate .env Schema / tier-1-env-validation (push) Successful in 52s
Validate .env Schema / tier-2-env-validation (push) Successful in 44s
Validate .env Schema / tier-3-env-validation (push) Successful in 52s
Validate .env Schema / tier-4-env-validation (push) Successful in 51s
Validate Extensions Catalog / Check catalog is up-to-date (push) Failing after 9m47s
Secret Scan / Scan for secrets (push) Failing after 21m4s
Validate Docker Compose / Validate Docker Compose files (push) Has been cancelled
Python Type Check / Type check with mypy (push) Has been cancelled
Validate .env Schema / tier-0-env-validation (push) Has been cancelled
Test Linux / integration-smoke (push) Has been cancelled
Lint PowerShell / powershell-lint (windows-latest) (push) Has been cancelled
Matrix Smoke / macos-smoke (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:33 +08:00

113 lines
4.7 KiB
Bash

#!/usr/bin/env bash
# Regression checks for Linux cloud mode. Cloud/external LLM installs must not
# require a local llama-server container or local-mode dependency overlays.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
pass() { printf '[PASS] %s\n' "$1"; }
fail() { printf '[FAIL] %s\n' "$1" >&2; exit 1; }
contains() {
local haystack="$1" needle="$2" label="$3"
[[ "$haystack" == *"$needle"* ]] && pass "$label" || fail "$label"
}
rejects() {
local haystack="$1" needle="$2" label="$3"
[[ "$haystack" != *"$needle"* ]] && pass "$label" || fail "$label"
}
PY="${ODS_PYTHON_CMD:-}"
if [[ -z "$PY" ]]; then
if command -v python3 >/dev/null 2>&1; then
PY=python3
elif command -v python >/dev/null 2>&1; then
PY=python
else
fail "python is required"
fi
fi
flags="$(ODS_PYTHON_CMD="$PY" ./scripts/resolve-compose-stack.sh \
--script-dir "$ROOT_DIR" \
--tier CLOUD \
--gpu-backend cpu \
--gpu-count 0 \
--ods-mode cloud)"
flags="${flags//\\//}"
contains "$flags" "docker-compose.base.yml" "cloud mode keeps base stack"
contains "$flags" "docker-compose.cloud.yml" "cloud mode layers cloud overlay"
contains "$flags" "extensions/services/litellm/compose.yaml" "cloud mode includes LiteLLM gateway"
rejects "$flags" "docker-compose.cpu.yml" "cloud mode does not include CPU llama-server overlay"
rejects "$flags" "compose.local.yaml" "cloud mode does not include local dependency overlays"
lemonade_flags="$(LEMONADE_EXTERNAL=true AMD_INFERENCE_RUNTIME=lemonade AMD_INFERENCE_MANAGED=false ODS_PYTHON_CMD="$PY" ./scripts/resolve-compose-stack.sh \
--script-dir "$ROOT_DIR" \
--tier CLOUD \
--gpu-backend cpu \
--gpu-count 0 \
--ods-mode lemonade)"
lemonade_flags="${lemonade_flags//\\//}"
contains "$lemonade_flags" "docker-compose.base.yml" "external Lemonade keeps base stack"
contains "$lemonade_flags" "docker-compose.cloud.yml" "external Lemonade profiles managed llama-server out"
contains "$lemonade_flags" "docker-compose.lemonade-external.yml" "external Lemonade layers dedicated overlay"
rejects "$lemonade_flags" "docker-compose.cpu.yml" "external Lemonade does not include CPU llama-server overlay"
if grep -q 'profiles:' docker-compose.cloud.yml && grep -q 'local-inference' docker-compose.cloud.yml; then
pass "cloud overlay profiles local llama-server out of default startup"
else
fail "cloud overlay must profile local llama-server out of default startup"
fi
if grep -Fq -- '--ods-mode "${ODS_MODE:-local}"' installers/lib/compose-select.sh \
&& grep -Fq -- '--ods-mode "${ODS_MODE:-local}"' installers/phases/03-features.sh \
&& grep -Fq -- '--ods-mode "${ODS_MODE:-local}"' installers/phases/11-services.sh \
&& grep -Fq -- '--ods-mode "${ODS_MODE:-local}"' ods-cli; then
pass "installer and CLI pass ods mode to compose resolver"
else
fail "all installer/CLI resolver calls must pass --ods-mode"
fi
if grep -q 'ODS_MODE:-local.*cloud' installers/phases/12-health.sh \
&& grep -Fq 'LiteLLM' installers/phases/12-health.sh \
&& grep -Fq 'skipping local llama-server pre-warm' installers/phases/12-health.sh; then
pass "cloud health path skips local llama-server"
else
fail "cloud health path must skip local llama-server"
fi
if grep -Fq 'image: ${HERMES_AGENT_IMAGE:-nousresearch/hermes-agent:v2026.5.16}' extensions/services/hermes/compose.yaml \
&& grep -Fq '${HERMES_AGENT_IMAGE:-nousresearch/hermes-agent:v2026.5.16}|HERMES' installers/phases/08-images.sh \
&& grep -Fq 'HERMES_AGENT_IMAGE_FALLBACK' installers/phases/08-images.sh \
&& ! grep -R -q 'nousresearch/hermes-agent:sha-' extensions/services/hermes installers/phases config/dependency-lock.json; then
pass "Hermes image default is resolvable and overrideable for cloud installs"
else
fail "Hermes image default must not rely on removed sha-* Docker tags"
fi
"$PY" - "$ROOT_DIR" <<'PY'
from pathlib import Path
import sys
root = Path(sys.argv[1])
text = (root / "installers/phases/11-services.sh").read_text(encoding="utf-8")
model_config = text.index('mkdir -p "$INSTALL_DIR/config/llama-server"')
hermes_block = text.index('if [[ "${ENABLE_HERMES:-false}" == "true" ]]; then')
soul_block = text.index('_soul_output="$INSTALL_DIR/data/persona/SOUL.md"')
if model_config < hermes_block < soul_block:
# Make sure the local-model block was closed before Hermes/SOUL rendering begins.
between = text[model_config:hermes_block]
if '\n fi\n' in between:
print("[PASS] SOUL.md render is outside local-model-only block")
sys.exit(0)
print("[FAIL] SOUL.md render must run for cloud installs too", file=sys.stderr)
sys.exit(1)
PY
echo "[PASS] linux cloud mode contracts"