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}"