Skip to content

feat(packaging): version git archives of arbitrary commits - #15023

Merged
RonnyPfannschmidt merged 1 commit into
pytest-dev:mainfrom
RonnyPfannschmidt:packaging/git-archival
Sep 14, 2026
Merged

RonnyPfannschmidt merged 1 commit into
pytest-dev:mainfrom
RonnyPfannschmidt:packaging/git-archival

Conversation

@RonnyPfannschmidt

@RonnyPfannschmidt RonnyPfannschmidt commented Sep 14, 2026

Copy link
Copy Markdown
Member

AI-authored. I prompted the exploration; an agent (Claude Opus 5 via Claude Code) assessed the state, wrote the change, ran the builds and wrote this description. I reviewed it and I am posting it. Credited in the commit's Co-authored-by trailer.

Closes #11680.

GitHub serves a source tarball for every commit, not only for tags, but so far only a tag's tarball could be built — without a .git directory setuptools-scm had nothing to read a version from.

This adds a .git_archival.txt expanded by git archive via export-subst.

It uses the stable template — node, node-date, describe-name, deliberately no ref-names. Recording ref-names would tie an archive's content, and so its checksum, to whichever branches happen to point at the commit, so moving a branch afterwards would silently change an already-published download. That instability is why this was declined in 2023; the stable template did not exist yet. Describe output depends only on the commit and the tags reachable from it, so a branch moving cannot change it. Adding or moving a tag in the commit's ancestry still can.

A MANIFEST.in keeps the file out of the sdist. It only carries a version once git archive has expanded it, and an sdist states its version in its metadata anyway; shipping the bare template would leave a stray $Format:...$ for setuptools-scm to consider on every build from an unpacked sdist. Verified that the exclusion drops exactly that one file and nothing else.

While here: off the deprecated write_to onto version_file, and write_to_source = true stated explicitly — setuptools-scm is about to flip that default, and src/_pytest/_version.py should keep being written into checkouts. That option is what sets the new setuptools-scm>=10.1 floor; it can go back to >=8 if the floor is unwelcome, at the cost of a deprecation warning now and a silent behaviour change later.

Releases are unaffected — deploy.yml supplies SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST.

Verified

check result
git archive expansion describe-name matches git describe exactly
build from extracted archive (no .git) sdist + wheel, correct version
sdist file list, with vs without MANIFEST.in differs by .git_archival.txt alone
sdist → wheel correct version, no setuptools-scm warnings
pre-commit run -a passes

🤖 Generated with Claude Code

@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Sep 14, 2026
@RonnyPfannschmidt RonnyPfannschmidt added the backport 9.1.x apply to PRs at any point; backports the changes to the 9.1.x branch label Sep 14, 2026
GitHub serves a source tarball for every commit, not only for tags, but
so far only a tag's tarball could be built: without a .git directory
setuptools-scm had nothing to read the version from.

A .git_archival.txt expanded by ``git archive`` via ``export-subst``
gives it one. The stable template is deliberate -- recording ``ref-names``
as well would tie an archive's content, and so its checksum, to whichever
branches happen to point at the commit, so moving a branch afterwards
would silently change the download.

The file is excluded from the sdist. It only ever carries a version once
``git archive`` has expanded it, and an sdist states its version in its
metadata anyway; shipping the bare template would leave a stray
``$Format:...$`` for setuptools-scm to consider on every build from an
unpacked sdist.

While here, move off the deprecated ``write_to`` and state the
``write_to_source`` behaviour that setuptools-scm is about to flip
rather than inherit the change silently.

Closes pytest-dev#11680

Co-Authored-By: Claude Opus 5 (1M context) via Claude Code <noreply@anthropic.com>
@RonnyPfannschmidt
RonnyPfannschmidt merged commit de30d84 into pytest-dev:main Sep 14, 2026
36 checks passed
@patchback

patchback Bot commented Sep 14, 2026

Copy link
Copy Markdown

Backport to 9.1.x: 💚 backport PR created

✅ Backport PR branch: patchback/backports/9.1.x/de30d8417f3d93bc0c16fc0a64092e197c46e36a/pr-15023

Backported as #15025

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport 9.1.x apply to PRs at any point; backports the changes to the 9.1.x branch bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[packaging] Allow versioning arbitrary Git commits

2 participants