erldistpy/.gitlab-ci.yml
russell@unturf.com 16b33c6a37
ci: modern twine, classic auth via group vars, v0.1.6
After protecting the * tag pattern on the python/ group, the group-
scoped Protected TWINE_USERNAME/TWINE_PASSWORD vars inject into tag
pipelines. Twine 6+ sees them set and uses classic auth directly,
skipping Trusted Publishing (which can't work for self-hosted
git.unturf.com — see docs/PYPI-TRUSTED-PUBLISHING.md).

What this commit changes:
  - .gitlab-ci.yml drops the --trusted-publishing flag (unrecognized
    by the runner's twine anyway) — twine sees env vars and is happy
  - pyproject.toml stays on the latest setuptools (no <77 cap needed
    since we're not pinning twine<6 anymore)
  - Diagnostic for TWINE_USERNAME/TWINE_PASSWORD presence stays so
    future failures surface fast
2026-06-16 15:18:54 -04:00

58 lines
2.4 KiB
YAML

stages:
- test
- pypi-twine
# ---------------------------------------------------------------------------
# Tests run on every push to any branch.
#
# Live-integration tests need EPMD on the runner — ``make all`` skips
# them automatically when EPMD isn't reachable. CI runners typically
# don't run EPMD, so we get unit-level coverage in CI and full
# integration coverage on the dev machine.
# ---------------------------------------------------------------------------
test:
stage: test
tags: ["build"]
except:
- tags
script:
- python3 -m venv .venv
- . .venv/bin/activate
- pip install --upgrade pip wheel
- pip install -e ".[dev]"
- pytest -v
# ---------------------------------------------------------------------------
# Ship to PyPI on tag pushes.
#
# Auth: TWINE_USERNAME + TWINE_PASSWORD env vars come from project-scoped
# GitLab CI variables (Settings → CI/CD → Variables, masked + protected).
# Standard values: TWINE_USERNAME=__token__ and TWINE_PASSWORD=<pypi-...>.
#
# Trusted Publishing OIDC would be cleaner but PyPI's GitLab provider is
# hardcoded to gitlab.com — git.unturf.com self-hosted isn't supported.
# See docs/PYPI-TRUSTED-PUBLISHING.md for the migration recipe whenever
# PyPI adds custom-issuer support (or whenever we mirror to gitlab.com).
# ---------------------------------------------------------------------------
pypi-twine:
stage: pypi-twine
tags: ["build"]
only:
- tags
script:
# Sanity-check that the group-scoped CI vars actually landed in the
# env on this pipeline. Prints "set" or "MISSING" — never the value,
# never echoes them anywhere — so masked/protected flags stay safe.
- 'test -n "${TWINE_USERNAME:-}" && echo "TWINE_USERNAME: set" || echo "TWINE_USERNAME: MISSING (check group vars Protected flag vs tag protection)"'
- 'test -n "${TWINE_PASSWORD:-}" && echo "TWINE_PASSWORD: set" || echo "TWINE_PASSWORD: MISSING (check group vars Protected flag vs tag protection)"'
- python3 -m venv .venv
- . .venv/bin/activate
- pip install --upgrade pip
- pip install build twine
- python -m build
- twine check dist/*
# Twine 6 prefers Trusted Publishing IF TWINE_USERNAME/TWINE_PASSWORD
# are unset. With both set, classic auth is used directly. If the
# diagnostic above shows MISSING, fix the group var Protected flag
# or mark tags as Protected refs on the python/ group.
- twine upload --non-interactive dist/*