fix(AI-3750): stop duplicate _ui_dist wheel entry on VCS-less source builds - #623
Conversation
…builds hatchling's force-include for _ui_dist/ relies on .gitignore-based exclusion to avoid double-adding the path, but that exclusion needs a .git directory to run `git check-ignore` against. A git+ install that hands hatchling a plain exported tree (no .git) skips it, so _ui_dist/index.html gets added twice and the build aborts. Add an explicit wheel-target exclude so it works regardless of VCS state, and document the undocumented Python >=3.12 floor in the README install instructions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@claude review |
There was a problem hiding this comment.
Pull request overview
This PR fixes a wheel-build failure that occurs when building from a VCS-less exported source tree (no .git directory), where src/keboola_agent_cli/_ui_dist/ could be collected twice (default package collection + force-include) and abort the build with a duplicate-archive-path error. It also adds a regression test to exercise that no-.git build path and documents the project’s Python version floor in the install instructions.
Changes:
- Prevent duplicate
_ui_dist/inclusion by explicitly excludingsrc/keboola_agent_cli/_ui_distfrom default wheel collection while keepingforce-includeas the single inclusion path. - Add an end-to-end test that builds a wheel in a
.git-less temporary project and asserts_ui_dist/index.htmlappears exactly once. - Document the Python >= 3.12 requirement (and
UV_PYTHON=3.12workaround) in the README install section.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
pyproject.toml |
Adds an explicit wheel exclude to avoid duplicate _ui_dist/ entries in VCS-less builds while retaining force-include. |
tests/test_build_hook.py |
Adds an end-to-end regression test that builds a wheel without a .git directory and checks _ui_dist isn’t duplicated. |
README.md |
Documents Python >= 3.12 install requirement and a uv interpreter selection workaround. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Closing -- scope was wrong for this issue; redoing the actual fix (ai-kit docs cross-references) in keboola/ai-kit instead. |
Summary
uv tool install git+https://github.com/keboola/cli(theinstall.shfallback path) on a source tree with no.gitdirectory.force-include's de-dup with hatchling's default package globbing for_ui_dist/relies on.gitignore-based exclusion, which needs a.gitdir to rungit check-ignoreagainst. Without one, the (gitignored)_ui_dist/the build hook just populated gets picked up by both the default globbing andforce-include→ duplicate archive entry → build aborts.exclude = ["src/keboola_agent_cli/_ui_dist"]under[tool.hatch.build.targets.wheel]— a plain glob evaluated unconditionally, independent of VCS state, soforce-includeis the only path that adds it.tests/test_build_hook.py::TestForceIncludeNoDuplicate) that builds a real wheel in a.git-less tree; verified it fails on the pre-fix config and passes on the post-fix one.UV_PYTHON=3.12workaround for whenuvdoesn't auto-fetch a matching interpreter.Filed against AI-3750. Note: this PR covers only Defects 2 & 3 from that issue (the wheel-build crash and the undocumented Python floor). Defect 1 (ai-kit's docs pointing at the wrong CLI /
developers.keboola.com/cli) lives entirely in the separatekeboola/ai-kitrepo — nothing in this repo references it, so there's nothing to fix here for that part.Test plan
.git, populated a fake SPA dist, ranuv build --wheel→ sameValueError: A second file is being added to the wheel archive at the same pathtraceback.excludefix, reran the same reproduction → build succeeds; confirmed viazipfileinspection that_ui_dist/index.htmlandpy.typedare each present exactly once..gitpresent, both with and without a prebuilt SPA dist) → no regression.TestForceIncludeNoDuplicate::test_wheel_builds_without_git_directoryadded; confirmed it fails without thepyproject.tomlfix and passes with it (git-stash round-trip).ruff check/ruff format --checkclean on changed files.uv run pytest tests/ -m "not e2e", 5.6k+ tests) passes.Related issues
AI-3750
🤖 Generated with Claude Code