Skip to content

Commit 06e7feb

Browse files
chore(packaging): whitelist sdist contents to block local-publish leaks
Hatchling's default sdist behavior packs everything in the project root, which is fine in CI (clean checkout) but ships per-developer state from a laptop: .mg-tools/, .claude/, .claude.bak.*/, CLAUDE.md, ROADMAP.md, work diaries, scratch reports, .coverage, etc. None of those have ever been on PyPI because every release has shipped via the publish.yml workflow's clean GitHub Actions checkout — but a single accidental `uv publish` from a dev machine would have leaked all of them. This adds an explicit `[tool.hatch.build.targets.sdist]` include list plus a small exclude list for the internal docs that live inside included dirs (docs/DEVELOPERS.md, docs/quick_start.ipynb). Even from a developer's laptop, only the listed paths can now end up on PyPI. Verified locally: `uv build` produces a sdist whose top-level entries are .github, .gitignore, CHANGELOG.md, docs, LICENSE, PKG-INFO, pyproject.toml, README.md, scripts, tango, tests. No more .mg-tools, .claude, CLAUDE.md, .coverage, DEVELOPERS.md, or quick_start.ipynb. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c21637b commit 06e7feb

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,34 @@ exclude_lines = [
122122
[tool.hatch.build.targets.wheel]
123123
packages = ["tango"]
124124

125+
# Sdist whitelist — `uv build` / `hatch build sdist` only includes these.
126+
#
127+
# Hatchling's default behavior packs everything in the project root that
128+
# isn't matched by .gitignore, which is fine in CI (clean checkout) but
129+
# leaks per-developer state (`.mg-tools/`, `.claude/`, `CLAUDE.md`, work
130+
# diaries, scratch reports, etc.) when anyone runs `uv publish` locally.
131+
# The explicit whitelist is belt-and-suspenders for that foot-gun: even
132+
# from a developer laptop, only these paths can ever end up on PyPI.
133+
[tool.hatch.build.targets.sdist]
134+
include = [
135+
"/tango",
136+
"/tests",
137+
"/docs",
138+
"/scripts",
139+
"/.github/workflows",
140+
"/README.md",
141+
"/LICENSE",
142+
"/CHANGELOG.md",
143+
"/pyproject.toml",
144+
]
145+
exclude = [
146+
# Internal-only docs / artifacts that exist inside the included dirs.
147+
"/docs/DEVELOPERS.md",
148+
"/docs/quick_start.ipynb",
149+
"**/__pycache__",
150+
"**/*.pyc",
151+
]
152+
125153
[[tool.mypy.overrides]]
126154
module = "tango.webhooks.cli"
127155
disallow_untyped_decorators = false

0 commit comments

Comments
 (0)