From 309826ccb639fa456e3027bebb8658b8e0c591ee Mon Sep 17 00:00:00 2001 From: Claude <4+claude@noreply.git.ihre-ideenfabrik.de> Date: Tue, 12 May 2026 05:34:06 +0000 Subject: [PATCH] feat(release-plugin): Auto-Modus bei push auf main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Trigger-Erkennung im "Variablen ableiten"-Step (refs/tags/* vs refs/heads/*) - Auto-Modus: Header-Version aus Plugin-PHP lesen, Tag v{version} prüfen → wenn Tag existiert: stiller Skip; sonst Pre-Flight + Build + Release - Release-API-Call mit target_commitish, damit Tag im Auto-Modus aus dem aktuellen HEAD-Commit erzeugt wird - Klassischer Tag-Push-Modus bleibt unverändert - Nachfolgende Steps mit if: steps.vars.outputs.skip != 'true' geguarded --- .gitea/workflows/release-plugin.yml | 61 ++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/release-plugin.yml b/.gitea/workflows/release-plugin.yml index c91a47b..983480b 100644 --- a/.gitea/workflows/release-plugin.yml +++ b/.gitea/workflows/release-plugin.yml @@ -21,7 +21,12 @@ name: Release Plugin # "== Changelog ==" in readme.txt wird beim Build aus CHANGELOG.md # generiert und ist nur im fertigen ZIP vollständig. # -# Trigger im aufrufenden Repo: push eines Tags der Form v... +# Trigger im aufrufenden Repo: +# - push auf main → Auto-Modus: Header-Version wird ausgelesen, Tag v +# wird erzeugt (sofern noch nicht vorhanden), Release wird gebaut. +# Existiert der Tag bereits, beendet der Workflow still (kein Release). +# - push eines Tags v.. → klassischer Modus: Tag wird +# direkt für den Release verwendet. # Ausführung auf dem IDF-Runner (self-hosted, Host-Modus). on: @@ -50,14 +55,12 @@ jobs: - name: Checkout Tag uses: actions/checkout@v4 - - name: Variablen ableiten + - name: Variablen ableiten (Auto-Modus oder Tag-Modus) id: vars shell: bash run: | set -euo pipefail SLUG="${{ inputs.slug }}" - TAG="${GITHUB_REF_NAME}" - VERSION="${TAG#v}" MAIN_FILE="${{ inputs.main_file }}" [[ -z "$MAIN_FILE" ]] && MAIN_FILE="${SLUG}.php" CONST="${{ inputs.version_constant }}" @@ -66,6 +69,37 @@ jobs: base_upper="$(echo "$base" | tr '[:lower:]-' '[:upper:]_')" CONST="IDF_${base_upper}_VERSION" fi + + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + # Klassischer Modus — Tag-Push + MODE="tag" + TAG="${GITHUB_REF_NAME}" + VERSION="${TAG#v}" + else + # Auto-Modus — Push auf Branch (z.B. main) + MODE="auto" + if [[ ! -f "$MAIN_FILE" ]]; then + echo "::error::Plugin-Haupt-PHP nicht gefunden: $MAIN_FILE" + exit 1 + fi + HEADER_VERSION="$(grep -iE '^[[:space:]]*\*?[[:space:]]*Version:[[:space:]]*' "$MAIN_FILE" | head -n1 | sed -E 's/^[^0-9]*([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')" + if [[ -z "$HEADER_VERSION" ]]; then + echo "::error::Header-Version in $MAIN_FILE nicht lesbar" + exit 1 + fi + VERSION="$HEADER_VERSION" + TAG="v$VERSION" + fi + + # Skip-Check (nur Auto-Modus): existiert der Tag schon, kein neues Release + SKIP=false + if [[ "$MODE" == "auto" ]]; then + if git ls-remote --tags origin "refs/tags/${TAG}" 2>/dev/null | grep -q "refs/tags/${TAG}"; then + echo "Tag $TAG existiert bereits — Skip (kein neues Release)." + SKIP=true + fi + fi + ZIPNAME="${SLUG}_v${VERSION}.zip" { echo "slug=$SLUG" @@ -74,10 +108,13 @@ jobs: echo "main_file=$MAIN_FILE" echo "const=$CONST" echo "zipname=$ZIPNAME" + echo "mode=$MODE" + echo "skip=$SKIP" } >> "$GITHUB_OUTPUT" - echo "Ermittelt: slug=$SLUG tag=$TAG version=$VERSION main_file=$MAIN_FILE const=$CONST" + echo "Ermittelt: mode=$MODE tag=$TAG version=$VERSION main_file=$MAIN_FILE const=$CONST skip=$SKIP" - name: Pre-Flight — Tag-Format + if: steps.vars.outputs.skip != 'true' shell: bash run: | set -euo pipefail @@ -89,6 +126,7 @@ jobs: echo "Tag-Format OK: $TAG" - name: Pre-Flight — Pflichtdateien + if: steps.vars.outputs.skip != 'true' shell: bash run: | set -euo pipefail @@ -102,6 +140,7 @@ jobs: echo "Pflichtdateien OK" - name: Pre-Flight — Plugin-Header-Version + if: steps.vars.outputs.skip != 'true' shell: bash run: | set -euo pipefail @@ -123,6 +162,7 @@ jobs: echo "Header-Version OK: $HEADER_VERSION" - name: Pre-Flight — Versions-Konstante + if: steps.vars.outputs.skip != 'true' shell: bash run: | set -euo pipefail @@ -141,6 +181,7 @@ jobs: echo "Konstante OK: $CONST=$CONST_VERSION" - name: Pre-Flight — readme.txt Stable tag + if: steps.vars.outputs.skip != 'true' shell: bash run: | set -euo pipefail @@ -157,6 +198,7 @@ jobs: echo "Stable tag OK: $STABLE_TAG" - name: Changelog-Block aus CHANGELOG.md extrahieren + if: steps.vars.outputs.skip != 'true' id: changelog shell: bash env: @@ -190,6 +232,7 @@ jobs: echo "Changelog-Block extrahiert (${#BLOCK} Zeichen)." - name: ZIP bauen (readme.txt Changelog-Section aus CHANGELOG.md generieren) + if: steps.vars.outputs.skip != 'true' id: zip shell: bash env: @@ -303,6 +346,7 @@ jobs: echo "zippath=/tmp/$ZIPNAME" >> "$GITHUB_OUTPUT" - name: Gitea-Release anlegen und Asset anhängen + if: steps.vars.outputs.skip != 'true' shell: bash env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN || github.token }} @@ -314,11 +358,16 @@ jobs: set -euo pipefail SERVER="${GITHUB_SERVER_URL:-https://git.ihre-ideenfabrik.de}" REPO="${GITHUB_REPOSITORY}" + # target_commitish setzt den Commit, aus dem der Tag erzeugt wird, + # falls er noch nicht existiert (Auto-Modus). Bei Tag-Push ist es egal, + # weil der Tag schon den Commit kennt — Gitea ignoriert das Feld dann. + TARGET_SHA="${GITHUB_SHA}" PAYLOAD="$(jq -n \ --arg tag "$TAG" \ --arg name "$TAG" \ --arg body "$BODY" \ - '{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:false}')" + --arg target "$TARGET_SHA" \ + '{tag_name:$tag, name:$name, body:$body, target_commitish:$target, draft:false, prerelease:false}')" RESP="$(curl -sSf \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \