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:
|
# Erwartete Struktur im aufrufenden Repo:
|
||||||
# - <slug>.php (Plugin-Haupt-PHP mit "Version: X.Y.Z" im Header)
|
# - <slug>.php (Plugin-Haupt-PHP mit "Version: X.Y.Z" im Header)
|
||||||
# - Irgendwo in einer PHP-Datei: define('IDF_<UPPER>_VERSION', 'X.Y.Z')
|
# - 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>.
|
# Trigger im aufrufenden Repo: push eines Tags der Form v<MAJOR>.<MINOR>.<PATCH>.
|
||||||
|
|
||||||
@@ -81,6 +85,16 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "Tag-Format OK: $TAG"
|
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
|
- name: Pre-Flight — Plugin-Header-Version
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -120,35 +134,56 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "Konstante OK: $CONST=$CONST_VERSION"
|
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
|
id: changelog
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ steps.vars.outputs.version }}
|
VERSION: ${{ steps.vars.outputs.version }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if [[ ! -f CHANGELOG.md ]]; then
|
|
||||||
echo "::error::CHANGELOG.md fehlt im Repo"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
BLOCK="$(python3 - <<'PY'
|
BLOCK="$(python3 - <<'PY'
|
||||||
import re, sys, os
|
import re, sys, os
|
||||||
version = os.environ["VERSION"]
|
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()
|
content = f.read()
|
||||||
# Match "## v<version>" optionally followed by spaces and any suffix (e.g. date),
|
# 1) "== Changelog ==" Abschnitt finden (bis zum nächsten "==…==" oder Dateiende)
|
||||||
# capture until the next "## v<x.y.z>" or a "---" separator line or EOF.
|
section_pat = re.compile(
|
||||||
pat = re.compile(
|
r"^==\s*Changelog\s*==\s*$\n(.*?)(?=^==[^=\n]+==\s*$|\Z)",
|
||||||
r"^##\s+v" + re.escape(version) + r"(?:\s+.*)?$\n(.*?)(?=^##\s+v\d|^---\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,
|
re.MULTILINE | re.DOTALL,
|
||||||
)
|
)
|
||||||
m = pat.search(content)
|
block_m = block_pat.search(section)
|
||||||
if not m:
|
if not block_m:
|
||||||
sys.stderr.write(f"No block for v{version} found in CHANGELOG.md\n")
|
sys.stderr.write(f"No block '= {version} =' found in == Changelog == section\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
print(m.group(1).strip())
|
print(block_m.group(1).strip())
|
||||||
PY
|
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 "body<<CHANGELOG_EOF"
|
||||||
echo "$BLOCK"
|
echo "$BLOCK"
|
||||||
@@ -180,8 +215,14 @@ jobs:
|
|||||||
--exclude='tests' \
|
--exclude='tests' \
|
||||||
--exclude='phpunit.xml*' \
|
--exclude='phpunit.xml*' \
|
||||||
--exclude='phpcs.xml*' \
|
--exclude='phpcs.xml*' \
|
||||||
|
--exclude='CHANGELOG.md' \
|
||||||
--exclude='*.zip' \
|
--exclude='*.zip' \
|
||||||
./ "$WORK/$SLUG/"
|
./ "$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")
|
(cd "$WORK" && zip -qr "/tmp/$ZIPNAME" "$SLUG")
|
||||||
ls -la "/tmp/$ZIPNAME"
|
ls -la "/tmp/$ZIPNAME"
|
||||||
# Validierung: Top-Level im ZIP ist genau $SLUG/
|
# Validierung: Top-Level im ZIP ist genau $SLUG/
|
||||||
|
|||||||
Reference in New Issue
Block a user