From ba2b149f74928b0a546bf3b2ad5b2d100c70c714 Mon Sep 17 00:00:00 2001 From: Eric Hackathorn Date: Mon, 1 Jun 2026 17:26:37 +0000 Subject: [PATCH 1/2] fix(ci): unbreak lint/test by decoupling optional guardrails extra MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Run Tests workflow was failing at install time on `guardrails-ai (0.8.2)` because the entire `guardrails-ai` project is quarantined on PyPI — `https://pypi.org/simple/guardrails-ai/` returns `pypi:project-status: quarantined` with zero file links, so neither the locked 0.8.2 nor any other version (0.8.0, 0.8.1, 0.10.x) can be resolved or downloaded. Workflow changes (hotfix scope only): - Lint job: drop `-E guardrails`. The job only runs `ruff format --check` and `ruff check`; ruff is a dev-group dependency and never needed the runtime extra. - Core test job: drop `-E guardrails` and run `pytest -m "not guardrails"` so upstream churn in the optional extra cannot red the blocking coverage gate. Install remains `--with dev -E api`. - New `test-guardrails` job: installs `--with dev -E api -E guardrails`, runs `pytest -m guardrails` with coverage, and is `continue-on-error: true`. Mirrors the existing job's Python 3.10 pin, Poetry install, caching, and env. While the upstream quarantine persists this job will be yellow but non-blocking. - Cache key prefix bumped from `poetry-${{ runner.os }}-` to `poetry-v2-${{ runner.os }}-` in all three jobs so the first post-fix run does not restore stale PyPI index metadata. Not changed: - pyproject.toml: the `guardrails-ai = "^0.8.0"` optional dep and `guardrails` extra remain (the source-level `import guardrails` is already wrapped in a try/except and degrades to NullGuardrailsAdapter when missing). - poetry.lock: `poetry lock --regenerate --no-cache` fails with "Because zyra depends on guardrails-ai (^0.8.0) which doesn't match any versions, version solving failed" — and the same with ^0.10.0 — because PyPI exposes zero candidates. The existing lock entry (0.8.2) is only consulted when the `guardrails` extra is enabled, which is now exclusively the non-blocking job. Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: Eric Hackathorn --- .github/workflows/test.yaml | 84 +++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c5df91b0..cad49471 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -53,9 +53,9 @@ jobs: with: path: | ~/.cache/pypoetry - key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + key: poetry-v2-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | - poetry-${{ runner.os }}- + poetry-v2-${{ runner.os }}- - name: Show workspace (pre-install debug) run: | @@ -75,7 +75,7 @@ jobs: exit 1 fi echo "Using project directory: $DIR" - poetry -C "$DIR" install --no-root --with dev -E guardrails + poetry -C "$DIR" install --no-root --with dev - name: Ruff format check run: poetry run ruff format --check . @@ -119,9 +119,9 @@ jobs: with: path: | ~/.cache/pypoetry - key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + key: poetry-v2-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | - poetry-${{ runner.os }}- + poetry-v2-${{ runner.os }}- - name: Show workspace (pre-install debug) run: | @@ -141,7 +141,7 @@ jobs: exit 1 fi echo "Using project directory: $DIR" - poetry -C "$DIR" install --no-root --with dev -E api -E guardrails + poetry -C "$DIR" install --no-root --with dev -E api - name: Show workspace root (post-install debug) run: | @@ -157,7 +157,11 @@ jobs: # despite -s and verbose logging. The workflow's parallel executor # is covered by other tests. We'll re-enable once we've isolated the # environment-specific behavior in a dedicated CI job. - poetry run pytest --cov=src --cov-branch --cov-report=xml --cov-report=term-missing -s \ + # Guardrails-marked tests run in the separate test-guardrails job so + # upstream churn in the optional guardrails-ai extra cannot red the + # blocking coverage gate. + poetry run pytest -m "not guardrails" \ + --cov=src --cov-branch --cov-report=xml --cov-report=term-missing -s \ --timeout=5 --timeout-method=thread --durations=25 \ --ignore tests/workflow/test_parallel_dag.py @@ -166,3 +170,69 @@ jobs: with: name: coverage-report path: coverage.xml + + test-guardrails: + name: Test (guardrails extra, non-blocking) + runs-on: ubuntu-latest + continue-on-error: true + defaults: + run: + working-directory: ${{ github.workspace }} + env: + PYTHONPATH: src + ZYRA_USE_REDIS: 0 + AUTH_FAIL_DELAY_MS: 0 + DATAVIZHUB_DEFAULT_STDIN: tests/testdata/demo.nc + ZYRA_VERBOSITY: debug + ZYRA_WORKFLOW_PARALLEL_MODE: thread + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install Poetry + run: | + curl -sSL https://install.python-poetry.org | python3 - + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + - name: Cache Poetry cache and virtualenv + uses: actions/cache@v4 + with: + path: | + ~/.cache/pypoetry + key: poetry-v2-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + restore-keys: | + poetry-v2-${{ runner.os }}- + + - name: Install dependencies with Poetry (dev + API + guardrails extras) + run: | + set -euo pipefail + if [ -f pyproject.toml ]; then + DIR="." + else + DIR=$(dirname "$(find "$GITHUB_WORKSPACE" -name pyproject.toml -print -quit || true)") + fi + if [ -z "$DIR" ] || [ ! -f "$DIR/pyproject.toml" ]; then + echo "No pyproject.toml found in repository" >&2 + exit 1 + fi + echo "Using project directory: $DIR" + poetry -C "$DIR" install --no-root --with dev -E api -E guardrails + + - name: Run guardrails-marked tests with coverage + run: | + poetry run coverage erase + poetry run pytest -m guardrails \ + --cov=src --cov-branch --cov-report=xml --cov-report=term-missing -s \ + --timeout=5 --timeout-method=thread --durations=25 + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: coverage-report-guardrails + path: coverage.xml From 7728b78f1830aedb2336e3d3914f970d36b9a1f7 Mon Sep 17 00:00:00 2001 From: Eric Hackathorn Date: Mon, 1 Jun 2026 18:10:13 +0000 Subject: [PATCH 2/2] fix(ci): make test-guardrails job render green by moving continue-on-error to step level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `continue-on-error: true` at the JOB level prevents the failure from cascading to the workflow conclusion, but the job itself still shows as a red ❌ on the PR check list. Moving the flag onto the install and pytest steps makes failed steps render as yellow ⚠ warnings while the job's overall conclusion is success/green — accurate signal that the optional extra is upstream-broken without the visual noise of a red required-looking check. Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: Eric Hackathorn --- .github/workflows/test.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cad49471..a5fb4c14 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -174,7 +174,6 @@ jobs: test-guardrails: name: Test (guardrails extra, non-blocking) runs-on: ubuntu-latest - continue-on-error: true defaults: run: working-directory: ${{ github.workspace }} @@ -210,6 +209,10 @@ jobs: poetry-v2-${{ runner.os }}- - name: Install dependencies with Poetry (dev + API + guardrails extras) + # Step-level continue-on-error so an upstream PyPI outage (e.g. the + # current guardrails-ai quarantine) surfaces as a yellow warning and + # the job's overall conclusion stays green/non-blocking. + continue-on-error: true run: | set -euo pipefail if [ -f pyproject.toml ]; then @@ -225,6 +228,7 @@ jobs: poetry -C "$DIR" install --no-root --with dev -E api -E guardrails - name: Run guardrails-marked tests with coverage + continue-on-error: true run: | poetry run coverage erase poetry run pytest -m guardrails \