Release-Workflow: ZIP bei jedem Merge nach main
Some checks are pending
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Some checks are pending
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
.github/workflows/release.yml baut bei jedem Push auf main (also auch
nach jedem gemergten Pull Request) ein installierbares Paket und hängt es
an das rollende Vorab-Release "latest-main". Der Download-Link bleibt
damit stabil und zeigt immer auf den aktuellen Stand. Ein Tag v* erzeugt
mit derselben Mechanik ein reguläres Release.
Details:
- das ZIP entsteht per `git archive`, die Auswahl steuert .gitattributes
(export-ignore) – docs/, tests/, tools/ und CI bleiben draußen, das
Paket ist rund 1,4 MB groß
- eine Prüfschritt kontrolliert, dass Kerndateien wirklich enthalten sind,
dazu gibt es eine .sha256-Datei
- zusätzlich als Build-Artefakt abgelegt (optional, bricht nicht ab, wenn
der Artefakt-Speicher fehlt)
- Release-API wird über den automatisch bereitgestellten Token
angesprochen, FORGEJO_TOKEN dient als Ausweichweg; ohne Token wird der
Schritt übersprungen statt fehlzuschlagen
Neu ist die Datei VERSION als einzige Quelle der Versionsnummer: sie
benennt das Paket und erscheint über Ui::version() unten in der
Admin-Seitenleiste ("v2.6.0 · Entwickelt von Loheide.eu").
Geprüft: Paket lokal gebaut, entpackt und die Anwendung daraus gestartet –
alle Seiten antworten mit 200, keine fehlenden Dateien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b7f13d8fac
commit
8facc71455
15 changed files with 216 additions and 3 deletions
152
.github/workflows/release.yml
vendored
Normal file
152
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
name: Release-Paket
|
||||
|
||||
# Bei jedem Merge nach main entsteht ein installierbares ZIP und landet als
|
||||
# Vorab-Release "latest-main" im Repository. Wird ein Tag v* gepusht, wird
|
||||
# daraus ein regulaeres Release mit derselben Mechanik.
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: [ 'v*' ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
package:
|
||||
name: ZIP bauen und veröffentlichen
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Version und Dateinamen bestimmen
|
||||
id: meta
|
||||
run: |
|
||||
set -eu
|
||||
VERSION="$(tr -d ' \r\n' < VERSION)"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
BUILD_DATE="$(date -u +%Y-%m-%d)"
|
||||
|
||||
if [ "${GITHUB_REF_TYPE:-branch}" = "tag" ]; then
|
||||
TAG="${GITHUB_REF_NAME}"
|
||||
NAME="unifi-voucher-tool-${TAG}"
|
||||
TITLE="Version ${TAG}"
|
||||
PRERELEASE="false"
|
||||
else
|
||||
TAG="latest-main"
|
||||
NAME="unifi-voucher-tool-${VERSION}+${BUILD_DATE}.${SHORT_SHA}"
|
||||
TITLE="Aktueller Stand von main – ${VERSION} (${SHORT_SHA})"
|
||||
PRERELEASE="true"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "version=${VERSION}"
|
||||
echo "short_sha=${SHORT_SHA}"
|
||||
echo "build_date=${BUILD_DATE}"
|
||||
echo "tag=${TAG}"
|
||||
echo "name=${NAME}"
|
||||
echo "title=${TITLE}"
|
||||
echo "prerelease=${PRERELEASE}"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: ZIP erzeugen
|
||||
run: |
|
||||
set -eu
|
||||
mkdir -p dist
|
||||
# git archive wertet die export-ignore-Regeln aus .gitattributes aus,
|
||||
# docs/, tests/, tools/ und CI-Dateien bleiben also draußen.
|
||||
git archive --format=zip -9 \
|
||||
--prefix="unifi-voucher-tool/" \
|
||||
-o "dist/${{ steps.meta.outputs.name }}.zip" HEAD
|
||||
cd dist
|
||||
sha256sum "${{ steps.meta.outputs.name }}.zip" > "${{ steps.meta.outputs.name }}.zip.sha256"
|
||||
ls -lh
|
||||
|
||||
- name: Inhalt kurz prüfen
|
||||
run: |
|
||||
set -eu
|
||||
# Ein paar Dateien muessen enthalten sein, sonst ist das Paket kaputt.
|
||||
for required in \
|
||||
unifi-voucher-tool/index.php \
|
||||
unifi-voucher-tool/install.php \
|
||||
unifi-voucher-tool/database.sql \
|
||||
unifi-voucher-tool/assets/global.css \
|
||||
unifi-voucher-tool/assets/vendor/inter/inter.css \
|
||||
unifi-voucher-tool/includes/Ui.php
|
||||
do
|
||||
if ! unzip -l "dist/${{ steps.meta.outputs.name }}.zip" | grep -q "$required"; then
|
||||
echo "Fehlt im Paket: $required" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "Paket vollständig."
|
||||
|
||||
- name: Als Build-Artefakt sichern
|
||||
uses: actions/upload-artifact@v3
|
||||
continue-on-error: true # Artefakt-Speicher ist optional
|
||||
with:
|
||||
name: ${{ steps.meta.outputs.name }}
|
||||
path: dist/*
|
||||
retention-days: 30
|
||||
|
||||
- name: Release anlegen bzw. auffrischen
|
||||
env:
|
||||
# Forgejo stellt den Token automatisch bereit; FORGEJO_TOKEN
|
||||
# (persönlicher Token) dient als Ausweichweg.
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN || secrets.FORGEJO_TOKEN }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ steps.meta.outputs.tag }}
|
||||
NAME: ${{ steps.meta.outputs.name }}
|
||||
TITLE: ${{ steps.meta.outputs.title }}
|
||||
PRERELEASE: ${{ steps.meta.outputs.prerelease }}
|
||||
VERSION: ${{ steps.meta.outputs.version }}
|
||||
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
||||
BUILD_DATE: ${{ steps.meta.outputs.build_date }}
|
||||
run: |
|
||||
set -eu
|
||||
if [ -z "${TOKEN:-}" ]; then
|
||||
echo "Kein Token vorhanden – Release wird übersprungen." >&2
|
||||
exit 0
|
||||
fi
|
||||
AUTH="Authorization: token ${TOKEN}"
|
||||
|
||||
# Rollendes Vorab-Release durch ein frisches ersetzen, damit der
|
||||
# Download-Link stabil bleibt und auf den aktuellen Stand zeigt.
|
||||
if [ "$TAG" = "latest-main" ]; then
|
||||
OLD_ID="$(curl -sf -H "$AUTH" "${API}/releases/tags/${TAG}" \
|
||||
| grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true)"
|
||||
if [ -n "${OLD_ID:-}" ]; then
|
||||
curl -sf -X DELETE -H "$AUTH" "${API}/releases/${OLD_ID}" || true
|
||||
curl -sf -X DELETE -H "$AUTH" "${API}/tags/${TAG}" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Release-Text bewusst ohne Anfuehrungszeichen und Backslashes,
|
||||
# damit er ohne jq direkt in den JSON-Body passt (\n bleibt literal).
|
||||
BODY="Automatisch gebaut aus Commit ${SHORT_SHA}.\n\n"
|
||||
BODY="${BODY}| | |\n|---|---|\n"
|
||||
BODY="${BODY}| Version | ${VERSION} |\n"
|
||||
BODY="${BODY}| Commit | ${SHORT_SHA} |\n"
|
||||
BODY="${BODY}| Gebaut am | ${BUILD_DATE} |\n\n"
|
||||
BODY="${BODY}**Neuinstallation:** ZIP entpacken, Dateien auf den Webserver legen, install.php aufrufen.\n\n"
|
||||
BODY="${BODY}**Update einer bestehenden Installation:** config.php, uploads/ und updater/storage/ nicht ueberschreiben "
|
||||
BODY="${BODY}- oder gleich den eingebauten Updater unter Administration, System-Update verwenden.\n\n"
|
||||
BODY="${BODY}Pruefsumme: siehe beigelegte .sha256-Datei."
|
||||
|
||||
RELEASE_ID="$(curl -sf -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d "{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${GITHUB_SHA}\",\"name\":\"${TITLE}\",\"body\":\"${BODY}\",\"draft\":false,\"prerelease\":${PRERELEASE}}" \
|
||||
"${API}/releases" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)"
|
||||
|
||||
if [ -z "${RELEASE_ID:-}" ]; then
|
||||
echo "Release konnte nicht angelegt werden." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in "dist/${NAME}.zip" "dist/${NAME}.zip.sha256"; do
|
||||
curl -sf -X POST -H "$AUTH" \
|
||||
-F "attachment=@${file}" \
|
||||
"${API}/releases/${RELEASE_ID}/assets?name=$(basename "$file")" > /dev/null
|
||||
echo "Angehängt: $(basename "$file")"
|
||||
done
|
||||
|
||||
echo "Release ${TITLE} steht bereit: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue