-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
Dynamic versioning from VCS (git tags, commit distance, etc.) is a standard practice in many ecosystems. Python packaging, for example, features a number of different tools like hatch-vcs, setuptools-scm, and poetry-dynamic-versioning to derive package versions from VCS metadata. Currently, these tools cannot work reliably in Docker builds because:
- Build contexts are isolated snapshots - The
.gitdirectory must be explicitly copied into the build context - Git submodules/worktrees break - In submodules and worktrees,
.gitis a file pointing to a location outside the submodule directory (e.g.,gitdir: ../.git/modules/submodule), making it impossible to include complete git context when the build context is limited to the submodule directory - Layer caching issues - Including .git in the context invalidates caching on every commit
The current workaround is to either:
- Copy in or mount
.git, accepting that a Dockerfile using that strategy will not work in a submodule/subtree/worktree - Compute the version on the host and passing via build args, which works but creates friction and breaks the principle of reproducible builds from source alone
Proposed Solution
Add a new mount type vcs that temporarily mounts the host's VCS repository (read-only) during a RUN instruction, similar to how the existing ssh and secret mount types can mount external context.
Example usage:
RUN --mount=type=vcs hatch version > /app/.version
RUN --mount=type=vcs,target=/repo git -C /repo describe --tags > /version.txtThis would:
- Mount the host's actual git repository (resolving .git file pointers for submodules/worktrees)
- Be read-only and temporary (not included in image layers)
- Work regardless of build context boundaries
- Let VCS-aware tooling access complete repository history
- Follow the established pattern of other mount types
Why I believe BuildKit is the right place for this functionality
BuildKit already extracts VCS metadata for provenance attestations, proving the infrastructure exists to:
- Detect VCS repositories
- Access VCS metadata
- Associate VCS info with builds
This proposal simply makes that existing capability available to Dockerfile instructions, not just attestation outputs. Doing so means that tooling inside and outside the Dockerfile can function identically when it comes to leveraging this important contextual information.
Benefits
- First-class support for VCS-based versioning: a common pattern that currently requires workarounds
- Solves submodule/worktree cases: BuildKit can resolve the actual repository location in a way logic inside a Dockerfile cannot
- Cleaner builds: no need to pollute build context with .git
- Better caching: VCS access only when explicitly needed
- Consistency with existing feature: same UX pattern as
--mount=type=sshet al.
Version control systems are for version control. Let's remove all the friction we can find making it harder to use VCS's as a source of truth for build versioning, so we can enable dynamic versioning to have first-class support in build systems.
Thank you to all the maintainers that do the hard work of giving us this critical infrastructure!