Skip to content

Commit e1c191f

Browse files
authored
feat: new documentation and CI improvements (#15)
Signed-off-by: Will Killian <william.killian@outlook.com>
1 parent 5d904d0 commit e1c191f

50 files changed

Lines changed: 4899 additions & 994 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 4
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.{py,pyi}]
12+
indent_size = 4

.github/workflows/docs.yml

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,60 @@
1+
# Publish Fern docs to https://mucsci-scheduler.docs.buildwithfern.com
2+
# Requires repository secret FERN_TOKEN (see Fern Dashboard / `fern token`).
3+
14
name: documentation
25

36
on:
47
push:
5-
tags:
6-
- '*'
8+
branches:
9+
- main
10+
paths:
11+
- "fern/**"
12+
- "scripts/**"
13+
- "src/scheduler/**"
14+
- ".github/workflows/docs.yml"
15+
workflow_dispatch:
716

817
permissions:
918
contents: read
1019

1120
jobs:
12-
build:
21+
publish:
1322
runs-on: ubuntu-latest
1423
steps:
1524
- name: Checkout
1625
uses: actions/checkout@v6
1726
with:
1827
persist-credentials: false
19-
28+
2029
- name: Set up Python
2130
uses: actions/setup-python@v6
2231
with:
23-
python-version: '3.12'
32+
python-version: "3.12"
2433

2534
- name: Install uv
2635
uses: astral-sh/setup-uv@v7
2736

37+
- name: Set up Node
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: "20"
41+
2842
- name: Install the project
29-
run: uv sync --locked --all-extras --dev
43+
run: uv sync --locked --group dev
3044

31-
- name: Build the documentation
32-
run: uv run pdoc -o docs/ scheduler
45+
- name: Generate OpenAPI, JSON Schema, and Python API reference
46+
run: |
47+
uv run python scripts/export_openapi.py
48+
uv run python scripts/export_config_schema.py
49+
uv run python scripts/gen_python_api_mdx.py
3350
34-
- name: Upload the documentation
35-
uses: actions/upload-pages-artifact@v4
36-
with:
37-
path: docs/
51+
- name: Install Fern CLI
52+
run: npm install -g fern-api@4.35.0
3853

39-
# Deploy the artifact to GitHub pages.
40-
# This is a separate job so that only actions/deploy-pages has the necessary permissions.
41-
deploy:
42-
needs: build
43-
runs-on: ubuntu-latest
44-
permissions:
45-
pages: write
46-
id-token: write
47-
environment:
48-
name: github-pages
49-
url: ${{ steps.deployment.outputs.page_url }}
50-
steps:
51-
- id: deployment
52-
uses: actions/deploy-pages@v4
54+
- name: Fern check
55+
run: fern check
56+
57+
- name: Publish docs to Fern
58+
env:
59+
FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
60+
run: fern generate --docs

.github/workflows/linting.yml

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ on:
55
branches:
66
- main
77
pull_request:
8+
branches:
9+
- main
810

911
jobs:
1012
lint:
1113
runs-on: ubuntu-latest
1214
steps:
1315
- name: Checkout
1416
uses: actions/checkout@v6
15-
17+
1618
- name: Set up Python
1719
uses: actions/setup-python@v6
1820
with:
@@ -22,10 +24,27 @@ jobs:
2224
uses: astral-sh/setup-uv@v7
2325

2426
- name: Install the project
25-
run: uv sync --locked --all-extras --dev
27+
run: uv sync --locked --group dev
2628

27-
- name: Run Ruff check
28-
run: uv run ruff check . --output-format=github
29+
- name: Run prek (lint, format, typecheck, file checks)
30+
run: uv run prek run --all-files
31+
32+
test:
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Checkout
36+
uses: actions/checkout@v5
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v6
40+
with:
41+
python-version: '3.12'
42+
43+
- name: Install uv
44+
uses: astral-sh/setup-uv@v7
45+
46+
- name: Install the project
47+
run: uv sync --locked --group dev
2948

30-
- name: Run Ty check
31-
run: uv run ty check .
49+
- name: Run tests
50+
run: uv run pytest

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: actions/checkout@v6
1919
with:
2020
persist-credentials: false
21-
21+
2222
- name: Set up Python
2323
uses: actions/setup-python@v6
2424
with:
@@ -28,7 +28,7 @@ jobs:
2828
uses: astral-sh/setup-uv@v7
2929

3030
- name: Install the project
31-
run: uv sync --locked --all-extras --dev
31+
run: uv sync --locked --group dev
3232

3333
- name: Build the package
3434
run: uv build

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
.venv
22

3+
.env
4+
.env.*
5+
!.env.example
6+
37
**/__pycache__
48
**/*.pyc
59
**/*egg-info*
610

711
dist/
812
.ruff_cache/
913

14+
.coverage
15+
htmlcov/
16+
1017
**/*~
1118
**/#*#
1219

1320
**/*.json
1421
!example.json
22+
!tests/fixtures/**/*.json
1523

1624
**/.DS_Store

.pre-commit-config.yaml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v6.0.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: end-of-file-fixer
7+
- id: check-yaml
8+
- id: check-json
9+
- id: check-toml
10+
- id: check-merge-conflict
11+
- id: detect-private-key
12+
- id: mixed-line-ending
13+
- id: check-added-large-files
14+
args: [--maxkb=500]
15+
- id: check-ast
16+
types: [python]
17+
- id: debug-statements
18+
types: [python]
219
- repo: https://github.com/astral-sh/ruff-pre-commit
320
# Ruff version.
4-
rev: v0.12.12
21+
rev: v0.15.7
522
hooks:
623
# Run the linter.
724
- id: ruff-check
8-
types_or: [ python, pyi ]
25+
types_or: [ python, pyi, pyproject ]
926
args: [ --fix ]
1027
# Run the formatter.
1128
- id: ruff-format
@@ -14,5 +31,6 @@ repos:
1431
hooks:
1532
- id: ty
1633
name: ty check
17-
entry: uvx ty check . --ignore unresolved-import
18-
language: python
34+
entry: uv run ty check . --ignore unresolved-import
35+
language: system
36+
pass_filenames: false

CONTRIBUTING.md

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,8 @@ source .venv/bin/activate # On macOS/Linux
6060
# OR
6161
.venv\Scripts\activate # On Windows
6262

63-
# Install dependencies
63+
# Install dependencies and the package (dev group is included by default; see tool.uv in pyproject.toml)
6464
uv sync
65-
66-
# Install package in editable mode
67-
uv pip install -e .
6865
```
6966

7067
**Alternative (if uv is not available):**
@@ -83,13 +80,28 @@ pip install -e .
8380
### 3. Install Development Dependencies
8481

8582
```bash
86-
# Using uv (recommended)
83+
# Using uv (recommended): `uv sync` installs the dev group by default
84+
uv sync
85+
86+
# If you disabled default-groups, install dev explicitly:
8787
uv sync --group dev
8888

89-
# Using pip
90-
pip install -e ".[dev]"
89+
# Using pip: there is no `[project.optional-dependencies]` dev extra; use uv, or install
90+
# tools from the dev list in pyproject.toml manually after `pip install -e .`
91+
```
92+
93+
### Git hooks (prek)
94+
95+
After `uv sync`, install hooks so the same checks as CI run on each commit:
96+
97+
```bash
98+
uv run prek install
99+
# If you previously used pre-commit and need to replace its hook script:
100+
uv run prek install -f
91101
```
92102

103+
Configuration lives in `.pre-commit-config.yaml` (prek is compatible with this format).
104+
93105
### 4. Verify Installation
94106

95107
```bash
@@ -100,7 +112,7 @@ python -m scheduler.main --help
100112
python -m scheduler.server --help
101113

102114
# Run tests
103-
pytest
115+
uv run pytest
104116
```
105117

106118
## Project Structure
@@ -125,10 +137,22 @@ src/scheduler/
125137
│ └── csv_writer.py # CSV output writer
126138
└── time_slot_generator.py # Time slot generation utilities
127139
128-
docs/ # Documentation
129-
├── configuration.md # Configuration file format
130-
├── python_api.md # Python API
131-
└── rest_api.md # REST API
140+
fern/ # Fern documentation site (published to Fern Cloud)
141+
├── docs.yml # Site config, navigation, branding
142+
├── generators.yml # OpenAPI spec registration
143+
├── openapi.json # Generated from FastAPI (do not edit by hand)
144+
├── fern.config.json # Fern org + CLI version
145+
└── docs/
146+
├── pages/ # MDX guides (configuration, Python, dev, …)
147+
└── assets/ # Logos, favicon, combined-config.schema.json
148+
149+
docs/
150+
└── configuration.md # Redirect pointer to published docs
151+
152+
scripts/
153+
├── export_openapi.py # Refresh fern/openapi.json
154+
├── export_config_schema.py # Refresh JSON Schema asset
155+
└── gen_python_api_mdx.py # Refresh Python API reference from docstrings
132156
```
133157

134158
## Development Workflow
@@ -153,11 +177,17 @@ git checkout -b feature/your-feature-name
153177
### 3. Test Your Changes
154178

155179
```bash
180+
# Run tests
181+
uv run pytest
182+
156183
# Run linting
157-
ruff check
184+
uv run ruff check .
158185

159186
# Run type checking
160-
ty check
187+
uv run ty check . --ignore unresolved-import
188+
189+
# Or run the full hook suite (matches CI)
190+
uv run prek run --all-files
161191
```
162192

163193
### 4. Commit Your Changes
@@ -223,17 +253,17 @@ from .config import SchedulerConfig
223253
```python
224254
def generate_schedule(config: SchedulerConfig) -> List[CourseInstance]:
225255
"""Generate a course schedule based on configuration.
226-
256+
227257
**Args:**
228258
- config: The scheduler configuration containing courses, faculty, and constraints.
229-
259+
230260
**Returns:**
231261
A list of course instances representing the generated schedule.
232-
262+
233263
**Raises:**
234264
- ValueError: If the configuration is invalid.
235265
- RuntimeError: If no valid schedule can be generated.
236-
266+
237267
**Example:**
238268
>>> config = load_config_from_file("config.json")
239269
>>> schedule = generate_schedule(config, limit=5)
@@ -283,23 +313,25 @@ if not faculty_available:
283313
- Update REST API documentation for new endpoints
284314
- Include request/response examples
285315
- Document error codes and messages
286-
- Update OpenAPI schema if applicable
316+
- Regenerate **`fern/openapi.json`** with `uv run python scripts/export_openapi.py` when `server.py` or shared models change
317+
- Regenerate **`fern/docs/pages/python/reference.mdx`** with `uv run python scripts/gen_python_api_mdx.py` when public docstrings change
287318

288319
### User Documentation
289320

321+
- Update **Fern** pages under **`fern/docs/pages/`** (configuration, welcome, development)
290322
- Update README.md for new features
291-
- Add configuration examples
292-
- Update troubleshooting guides
293-
- Include performance considerations
323+
- Regenerate **`fern/docs/assets/combined-config.schema.json`** with `uv run python scripts/export_config_schema.py` when `CombinedConfig` changes
324+
- Preview locally: `npm install -g fern-api` then `fern docs dev` (after the generate scripts above)
294325

295326
## Submitting Changes
296327

297328
### Pull Request Checklist
298329

299330
Before submitting a pull request, ensure:
300331

301-
- [ ] Code passes linting (`ruff check`)
302-
- [ ] Type checking passes (`ty check`)
332+
- [ ] Code passes linting (`uv run ruff check .`)
333+
- [ ] Type checking passes (`uv run ty check . --ignore unresolved-import`)
334+
- [ ] Tests pass (`uv run pytest`)
303335
- [ ] Documentation is updated
304336
- [ ] Breaking changes are documented
305337
- [ ] Commit messages follow conventional format

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1616
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1717
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1818
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19-
SOFTWARE.
19+
SOFTWARE.

0 commit comments

Comments
 (0)