- Remove the push-triggered build-and-deploy-site pipeline and every "site" reference; Type B is now a single tag-triggered service pipeline (service-docker.yaml). - Inventory now covers packages + the auth-server service only (repos.json 11 -> 9; docs/mcp are no longer part of the standard). - Versioning standard: reconcile [Unreleased] against the last tag before promoting, and always show proposed entries to the user for approval. - Update registry.py compliance/release text and list_repos types, build.py component descriptions, and rebuild the MCP bundle + lib/wiki HTML.
202 lines
6.3 KiB
YAML
202 lines
6.3 KiB
YAML
# Drone standard — Type B: Docker deployment
|
|
#
|
|
# Canonical pipeline for a service that builds an image, pushes it to the
|
|
# private registry, and runs it on the Docker host (auth-server).
|
|
#
|
|
# build-and-deploy-service — fetch the git tag, fail unless it equals the
|
|
# repo-root VERSION file, skip if the image already
|
|
# exists, run the quality gate, build, push, and
|
|
# restart the container.
|
|
#
|
|
# Secrets (Drone): PIP_REPO_URL, PIP_USERNAME, PIP_PASSWORD, REGISTRY_HOST,
|
|
# REGISTRY_USER, REGISTRY_PASS, plus the service's runtime env (for example
|
|
# MONGO_* / JWT_SECRET).
|
|
#
|
|
# Placeholders to set per repo:
|
|
# <app> image / container / network name (e.g. auth-server).
|
|
# aetos/<app> image repository on the private registry.
|
|
# <host-port> published host port; <container-port> the in-image port.
|
|
# <env-var> runtime environment variable consumed by the service.
|
|
#
|
|
# Version guard: the tag-triggered pipeline fails unless the git tag equals the
|
|
# repo-root VERSION file (see the versioning standard).
|
|
---
|
|
kind: pipeline
|
|
type: docker
|
|
name: build-and-deploy-service
|
|
|
|
platform:
|
|
os: linux
|
|
arch: arm64
|
|
|
|
workspace:
|
|
path: /drone/src
|
|
|
|
volumes:
|
|
- name: dockersock
|
|
host:
|
|
path: /var/run/docker.sock
|
|
|
|
steps:
|
|
- name: fetch-tags
|
|
image: docker:24
|
|
volumes:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
commands:
|
|
- apk add --no-cache git
|
|
- git fetch --tags
|
|
- |
|
|
# Get latest Git tag and trim newline
|
|
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null | tr -d '\n')
|
|
echo "Latest Git tag fetched: $LATEST_TAG"
|
|
|
|
# Save to file for downstream steps
|
|
echo "$LATEST_TAG" > /drone/src/LATEST_TAG.txt
|
|
|
|
# Read back for verification
|
|
IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n')
|
|
echo "Image tag read from file: $IMAGE_TAG"
|
|
|
|
# Validate
|
|
if [ -z "$IMAGE_TAG" ]; then
|
|
echo "No git tags found! Cannot continue."
|
|
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:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
commands:
|
|
- IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n')
|
|
- echo "Checking if aetos/<app>:$IMAGE_TAG exists on remote Docker..."
|
|
- echo "Existing Docker tags for aetos/<app>:"
|
|
- docker images --format "{{.Repository}}:{{.Tag}}" | grep "^aetos/<app>" || echo "(none)"
|
|
- |
|
|
if docker image inspect aetos/<app>:$IMAGE_TAG > /dev/null 2>&1; then
|
|
echo "Docker image aetos/<app>:$IMAGE_TAG already exists; skipping build"
|
|
exit 78
|
|
else
|
|
echo "Docker image aetos/<app>:$IMAGE_TAG not found; proceeding to build..."
|
|
fi
|
|
|
|
- name: quality-gate
|
|
image: python:3.13-slim
|
|
environment:
|
|
PIP_REPO_URL:
|
|
from_secret: PIP_REPO_URL
|
|
PIP_USERNAME:
|
|
from_secret: PIP_USERNAME
|
|
PIP_PASSWORD:
|
|
from_secret: PIP_PASSWORD
|
|
commands:
|
|
- pip install --upgrade pip
|
|
- pip install --extra-index-url "https://$PIP_USERNAME:$PIP_PASSWORD@$PIP_REPO_URL/simple" -r requirements.txt
|
|
- pip install black ruff mypy
|
|
- echo "Running quality gate..."
|
|
- python -m black --check .
|
|
- python -m ruff check .
|
|
- python -m mypy .
|
|
- python -m pytest
|
|
|
|
- name: build-image
|
|
image: docker:24
|
|
volumes:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
environment:
|
|
PIP_REPO_URL:
|
|
from_secret: PIP_REPO_URL
|
|
PIP_USERNAME:
|
|
from_secret: PIP_USERNAME
|
|
PIP_PASSWORD:
|
|
from_secret: PIP_PASSWORD
|
|
commands:
|
|
- IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n')
|
|
- echo "Building Docker image aetos/<app>:$IMAGE_TAG ..."
|
|
- |
|
|
docker build \
|
|
--network=host \
|
|
--build-arg PIP_REPO_URL="$PIP_REPO_URL" \
|
|
--build-arg PIP_USERNAME="$PIP_USERNAME" \
|
|
--build-arg PIP_PASSWORD="$PIP_PASSWORD" \
|
|
-t aetos/<app>:$IMAGE_TAG \
|
|
-t aetos/<app>:latest \
|
|
/drone/src
|
|
|
|
- name: push-image
|
|
image: docker:24
|
|
environment:
|
|
REGISTRY_HOST:
|
|
from_secret: REGISTRY_HOST
|
|
REGISTRY_USER:
|
|
from_secret: REGISTRY_USER
|
|
REGISTRY_PASS:
|
|
from_secret: REGISTRY_PASS
|
|
volumes:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
commands:
|
|
- IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n')
|
|
- echo "Logging into registry $REGISTRY_HOST ..."
|
|
- echo "$REGISTRY_PASS" | docker login $REGISTRY_HOST -u "$REGISTRY_USER" --password-stdin
|
|
- echo "Tagging images with registry prefix..."
|
|
- docker tag aetos/<app>:$IMAGE_TAG $REGISTRY_HOST/aetos/<app>:$IMAGE_TAG
|
|
- docker tag aetos/<app>:$IMAGE_TAG $REGISTRY_HOST/aetos/<app>:latest
|
|
- echo "Pushing aetos/<app>:$IMAGE_TAG ..."
|
|
- docker push $REGISTRY_HOST/aetos/<app>:$IMAGE_TAG
|
|
- echo "Pushing aetos/<app>:latest ..."
|
|
- docker push $REGISTRY_HOST/aetos/<app>:latest
|
|
|
|
- name: stop-old
|
|
image: docker:24
|
|
volumes:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
commands:
|
|
- echo "Stopping old container..."
|
|
- docker rm -f <app> || true
|
|
|
|
- name: run-container
|
|
image: docker:24
|
|
volumes:
|
|
- name: dockersock
|
|
path: /var/run/docker.sock
|
|
environment:
|
|
<ENV_VAR>:
|
|
from_secret: <ENV_VAR>
|
|
commands:
|
|
- IMAGE_TAG=$(cat /drone/src/LATEST_TAG.txt | tr -d '\n')
|
|
- echo "Starting container aetos/<app>:$IMAGE_TAG ..."
|
|
- |
|
|
docker run -d \
|
|
--name <app> \
|
|
-p <host-port>:<container-port> \
|
|
--add-host private-pi:192.168.1.111 \
|
|
--restart always \
|
|
-e <ENV_VAR>=$<ENV_VAR> \
|
|
aetos/<app>:$IMAGE_TAG
|
|
|
|
trigger:
|
|
event:
|
|
- tag
|
|
|