#!/usr/bin/env bash # Публикация файлов из DIST_DIR в PyPI-реестр пакетов Gitea. # Уже загруженные (по имени файла в simple-индексе) пропускаются: twine 7 не # поддерживает --skip-existing для не-PyPI репозиториев. # # Переменные: # TOKEN (или GITEA_JOB_TOKEN) — обязательный токен (PAT write:package или # встроенный job-токен при packages: write) # DIST_DIR — каталог с *.whl/*.tar.gz (по умолчанию dist) # SERVER, OWNER — Gitea и владелец; если не заданы, берутся # из git remote (origin) # PYPI_USER — имя пользователя (по умолчанию актор) set -euo pipefail DIST_DIR="${DIST_DIR:-dist}" TOKEN="${TOKEN:-${GITEA_JOB_TOKEN:-}}" if [ -z "${SERVER:-}" ]; then SERVER="$(git remote get-url origin \ | sed -E 's#^git@([^:]+):.*#https://\1#; s#^(https?://[^/]+)/.*#\1#')" fi if [ -z "${OWNER:-}" ]; then REPO="${GITHUB_REPOSITORY:-$(git remote get-url origin \ | sed -E 's#.*[:/]([^/]+/[^/]+?)(\.git)?$#\1#')}" OWNER="${REPO%%/*}" fi USER_NAME="${PYPI_USER:-${GITHUB_ACTOR:-git}}" if [ -z "$TOKEN" ]; then echo "нет токена: задайте секрет PYPI_TOKEN (PAT write:package) или" >&2 echo "разрешите 'packages: write' для встроенного GITEA_TOKEN" >&2 exit 1 fi if [ ! -d "$DIST_DIR" ]; then echo "нет каталога $DIST_DIR" >&2 exit 1 fi INDEX="$SERVER/api/packages/$OWNER/pypi/simple/pyfglair/" pip install --upgrade --quiet twine for FILE in "$DIST_DIR"/*; do NAME="$(basename "$FILE")" if curl -fsS -u "$USER_NAME:$TOKEN" "$INDEX" 2>/dev/null \ | grep -qF "$NAME"; then echo "уже опубликовано: $NAME" continue fi python -m twine upload \ --repository-url "$SERVER/api/packages/$OWNER/pypi" \ --username "$USER_NAME" \ --password "$TOKEN" \ --non-interactive \ "$FILE" echo "опубликовано: $NAME" done echo "индекс: $INDEX"