Files
molecule-ai-workspace-runtime/.gitea/workflows/ci.yml
T
Molecule AI Dev Engineer A (Kimi) 2f9bf0bf5b test(boot): real-subprocess regression gate for build_routes 4-branch path (#88)
- Add tests/test_boot_routes_subprocess.py that exercises build_routes in
  child Python processes (no conftest a2a stubs) across all 4 branches:
  A executor happy-path, B not-configured fallback, C error surfacing,
  D empty-input defensive guard.
- Add an explicit CI step so the gate is visible and a missing real a2a-sdk
  shows up as a loud skip, not a silent green.

Fixes molecule-ai-workspace-runtime#88

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-27 00:42:13 +00:00

189 lines
7.3 KiB
YAML

name: ci
# Standalone-as-SSOT CI (post-migration 2026-05-20).
#
# This repo became the single source of truth for the molecule-runtime
# Python package as of the standalone-as-SSOT migration (issue #87
# follow-on, CTO-GO 2026-05-20). Edit Python under molecule_runtime/
# directly here; the monorepo workspace-server pins this wheel by
# version.
#
# Old mirror-guard CI removed — direct PRs are the canonical edit path.
on:
push:
branches: [main, staging]
pull_request:
permissions:
contents: read
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
- name: Install test dependencies
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: |
# Install the editable package so CI exercises pyproject.toml's
# runtime dependency contract. This intentionally catches SDK/API
# drift in package-local adapter tests, not only tests under tests/.
pip install -e . pytest pytest-asyncio
- name: Run unit tests
# Exclude the over-the-wire responsiveness e2e (its own job below) —
# it boots real uvicorn servers and a 50s busy window, too slow for
# the fast unit lane.
run: pytest -q --ignore=tests/integration
- name: Run build_routes real-subprocess regression gate
# Explicit, loud step for issue #88: the 4-branch build_routes contract
# must be exercised against the REAL a2a-sdk in child processes. A skip
# here means the real SDK is missing and the gate is inert.
run: pytest -v -rs tests/test_boot_routes_subprocess.py
responsiveness-e2e:
# Deterministic, merge-BLOCKING integration gate for the "busy agent
# becomes unreachable / blocks ~300s" regression class (2026-06-10).
#
# It drives a REAL RuntimeA2AExecutor mounted in REAL a2a-sdk JSON-RPC
# Starlette routes served by REAL uvicorn, over REAL HTTP, and asserts:
# (a) a concurrent same-context POST fast-acks (no head-of-line block)
# — locks in the non-blocking flip (#116);
# (b) the agent never goes 'stale' across a busy window that EXCEEDS
# the old 45s stale threshold — locks in the stale-window fix;
# (c) both turns complete + the agent recovers to idle;
# (d) a tool that hangs past the per-turn idle cap is bounded and the
# executor recovers instead of wedging — locks in A1 tool-timeout.
#
# No external creds / infra (localhost only + a scripted, LLM-free
# agent), so it is a deterministic merge gate — NOT a gated-nightly.
# The integration conftest LOUD-SKIPS (never silent-passes) if the real
# a2a-sdk wheel is somehow absent.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
- name: Install test dependencies
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: |
# -e . pulls the REAL a2a-sdk[http-server] + starlette + uvicorn +
# httpx so the e2e exercises the production wire, not stubs.
pip install -e . pytest pytest-asyncio
- name: Run agent-responsiveness-under-load e2e
# CI-tuned timings: the busy window (50s) still comfortably EXCEEDS
# the asserted stale window (20s), so the >45s-stale-window contract
# is genuinely exercised, while keeping the job ~1 min. All timings
# are env-tunable so a slower runner can widen slack without code
# edits.
env:
RESP_E2E_A_BUSY_SECONDS: "50"
RESP_E2E_STALE_WINDOW_SECONDS: "20"
RESP_E2E_HEARTBEAT_INTERVAL: "4"
RESP_E2E_FAST_ACK_CEILING: "5"
RESP_E2E_IDLE_CAP: "3"
RESP_E2E_POLL_DEADLINE: "25"
run: pytest -q tests/integration
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
- name: Install ruff
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: pip install ruff
- name: Lint with ruff (syntax + obvious errors only)
# Initial lint scope is intentionally narrow — E9 (syntax), F (pyflakes
# errors only, not warnings). Broadening to full ruff rules is a
# follow-up task once the SSOT settles.
run: ruff check --select=E9,F63,F7,F82 molecule_runtime/
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
- name: Install build tooling
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: pip install build twine
- name: Build wheel + sdist
run: python -m build
- name: Verify package metadata
run: python -m twine check dist/*
- name: Upload wheel artifact
uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3
with:
name: wheel
path: dist/*.whl
retention-days: 7
smoke-install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
- name: Build local wheel for smoke install
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: |
pip install build
python -m build --wheel
- name: Install wheel in clean venv + smoke-import
env:
PIP_INDEX_URL: https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/
run: |
set -eu
python -m venv /tmp/smoke-venv
/tmp/smoke-venv/bin/pip install --quiet dist/*.whl
# Verify the package + the canonical multi-WS / runtime imports.
/tmp/smoke-venv/bin/python -c "
from molecule_runtime import executor_helpers
from molecule_runtime.mcp_workspace_resolver import resolve_workspaces
from molecule_runtime import mcp_cli
from molecule_runtime.executor_helpers import extract_attached_files
from molecule_runtime.llm_auth import normalise_llm_env
from molecule_runtime.credential_helper import install_credential_helper
from molecule_runtime.precommit_hook import install_pre_commit_hook
print('smoke-import: all canonical surfaces import cleanly')
"
# CLI entry-point — molecule-mcp must be installed + show help.
/tmp/smoke-venv/bin/molecule-mcp --help | head -5