Files
configure_nginx_manager/.github/workflows/release.yml

298 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: "Релиз: архив исходников"
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Тег релиза (например: v2.2.0)"
required: true
permissions:
contents: write
env:
DIST_DIR: dist
jobs:
release:
name: "Упаковка и публикация релиза"
runs-on: native
steps:
- name: "Получение исходного кода"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ github.event.inputs.tag }}"
else
TAG="${GITHUB_REF_NAME}"
fi
if [ -z "${TAG}" ]; then
echo "ОШИБКА: не удалось определить тег релиза."
exit 1
fi
echo ">>> Клонирование ${REPO} (тег: ${TAG})"
if [ -n "${TOKEN}" ]; then
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
fi
else
CLONE_URL="${SERVER}/${REPO}.git"
fi
git clone --branch "${TAG}" --depth 1 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
git fetch --tags --force 2>/dev/null || true
echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV"
echo ">>> Исходный код получен: $(git log --oneline -1)"
- name: "Подготовка метаданных релиза"
id: meta
shell: bash
run: |
set -euo pipefail
TAG="${RELEASE_TAG}"
VERSION="${TAG#v}"
PREV_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
echo "══════════════════════════════════════"
echo " Тег: ${TAG}"
echo " Версия: ${VERSION}"
echo " Пред. тег: ${PREV_TAG:-<первый релиз>}"
echo " Коммит: ${GITHUB_SHA:0:8}"
echo "══════════════════════════════════════"
- name: "Создание архивов исходного кода"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
REPO_NAME="${GITHUB_REPOSITORY##*/}"
ARCHIVE_BASE="${REPO_NAME}-${TAG}"
rm -rf .release-work "${DIST_DIR}"
mkdir -p .release-work "${DIST_DIR}"
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.git/' \
--exclude '.src-repo/' \
--exclude '.wiki-repo/' \
--exclude '.release-work/' \
--exclude "${DIST_DIR}/" \
./ ".release-work/${ARCHIVE_BASE}/"
else
cp -a . ".release-work/${ARCHIVE_BASE}"
rm -rf \
".release-work/${ARCHIVE_BASE}/.git" \
".release-work/${ARCHIVE_BASE}/.src-repo" \
".release-work/${ARCHIVE_BASE}/.wiki-repo" \
".release-work/${ARCHIVE_BASE}/.release-work" \
".release-work/${ARCHIVE_BASE}/${DIST_DIR}"
fi
tar -czf "${DIST_DIR}/${ARCHIVE_BASE}.tar.gz" -C .release-work "${ARCHIVE_BASE}"
if command -v zip >/dev/null 2>&1; then
(
cd .release-work
zip -qr "../${DIST_DIR}/${ARCHIVE_BASE}.zip" "${ARCHIVE_BASE}"
)
else
ARCHIVE_BASE="${ARCHIVE_BASE}" DIST_DIR="${DIST_DIR}" python3 - <<'PY'
import os
import zipfile
base = os.environ["ARCHIVE_BASE"]
src = os.path.join(".release-work", base)
dst = os.path.join(os.environ["DIST_DIR"], f"{base}.zip")
with zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zf:
for root, _, files in os.walk(src):
for file_name in files:
full = os.path.join(root, file_name)
arc = os.path.relpath(full, ".release-work")
zf.write(full, arc)
PY
fi
sha256sum "${DIST_DIR}"/* > "${DIST_DIR}/checksums-sha256.txt"
echo "ARCHIVE_BASE=${ARCHIVE_BASE}" >> "$GITHUB_ENV"
echo ">>> Артефакты релиза:"
ls -lh "${DIST_DIR}"
- name: "Генерация описания релиза"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
PREV_TAG="${{ steps.meta.outputs.prev_tag }}"
DATE_UTC=$(date -u '+%Y-%m-%d %H:%M UTC')
CHANGELOG_FILE=""
if [ -f "docs/ru/CHANGELOG.md" ]; then
CHANGELOG_FILE="docs/ru/CHANGELOG.md"
elif [ -f "docs/en/CHANGELOG_EN.md" ]; then
CHANGELOG_FILE="docs/en/CHANGELOG_EN.md"
fi
CHANGELOG_SECTION=""
if [ -n "${CHANGELOG_FILE}" ]; then
CHANGELOG_SECTION=$(awk -v ver="${VERSION}" '
$0 ~ "^## \\[" ver "\\]" { in_section=1; next }
/^## \[/ && in_section { exit }
in_section { print }
' "${CHANGELOG_FILE}")
fi
if [ -n "${PREV_TAG}" ]; then
COMMITS=$(git log --pretty=format:'- %s (%h)' "${PREV_TAG}..${TAG}" --no-merges | head -50)
else
COMMITS=$(git log --pretty=format:'- %s (%h)' --no-merges | head -50)
fi
{
echo "## ${TAG}"
echo ""
echo "Релиз скриптового проекта без компиляции бинарников."
echo ""
echo "### Что входит в релиз"
echo "- Исходный код в форматах: ${ARCHIVE_BASE}.tar.gz, ${ARCHIVE_BASE}.zip"
echo "- Контрольные суммы: checksums-sha256.txt"
echo ""
if [ -n "${CHANGELOG_SECTION}" ]; then
echo "### Что сделано (из CHANGELOG)"
echo "${CHANGELOG_SECTION}"
echo ""
fi
echo "### Коммиты релиза"
if [ -n "${COMMITS}" ]; then
echo "${COMMITS}"
else
echo "- Изменения не найдены"
fi
echo ""
echo "---"
echo ""
echo "- Тег: ${TAG}"
echo "- Коммит: ${GITHUB_SHA}"
echo "- Дата (UTC): ${DATE_UTC}"
} > /tmp/release_body.md
echo ">>> Сформировано описание релиза: /tmp/release_body.md"
- name: "Создание релиза и загрузка архивов"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
if [ -z "${TOKEN}" ]; then
echo "ОШИБКА: не задан секрет GIT_TOKEN (или GITEA_TOKEN)."
exit 1
fi
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
TAG="${{ steps.meta.outputs.tag }}"
BODY_JSON=$(python3 - <<'PY'
import json
with open('/tmp/release_body.md', 'r', encoding='utf-8') as f:
print(json.dumps(f.read(), ensure_ascii=False))
PY
)
if [ "${HOST}" = "github.com" ]; then
CREATE_URL="https://api.github.com/repos/${REPO}/releases"
AUTH_HEADER="Authorization: Bearer ${TOKEN}"
EXTRA_HEADERS=(-H "Accept: application/vnd.github+json")
else
CREATE_URL="${SERVER}/api/v1/repos/${REPO}/releases"
AUTH_HEADER="Authorization: token ${TOKEN}"
EXTRA_HEADERS=()
fi
RELEASE_JSON=$(curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/json" \
"${EXTRA_HEADERS[@]}" \
"${CREATE_URL}" \
-d "{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${GITHUB_SHA}\",\"name\":\"${TAG}\",\"body\":${BODY_JSON},\"draft\":false,\"prerelease\":false}")
RELEASE_ID=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))")
if [ -z "${RELEASE_ID}" ]; then
echo "ОШИБКА: не удалось получить ID релиза"
echo "${RELEASE_JSON}"
exit 1
fi
if [ "${HOST}" = "github.com" ]; then
UPLOAD_BASE=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('upload_url','').split('{')[0])")
RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG}"
else
UPLOAD_BASE="${SERVER}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets"
RELEASE_URL="${SERVER}/${REPO}/releases/tag/${TAG}"
fi
echo ">>> Загрузка файлов в релиз ${TAG}"
for file in "${DIST_DIR}"/*; do
[ -f "${file}" ] || continue
name=$(basename "${file}")
if [ "${HOST}" = "github.com" ]; then
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
"${EXTRA_HEADERS[@]}" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
else
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
fi
echo " ✓ ${name}"
done
echo ""
echo ">>> Релиз опубликован: ${RELEASE_URL}"