mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-29 11:42:04 +00:00
ci: run only the lanes a PR affects (python/frontend/site)
Heavy PR checks run on every PR because the workflows deliberately avoid `on.paths` filters — a path-gated workflow leaves its required check pending forever when no matching file changes, blocking merge. So a docs-only PR still spins up the TypeScript matrix, the full Python suite, and ruff/ty. Keep every workflow triggering on every PR (checks always report) but gate the expensive *steps* on what the PR touches. Skipping a step (not the job) leaves the job green, so required checks never hang — the same idiom already proven in contributor-check.yml. A classifier (scripts/ci/classify_changes.py) maps the PR diff to three lanes — python, frontend, site — surfaced as step outputs by a composite action (.github/actions/detect-changes). Fail-open: an empty diff or any .github/ change runs everything; python is a denylist (skipped only when every file is provably prose or a frontend-only package); skills/**/SKILL.md counts as python-relevant since the skill-doc tests read that tree. Non-PR events always run the full pipeline.
This commit is contained in:
parent
351afd353d
commit
45540cfb5e
7 changed files with 272 additions and 5 deletions
30
.github/workflows/tests.yml
vendored
30
.github/workflows/tests.yml
vendored
|
|
@ -31,8 +31,18 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0 # full history so detect-changes can diff base...head
|
||||
|
||||
# On PRs that touch no Python, every step below is skipped and the job
|
||||
# reports green. The check still runs (no `on.paths` filter), so the
|
||||
# required status never hangs.
|
||||
- name: Detect affected areas
|
||||
id: changes
|
||||
uses: ./.github/actions/detect-changes
|
||||
|
||||
- name: Restore duration cache
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: test_durations.json
|
||||
|
|
@ -44,6 +54,7 @@ jobs:
|
|||
key: test-durations
|
||||
|
||||
- name: Install ripgrep (prebuilt binary)
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
RG_VERSION=15.1.0
|
||||
|
|
@ -58,6 +69,7 @@ jobs:
|
|||
rg --version
|
||||
|
||||
- name: Install uv
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
|
||||
with:
|
||||
# Persist uv's download/wheel cache (~/.cache/uv) across runs.
|
||||
|
|
@ -71,9 +83,11 @@ jobs:
|
|||
uv.lock
|
||||
|
||||
- name: Set up Python 3.11
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: uv python install 3.11
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
# `uv sync --locked` installs the exact pinned set from uv.lock (and
|
||||
# fails if the lock is out of sync with pyproject.toml), giving a
|
||||
# reproducible env. It also creates .venv itself, so no separate
|
||||
|
|
@ -81,11 +95,13 @@ jobs:
|
|||
run: uv sync --locked --python 3.11 --extra all --extra dev
|
||||
|
||||
- name: Minimize uv cache
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
# Optimized for CI: prunes pre-built wheels that are cheap to
|
||||
# re-download, keeping the persisted cache small and fast to restore.
|
||||
run: uv cache prune --ci
|
||||
|
||||
- name: Run tests (slice ${{ matrix.slice }}/6)
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
# Per-file isolation via scripts/run_tests_parallel.py: discovers
|
||||
# every test_*.py file under tests/ (excluding integration/ + e2e/),
|
||||
# then runs `python -m pytest <file>` in a freshly-spawned subprocess
|
||||
|
|
@ -119,6 +135,7 @@ jobs:
|
|||
NOUS_API_KEY: ""
|
||||
|
||||
- name: Upload per-slice durations
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: test-durations-slice-${{ matrix.slice }}
|
||||
|
|
@ -164,8 +181,15 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0 # full history so detect-changes can diff base...head
|
||||
|
||||
- name: Detect affected areas
|
||||
id: changes
|
||||
uses: ./.github/actions/detect-changes
|
||||
|
||||
- name: Install ripgrep (prebuilt binary)
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
RG_VERSION=15.1.0
|
||||
|
|
@ -180,6 +204,7 @@ jobs:
|
|||
rg --version
|
||||
|
||||
- name: Install uv
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
|
||||
with:
|
||||
# Persist uv's download/wheel cache (~/.cache/uv) across runs.
|
||||
|
|
@ -193,9 +218,11 @@ jobs:
|
|||
uv.lock
|
||||
|
||||
- name: Set up Python 3.11
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: uv python install 3.11
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
# `uv sync --locked` installs the exact pinned set from uv.lock (and
|
||||
# fails if the lock is out of sync with pyproject.toml), giving a
|
||||
# reproducible env. It also creates .venv itself, so no separate
|
||||
|
|
@ -203,16 +230,19 @@ jobs:
|
|||
run: uv sync --locked --python 3.11 --extra all --extra dev
|
||||
|
||||
- name: Minimize uv cache
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
# Optimized for CI: prunes pre-built wheels that are cheap to
|
||||
# re-download, keeping the persisted cache small and fast to restore.
|
||||
run: uv cache prune --ci
|
||||
|
||||
- name: Packaged-wheel i18n smoke test
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
python -m pytest -m integration tests/test_wheel_locales_e2e.py -v
|
||||
|
||||
- name: Run e2e tests
|
||||
if: steps.changes.outputs.python == 'true'
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
python -m pytest tests/e2e/ -v --tb=short
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue