Files
WP-LIT-MCP/bin/release.sh
T

116 lines
6.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Builds and signs a WP-LIT-MCP release from the committed state; with --publish it also tags and publishes it.
#
# bin/release.sh dry run: checks, tests, build, signature, ZIP checks – publishes nothing
# bin/release.sh --publish additionally: git tag + push, Gitea release with ZIP and .sig, check of the result
#
# Needs: bsdtar, composer, curl, jq, php (sodium). For --publish a Gitea token with write access to the repository in
# $GITEA_TOKEN. The signing key (php bin/release-sign.php keygen) lives outside the repository.
#
# Environment: LIT_MCP_RELEASE_KEY (default ~/.config/wp-lit-mcp/release.key), LIT_MCP_DIVI_CHECK (command that must
# succeed before a release, default: ddev wp --user=janniclas lit-mcp divi-check).
set -euo pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$root"
repo_url="https://git.loosen-it.de/janniclas.loosen/WP-LIT-MCP"
api="https://git.loosen-it.de/api/v1/repos/janniclas.loosen/WP-LIT-MCP"
key="${LIT_MCP_RELEASE_KEY:-$HOME/.config/wp-lit-mcp/release.key}"
divi_check="${LIT_MCP_DIVI_CHECK:-ddev wp --user=janniclas lit-mcp divi-check}"
publish=0
[[ "${1:-}" == "--publish" ]] && publish=1
fail() { echo "ABBRUCH: $*" >&2; exit 1; }
step() { echo "==> $*"; }
# --- 1. The three version places agree, the tree is committed, nothing is released twice ----------------------------
step "Version und Zustand prüfen"
version="$(sed -n "s/.*const VERSION = '\(.*\)';/\1/p" src/Plugin.php)"
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "Plugin::VERSION ist keine Version x.y.z: '$version'"
[[ "$(sed -n 's/^ \* Version: //p' wp-lit-mcp.php)" == "$version" ]] || fail "Header-Version in wp-lit-mcp.php weicht ab"
[[ "$(sed -n 's/^Stable tag: //p' readme.txt)" == "$version" ]] || fail "Stable tag in readme.txt weicht ab"
grep -q "^= $version =\$" readme.txt || fail "readme.txt hat keinen Changelog-Eintrag für $version"
[[ -z "$(git status --porcelain)" ]] || fail "Arbeitsbaum nicht sauber: erst committen, das ZIP entsteht aus HEAD"
! git rev-parse -q --verify "refs/tags/v$version" >/dev/null || fail "Tag v$version existiert schon"
[[ -r "$key" ]] || fail "Signierschlüssel fehlt: $key (php bin/release-sign.php keygen <Datei>)"
if [[ $publish -eq 1 ]]; then
[[ -n "${GITEA_TOKEN:-}" ]] || fail "GITEA_TOKEN ist nicht gesetzt"
fi
# --- 2. Tests and the Divi check must be green ------------------------------------------------------------------------
step "Tests"
composer test
step "Divi-Prüfung ($divi_check)"
eval "$divi_check" || fail "Divi-Prüfung nicht grün: kein Release"
# --- 3. Build from the commit: git archive honours export-ignore, then production dependencies ----------------------
step "ZIP bauen"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
mkdir "$work/wp-lit-mcp"
git archive HEAD | tar -x -C "$work/wp-lit-mcp"
(cd "$work/wp-lit-mcp" && composer install --no-dev --optimize-autoloader --no-interaction --quiet)
name="wp-lit-mcp-$version.zip"
mkdir -p dist
zip="$root/dist/$name"
rm -f "$zip" "$zip.sig"
(cd "$work" && bsdtar --format zip -cf "$zip" wp-lit-mcp)
# --- 4. Look into the ZIP like WordPress will: one folder, the plugin, its autoloader, the right version --------------
step "ZIP prüfen"
entries="$(bsdtar -tf "$zip")"
if grep -qv '^wp-lit-mcp/' <<<"$entries"; then fail "ZIP enthält Einträge außerhalb von wp-lit-mcp/"; fi
for need in wp-lit-mcp/wp-lit-mcp.php wp-lit-mcp/vendor/autoload_packages.php; do
grep -qx "$need" <<<"$entries" || fail "Im ZIP fehlt $need"
done
if grep -qE '^wp-lit-mcp/(tests|bin|docs/superpowers|\.git)(/|$)' <<<"$entries"; then
fail "Entwicklungsdateien im ZIP"
fi
[[ "$(bsdtar -xOf "$zip" wp-lit-mcp/wp-lit-mcp.php | sed -n 's/^ \* Version: //p')" == "$version" ]] \
|| fail "Version im ZIP stimmt nicht mit $version überein"
# --- 5. Sign, and prove the signature against the key built into the plugin -------------------------------------------
step "Signieren"
php bin/release-sign.php sign "$zip" "$key" > "$zip.sig"
php bin/release-sign.php verify "$zip" "$zip.sig" >/dev/null || fail "Signatur passt nicht zum Schlüssel im Plugin (PackageSignature::RELEASE_KEY)"
if [[ $publish -eq 0 ]]; then
echo "Probelauf in Ordnung: dist/$name und dist/$name.sig"
echo "Veröffentlichen: GITEA_TOKEN=… bin/release.sh --publish"
exit 0
fi
# --- 6. Publish ---------------------------------------------------------------------------------------------------------
step "Tag v$version setzen und pushen"
git tag -a "v$version" -m "WP-LIT-MCP $version"
git push origin "v$version"
step "Release auf Gitea anlegen"
auth=(-H "Authorization: token $GITEA_TOKEN")
notes="$(awk -v header="= $version =" '$0 == header { on = 1; next } /^= / { on = 0 } on' readme.txt)"
release_id="$(curl -fsS "${auth[@]}" -H 'Content-Type: application/json' \
-d "$(jq -n --arg tag "v$version" --arg body "$notes" '{tag_name: $tag, name: $tag, body: $body}')" \
"$api/releases" | jq -r .id)"
for file in "$zip" "$zip.sig"; do
curl -fsS "${auth[@]}" -F "attachment=@$file" "$api/releases/$release_id/assets?name=$(basename "$file")" >/dev/null
done
# --- 7. Check what a customer site will see: latest release, public asset URLs, a signature that verifies ------------
step "Ergebnis prüfen (ohne Token, wie eine Kundenseite)"
latest="$(curl -fsS "$api/releases/latest")"
[[ "$(jq -r .tag_name <<<"$latest")" == "v$version" ]] || fail "releases/latest liefert nicht v$version"
asset_url() { jq -r --arg n "$1" '.assets[] | select(.name == $n) | .browser_download_url' <<<"$latest"; }
zip_url="$(asset_url "$name")"
sig_url="$(asset_url "$name.sig")"
for url in "$zip_url" "$sig_url"; do
[[ "$url" == "$repo_url/releases/download/"* ]] || fail "Asset-URL nicht wie erwartet: '$url'"
done
mkdir "$work/check"
curl -fsSL "$zip_url" -o "$work/check/$name"
curl -fsSL "$sig_url" -o "$work/check/$name.sig"
php bin/release-sign.php verify "$work/check/$name" "$work/check/$name.sig" >/dev/null \
|| fail "Heruntergeladenes Release besteht die Signaturprüfung nicht"
echo "Release v$version veröffentlicht: $repo_url/releases/tag/v$version"