mirror of
https://scm.tikali.ai/tikali/applications/monky/monky-deployd.git
synced 2026-09-18 04:36:15 +00:00
8fde0ba079
Pipeline 6999 built the openziti 1.7.1 wheel (github.com + pypi.org) and the nfpm .deb; the allow_failure escape hatches are no longer honest. package now requires the wheel so a .deb can never ship without transport sdk. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KLB7jieMNRkTsJ2epr4Ds1
193 lines
9.3 KiB
YAML
193 lines
9.3 KiB
YAML
# monky-deployd CI/CD (mirrors monky-tenancy's conventions)
|
|
#
|
|
# lint -> test -> build (openziti wheel) -> package (.deb via nfpm) -> release (v* tags) -> docs
|
|
#
|
|
# Every script line is single-quoted (a bare ": " turns the line into a YAML map and silently
|
|
# yields a 0-job pipeline). Runner egress to github.com + pypi.org was PROVEN on the v0.1.0 tag
|
|
# pipeline (6999: openziti 1.7.1 wheel built, nfpm .deb packaged), so wheel/package are blocking.
|
|
#
|
|
# CI/CD variables (project or group level):
|
|
# GITEA_TOKEN — Gitea API token (write:repository) for `release:gitea`; without it the job is manual
|
|
# GITLAB_TRANSLATE_TOKEN — used by the translate-docs component (group level)
|
|
|
|
include:
|
|
# doc-translator via the CI/CD component; PARTIAL PIN @11.3 tracks 11.3.x (no `v`).
|
|
- component: $CI_SERVER_FQDN/tikali/platform/doc-translator/translate-docs@11.3
|
|
inputs:
|
|
docs_stage: docs
|
|
|
|
stages: [lint, test, build, package, release, docs]
|
|
|
|
# One pipeline per change: MR pipeline for merge requests, branch pipeline otherwise, never both.
|
|
workflow:
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG'
|
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"'
|
|
when: never
|
|
- if: '$CI_COMMIT_BRANCH'
|
|
|
|
variables:
|
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
OPENZITI_VERSION: "1.7.1"
|
|
NFPM_VERSION: "2.43.0"
|
|
|
|
cache:
|
|
key: "$CI_JOB_NAME"
|
|
paths: [.cache/pip]
|
|
|
|
.run_rules:
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG'
|
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
- if: '$CI_COMMIT_BRANCH'
|
|
|
|
lint:
|
|
extends: [.run_rules]
|
|
stage: lint
|
|
image: python:3.12-slim
|
|
before_script:
|
|
- 'pip install -q "ruff>=0.16,<0.17"'
|
|
script:
|
|
- 'ruff check .'
|
|
- 'ruff format --check .'
|
|
- 'bash -n packaging/install.sh'
|
|
- 'bash -n packaging/scripts/postinstall.sh packaging/scripts/preremove.sh packaging/scripts/postremove.sh'
|
|
- 'python -c "import ast,sys; [ast.parse(open(f).read()) for f in sys.argv[1:]]" tests/fakebin/docker'
|
|
# the release version must match the tag when there is one
|
|
- 'if [ -n "$CI_COMMIT_TAG" ]; then v=$(python -c "import monky_deployd;print(monky_deployd.__version__)"); [ "v$v" = "$CI_COMMIT_TAG" ] || { echo "tag $CI_COMMIT_TAG != __version__ $v"; exit 1; }; fi'
|
|
|
|
test:
|
|
extends: [.run_rules]
|
|
stage: test
|
|
image: python:3.12-slim
|
|
before_script:
|
|
- 'pip install -q pytest'
|
|
script:
|
|
- 'chmod +x tests/fakebin/docker'
|
|
- 'pytest --junitxml=report.xml'
|
|
artifacts:
|
|
when: always
|
|
reports:
|
|
junit: report.xml
|
|
|
|
# --- the openziti wheel ---------------------------------------------------------------------
|
|
# PyPI ships `openziti` as an sdist whose build fetches ziti-sdk-c (+ prebuilt tlsuv/uv-mbed
|
|
# via cmake FetchContent) from github.com at install time. Building it here on ubuntu:26.04
|
|
# (the target OS; python3 = the target's python3) gives us a wheel to vendor into the venv.
|
|
# NEEDS runner egress to github.com + pypi.org (proven 2026-09-05, pipeline 6999).
|
|
wheel:
|
|
stage: build
|
|
image: ubuntu:26.04
|
|
needs: ["test"]
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG'
|
|
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
when: manual
|
|
allow_failure: true
|
|
variables:
|
|
DEBIAN_FRONTEND: noninteractive
|
|
script:
|
|
- 'apt-get update -qq && apt-get install -y -qq --no-install-recommends python3 python3-venv python3-dev build-essential cmake ninja-build git pkg-config libssl-dev zlib1g-dev ca-certificates curl >/dev/null'
|
|
- 'python3 -m venv /tmp/wb && /tmp/wb/bin/pip install -q --upgrade pip wheel setuptools'
|
|
- 'mkdir -p vendor'
|
|
- '/tmp/wb/bin/pip wheel --no-deps --no-binary openziti "openziti==${OPENZITI_VERSION}" -w vendor/'
|
|
- 'ls -l vendor/'
|
|
artifacts:
|
|
paths: [vendor/*.whl]
|
|
expire_in: 30 days
|
|
|
|
# --- the .deb --------------------------------------------------------------------------------------
|
|
# venv at its final path (/opt/monky-deployd/venv is where the .deb puts it; venvs are not
|
|
# relocatable) + nfpm. nfpm comes from GitHub releases (egress) with the goreleaser apt repo as
|
|
# fallback (proven 2026-09-05, pipeline 6999). The wheel is required: a .deb without it would
|
|
# silently ship a broken `transport: sdk`.
|
|
package:
|
|
stage: package
|
|
image: ubuntu:26.04
|
|
needs:
|
|
- job: test
|
|
- job: wheel
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG'
|
|
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
when: manual
|
|
allow_failure: true
|
|
variables:
|
|
DEBIAN_FRONTEND: noninteractive
|
|
script:
|
|
- 'apt-get update -qq && apt-get install -y -qq --no-install-recommends python3 python3-venv python3-pip ca-certificates curl gnupg >/dev/null'
|
|
- 'VERSION=$(python3 -c "import monky_deployd;print(monky_deployd.__version__)"); echo "VERSION=$VERSION" | tee build.env'
|
|
- 'python3 -m venv /opt/monky-deployd/venv'
|
|
- '/opt/monky-deployd/venv/bin/pip install -q --upgrade pip'
|
|
- '/opt/monky-deployd/venv/bin/pip install -q .'
|
|
- 'ls vendor/*.whl >/dev/null 2>&1 || { echo "no vendored openziti wheel (wheel job artifact missing)"; exit 1; }'
|
|
- '/opt/monky-deployd/venv/bin/pip install -q vendor/*.whl'
|
|
- '/opt/monky-deployd/venv/bin/python -c "import openziti; print(\"openziti import ok\")"'
|
|
- '/opt/monky-deployd/venv/bin/python -m monky_deployd version'
|
|
- 'mkdir -p build dist && cp -a /opt/monky-deployd/venv build/venv'
|
|
# nfpm: GitHub release .deb, else the goreleaser apt repo
|
|
- 'curl -fsSL -o /tmp/nfpm.deb "https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_amd64.deb" && apt-get install -y -qq /tmp/nfpm.deb >/dev/null || { echo "deb [trusted=yes] https://repo.goreleaser.com/apt/ /" > /etc/apt/sources.list.d/goreleaser.list; apt-get update -qq; apt-get install -y -qq nfpm; }'
|
|
- 'VERSION=$VERSION nfpm package --config packaging/nfpm.yaml --packager deb --target dist/'
|
|
- 'cd dist && for f in *.deb; do sha256sum "$f" > "$f.sha256"; done && ls -l && cd ..'
|
|
- 'cp packaging/install.sh dist/install.sh'
|
|
artifacts:
|
|
paths: [dist/]
|
|
reports:
|
|
dotenv: build.env
|
|
expire_in: 90 days
|
|
|
|
# --- GitLab release (v* tags): generic package registry + release with asset links -------------
|
|
release:
|
|
stage: release
|
|
image:
|
|
name: registry.gitlab.com/gitlab-org/release-cli:latest
|
|
entrypoint: [""]
|
|
needs: ["package"]
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG =~ /^v/'
|
|
script:
|
|
- 'apk add --no-cache curl >/dev/null 2>&1 || true'
|
|
- 'VERSION=${CI_COMMIT_TAG#v}; PKG="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/monky-deployd/${VERSION}"'
|
|
- 'for f in dist/*.deb dist/*.sha256 dist/install.sh; do curl -fsS --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file "$f" "$PKG/$(basename "$f")"; echo; done'
|
|
- 'DEB=$(basename dist/*.deb)'
|
|
- >-
|
|
release-cli create --name "monky-deployd $CI_COMMIT_TAG" --tag-name "$CI_COMMIT_TAG"
|
|
--description "See CHANGELOG.md. Public install assets are on the Gitea mirror: https://gitea.cbs.tikali.net/mdella/monky-deployd/releases/tag/$CI_COMMIT_TAG"
|
|
--assets-link "{\"name\":\"$DEB\",\"url\":\"$PKG/$DEB\",\"link_type\":\"package\"}"
|
|
--assets-link "{\"name\":\"$DEB.sha256\",\"url\":\"$PKG/$DEB.sha256\",\"link_type\":\"other\"}"
|
|
--assets-link "{\"name\":\"install.sh\",\"url\":\"$PKG/install.sh\",\"link_type\":\"other\"}"
|
|
|
|
# --- Gitea release (the PUBLIC download the installer uses) ------------------------------------------
|
|
# The GitLab project is private, so install.sh fetches from the Gitea mirror
|
|
# https://gitea.cbs.tikali.net/mdella/monky-deployd/releases/download/v<ver>/... . This job
|
|
# waits for the pull-mirror to carry the tag, creates the release and uploads the assets.
|
|
# Automatic when GITEA_TOKEN is set; otherwise a manual, non-blocking job (docs/OPERATIONS.md
|
|
# has the by-hand recipe).
|
|
release:gitea:
|
|
stage: release
|
|
image:
|
|
name: alpine:3.20
|
|
entrypoint: [""]
|
|
needs: ["package"]
|
|
rules:
|
|
- if: '$CI_COMMIT_TAG =~ /^v/ && $GITEA_TOKEN'
|
|
- if: '$CI_COMMIT_TAG =~ /^v/'
|
|
when: manual
|
|
allow_failure: true
|
|
variables:
|
|
GITEA_API: "https://gitea.cbs.tikali.net/api/v1/repos/mdella/monky-deployd"
|
|
script:
|
|
- 'apk add --no-cache curl jq >/dev/null'
|
|
- '[ -n "$GITEA_TOKEN" ] || { echo "GITEA_TOKEN is not set"; exit 1; }'
|
|
- 'H="Authorization: token $GITEA_TOKEN"'
|
|
- 'curl -fsS -X POST -H "$H" "$GITEA_API/mirror-sync" >/dev/null || echo "mirror-sync trigger failed; polling anyway"'
|
|
- 'for i in $(seq 1 30); do curl -fsS -H "$H" "$GITEA_API/tags/$CI_COMMIT_TAG" >/dev/null 2>&1 && break; echo "waiting for the mirror to carry $CI_COMMIT_TAG ($i)"; sleep 10; done'
|
|
- 'curl -fsS -H "$H" "$GITEA_API/tags/$CI_COMMIT_TAG" >/dev/null || { echo "tag not on the mirror yet"; exit 1; }'
|
|
- 'RID=$(curl -fsS -H "$H" "$GITEA_API/releases/tags/$CI_COMMIT_TAG" 2>/dev/null | jq -r .id || true)'
|
|
- 'if [ -z "$RID" ] || [ "$RID" = "null" ]; then RID=$(curl -fsS -X POST -H "$H" -H "Content-Type: application/json" "$GITEA_API/releases" -d "{\"tag_name\":\"$CI_COMMIT_TAG\",\"name\":\"monky-deployd $CI_COMMIT_TAG\",\"body\":\"See CHANGELOG.md\",\"draft\":false,\"prerelease\":false}" | jq -r .id); fi'
|
|
- 'echo "release id $RID"'
|
|
- 'for f in dist/*.deb dist/*.sha256 dist/install.sh; do n=$(basename "$f"); curl -fsS -X POST -H "$H" -F "attachment=@$f" "$GITEA_API/releases/$RID/assets?name=$n" >/dev/null && echo "uploaded $n"; done'
|