Skip to content

Commit e50f9cb

Browse files
Scope the sdist and wheel to the package
The wheel was scoped to the oxarchive package but the sdist had no list, so the build backend packaged every non-ignored file in the directory. Both targets now include only the package's Python sources plus the readme, changelog, licence and project file. A CI job plants untracked files and fails unless every packaged file is tracked source or build metadata. Agent working directories are ignored.
1 parent f096f58 commit e50f9cb

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Package contents
2+
3+
# Plants untracked files in the tree, builds the sdist and the wheel, and fails
4+
# unless every file in them is a tracked source file or metadata the build
5+
# backend generates. The check is an allowlist on purpose: anything else fails.
6+
on:
7+
pull_request:
8+
push:
9+
branches: [master, main]
10+
11+
jobs:
12+
package-scope:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-python@v5
17+
with:
18+
python-version: '3.11'
19+
- run: pip install build
20+
- name: Plant untracked files that must not be packaged
21+
run: |
22+
mkdir -p .claude/worktrees/probe && echo stray > .claude/worktrees/probe/stray.rs
23+
echo stray > oxarchive/stray.txt
24+
mkdir -p oxarchive/.claude && echo stray > oxarchive/.claude/stray.py
25+
- run: python -m build --outdir dist-check
26+
- name: Every packaged file is tracked source or build metadata
27+
run: |
28+
set -euo pipefail
29+
git ls-files > /tmp/tracked.txt
30+
python - <<'PY'
31+
import glob, sys, tarfile, zipfile
32+
tracked = set(open("/tmp/tracked.txt").read().split())
33+
sdist = tarfile.open(glob.glob("dist-check/*.tar.gz")[0])
34+
sdist_files = {m.name.split("/", 1)[1] for m in sdist.getmembers() if m.isfile()}
35+
wheel_files = set(zipfile.ZipFile(glob.glob("dist-check/*.whl")[0]).namelist())
36+
bad = sorted(f for f in sdist_files if f not in tracked and f != "PKG-INFO")
37+
bad += sorted(f for f in wheel_files
38+
if f not in tracked and ".dist-info/" not in f)
39+
print("sdist:", len(sdist_files), "files; wheel:", len(wheel_files), "files")
40+
if not any(f.startswith("oxarchive/") for f in wheel_files):
41+
sys.exit("::error::the wheel has no oxarchive package")
42+
sys.exit(f"::error::unexpected packaged files: {bad}" if bad else 0)
43+
PY

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,7 @@ dmypy.json
7777
# OS
7878
.DS_Store
7979
Thumbs.db
80+
81+
# Agent working directories. Not source, never packaged.
82+
.claude/
83+
.codex/

‎pyproject.toml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ Issues = "https://github.com/0xArchiveIO/sdk-python/issues"
5454

5555
[tool.hatch.build.targets.wheel]
5656
packages = ["oxarchive"]
57+
include = ["/oxarchive/**/*.py"]
58+
59+
# The sdist needs its own list: without one, hatchling packages every
60+
# non-ignored file in the directory. List what ships instead of trusting the
61+
# default.
62+
[tool.hatch.build.targets.sdist]
63+
include = [
64+
"/oxarchive/**/*.py",
65+
"/README.md",
66+
"/CHANGELOG.md",
67+
"/LICENSE",
68+
"/pyproject.toml",
69+
]
5770

5871
[tool.ruff]
5972
line-length = 100

0 commit comments

Comments
 (0)