build: derive package version from git via setuptools-scm
Replace hatchling and the static version with setuptools + setuptools-scm, following Kaya's pre-uv packaging setup: dynamic version, generated _version.py, and release/* tag prefix. The Docker builder now includes git and the .git directory so the image is versioned from the checkout. CI checks out full history and tags for the tag-triggered builds.
This commit is contained in:
+5
-1
@@ -1,4 +1,3 @@
|
|||||||
.git/
|
|
||||||
.gitignore
|
.gitignore
|
||||||
.venv/
|
.venv/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
@@ -15,3 +14,8 @@ Dockerfile
|
|||||||
!README.md
|
!README.md
|
||||||
xmcp.yml
|
xmcp.yml
|
||||||
xmcp.example.yml
|
xmcp.example.yml
|
||||||
|
|
||||||
|
# Generated at build time
|
||||||
|
src/xmcp/_version.py
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
# setuptools-scm needs tags and history to derive the package version.
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Login to Gitea container registry
|
- name: Login to Gitea container registry
|
||||||
|
|||||||
@@ -10,3 +10,9 @@ xmcp.yml
|
|||||||
xmcp.local.yml
|
xmcp.local.yml
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
|
||||||
|
# Generated version metadata and build artifacts
|
||||||
|
src/xmcp/_version.py
|
||||||
|
*.egg-info/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
|||||||
+6
-1
@@ -6,6 +6,9 @@
|
|||||||
FROM python:3.14-alpine3.24 AS builder
|
FROM python:3.14-alpine3.24 AS builder
|
||||||
COPY --from=ghcr.io/astral-sh/uv:0.13.1 /uv /uvx /bin/
|
COPY --from=ghcr.io/astral-sh/uv:0.13.1 /uv /uvx /bin/
|
||||||
|
|
||||||
|
# setuptools-scm derives the package version from git history and tags.
|
||||||
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
ENV UV_COMPILE_BYTECODE=1 \
|
ENV UV_COMPILE_BYTECODE=1 \
|
||||||
UV_LINK_MODE=copy \
|
UV_LINK_MODE=copy \
|
||||||
UV_PYTHON_DOWNLOADS=never
|
UV_PYTHON_DOWNLOADS=never
|
||||||
@@ -17,9 +20,11 @@ COPY pyproject.toml uv.lock .python-version ./
|
|||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
uv sync --frozen --no-dev --no-install-project
|
uv sync --frozen --no-dev --no-install-project
|
||||||
|
|
||||||
# Then install the project itself as a regular wheel.
|
# Then install the project itself as a regular wheel. The git metadata is
|
||||||
|
# required by setuptools-scm to derive the package version.
|
||||||
COPY README.md ./
|
COPY README.md ./
|
||||||
COPY src ./src
|
COPY src ./src
|
||||||
|
COPY .git ./.git
|
||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
uv sync --frozen --no-dev --no-editable
|
uv sync --frozen --no-dev --no-editable
|
||||||
|
|
||||||
|
|||||||
@@ -220,6 +220,11 @@ git push origin release/0.2.0
|
|||||||
This publishes `gitea.woggioni.net/woggioni/xmcp:0.2.0` and
|
This publishes `gitea.woggioni.net/woggioni/xmcp:0.2.0` and
|
||||||
`gitea.woggioni.net/woggioni/xmcp:latest`.
|
`gitea.woggioni.net/woggioni/xmcp:latest`.
|
||||||
|
|
||||||
|
The Python package version is derived from the pushed `release/*` tag with
|
||||||
|
[setuptools-scm](https://setuptools-scm.readthedocs.io): `release/0.2.0`
|
||||||
|
produces package version `0.2.0`. Builds from untagged commits carry a PEP 440
|
||||||
|
development version (for example `0.2.1.dev3+gabc1234`).
|
||||||
|
|
||||||
## Project layout
|
## Project layout
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
+11
-5
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "xmcp"
|
name = "xmcp"
|
||||||
version = "0.2.0"
|
dynamic = ["version"]
|
||||||
description = "MCP server generated from an OpenAPI specification, built with FastMCP"
|
description = "MCP server generated from an OpenAPI specification, built with FastMCP"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.14"
|
requires-python = ">=3.14"
|
||||||
@@ -14,8 +14,14 @@ dependencies = [
|
|||||||
xmcp = "xmcp.server:main"
|
xmcp = "xmcp.server:main"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["setuptools>=61.0", "setuptools-scm>=8"]
|
||||||
build-backend = "hatchling.build"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
[tool.setuptools.packages.find]
|
||||||
packages = ["src/xmcp"]
|
where = ["src"]
|
||||||
|
|
||||||
|
[tool.setuptools_scm]
|
||||||
|
version_file = "src/xmcp/_version.py"
|
||||||
|
|
||||||
|
[tool.setuptools_scm.tag]
|
||||||
|
prefix = "release/"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
"""xmcp: an MCP server generated from an OpenAPI specification with FastMCP."""
|
"""xmcp: an MCP server generated from an OpenAPI specification with FastMCP."""
|
||||||
|
|
||||||
__version__ = "0.2.0"
|
from ._version import __version__
|
||||||
|
|
||||||
|
__all__ = ["__version__"]
|
||||||
|
|||||||
Reference in New Issue
Block a user