Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e1a92ce
Apply ruff format and lint autofixes across the codebase
aviv1ron1 Jul 9, 2026
24f1bad
Add CI/CD: pre-commit hooks, GitHub Actions, and blocking ruff gate
aviv1ron1 Jul 9, 2026
5c27167
Point .git-blame-ignore-revs at the reformat commit
aviv1ron1 Jul 9, 2026
5409437
improve documentation for DCO, add auto sign off hook
aviv1ron1 Jul 9, 2026
384d5b2
fix tests to run on github actions
aviv1ron1 Jul 9, 2026
c07d4c9
remove uv from pre commit execution documentation
aviv1ron1 Jul 9, 2026
584437b
fix pre commit order
aviv1ron1 Jul 9, 2026
6ac9465
run pre commit hooks as post commit validations
aviv1ron1 Jul 9, 2026
d589514
update plan
aviv1ron1 Jul 9, 2026
28acc8b
remove composer tests from ci
aviv1ron1 Jul 9, 2026
991c35d
remove hf tests
aviv1ron1 Jul 9, 2026
1fc4cda
remove hf tests from ci
aviv1ron1 Jul 9, 2026
4103aec
remove hf tests from ci
aviv1ron1 Jul 9, 2026
ea864f7
Harden validate_links against malformed pyproject.toml
aviv1ron1 Jul 12, 2026
0458e5a
Order config validators before ruff in pre-commit
aviv1ron1 Jul 12, 2026
7af9691
Enforce large-file check in CI via --enforce-all
aviv1ron1 Jul 12, 2026
c292762
Run merge-conflict check in CI via --assume-in-merge
aviv1ron1 Jul 13, 2026
3bbb162
Document whole-tree CI enforcement for large-file and merge-conflict …
aviv1ron1 Jul 13, 2026
630440d
Document CPU-only local setup for macOS/no-GPU in CONTRIBUTING
aviv1ron1 Jul 13, 2026
10cc8f5
Fix inaccurate uv lock note in CONTRIBUTING
aviv1ron1 Jul 13, 2026
004a293
Scope coverage measurement to CPU-testable modules
aviv1ron1 Jul 13, 2026
68ed984
update cicd plan
aviv1ron1 Jul 14, 2026
aac20b8
turn images into non relative urls, so they show up on pypi
aviv1ron1 Jul 14, 2026
c9328b9
reflect package version instead of hard coding a version
aviv1ron1 Jul 14, 2026
2b1b638
turn relative links into absolute so they work on pypi as well
aviv1ron1 Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Commits listed here are ignored by `git blame` so that bulk
# reformatting commits don't obscure authorship of real changes.
#
# Enable locally with:
# git config blame.ignoreRevsFile .git-blame-ignore-revs

# Apply ruff format and lint autofixes across the codebase
e1a92ceab87dc0ab6517916954a430d16b2da1b6
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# This covers every file in the repo
* @antonpibm @freunda @yairallouche
* @antonpibm @freunda @yairallouche
77 changes: 77 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# SPDX-License-Identifier: Apache-2.0

name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
pre-commit:
name: Pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

# Run the exact same hooks as the local pre-commit stage (ruff, toml/yaml
# validity, link/import validation, SPDX headers, whitespace/EOF, uv-lock,
# nbstripout, ...) so CI and pre-commit can never drift. `uv` must be on
# PATH for the uv-lock hook.
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Cache pre-commit hook environments
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}

- name: Run pre-commit hooks
run: uvx pre-commit run --all-files --show-diff-on-failure --color=always

test-cpu:
name: CPU Tests (Python ${{ matrix.python-version }})
needs: pre-commit
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4

- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

- run: uv sync --frozen --group dev --extra hf --extra compose

- name: Run CPU tests
run: |
# CI runs only tests/unit/ — the fast, self-contained CPU set.
# The marker filter still applies: tests that download/compose real
# models (requires_model), need CUDA (gpu), hit the network / take
# long (slow), or are the expensive code-theory suite (deep) are
# excluded.
# tests/composer/ and tests/hf/ are NOT run here: even filtered they
# are heavy enough to exhaust the GitHub Actions CPU-minutes quota and
# get killed mid-run. All of that coverage runs on the GPU cluster.
uv run pytest tests/unit/ \
-m "not requires_model and not gpu and not slow and not deep" \
-v -s --tb=short -x \
--cov=granite_switch --cov-report=xml

- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.xml
fail_ci_if_error: false
51 changes: 51 additions & 0 deletions .github/workflows/dco.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SPDX-License-Identifier: Apache-2.0

name: DCO Check

on:
pull_request:
branches: [main]

jobs:
dco:
name: DCO Sign-off
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check DCO sign-off
shell: bash
run: |
COMMITS=$(git log origin/${{ github.base_ref }}..${{ github.sha }} --format="%H")
MISSING_DCO=false

for commit in $COMMITS; do
PARENTS=$(git rev-list --parents -n 1 $commit | wc -w)
if [ "$PARENTS" -gt 2 ]; then
echo "ℹ️ Skipping merge commit $commit"
continue
fi

MESSAGE=$(git log -1 --format=%B $commit)
if ! echo "$MESSAGE" | grep -q "^Signed-off-by:"; then
echo "❌ Commit $commit is missing DCO sign-off"
echo " Commit message:"
echo "$MESSAGE" | head -5
echo ""
MISSING_DCO=true
fi
done

if [ "$MISSING_DCO" = true ]; then
echo ""
echo "Error: One or more commits are missing DCO sign-off!"
echo "Please sign your commits with: git commit -s"
echo ""
echo "To fix existing commits:"
echo " git rebase --signoff origin/${{ github.base_ref }}"
exit 1
fi

echo "✅ All commits have DCO sign-off"
23 changes: 23 additions & 0 deletions .github/workflows/gpu-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SPDX-License-Identifier: Apache-2.0

name: GPU Tests

on:
workflow_dispatch: # admin-only trigger (requires write access)

jobs:
gpu-tests:
name: GPU Tests
runs-on: [self-hosted, gpu]
steps:
- uses: actions/checkout@v4

- uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- run: uv sync --frozen --group dev --extra hf --extra vllm --extra compose

- name: Run GPU tests
run: |
uv run pytest tests/vllm/ tests/integration/ -v -s --tb=short -x
27 changes: 27 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-License-Identifier: Apache-2.0

name: Publish to PyPI

on:
release:
types: [published]

jobs:
build-and-publish:
name: Build and publish
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write # required for PyPI Trusted Publisher (OIDC)
steps:
- uses: actions/checkout@v4

- uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Build wheel and sdist
run: uv build

- name: Publish to PyPI
run: uv publish
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ htmlcov/
# Local design/planning doc (keep on disk, do not version)
docs/KV_CACHE_OVERHEAD_REMOVAL.md
docs/KV_CACHE_OVERHEAD_REMOVAL.html
docs/KV_CACHE_OVERHEAD_REMOVAL*.html
docs/KV_CACHE_OVERHEAD_REMOVAL*.html
85 changes: 85 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
fail_fast: true
# Restrict hooks to the pre-commit stage by default so they don't also fire at
# prepare-commit-msg / commit-msg (which are installed for the DCO hooks below).
# The two DCO hooks override this with their own explicit `stages:`.
default_stages: [pre-commit]
repos:
# Config-file validators run first: ruff loads its config from pyproject.toml,
# so a malformed pyproject.toml makes ruff itself abort with a parser error
# instead of the clean check-toml message. With fail_fast, running check-toml /
# check-yaml before ruff means syntax errors are reported by the validator that
# exists for that purpose, consistently between local commits and CI --all-files.
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-toml
- id: check-yaml
- id: check-merge-conflict
# --assume-in-merge makes the hook scan even when no merge is in
# progress. Without it the hook returns early unless .git/MERGE_HEAD
# exists, so it would be a no-op in CI's `pre-commit run --all-files`
# (a clean checkout is never mid-merge). This lets CI catch conflict
# markers that were committed (e.g. via --no-verify).
args: [--assume-in-merge]
- id: check-added-large-files
# --enforce-all checks every file, not just staged additions, so the
# hook also runs in CI's `pre-commit run --all-files` (a clean checkout
# has nothing staged, so without this it would be a no-op there).
# uv.lock is intentionally large (~2.3 MB) and excluded.
args: [--maxkb=500, --enforce-all]
exclude: ^uv\.lock$
- id: check-case-conflict
- id: mixed-line-ending
args: [--fix=lf]
- id: end-of-file-fixer
exclude: \.ipynb$
- id: trailing-whitespace
exclude: \.ipynb$

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff-format
args: [--config=pyproject.toml]
- id: ruff
args: [--exit-non-zero-on-fix, --fix, --config=pyproject.toml]

- repo: local
hooks:
- id: check-headers
name: Check SPDX headers
entry: python ci/check_headers.py
language: system
args: [--fix]
files: '^(src|tests)/.*\.py$'
pass_filenames: true

- id: add-signoff
name: Add DCO sign-off
entry: python ci/add_signoff.py
language: system
stages: [prepare-commit-msg]

- id: check-dco
name: Check DCO sign-off
entry: python ci/check_dco.py
language: system
stages: [commit-msg]

- id: validate-links
name: Validate links and first-party imports
entry: python .pre-commit/validate_links.py
language: system
pass_filenames: false
always_run: true
files: \.(ipynb|md|py)$

- repo: https://github.com/kynan/nbstripout
rev: 0.8.1
hooks:
- id: nbstripout

- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.8.4
hooks:
- id: uv-lock
Loading
Loading