chore: publish ArmaraOS CLI v0.8.4 for Intel macs (x86_64-apple-darwin) #656
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| branches: [main, master] | |
| schedule: | |
| - cron: "0 3 * * *" | |
| workflow_dispatch: | |
| jobs: | |
| docs-contract: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run docs contract check (PR diff-aware) | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| python scripts/check_docs_contracts.py --scope changed --base-ref "origin/${{ github.base_ref }}" | |
| - name: Run docs contract check (full) | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| python scripts/check_docs_contracts.py --scope all | |
| core-pr: | |
| if: github.event_name != 'schedule' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ["3.10", "3.11"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run core profile | |
| run: python scripts/run_test_profiles.py --profile core | |
| # Named gate: a2a unit tests + local threaded HTTPServer integration (skips bind in strict sandboxes). | |
| - name: A2A adapter (tests.test_a2a_adapter + tests.test_a2a_adapter_integration) | |
| run: python -m pytest -q tests/test_a2a_adapter.py tests/test_a2a_adapter_integration.py | |
| # Explicit gate: compile → RuntimeEngine → SolanaAdapter (includes dry-run mutating verbs). | |
| # Core profile already runs this file; this step names the contract in CI logs. | |
| - name: Solana prediction-market E2E (dry-run runtime) | |
| run: python -m pytest -q tests/test_solana_prediction_market_e2e.py | |
| - name: Verify adapter manifest consistency | |
| run: python -m pytest -q tests/test_adapter_manifest.py | |
| - name: Verify artifact profile consistency | |
| run: | | |
| python scripts/check_all_strict.py | |
| python scripts/check_all_nonstrict.py | |
| python -m pytest -q tests/test_artifact_profiles.py | |
| parser-compat: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Validate S+cron schedule lines (IR services.path) | |
| run: python scripts/validate_s_cron_schedules.py | |
| - name: Run parser compatibility gate | |
| run: | | |
| python -m pytest -q \ | |
| tests/test_compiler_patch_a_guardrails.py \ | |
| tests/test_sanity_fixes.py \ | |
| tests/test_ir_canonical.py \ | |
| tests/test_emits_artifacts.py \ | |
| tests/test_conformance.py::test_minimal_api_emit_openapi_has_path | |
| - name: Wishlist examples strict + no-network smoke (01, 05b) | |
| run: | | |
| set -euo pipefail | |
| python -m pytest -q tests/test_wishlist_examples_strict.py | |
| python -m cli.main run examples/wishlist/01_cache_and_memory.ainl --json \ | |
| --frame-json '{"session_key":"ci","note":"hello"}' 2>/dev/null \ | |
| | python -c "import sys,json; d=json.load(sys.stdin); assert d.get('ok') is True, d" | |
| python -m cli.main run examples/wishlist/05b_unified_llm_offline_config.ainl --json \ | |
| --config examples/wishlist/fixtures/llm_offline.yaml \ | |
| --frame-json '{"user_query":"ci rust smoke"}' 2>/dev/null \ | |
| | python -c "import sys,json; d=json.load(sys.stdin); assert d.get('ok') is True, d; assert 'OFFLINE_LLM' in str(d.get('result')), d" | |
| # No outbound network required: a2a unit tests only (integration may skip in stricter sandboxes; core-pr also runs both). | |
| a2a-adapter-unit: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: A2A adapter unit tests only | |
| run: python -m pytest -q tests/test_a2a_adapter.py | |
| conformance-matrix: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run conformance matrix | |
| run: make conformance | |
| openapi-compat: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run OpenAPI compatibility gate | |
| run: | | |
| python -m pytest -q \ | |
| tests/test_compiler_patch_c_openapi_types.py \ | |
| tests/test_conformance.py::test_minimal_api_emit_openapi_has_path \ | |
| tests/test_lossless.py::test_openapi_array_inner_type_ref_for_model \ | |
| tests/test_lossless.py::test_openapi_json_type_maps_to_object_schema \ | |
| tests/test_lossless.py::test_openapi_response_data_allows_array_or_object | |
| apollo-promoter: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Apollo promoter safety net (strict + gateway tests) | |
| run: make check-apollo-promoter | |
| compiler-compat-required: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| needs: [parser-compat, openapi-compat] | |
| steps: | |
| - name: Compatibility gates passed | |
| run: echo "parser-compat and openapi-compat both passed" | |
| integration-nightly: | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install deps | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run full profile | |
| run: python scripts/run_test_profiles.py --profile full | |
| # Benchmarks + JSON regression gate: prefers committed CI baselines (tooling/benchmark_*_ci.json) | |
| # when present on the base SHA; otherwise falls back to full reports (benchmark_size.json, | |
| # benchmark_runtime_results.json). | |
| benchmark-regression: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| env: | |
| BENCH_THRESHOLD: "0.10" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Cache pip | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-bench-${{ hashFiles('pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-bench- | |
| - name: Install deps (dev + benchmark) | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev,benchmark] | |
| - name: Resolve baseline SHA | |
| id: baseline | |
| run: | | |
| git fetch origin main --depth=1 2>/dev/null || true | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "sha=${{ github.event.pull_request.base.sha }}" >> "$GITHUB_OUTPUT" | |
| elif [ "${{ github.event_name }}" = "push" ] \ | |
| && [ -n "${{ github.event.before }}" ] \ | |
| && [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then | |
| echo "sha=${{ github.event.before }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "sha=$(git rev-parse origin/main 2>/dev/null || echo "")" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Extract baseline JSON (from git) | |
| id: baselines | |
| run: | | |
| set -euo pipefail | |
| SHA="${{ steps.baseline.outputs.sha }}" | |
| mkdir -p /tmp/bench-baseline | |
| if [ -z "$SHA" ]; then | |
| echo "size_ci=missing" >> "$GITHUB_OUTPUT" | |
| echo "size=missing" >> "$GITHUB_OUTPUT" | |
| echo "runtime_ci=missing" >> "$GITHUB_OUTPUT" | |
| echo "runtime=missing" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if git cat-file -e "${SHA}:tooling/benchmark_size_ci.json" 2>/dev/null; then | |
| git show "${SHA}:tooling/benchmark_size_ci.json" > /tmp/bench-baseline/benchmark_size_ci.json | |
| echo "size_ci=present" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "size_ci=missing" >> "$GITHUB_OUTPUT" | |
| fi | |
| if git cat-file -e "${SHA}:tooling/benchmark_size.json" 2>/dev/null; then | |
| git show "${SHA}:tooling/benchmark_size.json" > /tmp/bench-baseline/benchmark_size.json | |
| echo "size=present" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "size=missing" >> "$GITHUB_OUTPUT" | |
| fi | |
| if git cat-file -e "${SHA}:tooling/benchmark_runtime_ci.json" 2>/dev/null; then | |
| git show "${SHA}:tooling/benchmark_runtime_ci.json" > /tmp/bench-baseline/benchmark_runtime_ci.json | |
| echo "runtime_ci=present" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "runtime_ci=missing" >> "$GITHUB_OUTPUT" | |
| fi | |
| if git cat-file -e "${SHA}:tooling/benchmark_runtime_results.json" 2>/dev/null; then | |
| git show "${SHA}:tooling/benchmark_runtime_results.json" > /tmp/bench-baseline/benchmark_runtime_results.json | |
| echo "runtime=present" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "runtime=missing" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Run size benchmark (CI slice) | |
| run: | | |
| python scripts/benchmark_size.py \ | |
| --mode minimal_emit \ | |
| --profile-name canonical_strict_valid \ | |
| --compare-baselines \ | |
| --cost-model gpt-4o \ | |
| --json-out tooling/benchmark_size_ci.json \ | |
| --skip-markdown-inject | |
| - name: Run runtime benchmark | |
| run: | | |
| python scripts/benchmark_runtime.py \ | |
| --profile-name canonical_strict_valid \ | |
| --compare-baselines \ | |
| --reliability-runs 10 \ | |
| --cost-model gpt-4o \ | |
| --json-out tooling/benchmark_runtime_ci.json \ | |
| --skip-markdown-inject | |
| - name: Upload benchmark JSON (pre-regression) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-json-precheck-${{ github.run_id }} | |
| if-no-files-found: warn | |
| path: | | |
| tooling/benchmark_size_ci.json | |
| tooling/benchmark_runtime_ci.json | |
| - name: Regression check (size) | |
| if: steps.baselines.outputs.size_ci == 'present' || steps.baselines.outputs.size == 'present' | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ steps.baselines.outputs.size_ci }}" = "present" ]; then | |
| OLD_JSON=/tmp/bench-baseline/benchmark_size_ci.json | |
| else | |
| OLD_JSON=/tmp/bench-baseline/benchmark_size.json | |
| fi | |
| python scripts/compare_benchmark_json.py \ | |
| --old-json "$OLD_JSON" \ | |
| --new-json tooling/benchmark_size_ci.json \ | |
| --threshold "$BENCH_THRESHOLD" | |
| - name: Regression check (size baseline missing) | |
| if: steps.baselines.outputs.size_ci != 'present' && steps.baselines.outputs.size != 'present' | |
| run: | | |
| echo "::notice::No tooling/benchmark_size_ci.json or benchmark_size.json at baseline SHA; skipping size regression compare." | |
| - name: Regression check (runtime) | |
| id: runtime_regression | |
| if: (steps.baselines.outputs.runtime_ci == 'present' || steps.baselines.outputs.runtime == 'present') && github.event_name != 'pull_request' | |
| continue-on-error: true | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ steps.baselines.outputs.runtime_ci }}" = "present" ]; then | |
| OLD_JSON=/tmp/bench-baseline/benchmark_runtime_ci.json | |
| else | |
| OLD_JSON=/tmp/bench-baseline/benchmark_runtime_results.json | |
| fi | |
| python scripts/compare_benchmark_json.py \ | |
| --old-json "$OLD_JSON" \ | |
| --new-json tooling/benchmark_runtime_ci.json \ | |
| --threshold "$BENCH_THRESHOLD" | |
| - name: Runtime benchmark compare (PR informational) | |
| if: (steps.baselines.outputs.runtime_ci == 'present' || steps.baselines.outputs.runtime == 'present') && github.event_name == 'pull_request' | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ steps.baselines.outputs.runtime_ci }}" = "present" ]; then | |
| OLD_JSON=/tmp/bench-baseline/benchmark_runtime_ci.json | |
| else | |
| OLD_JSON=/tmp/bench-baseline/benchmark_runtime_results.json | |
| fi | |
| python scripts/compare_benchmark_json.py \ | |
| --old-json "$OLD_JSON" \ | |
| --new-json tooling/benchmark_runtime_ci.json \ | |
| --threshold "$BENCH_THRESHOLD" || true | |
| - name: Runtime baseline missing (informational) | |
| if: steps.baselines.outputs.runtime_ci != 'present' && steps.baselines.outputs.runtime != 'present' | |
| run: | | |
| echo "::notice::No tooling/benchmark_runtime_ci.json or benchmark_runtime_results.json at baseline SHA; commit those files on main to enable runtime regression checks." | |
| - name: Upload benchmark JSON artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-json-${{ github.run_id }} | |
| if-no-files-found: warn | |
| path: | | |
| tooling/benchmark_size_ci.json | |
| tooling/benchmark_runtime_ci.json | |
| install-smoke: | |
| if: github.event_name != 'schedule' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Normal install smoke (venv) | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python -m venv .venv-smoke | |
| . .venv-smoke/bin/activate | |
| python -m pip install --upgrade pip | |
| python -m pip install ".[mcp]" | |
| python -m pip check | |
| ainl --help >/dev/null | |
| ainl-mcp --help >/dev/null | |
| - name: User install smoke (no sudo) | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| export PYTHONUSERBASE="${RUNNER_TEMP}/ainl-userbase" | |
| mkdir -p "${PYTHONUSERBASE}" | |
| python -m pip install --upgrade pip | |
| python -m pip install --user --constraint constraints/py313-mcp.txt ".[mcp]" | |
| python -m pip check | |
| "${PYTHONUSERBASE}/bin/ainl" --help >/dev/null | |
| "${PYTHONUSERBASE}/bin/ainl-mcp" --help >/dev/null | |
| - name: Break-system-packages install smoke | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python -m pip install --upgrade pip | |
| python -m pip install --break-system-packages --constraint constraints/py313-mcp.txt ".[mcp]" | |
| python -m pip check | |
| SCRIPT_DIR="$(python -c 'import sysconfig; print(sysconfig.get_path("scripts"))')" | |
| "${SCRIPT_DIR}/ainl" --help >/dev/null | |
| "${SCRIPT_DIR}/ainl-mcp" --help >/dev/null | |
| wheel-integrity: | |
| if: github.event_name != 'schedule' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Build wheel | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python -m pip install --upgrade pip build | |
| python -m build | |
| - name: Wheel install integrity + imports | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python -m venv .venv-wheel | |
| . .venv-wheel/bin/activate | |
| python -m pip install --upgrade pip | |
| WHEEL="$(ls dist/*.whl | head -n 1)" | |
| python -m pip install --force-reinstall --constraint constraints/py313-mcp.txt "${WHEEL}[mcp]" | |
| python -m pip check | |
| python -c "import runtime.compat, adapters, cli.main" | |
| ainl --help >/dev/null | |
| ainl-mcp --help >/dev/null | |
| container-install-smoke: | |
| if: github.event_name != 'schedule' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: ["python:3.10-slim", "python:3.11-slim", "python:3.12-slim", "python:3.13-slim"] | |
| container: | |
| image: ${{ matrix.image }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Non-root container install smoke | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| useradd -m -u 1000 ainl 2>/dev/null || true | |
| chown -R 1000:1000 "$GITHUB_WORKSPACE" | |
| su -s /bin/bash ainl -c ' | |
| cd "$GITHUB_WORKSPACE" && \ | |
| python -m venv .venv-container && \ | |
| . .venv-container/bin/activate && \ | |
| python -m pip install --upgrade pip && \ | |
| python -m pip install --constraint constraints/py313-mcp.txt ".[mcp]" && \ | |
| python -m pip check && \ | |
| ainl --help >/dev/null && \ | |
| ainl-mcp --help >/dev/null | |
| ' |