From ac97f08527c0dc1ece395c03e9c03a1b3be1eb77 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Thu, 15 Oct 2026 18:50:44 +0530 Subject: [PATCH] ci(drone): adopt standard PyPI pipeline with tag==version guard Replace .drone.yml with the canonical Type A template: the tag build now fails unless the git tag equals the pyproject.toml version (both in the publish pipeline and the backfill replay), preventing a tag from silently publishing nothing. Also drops the emoji log decorations to match the standard. --- .drone.yml | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/.drone.yml b/.drone.yml index cc05597..122d0f6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,3 +1,21 @@ +# Drone standard — Type A: PyPI package +# +# Canonical pipeline for internal Python libraries that ship a wheel/sdist to +# the private index (dagpipe, doc-forge, hexa, mail-intake, mongo-ops, +# omniread, openapi-first, py-jwt). +# +# Two pipelines ship together: +# build-and-publish-pypi — tag-triggered build + quality gate + publish. +# backfill-pypi-from-tags — custom-triggered replay of every git tag that is +# missing from the index (disaster recovery). +# +# Secrets (Drone): PIP_REPO_URL, PIP_USERNAME, PIP_PASSWORD. +# Copy to /.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 @@ -23,13 +41,18 @@ 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) - - echo "🔍 Checking if $PACKAGE_NAME==$VERSION exists on $PIP_REPO_URL ..." + - | + 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 - echo "✅ $PACKAGE_NAME==$VERSION already exists — skipping build." + echo "$PACKAGE_NAME==$VERSION already exists; skipping build." exit 78 else - echo "🆕 New version detected: $PACKAGE_NAME==$VERSION" + echo "New version detected: $PACKAGE_NAME==$VERSION" fi - name: quality-gate @@ -46,7 +69,7 @@ steps: - | AUTH_URL="https://${PIP_USERNAME}:${PIP_PASSWORD}@$(echo "${PIP_REPO_URL#*://}" | sed 's:/*$::')/simple" pip install --index-url "$AUTH_URL" --extra-index-url https://pypi.org/simple/ -U ".[dev]" "pydoclint>=0.9.1" - - echo "🛡️ Running quality gate..." + - echo "Running quality gate..." - python -m black --check . - python -m ruff check . - python -m mypy @@ -57,7 +80,7 @@ steps: image: python:3.13-slim commands: - pip install --upgrade pip build - - echo "📦 Building Python package..." + - echo "Building Python package..." - python -m build - ls -l dist @@ -72,7 +95,7 @@ steps: from_secret: PIP_PASSWORD commands: - pip install --upgrade twine - - echo "🚀 Uploading to private PyPI at $PIP_REPO_URL ..." + - echo "Uploading to private PyPI at $PIP_REPO_URL ..." - | twine upload \ --repository-url "$PIP_REPO_URL" \ @@ -119,25 +142,31 @@ steps: set -e PACKAGE_NAME=$(grep -E '^name\s*=' pyproject.toml | cut -d'"' -f2) - echo "📦 Package: $PACKAGE_NAME" + echo "Package: $PACKAGE_NAME" for TAG in $(git tag --sort=version:refname); do VERSION="$TAG" - echo "🔁 Version: $VERSION" + echo "Version: $VERSION" if curl -fsSL -u "$PIP_USERNAME:$PIP_PASSWORD" \ "$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -qE "${PACKAGE_NAME}-${VERSION}(-|\.tar\.gz|\.whl)"; then - echo "⏭️ Exists, skipping" + echo "Exists, skipping" continue fi git checkout --force "$TAG" - echo "🏗️ Building $VERSION" + 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 - echo "⬆️ Uploading $VERSION" + echo "Uploading $VERSION" twine upload \ --repository-url "$PIP_REPO_URL" \ -u "$PIP_USERNAME" \