Repository navigation
chore(deps): bump actions/checkout from 4.2.2 to 7.0.1 #48
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: tests | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| jobs: | |
| pytest: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install (hash-pinned) | |
| run: | | |
| # toolchain first, oev closure last: where the locks disagree | |
| # (huggingface-hub, numpy), the oev pins must win, and no step | |
| # re-installs the toolchain afterwards | |
| python -m pip install --require-hashes --no-deps -r ci/requirements.txt | |
| python -m pip install --require-hashes --no-deps -r ci/requirements-oev.txt --extra-index-url https://download.pytorch.org/whl/cpu | |
| python -m pip install --require-hashes --no-deps -r ci/requirements-build.txt | |
| python -m build --wheel --no-isolation | |
| python -m installer dist/*.whl | |
| - name: Run tests | |
| run: python -m pytest -q | |
| - name: Ruff | |
| # ruff ships in the toolchain lock installed above | |
| run: ruff check oev scripts tests app.py space_ui | |
| - name: Dependency audit (pip-audit, known CVEs fail the build) | |
| # pip-audit ships in the toolchain lock installed above; auditing | |
| # this exact env, no reinstall that could clobber resolved pins | |
| run: pip-audit | |
| - name: README image links resolve (HTTP 200) | |
| run: | | |
| python - <<'PY' | |
| import io, re, urllib.request | |
| text = io.open("README.md", encoding="utf-8").read() | |
| urls = sorted(set(re.findall(r'https://raw\.githubusercontent\.com/[^"\s)]+', text))) | |
| bad = [] | |
| for u in urls: | |
| try: | |
| with urllib.request.urlopen(urllib.request.Request(u, method="HEAD")) as r: | |
| if r.status != 200: | |
| bad.append(f"{u} -> {r.status}") | |
| except Exception as e: | |
| bad.append(f"{u} -> {e}") | |
| assert not bad, f"broken image URLs in README.md: {bad}" | |
| print(f"image links OK ({len(urls)} URLs resolve)") | |
| PY | |
| claims-integrity: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Claims integrity (version parity + claims map + eval commands) | |
| run: python scripts/check_claims.py | |
| - name: Validate community metadata files | |
| run: | | |
| python - <<'PY' | |
| import re, tomllib | |
| py = tomllib.load(open("pyproject.toml", "rb"))["project"]["version"] | |
| src = open("oev/__init__.py", encoding="utf-8").read() | |
| init = re.search(r'__version__\s*=\s*"([^"]+)"', src).group(1) | |
| cff = open("CITATION.cff", encoding="utf-8").read() | |
| m = re.search(r'^version:\s*(\S+)', cff, re.M) | |
| assert m, "CITATION.cff has no version field" | |
| cff_ver = m.group(1).strip('"') | |
| assert py == init == cff_ver, f"version mismatch: pyproject {py}, __init__ {init}, CITATION.cff {cff_ver}" | |
| for field in ("title", "authors", "abstract", "license", "repository-code"): | |
| assert re.search(rf"^{field}:", cff, re.M), f"CITATION.cff missing {field}" | |
| sec = open("SECURITY.md", encoding="utf-8").read() | |
| assert "security/advisories/new" in sec, "SECURITY.md must link private reporting" | |
| print(f"community metadata OK (version {py} in pyproject, __init__ and CITATION.cff)") | |
| PY | |
| - name: Chart freshness (tracked PNGs match the generator, pixel-identical) | |
| run: | | |
| python -m pip install --require-hashes --no-deps -r ci/requirements.txt | |
| python - <<'PY' | |
| import os, shutil, subprocess, sys, tempfile | |
| from pathlib import Path | |
| import numpy as np | |
| from PIL import Image | |
| with tempfile.TemporaryDirectory() as td: | |
| # mirror the repo layout: scripts/ next to docs/, because | |
| # chartdata.load() resolves the repo root from the module path | |
| os.makedirs(os.path.join(td, "scripts")) | |
| os.makedirs(os.path.join(td, "docs")) | |
| for f in ("make_charts.py", "chartstyle.py", "chartdata.py"): | |
| shutil.copy(os.path.join("scripts", f), os.path.join(td, "scripts", f)) | |
| shutil.copy(os.path.join("docs", "claims.json"), os.path.join(td, "docs", "claims.json")) | |
| r = subprocess.run([sys.executable, "scripts/make_charts.py"], cwd=td, | |
| capture_output=True, text=True) | |
| assert r.returncode == 0, r.stderr | |
| fresh = sorted(f for f in os.listdir(os.path.join(td, "assets")) | |
| if f.endswith(".png")) | |
| assert fresh, "generator produced no charts" | |
| problems = [] | |
| for f in fresh: | |
| repo_p = os.path.join("assets", f) | |
| if not os.path.exists(repo_p): | |
| problems.append(f"{f}: generated but not tracked in assets/") | |
| continue | |
| a = np.asarray(Image.open(os.path.join(td, "assets", f)).convert("RGBA")) | |
| b = np.asarray(Image.open(repo_p).convert("RGBA")) | |
| if a.shape != b.shape or not np.array_equal(a, b): | |
| problems.append(f) | |
| assert not problems, ( | |
| "stale chart assets (run scripts/make_charts.py locally, " | |
| f"then commit the regenerated PNGs): {problems}") | |
| print(f"chart freshness OK ({len(fresh)} charts, pixel-identical)") | |
| PY |