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
9 changes: 9 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ jobs:
- name: Build sdist and wheel
run: python -m build

- name: Install verification tools
run: uv pip install --system check-manifest==0.51 twine==6.2.0

- name: Verify sdist completeness
run: check-manifest --verbose

- name: Validate distribution metadata
run: twine check --strict dist/*

- name: Upload distribution artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,12 @@ repos:
additional_dependencies:
- pycparser
- click

- repo: https://github.com/mgedmin/check-manifest
rev: "0.51"
hooks:
- id: check-manifest
args: [--no-build-isolation]
additional_dependencies:
- setuptools>=61
- wheel
Comment thread
elijahr marked this conversation as resolved.
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [3.2.3] - 2026-06-05

### Fixed
- **Incomplete source distribution** - The PyPI sdist now ships the full test
suite, including helper modules (`test/assertions.py`, `test/cython_utils.py`,
`test/conftest.py`, `test/header_cache.py`, `test/library_detection.py`),
fixtures, and data directories. Previously these were omitted, causing
`ModuleNotFoundError: No module named 'test.assertions'` when downstream
packagers ran the tests from the sdist (NixOS/nixpkgs#524341). The release
workflow now runs `check-manifest` and `twine check --strict` before publishing
so an incomplete sdist cannot ship again.

Note for downstream packagers without network access: the `real_headers` tests
download library headers at runtime and must be deselected with
`pytest -m "not real_headers"`.
- **Missing runtime stub in wheel and sdist** - Ship
`autopxd/stubs/darwin-include/.supports-builtin-modules` in both the wheel and
the sdist. The `stubs/darwin-include/**/*` package-data glob silently skipped
leading-dot files, so this runtime include-tree stub was missing from every
previous wheel.

## [3.2.2] - 2025-12-19

### Fixed
Expand Down Expand Up @@ -179,7 +200,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- macOS support

[Unreleased]: https://github.com/elijahr/python-autopxd2/compare/v3.2.0...HEAD
[Unreleased]: https://github.com/elijahr/python-autopxd2/compare/v3.2.3...HEAD
[3.2.3]: https://github.com/elijahr/python-autopxd2/compare/v3.2.2...v3.2.3
[3.2.2]: https://github.com/elijahr/python-autopxd2/compare/v3.2.1...v3.2.2
[3.2.1]: https://github.com/elijahr/python-autopxd2/compare/v3.2.0...v3.2.1
[3.2.0]: https://github.com/elijahr/python-autopxd2/compare/v3.1.1...v3.2.0
[3.1.1]: https://github.com/elijahr/python-autopxd2/compare/v3.1.0...v3.1.1
[3.1.0]: https://github.com/elijahr/python-autopxd2/compare/v3.0.0...v3.1.0
Expand Down
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,24 @@ This section is for project maintainers who can publish releases.
git push origin master
```

> **Important:** The git ref you release from (the tag, or the SHA passed to
> the manual `workflow_dispatch`) MUST contain the `pyproject.toml` version
> bump. `workflow_dispatch` accepts an arbitrary ref and will happily build
> and publish from a ref that lacks the bump.

### Sdist completeness guard

The publish workflow builds the sdist and wheel, then runs `check-manifest`
and `twine check --strict` **before** uploading the distribution artifacts. If
the sdist is missing any version-controlled file that belongs in it (for
example, a new test helper or fixture), `check-manifest` fails, the `build`
job fails, and because `publish-pypi` depends on `build`, nothing is published.

`check-manifest` also runs locally via pre-commit, so drift is usually caught
before you push. If it flags a new file, update `MANIFEST.in` (to ship it) or
the `[tool.check-manifest]` `ignore` list in `pyproject.toml` (to keep it out
of the sdist) — never weaken the gate to make it pass.

### 2. Create a GitHub Release

1. Go to [Releases](https://github.com/elijahr/python-autopxd2/releases)
Expand Down
34 changes: 34 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Sdist content spec. The wheel is unaffected (include_package_data is not set;
# packages are controlled by [tool.setuptools.packages.find]).
# Ship the complete test tree so downstream packagers (e.g. nixpkgs) can run the
# suite from the sdist. See NixOS/nixpkgs#524341.

# --- Test suite: helpers, fixtures, and data (the fix) ---
# Ship the entire tracked test tree; byte-compiled cruft is excluded below.
graft test

# --- Runtime stub dotfile dropped by setuptools globbing ---
# The "stubs/darwin-include/**/*" package-data glob does not match leading-dot
# files, so the sdist's default include misses this tracked stub. It is read at
# runtime (clang -I include path), so ship it explicitly.
include autopxd/stubs/darwin-include/.supports-builtin-modules

# --- Top-level docs/metadata worth shipping in source form ---
include CHANGELOG.md
include CONTRIBUTING.md
include regenerate_stubs.py

# --- Test-library install helpers referenced by test/test_real_headers.py ---
graft scripts

# --- Repo-only infrastructure: never ship ---
exclude .gitignore
exclude .dockerignore
exclude .pre-commit-config.yaml
exclude Dockerfile
exclude mkdocs.yml
prune .github
prune docs

# --- Hygiene: keep graft from sweeping byte-compiled files ---
global-exclude *.py[cod]
20 changes: 18 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools", "wheel"]
requires = ["setuptools>=61", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "autopxd2"
version = "3.2.2"
version = "3.2.3"
description = "Automatically generate Cython pxd files from C headers"
readme = "README.md"
license = { file = "LICENSE" }
Expand Down Expand Up @@ -67,6 +67,11 @@ autopxd = [
"stubs/include/**/*",
"stubs/darwin-include/*",
"stubs/darwin-include/**/*",
# Leading-dot files are not matched by the "*" globs above (setuptools
# mirrors shell semantics where "*" skips dotfiles). This stub is consumed
# at runtime via the clang -I include path (declarations.py /
# pycparser_backend.py), so it must ship in the wheel as well as the sdist.
"stubs/darwin-include/.supports-builtin-modules",
]

[tool.ruff]
Expand Down Expand Up @@ -120,3 +125,14 @@ markers = [
"libclang: tests/parameterizations using the libclang backend (includes C++ tests)",
"real_headers: tests against real system libraries (requires library installation)",
]

[tool.check-manifest]
ignore = [
".gitignore",
".dockerignore",
".pre-commit-config.yaml",
"Dockerfile",
"mkdocs.yml",
".github/**",
"docs/**",
]
Loading