feat(standards): add versioning + changelog standard, release templates, and Drone version guard
Add lib page 11 (SemVer contract, pre-1.0 rule, tag==version invariant, Keep a Changelog), the releasing wiki runbook, and canonical release templates (CHANGELOG.md, VERSION). Vendor them into the MCP bundle as templates/release + release.json and expose registry://release with list/get tools. Add a changelog component to the app template. Enforce the tag<->version contract in both Drone shapes: Type A check-version and the backfill loop verify pyproject version; Type B adds a VERSION guard step.
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
# Secrets (Drone): PIP_REPO_URL, PIP_USERNAME, PIP_PASSWORD.
|
||||
# Copy to <repo>/.drone.yml unchanged; the package name and version are read
|
||||
# from pyproject.toml, so no per-repo edits are required.
|
||||
#
|
||||
# Version guard: the tag build fails unless the git tag equals the version in
|
||||
# pyproject.toml (see the versioning standard). This stops a tag from looking
|
||||
# like a release while silently publishing nothing.
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@@ -37,6 +41,11 @@ steps:
|
||||
commands:
|
||||
- PACKAGE_NAME=$(grep -E '^name\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
|
||||
- VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
|
||||
- |
|
||||
if [ "$DRONE_TAG" != "$VERSION" ]; then
|
||||
echo "Tag '$DRONE_TAG' does not match pyproject version '$VERSION'; refusing to publish."
|
||||
exit 1
|
||||
fi
|
||||
- echo "Checking if $PACKAGE_NAME==$VERSION exists on $PIP_REPO_URL ..."
|
||||
- |
|
||||
if curl -fsSL -u "$PIP_USERNAME:$PIP_PASSWORD" "$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -qE "${PACKAGE_NAME}-${VERSION}(-|\.tar\.gz|\.whl)"; then
|
||||
@@ -147,6 +156,12 @@ steps:
|
||||
|
||||
git checkout --force "$TAG"
|
||||
|
||||
TAG_VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
|
||||
if [ "$TAG" != "$TAG_VERSION" ]; then
|
||||
echo "Tag $TAG != pyproject version $TAG_VERSION at that commit; skipping"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Building $VERSION"
|
||||
rm -rf dist
|
||||
python -m build
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
# <host-port> published host port; <container-port> the in-image port.
|
||||
# <site> site image name for the site variant (e.g. docs, mcp).
|
||||
# <env-var> runtime environment variable consumed by the service.
|
||||
#
|
||||
# Version guard: the tag-triggered service variant fails unless the git tag
|
||||
# equals the repo-root VERSION file (see the versioning standard). The
|
||||
# push-triggered site variant ships :latest only and has no version to guard.
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
@@ -64,6 +68,22 @@ steps:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: check-version
|
||||
image: alpine:3.20
|
||||
commands:
|
||||
- VERSION=$(cat VERSION 2>/dev/null | tr -d '\n')
|
||||
- echo "tag=$DRONE_TAG version=$VERSION"
|
||||
- |
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "VERSION file missing or empty; add it (see versioning standard)."
|
||||
exit 1
|
||||
fi
|
||||
- |
|
||||
if [ "$DRONE_TAG" != "$VERSION" ]; then
|
||||
echo "Tag '$DRONE_TAG' does not match VERSION '$VERSION'; refusing to deploy."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: check-remote-image
|
||||
image: docker:24
|
||||
volumes:
|
||||
|
||||
Reference in New Issue
Block a user