diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..8a49606 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Release script для 222a-seo-audit plugin. +# Использование: ./scripts/release.sh [--message "changelog text"] [--dry-run] +set -euo pipefail + +VERSION="${1:-}" +DRY_RUN=0 +MESSAGE="" + +shift || true +while [[ $# -gt 0 ]]; do + case "$1" in + --dry-run) DRY_RUN=1 ;; + --message) MESSAGE="$2"; shift ;; + *) echo "Unknown arg: $1"; exit 1 ;; + esac + shift +done + +# 1. Валидация semver +if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "ERROR: версия должна быть в формате MAJOR.MINOR.PATCH (например, 1.0.0)" + echo "Получено: '$VERSION'" + exit 1 +fi + +TAG="v${VERSION}" +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_ROOT" + +# 2. Проверка чистоты и ветки +if [[ "$DRY_RUN" -eq 0 ]]; then + if [[ -n "$(git status --porcelain)" ]]; then + echo "ERROR: рабочая копия не чистая. Закоммитьте или стэшните изменения." + exit 1 + fi + CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" + if [[ "$CURRENT_BRANCH" != "main" ]]; then + echo "ERROR: релиз только из ветки main. Текущая: $CURRENT_BRANCH" + exit 1 + fi +fi + +# 3. Проверка, что тег ещё не существует +if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "ERROR: тег $TAG уже существует" + exit 1 +fi + +if [[ "$DRY_RUN" -eq 1 ]]; then + echo "Would release $VERSION (dry-run)" + exit 0 +fi + +# 4. Подменить версию в 3 json-файлах (sed inline) +PLUGIN_JSON="plugins/222a-seo-audit/.claude-plugin/plugin.json" +MCP_JSON="plugins/222a-seo-audit/.mcp.json" +MARKETPLACE_JSON=".claude-plugin/marketplace.json" + +# Используем python для безопасной правки JSON +python3 - "$VERSION" "$PLUGIN_JSON" "$MCP_JSON" "$MARKETPLACE_JSON" <<'PY' +import json, sys +version = sys.argv[1] +plugin_json, mcp_json, marketplace_json = sys.argv[2], sys.argv[3], sys.argv[4] + +with open(plugin_json) as f: p = json.load(f) +p["version"] = version +with open(plugin_json, "w") as f: json.dump(p, f, indent=2, ensure_ascii=False); f.write("\n") + +with open(mcp_json) as f: m = json.load(f) +m["mcpServers"]["222a-seo-audit"]["headers"]["X-Plugin-Version"] = version +with open(mcp_json, "w") as f: json.dump(m, f, indent=2, ensure_ascii=False); f.write("\n") + +with open(marketplace_json) as f: mk = json.load(f) +mk["plugins"][0]["version"] = version +with open(marketplace_json, "w") as f: json.dump(mk, f, indent=2, ensure_ascii=False); f.write("\n") + +print(f"Updated version to {version} in 3 files") +PY + +# 5. Обновить CHANGELOG.md +CHANGELOG="plugins/222a-seo-audit/CHANGELOG.md" +TODAY="$(date +%Y-%m-%d)" + +if [[ -n "$MESSAGE" ]]; then + # Вставить новую секцию после "## [Unreleased]" + TMP="$(mktemp)" + awk -v v="$VERSION" -v d="$TODAY" -v m="$MESSAGE" ' + /^## \[Unreleased\]/ { print; print ""; print "## [" v "] - " d; print ""; print m; print ""; next } + { print } + ' "$CHANGELOG" > "$TMP" + mv "$TMP" "$CHANGELOG" +else + # Открыть редактор для ручного ввода + echo "Откройте $CHANGELOG, добавьте секцию для $VERSION в начало, сохраните и закройте." + ${EDITOR:-nano} "$CHANGELOG" +fi + +# 6. Коммит, тег, push +git add "$PLUGIN_JSON" "$MCP_JSON" "$MARKETPLACE_JSON" "$CHANGELOG" +git commit -m "release: v$VERSION" +git tag -a "$TAG" -m "Release $VERSION" +git push origin main +git push origin "$TAG" + +echo "" +echo "Released $VERSION (tag $TAG)." +echo "Клиенты обновятся через:" +echo " /plugin marketplace update" +echo " /plugin update 222a-seo-audit" diff --git a/scripts/test-release.sh b/scripts/test-release.sh new file mode 100755 index 0000000..9941174 --- /dev/null +++ b/scripts/test-release.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Smoke-тесты для release.sh. Запускать вручную перед коммитом изменений в release.sh. +set -euo pipefail + +cd "$(dirname "$0")/.." + +# Тест 1: невалидный semver должен фейлиться +if ./scripts/release.sh "1.0" 2>/dev/null; then + echo "FAIL: невалидный semver принят" + exit 1 +fi +echo "OK: невалидный semver отклонён" + +# Тест 2: dry-run на корректном semver должен пройти валидацию +if ! ./scripts/release.sh "9.9.9" --dry-run 2>&1 | grep -q "Would release"; then + echo "FAIL: dry-run на 9.9.9 не сработал" + exit 1 +fi +echo "OK: dry-run работает" + +echo "All smoke tests passed"