From 3a3f4dcfeb077d7310c94fb838ea8adb240d14ec Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 18 May 2026 08:26:26 -0700 Subject: [PATCH] chore: add agent and copilot setup files (#2861) * chore: Add agent and copilot setup files Add AGENTS.md with project-specific developer notes for AI agents. Add GitHub Actions workflow to validate Copilot setup steps. Add changelog-entry skill for automated changelog generation. Assisted-by: OpenCode:kimi * Update .gitignore to include CLAUDE.md Add CLAUDE.md to .gitignore for symlink instructions --- .agents/skills/changelog-entry/SKILL.md | 122 ++++++++++++++++++++++ .github/workflows/copilot-setup-steps.yml | 40 +++++++ .gitignore | 3 + AGENTS.md | 57 ++++++++++ 4 files changed, 222 insertions(+) create mode 100644 .agents/skills/changelog-entry/SKILL.md create mode 100644 .github/workflows/copilot-setup-steps.yml create mode 100644 AGENTS.md diff --git a/.agents/skills/changelog-entry/SKILL.md b/.agents/skills/changelog-entry/SKILL.md new file mode 100644 index 00000000..62fd01e7 --- /dev/null +++ b/.agents/skills/changelog-entry/SKILL.md @@ -0,0 +1,122 @@ +--- +name: changelog-entry +description: Generate a new changelog entry for cibuildwheel based on all changes since the last tag. Use when updating the changelog or preparing a release. +--- + +# Generate Changelog Entry + +Produce a new version section at the top of `docs/changelog.md` summarizing all changes since the last git tag. + +## Steps + +1. **Find the last tag** — run `git tag --sort=-version:refname | head -1` to get the most recent version tag. +2. **Gather changes** — run `git log ..HEAD --oneline` and `git log ..HEAD --format="%H %s"` to see all commits since that tag. +3. **Read each merge/commit** — for substantive commits, read the full message and any linked PRs to understand the change. Use `git log ..HEAD --format="---%n%B"` for full messages. If a commit message is ambiguous, use `gh pr view ` to get richer context from GitHub. +4. **Classify and draft entries** — assign each change an emoji and write a one-line description following the style rules below. Combine related small PRs of the same type (bot dependency updates, dependabot CI action bumps, pre-commit autoupdates) into a single entry listing all PR numbers. Skip meta-changelog PRs (e.g., "Add missing CHANGELOG entries") — they don't describe user-facing changes. If a bot/dependency PR contains a substantive fix mixed in (e.g., a pip revert inside a dependency update), split it: mention the fix separately under its own category. +5. **Determine the new version number** — inspect commits for breaking changes or new features to decide patch/minor/major bump. Ask the user if unclear. +6. **Determine the date** — use today's date. +7. **Insert the new section** — add it at the top of `docs/changelog.md`, right after the `# Changelog` heading and a blank line, before any existing version sections. + +## Style Rules + +These are non-negotiable formatting conventions derived from the existing changelog. + +### Version heading + +```markdown +### v3.4.2 +``` + +`###` heading, `v` prefix, full semver. + +### Date line + +```markdown +_14 May 2026_ +``` + +Italic (underscore-wrapped), day without leading zero, full month name, 4-digit year. One blank line after the date. + +### Entry format + +```markdown +- (#) +``` + +- Each entry is a single bullet starting with `- `. +- Emoji immediately after the dash-space. +- Space between emoji and description text. +- PR number(s) in parens at end: `(#1234)` or `(#1234, #5678)`. +- No trailing period for single-sentence entries. +- Period at end of multi-sentence entries only. + +### Emoji categories + +Use exactly one emoji per entry, chosen by category: + +| Emoji | Category | Used for | +|-------|----------|----------| +| 🌟 | Major feature | New platforms, significant new capabilities | +| ✨ | Feature | New features, additions, user-visible enhancements | +| 🐛 | Bug fix | Bug fixes | +| 🛠 | Maintenance | Dep updates, internal improvements, behavior tweaks | +| ⚠️ | Warning | Deprecations, breaking changes, dropped support | +| 📚 | Docs | Documentation changes | +| 💼 | Internal | Non-user-facing infra/tooling changes | +| 🧪 | Tests | Test changes | +| 🔐 | Security | Security-related changes (used in past changelogs) | + +### Category disambiguation + +When a change could fit multiple categories, use these tiebreakers: + +- **CI/workflow fixes** → 💼 (not 🧪) — they fix infra, not test logic. +- **Test suite changes** → 🧪 — only for changes to the test code itself. +- **Diagnostic output changes** (e.g., printing more info during builds) → 🛠 (not 🐛) — they're improvements, not bug fixes. +- **A bug fix that also changes test code** → 🐛 — the user-facing fix takes priority; test changes are implicit. + +### Writing style + +- **Present tense**: "Adds", "Fixes", "Updates", not "Added", "Fixed". +- **Sentence case**: capitalize only the first word after the emoji. +- **Link option names to docs**: `[`option-name`](https://cibuildwheel.pypa.io/en/stable/options/#option-name)`. Option anchors match the option name — verify in `docs/options.md` by searching for `{: #option-name }`. +- Be specific about what changed and why, not just that something changed. + +### Ordering + +Within a version section, order entries by importance: + +1. 🌟 entries first +2. ⚠️ entries next +3. ✨ entries +4. 🐛 entries +5. 🛠 entries +6. 📚 entries +7. 💼 entries +8. 🧪 entries last + +### Multi-line entries + +For complex features needing explanation, use an indented italic paragraph: + +```markdown +- ✨ Short summary here. (#1234) + + _Longer explanation with details and caveats._ (#1234) +``` + +Adding a new Python beta version always has a specific longer explanation, check for a previous addition (like 3.14) for the note to use. + +### Blank lines + +- One blank line between version sections. +- No blank lines between bullets within a version. + +## Validation + +After inserting the new section: + +1. Check that the new section follows all style rules above. +2. Verify PR numbers match actual PRs in the commit log. +3. Ensure no duplicate entries — multiple commits to the same PR should produce one entry. +4. Run a final review of the file to confirm formatting is consistent with surrounding entries. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 00000000..dba7afd5 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,40 @@ +name: "Copilot Setup Steps" + +permissions: {} + +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + copilot-setup-steps: + name: Copilot Setup Steps + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.x" + allow-prereleases: true + + - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + + - name: Install tooling + run: | + uv tool install nox + uv tool install prek + + - name: Pre-install checks + run: | + prek prepare-hooks diff --git a/.gitignore b/.gitignore index 78a73045..d06a56b8 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,6 @@ site/ # OS files .DS_Store + +# This file should be a symlink or contain "See @AGENTS.md" +CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..186cc65e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,57 @@ +# cibuildwheel — Agent Notes + +## Always run + +- `prek -a` should be run after changes to reformat, lint, and type check + +## Developer commands +- `uv run pytest unit_test` — Quick run for unit tests +- `nox -s tests` — run doctests + unit tests + integration tests (slow, >30 min, requires system Python installs on macOS). +- `nox -s tests -- unit_test` — fast unit tests only. +- `nox -s tests -- test -k before_build` — single integration test/file via pytest `-k`. +- `nox -s lint` — run all linters (pre-commit/prek). +- `nox -s pylint` — run pylint separately (not in pre-commit). +- `nox -s docs` — mkdocs serve (interactive) or build (non-interactive). +- Set up local dev env at `.venv`: `uv sync` (dependency groups used). + +## Project layout +- `cibuildwheel/` — main package. Entry point: `cibuildwheel.__main__:main`. +- `test/` — **integration tests** (expensive, run actual wheel builds). +- `unit_test/` — **unit tests** (fast, no wheel builds). +- `bin/` — maintainer scripts (update pins, generate README tables, schema, etc.). +- `docs/` — mkdocs source. + +## Testing specifics +- Three test suites exist, run in this order by `bin/run_tests.py`: + 1. `pytest cibuildwheel` — doctests. + 2. `pytest unit_test [...]` — unit tests. + 3. `pytest test [...]` — integration tests (split into `serial` and `not serial` runs). +- Serial integration tests **must not** run in parallel; non-serial use pytest-xdist by default. +- Custom pytest options: + - `--run-docker` (unit_test + test): run OCI container tests. Linux only. + - `--run-podman`: run podman tests (Linux). + - `--run-emulation` (test): run QEMU emulation tests (e.g., `--run-emulation aarch64`). + - `--platform linux` (test): force integration tests to target Linux container builds even on macOS/Windows. + - `--enable` (test): sets `CIBW_ENABLE` env var (e.g., `pypy`, `graalpy`). +- Integration tests auto-set a default `CIBW_ENABLE` if the env var is absent. +- The `build_frontend_env` fixture parameterizes over `pip`, `build`, `build[uv]`, `uv` and skips unsupported combos per platform. +- Some integration tests require system Python.org installs on macOS; missing them prints a download URL in the error. +- iOS/Android/pyodide tests have dedicated pytest marks (`ios`, `android`, `pyodide`) and need platform-specific runners/simulators. + +## Lint / typecheck +- Ruff (lint + format) and mypy run via pre-commit. Pylint runs separately via `nox -s pylint`. +- Mypy is strict (`strict = true`) and targets Python 3.11 for the package, 3.14 for a second check in pre-commit. +- Ruff config in `pyproject.toml` (`line-length = 100`). +- Python 3.11 is the minimum supported version for the package itself. + +## Generated / maintained files +- `README.md` contains two **cog-generated** tables (options table, changelog preview). Pre-commit runs `cog -c -P -r -I ./bin README.md`. Edit the source scripts (`bin/readme_*.py`) or the upstream files (`docs/options.md`, `docs/changelog.md`) — do not hand-edit the generated blocks. Note the identifier is _not_ cog generated, and can be edited. +- `cibuildwheel/resources/cibuildwheel.schema.json` is generated by `bin/generate_schema.py` (run via `nox -s generate_schema`). +- `cibuildwheel/resources/constraints-*.txt` are generated via `nox -s update_constraints`. +- `cibuildwheel/resources/pinned_docker_images.cfg` and other resource files are updated via `nox -s update_pins`. + +## CI / release quirks +- CI uses `uv sync --no-dev --group test` for test installs, then `uv run --no-sync` to execute. +- The release workflow uses `hynek/build-and-inspect-python-package` for dist building. +- `test.yml` skips unrelated paths to avoid burning CI time on docs-only changes. +- A sample project artifact is built once and downloaded by downstream test jobs to avoid redundant work.