headroom/.github/workflows
chopratejas 183d51c8a8 fix(ci): include NOTICE in sdist + assert License-File metadata matches tarball
Every release since v0.20.16 has uploaded 12 wheels but no sdist. The
underlying failure is a 400 from PyPI:

    400 License-File NOTICE does not exist in distribution file
    headroom_ai-X.Y.Z.tar.gz at headroom_ai-X.Y.Z/NOTICE

Two-part regression:

1. The hatch -> maturin migration in 2a91cbb (single-wheel maturin build
   backend, May 4) replaced `[tool.hatch.build.targets.sdist].include`,
   which listed both `LICENSE` and `NOTICE`, with maturin's own include
   directive that only carried `LICENSE` over. Maturin's PEP 639 license
   auto-discovery still emits `License-File: NOTICE` into the sdist's
   PKG-INFO (because NOTICE exists at the project root and matches the
   default glob), so the sdist tarball declares a license file it
   doesn't physically contain. PyPI's PEP 639 validator rejects with
   400. Wheels were unaffected because maturin auto-injects both files
   into `*.dist-info/licenses/`.

2. CI showed "publish-pypi" green for ~22 releases despite this break
   because twine was bailing earlier with `400 File already exists` on
   the wheels (the version detector kept computing the same v0.21.5).
   PR #412 added `skip-existing: true` (May 6) to make wheel re-uploads
   idempotent. With wheels now silently skipping, twine proceeded to
   upload the sdist for the first time in three weeks - and the
   dormant License-File error surfaced as a hard 400.

Fix:

- Add `NOTICE` alongside `LICENSE` in `[tool.maturin].include` for the
  `sdist` format. Both files now ship in the tarball, matching what
  PEP 639 already declares in PKG-INFO.
- Replace the existing "verify sdist contains LICENSE" check with a
  generic "every License-File entry in PKG-INFO resolves to a real
  tarball member" check. This catches the same bug class for any
  future addition (COPYING, AUTHORS, etc.) without another bespoke
  literal.

Verified locally:

    $ maturin sdist --out dist
    Including license file `LICENSE`
    Including license file `NOTICE`
    Including files matching "LICENSE"
    Including files matching "NOTICE"
    Built source distribution to dist/headroom_ai-0.9.1.tar.gz

    $ tar -tzf dist/headroom_ai-0.9.1.tar.gz | grep -E '(LICENSE|NOTICE)$'
    headroom_ai-0.9.1/LICENSE
    headroom_ai-0.9.1/NOTICE

    $ twine check dist/headroom_ai-0.9.1.tar.gz
    Checking dist/headroom_ai-0.9.1.tar.gz: PASSED
2026-05-07 16:29:05 -07:00
..
ci.yml refactor: single-wheel maturin build backend (fixes #355) 2026-05-03 13:16:41 -07:00
devcontainers.yml fix: harden devcontainer worktree startup 2026-04-10 13:49:29 -05:00
docker.yml fix(ci): docker per-arch bake needs explicit image name in output 2026-05-04 12:26:46 -07:00
docs.yml Add MkDocs GitHub Pages documentation site 2026-01-30 20:33:29 -08:00
eval.yml fix(ci): skip smoke OpenAI eval cleanly when OPENAI_API_KEY secret unset 2026-05-05 18:07:15 -07:00
init-e2e.yml test: cover init install flows end to end 2026-04-21 20:15:11 -05:00
init-native-e2e.yml refactor: single-wheel maturin build backend (fixes #355) 2026-05-03 13:16:41 -07:00
publish.yml refactor: single-wheel maturin build backend (fixes #355) 2026-05-03 13:16:41 -07:00
release.yml fix(ci): include NOTICE in sdist + assert License-File metadata matches tarball 2026-05-07 16:29:05 -07:00
rust.yml fix(ci): yarnpkg GPG + YAML colon syntax in refactor 2026-05-03 13:22:49 -07:00
wrap-e2e.yml feat(ci): add docker wrap e2e workflow 2026-04-07 22:36:43 -05:00