Skip to content

Commit d8e3eab

Browse files
committed
ci: add prek pre-commit hooks, CI workflows, and tool config
Tooling: - Add prek/ipykernel/pandas-stubs to dev extras - Configure ruff (line-length, qmd as markdown, per-file F841 ignore in tests) - Configure mypy with ignore_missing_imports for arviz/xarray/numpy/pandas/polars - Add .pre-commit-config.yaml (trailing-ws, EOF, yaml/toml/merge-conflict checks, ruff + ruff-format on py/pyi/ipynb/qmd, mypy on tidydraws/) - Fix __init__.py re-export via __all__ + redundant-alias imports (F401) - Fix real mypy error in _coerce_to_dataframe (pd=None assigned to Module) - Makefile: install uses --all-extras, add precommit target, align type-check CI: - .github/workflows/ci.yml: test (uv sync --all-extras + pytest) and prek (changed-files on PRs, all-files on pushes) jobs - .github/workflows/docs.yml: build-docs runs on every push/PR to catch breakage; publish-docs is manual-only (workflow_dispatch) until the doc review pass completes — full Pages publish machinery wired so flipping to auto-on-main is a one-line trigger change PRD milestones ticked to reflect actual implementation status (v0.1 code + docs complete except GitHub Pages deploy; v0.2 docs partly done). prek reformatted several files on first run (whitespace/EOF/ruff-format normalization expected for a repo with no prior formatting); all green now.
1 parent 0867429 commit d8e3eab

19 files changed

Lines changed: 633 additions & 233 deletions

.github/workflows/ci.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
9+
permissions: {}
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
test:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
steps:
21+
- uses: actions/checkout@v4
22+
with:
23+
persist-credentials: false
24+
- name: Install uv
25+
uses: astral-sh/setup-uv@v8.2.0
26+
- name: Install dependencies
27+
run: uv sync --all-extras
28+
- name: Run tests
29+
run: uv run pytest -v
30+
31+
prek:
32+
runs-on: ubuntu-latest
33+
permissions:
34+
contents: read
35+
steps:
36+
- uses: actions/checkout@v4
37+
with:
38+
fetch-depth: 0
39+
persist-credentials: false
40+
- name: Install uv
41+
uses: astral-sh/setup-uv@v8.2.0
42+
- name: Install dependencies
43+
# Locked install so the mypy hook sees project deps, matching local
44+
# `make lint` behaviour.
45+
run: uv sync --all-extras
46+
- name: Run prek on changed files in PRs
47+
if: github.event_name == 'pull_request'
48+
run: uv run prek run --from-ref "$BASE_SHA" --to-ref "$HEAD_SHA"
49+
env:
50+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
51+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
52+
- name: Run prek on all files on pushes
53+
if: github.event_name != 'pull_request'
54+
run: uv run prek run --all-files

.github/workflows/docs.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: CI Docs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
workflow_dispatch:
9+
inputs:
10+
deploy:
11+
description: "Publish the built site to GitHub Pages"
12+
type: boolean
13+
default: false
14+
15+
# The repo is private and the docs are under review, so the site is NOT
16+
# auto-published yet. `build-docs` runs on every push/PR to catch breakage.
17+
# `publish-docs` only runs on manual `workflow_dispatch` with `deploy=true`.
18+
# Once the doc review pass is complete, flip the publish trigger to
19+
# `if: github.ref == 'refs/heads/main'` (tracked in the go-live issue).
20+
jobs:
21+
build-docs:
22+
name: "Build Docs"
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0 # Full history for accurate page timestamps
28+
29+
- name: Install uv
30+
uses: astral-sh/setup-uv@v8.2.0
31+
32+
- name: Install package and dependencies
33+
# uv sync installs the locked dependency set from uv.lock, so CI
34+
# resolves the exact versions used in local dev.
35+
run: uv sync --all-extras
36+
37+
- name: Register `python3` Jupyter kernel
38+
# .qmd files (and great-docs.yml) declare `jupyter: python3`, so the
39+
# CI runner needs a kernelspec under that name pointing at the same
40+
# Python interpreter the package was installed into above.
41+
run: uv run python -m ipykernel install --user --name python3
42+
43+
- name: Set up Quarto
44+
uses: quarto-dev/quarto-actions/setup@v2
45+
46+
- name: Build docs
47+
run: uv run great-docs build
48+
49+
- name: Verify agent-context files were generated
50+
# great-docs writes llms.txt / llms-full.txt / skill.md at build step,
51+
# but llms-full.txt is only emitted if `import tidydraws` succeeds and
52+
# that failure is swallowed. Assert the files landed in _site so a
53+
# silent skip fails CI instead of shipping an incomplete site.
54+
run: |
55+
for f in llms.txt llms-full.txt skill.md; do
56+
if [[ ! -s "great-docs/_site/$f" ]]; then
57+
echo "::error::great-docs/_site/$f missing or empty after build"
58+
exit 1
59+
fi
60+
echo "OK: $f ($(wc -c < "great-docs/_site/$f") bytes)"
61+
done
62+
63+
- name: Save docs artifact
64+
uses: actions/upload-artifact@v4
65+
with:
66+
name: docs-html
67+
path: great-docs/_site
68+
69+
publish-docs:
70+
name: "Publish Docs"
71+
runs-on: ubuntu-latest
72+
needs: "build-docs"
73+
if: github.event_name == 'workflow_dispatch' && inputs.deploy
74+
permissions:
75+
pages: write
76+
id-token: write
77+
environment:
78+
name: github-pages
79+
url: ${{ steps.deployment.outputs.page_url }}
80+
steps:
81+
- uses: actions/download-artifact@v4
82+
with:
83+
name: docs-html
84+
path: great-docs/_site
85+
86+
- name: Upload Pages artifact
87+
uses: actions/upload-pages-artifact@v3
88+
with:
89+
path: great-docs/_site
90+
91+
- name: Deploy to GitHub Pages
92+
id: deployment
93+
uses: actions/deploy-pages@v4

.pre-commit-config.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Pre-commit hooks run via `prek` (a fast, pre-commit-compatible runner).
2+
# CI mirrors local behaviour: `uv run prek run --all-files` (pushes) or
3+
# `uv run prek run --from-ref BASE --to-ref HEAD` (PRs).
4+
repos:
5+
- repo: https://github.com/pre-commit/pre-commit-hooks
6+
rev: v5.0.0
7+
hooks:
8+
- id: trailing-whitespace
9+
exclude_types: [svg]
10+
- id: end-of-file-fixer
11+
exclude_types: [svg]
12+
- id: check-yaml
13+
- id: check-toml
14+
- id: check-merge-conflict
15+
- id: check-added-large-files
16+
args: ["--maxkb=1500"]
17+
- repo: https://github.com/astral-sh/ruff-pre-commit
18+
rev: v0.15.12
19+
hooks:
20+
- id: ruff
21+
types_or: [python, pyi, jupyter]
22+
args: [--fix]
23+
- id: ruff-format
24+
types_or: [python, pyi, jupyter, text]
25+
files: \.(py|pyi|ipynb|qmd)$
26+
- repo: https://github.com/pre-commit/mirrors-mypy
27+
rev: v1.15.0
28+
hooks:
29+
- id: mypy
30+
args: [--ignore-missing-imports]
31+
files: ^tidydraws/
32+
additional_dependencies: [numpy>=1.20, pandas-stubs, polars]

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ tidydraws uses `uv` for managing dependencies. Make sure you have it installed b
5757
uv run mypy .
5858
```
5959

60-
## Testing
60+
## Testing
6161
Run tests with:
6262
```bash
6363
uv run pytest
@@ -120,7 +120,7 @@ This repo ships the [Great Docs Agent Skills](https://posit-dev.github.io/great-
120120

121121
## Pull Request Guidelines
122122

123-
- Reference relevant issues in your PR description
123+
- Reference relevant issues in your PR description
124124
- Ensure all tests pass
125125
- Add or update documentation as needed
126-
- Keep changes focused and atomic
126+
- Keep changes focused and atomic

Makefile

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
# Makefile for tidydraws development workflow
22

3-
.PHONY: help install test lint type-check docs docs-preview cleandocs build clean
3+
.PHONY: help install test lint type-check precommit docs docs-preview cleandocs build clean
44

55
# Help target to show available commands
66
help:
77
@echo "Available commands:"
8-
@echo " install - Install dependencies with uv"
8+
@echo " install - Install all dependencies (incl. dev) with uv"
99
@echo " test - Run all tests"
1010
@echo " lint - Run code linting with ruff"
1111
@echo " type-check - Run type checking with mypy"
12+
@echo " precommit - Run prek (pre-commit) hooks on all files"
1213
@echo " docs - Build the documentation site (great-docs)"
1314
@echo " docs-preview - Build and serve the docs locally with live reload"
1415
@echo " cleandocs - Remove the ephemeral great-docs/ build directory"
1516
@echo " clean - Clean build artifacts"
1617

1718
# Install dependencies
1819
install:
19-
uv sync
20+
uv sync --all-extras
2021

2122
# Run tests
2223
test:
@@ -28,7 +29,11 @@ lint:
2829

2930
# Type check with mypy
3031
type-check:
31-
uv run mypy .
32+
uv run mypy tidydraws
33+
34+
# Run pre-commit hooks via prek
35+
precommit:
36+
uv run prek run --all-files
3237

3338
# Build the documentation site into the ephemeral great-docs/_site/ directory
3439
docs:
@@ -46,4 +51,4 @@ cleandocs:
4651
clean: cleandocs
4752
rm -rf .pytest_cache/
4853
find . -name "*.pyc" -delete
49-
find . -name "__pycache__" -type d -exec rm -rf {} +
54+
find . -name "__pycache__" -type d -exec rm -rf {} +

PRD.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ def spread_draws_compare(
302302
Example
303303
-------
304304
# Extract posterior and prior for side-by-side forest plots
305-
compare_df = spread_draws_compare(dt, "beta[groups]",
305+
compare_df = spread_draws_compare(dt, "beta[groups]",
306306
groups=["posterior", "prior"])
307307
# → columns: chain, draw, groups, beta, source
308308
# → source ∈ {"posterior", "prior"}
@@ -898,5 +898,3 @@ Join only if you genuinely need both:
898898
spread_draws(...).join(add_epred_draws(...), on=["chain", "draw", "group"])
899899
→ Explicit, and the user understands what they're paying for
900900
```
901-
902-

0 commit comments

Comments
 (0)