Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
126 changes: 126 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: CI Pipeline

on:
push:
branches: [main, master, develop]
pull_request:
branches: [main, master]

jobs:
# ─────────────────────────────────────────────
# Job 1: Code Quality (lint + format check)
# ─────────────────────────────────────────────
lint:
name: Code Quality
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install linting tools
run: pip install flake8 black

- name: Run flake8 (style & syntax)
run: |
flake8 . \
--max-line-length=120 \
--exclude=SwinIR/,LoRA/,.git/ \
--extend-ignore=E203,W503 \
--count --statistics

- name: Check formatting with black
run: |
black --check --line-length=120 \
--exclude='/(SwinIR|LoRA|\.git)/' \
.

# ─────────────────────────────────────────────
# Job 2: Install deps & smoke-test imports
# ─────────────────────────────────────────────
smoke-test:
name: Install & Import Smoke Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip

- name: Install system dependencies (ImageMagick for Wand)
run: sudo apt-get update -q && sudo apt-get install -y libmagickwand-dev

- name: Install CPU-only PyTorch (faster, no GPU needed in CI)
run: |
pip install torch==2.2.0 torchvision==0.17.0 \
--index-url https://download.pytorch.org/whl/cpu

- name: Install remaining dependencies
run: |
pip install \
numpy==1.26.4 \
Pillow==10.4.0 \
Wand==0.6.13 \
matplotlib==3.9.2 \
opencv-python==4.4.0.46 \
tqdm==4.67.1 \
timm==0.4.12 \
ipython==7.19.0 \
pandas==2.3.1 \
pytest

- name: Run import smoke tests
run: python -m pytest tests/test_imports.py -v

# ─────────────────────────────────────────────
# Job 3: Unit tests
# ─────────────────────────────────────────────
test:
name: Unit Tests
runs-on: ubuntu-latest
needs: smoke-test

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip

- name: Install system dependencies (ImageMagick for Wand)
run: sudo apt-get update -q && sudo apt-get install -y libmagickwand-dev

- name: Install CPU-only PyTorch
run: |
pip install torch==2.2.0 torchvision==0.17.0 \
--index-url https://download.pytorch.org/whl/cpu

- name: Install remaining dependencies
run: |
pip install \
numpy==1.26.4 \
Pillow==10.4.0 \
Wand==0.6.13 \
matplotlib==3.9.2 \
opencv-python==4.4.0.46 \
tqdm==4.67.1 \
timm==0.4.12 \
ipython==7.19.0 \
pandas==2.3.1 \
pytest

- name: Run all tests
run: python -m pytest tests/ -v --tb=short
Empty file added tests/__init__.py
Empty file.
64 changes: 64 additions & 0 deletions tests/test_imports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Smoke tests: verify all core dependencies import cleanly.
These run in CI without any dataset or GPU.
"""


def test_torch_imports():
import torch
import torchvision

assert torch.__version__, "torch version should be non-empty"
assert torchvision.__version__, "torchvision version should be non-empty"


def test_timm_import():
import timm

assert timm.__version__, "timm version should be non-empty"


def test_image_libs():
import cv2
from PIL import Image
import numpy as np

# Basic sanity: create a tiny numpy array and wrap it as a PIL image
arr = np.zeros((4, 4, 3), dtype=np.uint8)
img = Image.fromarray(arr)
assert img.size == (4, 4)


def test_data_libs():
import numpy as np
import pandas as pd
import matplotlib

matplotlib.use("Agg") # non-interactive backend, safe in CI
import matplotlib.pyplot as plt

df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
assert list(df.columns) == ["a", "b"]


def test_torch_cpu_tensor():
import torch

t = torch.tensor([1.0, 2.0, 3.0])
assert t.sum().item() == 6.0


def test_resnet_model_instantiation():
"""Verify a ResNet can be instantiated (no dataset required)."""
import torchvision.models as models

model = models.resnet18(pretrained=False)
assert model is not None


def test_timm_swin_instantiation():
"""Verify a Swin Transformer variant can be instantiated via timm."""
import timm

model = timm.create_model("swin_tiny_patch4_window7_224", pretrained=False)
assert model is not None
Loading