refactor(release-plugin): readme.txt als Changelog-SSOT
- Pre-Flight prüft jetzt zusätzlich Stable tag: in readme.txt - Changelog-Block wird aus readme.txt == Changelog == gezogen - CHANGELOG.md fällt als Workflow-Abhängigkeit weg - readme.txt ist Pflichtdatei im Plugin-Repo Grund: readme.txt ist WP-natives Format, WordPress und Master-Key parsen es direkt (für CPT-Sync der öffentlichen Plugin-Seite). Damit gibt es eine SSOT zum Pflegen statt parallele CHANGELOG.md. Entscheidung dokumentiert in Notion: https://www.notion.so/32b36ebfe9178147ad16ee214302c994
This commit is contained in:
@@ -13,7 +13,11 @@ name: Release Plugin
|
||||
# Erwartete Struktur im aufrufenden Repo:
|
||||
# - <slug>.php (Plugin-Haupt-PHP mit "Version: X.Y.Z" im Header)
|
||||
# - Irgendwo in einer PHP-Datei: define('IDF_<UPPER>_VERSION', 'X.Y.Z')
|
||||
# - CHANGELOG.md mit Block "## v<X.Y.Z> — <Datum>"
|
||||
# - readme.txt im Repo-Root mit:
|
||||
# Stable tag: X.Y.Z
|
||||
# == Changelog ==
|
||||
# = X.Y.Z =
|
||||
# * ...
|
||||
#
|
||||
# Trigger im aufrufenden Repo: push eines Tags der Form v<MAJOR>.<MINOR>.<PATCH>.
|
||||
|
||||
@@ -81,6 +85,16 @@ jobs:
|
||||
fi
|
||||
echo "Tag-Format OK: $TAG"
|
||||
|
||||
- name: Pre-Flight — readme.txt vorhanden
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ ! -f readme.txt ]]; then
|
||||
echo "::error::readme.txt fehlt im Repo-Root (Pflichtdatei, siehe idf-ci README)"
|
||||
exit 1
|
||||
fi
|
||||
echo "readme.txt OK"
|
||||
|
||||
- name: Pre-Flight — Plugin-Header-Version
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -120,35 +134,56 @@ jobs:
|
||||
fi
|
||||
echo "Konstante OK: $CONST=$CONST_VERSION"
|
||||
|
||||
- name: Changelog-Block extrahieren
|
||||
- name: Pre-Flight — readme.txt Stable tag
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.vars.outputs.version }}"
|
||||
STABLE_TAG="$(grep -iE '^[[:space:]]*Stable tag:[[:space:]]*' readme.txt | head -n1 | sed -E 's/^[^0-9]*([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')"
|
||||
if [[ -z "$STABLE_TAG" ]]; then
|
||||
echo "::error::Konnte 'Stable tag: …' Zeile in readme.txt nicht finden"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$STABLE_TAG" != "$VERSION" ]]; then
|
||||
echo "::error::readme.txt Stable tag '$STABLE_TAG' != Tag '$VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
echo "Stable tag OK: $STABLE_TAG"
|
||||
|
||||
- name: Changelog-Block aus readme.txt extrahieren
|
||||
id: changelog
|
||||
shell: bash
|
||||
env:
|
||||
VERSION: ${{ steps.vars.outputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ ! -f CHANGELOG.md ]]; then
|
||||
echo "::error::CHANGELOG.md fehlt im Repo"
|
||||
exit 1
|
||||
fi
|
||||
BLOCK="$(python3 - <<'PY'
|
||||
import re, sys, os
|
||||
version = os.environ["VERSION"]
|
||||
with open("CHANGELOG.md", encoding="utf-8") as f:
|
||||
with open("readme.txt", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
# Match "## v<version>" optionally followed by spaces and any suffix (e.g. date),
|
||||
# capture until the next "## v<x.y.z>" or a "---" separator line or EOF.
|
||||
pat = re.compile(
|
||||
r"^##\s+v" + re.escape(version) + r"(?:\s+.*)?$\n(.*?)(?=^##\s+v\d|^---\s*$|\Z)",
|
||||
# 1) "== Changelog ==" Abschnitt finden (bis zum nächsten "==…==" oder Dateiende)
|
||||
section_pat = re.compile(
|
||||
r"^==\s*Changelog\s*==\s*$\n(.*?)(?=^==[^=\n]+==\s*$|\Z)",
|
||||
re.MULTILINE | re.DOTALL | re.IGNORECASE,
|
||||
)
|
||||
section_m = section_pat.search(content)
|
||||
if not section_m:
|
||||
sys.stderr.write("'== Changelog ==' section not found in readme.txt\n")
|
||||
sys.exit(1)
|
||||
section = section_m.group(1)
|
||||
# 2) Block "= <version> =" bis zum nächsten "= x.y.z =" oder Abschnittsende
|
||||
block_pat = re.compile(
|
||||
r"^=\s*" + re.escape(version) + r"\s*=\s*$\n(.*?)(?=^=\s*\d+\.\d+\.\d+\s*=\s*$|\Z)",
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
m = pat.search(content)
|
||||
if not m:
|
||||
sys.stderr.write(f"No block for v{version} found in CHANGELOG.md\n")
|
||||
block_m = block_pat.search(section)
|
||||
if not block_m:
|
||||
sys.stderr.write(f"No block '= {version} =' found in == Changelog == section\n")
|
||||
sys.exit(1)
|
||||
print(m.group(1).strip())
|
||||
print(block_m.group(1).strip())
|
||||
PY
|
||||
)" || { echo "::error::Kein Changelog-Block für v${VERSION} in CHANGELOG.md"; exit 1; }
|
||||
)" || { echo "::error::Kein Changelog-Block für $VERSION in readme.txt (Abschnitt '== Changelog ==')"; exit 1; }
|
||||
{
|
||||
echo "body<<CHANGELOG_EOF"
|
||||
echo "$BLOCK"
|
||||
@@ -180,8 +215,14 @@ jobs:
|
||||
--exclude='tests' \
|
||||
--exclude='phpunit.xml*' \
|
||||
--exclude='phpcs.xml*' \
|
||||
--exclude='CHANGELOG.md' \
|
||||
--exclude='*.zip' \
|
||||
./ "$WORK/$SLUG/"
|
||||
# readme.txt muss im Build enthalten sein (WP-Standard)
|
||||
if [[ ! -f "$WORK/$SLUG/readme.txt" ]]; then
|
||||
echo "::error::readme.txt fehlt im gebauten Plugin-Ordner"
|
||||
exit 1
|
||||
fi
|
||||
(cd "$WORK" && zip -qr "/tmp/$ZIPNAME" "$SLUG")
|
||||
ls -la "/tmp/$ZIPNAME"
|
||||
# Validierung: Top-Level im ZIP ist genau $SLUG/
|
||||
|
||||
Reference in New Issue
Block a user