Skip to content
Merged
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
102 changes: 102 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Copilot Instructions for PEP 723 Loader

## Project Overview

**PEP 723 Loader** auto-installs [PEP 723](https://peps.python.org/pep-0723/) inline script dependencies before running linters (mypy, ruff, basedpyright). Small Python 3.10+ project (~500 LOC) using uv for builds/deps, monorepo in `packages/pep723_loader/`.

**CRITICAL**: Install `uv` first: `pip install uv`

## Build and Validation Commands

### Initial Setup (ALWAYS run first)

```bash
uv sync # ~60-90s first run, <5s after. Installs all deps into .venv/
```

### Testing

```bash
uv run pytest # All tests with coverage (~10-15s), requires ≥70%
uv run pytest --no-cov # Faster iteration
uv run pytest path/to/test.py # Single file
uv run pytest path/to/test.py::TestClass::test_method # Single test
```

Expected: 39 tests pass, ~91% coverage.

### Linting, Formatting, Type Checking

```bash
uv run ruff check --fix . # Auto-fix issues (~2-3s)
uv run ruff format . # Format code (~1-2s)
uv run mypy packages/ # Type check (~5-8s)
uv run basedpyright packages/ # Alternative type checker (~10-15s)
uv run pre-commit run --all-files # All hooks (~30-60s first, ~10-20s after)
```

### Building

```bash
uv build # Creates wheel + sdist in dist/ (~5-10s)
```

### Full Pre-Push Validation

```bash
uv sync && uv run ruff check --fix . && uv run ruff format . && \
uv run mypy packages/ && uv run basedpyright packages/ && uv run pytest
```

## Project Layout & Architecture

```
packages/pep723_loader/
├── cli.py # Typer CLI entry, wraps commands, installs deps, propagates exit codes
├── pep723_checker.py # Core: discovers .py files, runs `uv export --script`, aggregates deps
├── dependencies.py # Reserved (empty)
├── version.py # Git tag-based version via hatch-vcs
└── tests/
├── unit/ # Mock subprocess calls, use fixtures in fixtures/
└── e2e/ # Real command execution tests
```

**Key Flow**: CLI → extract Python files from args → `Pep723Checker` runs `uv export --script` → install via `uv pip install` → execute wrapped command → propagate exit code.

**Config Files**:
- `pyproject.toml`: Tool configs (ruff: 120 char lines, Google docstrings; mypy: strict; pytest: ≥70% cov)
- `.pre-commit-config.yaml`: Hooks use `uv run --no-sync` with pep723-loader (dogfooding)
- `.gitignore`: Excludes `.venv/`, `dist/`, `__pycache__/`, cache dirs

## CI/CD Workflows

**auto-publish.yml** (on push to `main`): Bumps version → builds → publishes to PyPI via OIDC → creates GitHub release. Uses `astral-sh/setup-uv@v7`, requires `pypi` environment.

**zizmor.yml** (on push/PR): Scans workflows for security issues.

## Common Pitfalls

1. **`uv: command not found`**: Install with `pip install uv` or `curl -LsSf https://astral.sh/uv/install.sh | sh`
2. **Shallow clone warnings**: Harmless - from setuptools-scm in CI environments
3. **Import errors**: Run `uv sync` first
4. **Pre-commit fails**: Ensure `uv sync` ran; hooks use `--no-sync` for speed
5. **Coverage <70%**: Add tests; use `pytest --cov-report=html` for details
6. **Type errors in git.py**: Ignore - it's gitpython, not our code

## Code Conventions

- Python 3.10+ (use `|` for unions, not `Union`)
- Full type hints (mypy strict mode)
- Google-style docstrings, 120 char lines
- Path objects over strings
- f-strings over `.format()` or `%`
- Tests follow AAA pattern (Arrange, Act, Assert)

## When to Search Beyond This

These instructions are validated. Only search if:
- Command fails unexpectedly
- Adding new dependency/tool
- Instructions incomplete for your scenario

**Default validation**: `uv sync && uv run pytest`
13 changes: 8 additions & 5 deletions .github/workflows/auto-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false

- name: Bump version and push tag
id: tag_version
uses: anothrNick/github-tag-action@1.70.0
uses: anothrNick/github-tag-action@777684df761b882a3f4f70db16ac70d8cc78d0ea # 1.70.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true
Expand All @@ -32,13 +33,15 @@ jobs:

- name: Fetch tags and checkout new tag
if: steps.tag_version.outputs.new_tag
env:
NEW_TAG: ${{ steps.tag_version.outputs.new_tag }}
run: |
git fetch --tags
git checkout ${{ steps.tag_version.outputs.new_tag }}
git checkout "$NEW_TAG"

- name: Install uv
if: steps.tag_version.outputs.new_tag
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
with:
enable-cache: true

Expand All @@ -56,7 +59,7 @@ jobs:

- name: Create GitHub Release
if: steps.tag_version.outputs.new_tag
uses: ncipollo/release-action@v1
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.0
with:
tag: ${{ steps.tag_version.outputs.new_tag }}
name: Release ${{ steps.tag_version.outputs.new_tag }}
Expand Down