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
35 changes: 35 additions & 0 deletions .github/workflows/repo-hygiene.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Repo Hygiene

on:
pull_request:
push:
branches:
- main

jobs:
hygiene:
runs-on: ubuntu-latest

steps:
- name: Check out the repository
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- name: Install Python 3.12
run: uv python install 3.12

- name: Sync dependencies
run: uv sync --group dev --frozen
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Sync only dev tooling in hygiene CI

The hygiene workflow uses uv sync --group dev --frozen, but uv sync --help defines --group as additive, so this still installs default project dependencies (including TensorFlow/Torch) before lint and notebook checks run. That makes repo-hygiene failures depend on heavyweight ML package availability and install stability, even though the job only needs dev tools; use an --only-group dev style sync to avoid unrelated CI breakage/timeouts.

Useful? React with 👍 / 👎.


- name: Run pre-commit
run: uv run pre-commit run --all-files

- name: Validate tracked notebooks
run: uv run python scripts/validate_notebooks.py

- name: Run validator tests
run: uv run python -m unittest discover -s tests -p "test_*.py"
54 changes: 54 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ venv/
ENV/
env.bak/
venv.bak/
.ruff_cache/
.pytest_cache/

# Spyder project settings
.spyderproject
Expand All @@ -164,6 +166,19 @@ dmypy.json

# pytype static type analyzer
.pytype/
.tox/
.nox/
.hypothesis/
.cache/

# Notebook and interpreter state
.ipynb_checkpoints/
profile_default/
ipython_config.py

# Local editor settings
.idea/
.vscode/

# Cython debug symbols
cython_debug/
Expand Down Expand Up @@ -205,3 +220,42 @@ cython_debug/
marimo/_static/
marimo/_lsp/
__marimo__/


# Coverage, logs, and temporary reports
.coverage
.coverage.*
coverage.xml
htmlcov/
*.log

# Packaging or build output from local experiments
build/
dist/
*.egg-info/
*.egg

# uv and Python packaging helpers
.Python
.pdm-python
.pdm-build/
.pixi/
__pypackages__/

# Generated machine-learning artefacts are ignored by default.
# Curated exceptions can be allowlisted later if a specific project needs them.
**/checkpoints/
**/saved_model/
**/saved_model.pb
**/fingerprint.pb
**/*.ckpt
**/*.h5
**/*.keras
**/*.onnx
**/*.pt
**/*.pth
**/*.safetensors
**/*.tflite

# Site output if docs are added later.
site/
60 changes: 28 additions & 32 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
# These hooks keep the repository clean without turning the notebook hub into a
# heavyweight software project. The focus is on safe hygiene checks, not on
# executing notebooks or building package-style infrastructure.

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v4.4.0"
rev: "v4.6.0"
hooks:
- id: check-case-conflict
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: trailing-whitespace
exclude: "(^|/)(README\\.md|AGENTS\\.md)$"
- id: end-of-file-fixer
exclude: "(^|/)(README\\.md|AGENTS\\.md)$"
- id: detect-private-key

# Ruff gives us one fast linter and formatter for the small amount of Python
# infrastructure code we keep at the repo root.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.6.3"
rev: "v0.6.9"
hooks:
- id: ruff
args: [--exit-non-zero-on-fix]
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format

- repo: local
# Standard secret scanning with a reviewed baseline keeps the policy clear
# and avoids maintaining bespoke shell hooks.
- repo: https://github.com/Yelp/detect-secrets
rev: "v1.5.0"
hooks:
- id: prevent-credentials-commit
name: Prevent credentials.json commit
entry: |
bash -c '
if git diff --cached --name-only | grep -q "credentials.json"; then
echo "Error: Attempting to commit credentials.json. Aborting."
exit 1
fi
'
language: system
types: [file]
- id: detect-secrets
args:
- "--baseline"
- ".secrets.baseline"
exclude: "(^uv.lock$|^edgeai-mlops/models/.*|.*\\.ipynb$)"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove notebook exclusion from secret scanning

The detect-secrets hook excludes *.ipynb, which means any tokens or API keys committed inside notebook cells/outputs bypass the repository’s only broad secret scanner. Since this change positions the repo as notebook-first, that regex creates a direct security blind spot in the main artefact type and would let sensitive credentials through pre-commit and CI.

Useful? React with 👍 / 👎.


# Notebook validation stays local to this repository because the check is
# specific to how we want notebooks to behave on GitHub.
- repo: local
hooks:
- id: prevent-private-key-commit
name: Prevent private-key credentials.json commit
entry: |
bash -c '
for file in $(git diff --cached --name-only); do
# Skip .pre-commit-config.yaml and other excluded files
if [[ "$file" == ".pre-commit-config.yaml" ]]; then
continue
fi
# Check if the file contains "private_key"
if [ -f "$file" ] && grep -q '"private_key"' "$file"; then
echo "Error: Sensitive content detected in $file! Aborting commit."
exit 1
fi
done
'
- id: validate-notebooks
name: Validate notebook JSON and GitHub-safe metadata
entry: uv run python scripts/validate_notebooks.py
language: system
types: [file]
files: \.ipynb$
129 changes: 129 additions & 0 deletions .secrets.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"version": "1.5.0",
"plugins_used": [
{
"name": "ArtifactoryDetector"
},
{
"name": "AWSKeyDetector"
},
{
"name": "AzureStorageKeyDetector"
},
{
"name": "Base64HighEntropyString",
"limit": 4.5
},
{
"name": "BasicAuthDetector"
},
{
"name": "CloudantDetector"
},
{
"name": "DiscordBotTokenDetector"
},
{
"name": "GitHubTokenDetector"
},
{
"name": "GitLabTokenDetector"
},
{
"name": "HexHighEntropyString",
"limit": 3.0
},
{
"name": "IbmCloudIamDetector"
},
{
"name": "IbmCosHmacDetector"
},
{
"name": "IPPublicDetector"
},
{
"name": "JwtTokenDetector"
},
{
"name": "MailchimpDetector"
},
{
"name": "NpmDetector"
},
{
"name": "OpenAIDetector"
},
{
"name": "PrivateKeyDetector"
},
{
"name": "PypiTokenDetector"
},
{
"name": "SendGridDetector"
},
{
"name": "SlackDetector"
},
{
"name": "SoftlayerDetector"
},
{
"name": "SquareOAuthDetector"
},
{
"name": "StripeDetector"
},
{
"name": "TelegramBotTokenDetector"
},
{
"name": "TwilioKeyDetector"
}
],
"filters_used": [
{
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
},
{
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
"min_level": 2
},
{
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
},
{
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
},
{
"path": "detect_secrets.filters.heuristic.is_lock_file"
},
{
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
},
{
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
},
{
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
},
{
"path": "detect_secrets.filters.heuristic.is_sequential_string"
},
{
"path": "detect_secrets.filters.heuristic.is_swagger_file"
},
{
"path": "detect_secrets.filters.heuristic.is_templated_secret"
},
{
"path": "detect_secrets.filters.regex.should_exclude_file",
"pattern": [
"(^uv.lock$|^edgeai-mlops/models/.*|.*\\.ipynb$)"
]
}
],
"results": {},
"generated_at": "2026-04-12T00:00:00Z"
}
45 changes: 29 additions & 16 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,36 @@
default:
@just --list

# Install virtual environment and pre-commit hooks
# Install the shared notebook environment and register the repo hooks.
install:
echo "🚀 Creating virtual environment and syncing dependencies with uv"
uv sync
echo "🚀 Installing pre--commit hooks"
uv run pre-commit install
@echo "Syncing dependencies with uv"
uv sync --group dev --frozen
@if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then \
echo "Installing pre-commit hooks"; \
uv run pre-commit install; \
else \
echo "Skipping pre-commit installation because no Git repository was detected."; \
fi

# Create a virtual environment with uv
venv:
echo "🚀 Creating virtual environment with uv in folder .venv"
python3 -m venv .venv
echo "🚀 Installing uv in the virtual environment"
.venv/bin/pip install --upgrade uv

# Upgrading locked package versions
# Upgrade the lockfile and sync the shared notebook environment.
upgrade:
echo "🚀 Upgrading locked package versions"
@echo "Updating the lockfile and syncing dependencies"
uv lock --upgrade
echo "🚀 Syncing dependencies with uv"
uv sync
uv sync --group dev

# Format Python helper scripts and tests.
format:
uv run ruff format .

# Lint Python helper scripts and tests.
lint:
uv run ruff check .

# Validate tracked notebooks for JSON and GitHub-rendering compatibility.
check-notebooks:
uv run python scripts/validate_notebooks.py

# Run the repository-wide hygiene checks.
check:
uv run pre-commit run --all-files
uv run python -m unittest discover -s tests -p "test_*.py"
Loading
Loading