#!/bin/bash # Automatisches Release-Script mit CHANGELOG-Generierung set -e VERSION_TYPE=${1:-patch} CUSTOM_MESSAGE=${2:-""} if [[ ! "$VERSION_TYPE" =~ ^(patch|minor|major)$ ]]; then echo "❌ Ungültiger Version-Typ: $VERSION_TYPE" echo "Verwendung: ./scripts/release.sh [patch|minor|major] [optional: custom message]" exit 1 fi GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' NC='\033[0m' echo -e "${BLUE}🚀 Automated Release: ${YELLOW}${VERSION_TYPE}${NC}" echo "" # 1. Hole aktuelle Version vom letzten Git-Tag LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -z "$LAST_TAG" ]; then echo -e "${YELLOW}⚠️ Kein vorheriger Tag gefunden. Verwende Version aus package.json${NC}" CURRENT_VERSION=$(node -p "require('./frontend/package.json').version") else # Entferne führendes "v" falls vorhanden CURRENT_VERSION=${LAST_TAG#v} fi echo -e "📌 Aktuelle Version (Tag): ${CURRENT_VERSION}" # 2. Berechne neue Version basierend auf dem Tag IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" case $VERSION_TYPE in major) NEW_VERSION="$((MAJOR + 1)).0.0" ;; minor) NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" ;; patch) NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; esac echo -e "📦 Neue Version: ${GREEN}${NEW_VERSION}${NC}" echo "" # 3. Setze neue Version in package.json cd frontend npm version $NEW_VERSION --no-git-tag-version > /dev/null cd .. # 3. Synchronisiere alle Dateien echo "🔄 Synchronisiere Version überall..." ./scripts/sync-version.sh > /dev/null 2>&1 # 4. Sammle Commits seit letztem Tag echo "📝 Generiere CHANGELOG-Eintrag..." LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -z "$LAST_TAG" ]; then echo -e "${YELLOW}⚠️ Kein vorheriger Tag gefunden. Alle Commits werden verwendet.${NC}" echo " Tipp: Erstelle rückwirkend einen Tag für die letzte Version:" echo " git tag -a v1.1.0 -m 'Release 1.1.0'" echo "" COMMITS=$(git log --oneline --no-merges) else echo "📋 Commits seit Tag $LAST_TAG werden verwendet" COMMITS=$(git log ${LAST_TAG}..HEAD --oneline --no-merges) fi # 5. Gruppiere Commits nach Typ FEATURES=$(echo "$COMMITS" | grep "^[a-f0-9]* feat:" || true) FIXES=$(echo "$COMMITS" | grep "^[a-f0-9]* fix:" || true) REFACTOR=$(echo "$COMMITS" | grep "^[a-f0-9]* refactor:" || true) CHORE=$(echo "$COMMITS" | grep "^[a-f0-9]* chore:" || true) DOCS=$(echo "$COMMITS" | grep "^[a-f0-9]* docs:" || true) # 6. Erstelle CHANGELOG-Eintrag DATE=$(date +%Y-%m-%d) CHANGELOG_ENTRY="## [${NEW_VERSION}] - ${DATE}\n\n" if [ -n "$CUSTOM_MESSAGE" ]; then CHANGELOG_ENTRY+="${CUSTOM_MESSAGE}\n\n" fi if [ -n "$FEATURES" ]; then CHANGELOG_ENTRY+="### ✨ Features\n" while IFS= read -r line; do MSG=$(echo "$line" | sed -E 's/^[a-f0-9]+ feat: //') CHANGELOG_ENTRY+="- ${MSG}\n" done <<< "$FEATURES" CHANGELOG_ENTRY+="\n" fi if [ -n "$FIXES" ]; then CHANGELOG_ENTRY+="### 🐛 Fixes\n" while IFS= read -r line; do MSG=$(echo "$line" | sed -E 's/^[a-f0-9]+ fix: //') CHANGELOG_ENTRY+="- ${MSG}\n" done <<< "$FIXES" CHANGELOG_ENTRY+="\n" fi if [ -n "$REFACTOR" ]; then CHANGELOG_ENTRY+="### ♻️ Refactoring\n" while IFS= read -r line; do MSG=$(echo "$line" | sed -E 's/^[a-f0-9]+ refactor: //') CHANGELOG_ENTRY+="- ${MSG}\n" done <<< "$REFACTOR" CHANGELOG_ENTRY+="\n" fi if [ -n "$CHORE" ]; then CHANGELOG_ENTRY+="### 🔧 Chores\n" while IFS= read -r line; do MSG=$(echo "$line" | sed -E 's/^[a-f0-9]+ chore: //') CHANGELOG_ENTRY+="- ${MSG}\n" done <<< "$CHORE" CHANGELOG_ENTRY+="\n" fi # 7. Füge Eintrag in CHANGELOG.md ein (nach der Überschrift) if [ -f "CHANGELOG.md" ]; then # Temporäre Datei erstellen TEMP_FILE=$(mktemp) # Erste Zeilen (bis erste ##) behalten awk '/^## \[/ {exit} {print}' CHANGELOG.md > "$TEMP_FILE" # Neuen Eintrag hinzufügen echo -e "$CHANGELOG_ENTRY" >> "$TEMP_FILE" # Rest des alten CHANGELOG anhängen awk '/^## \[/ {found=1} found {print}' CHANGELOG.md >> "$TEMP_FILE" # Ersetzen mv "$TEMP_FILE" CHANGELOG.md echo -e "${GREEN}✓ CHANGELOG.md aktualisiert${NC}" else # CHANGELOG erstellen cat > CHANGELOG.md << EOF # Changelog Alle wichtigen Änderungen an diesem Projekt werden in dieser Datei dokumentiert. Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/), und dieses Projekt hält sich an [Semantic Versioning](https://semver.org/spec/v2.0.0.html). $CHANGELOG_ENTRY EOF echo -e "${GREEN}✓ CHANGELOG.md erstellt${NC}" fi # 8. Preview anzeigen echo "" echo -e "${BLUE}📄 CHANGELOG Preview:${NC}" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo -e "$CHANGELOG_ENTRY" | head -20 echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 9. Frage nach Bestätigung read -p "Sieht das gut aus? [Y/n] " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ ! -z $REPLY ]]; then echo "❌ Abgebrochen. Änderungen wurden NICHT committed." exit 1 fi # 10. Git Commit & Tag echo "" echo "📦 Erstelle Git Commit & Tag..." git add -A git commit -m "chore: release v${NEW_VERSION} 🔖 Version ${NEW_VERSION} $(echo -e "$CHANGELOG_ENTRY" | sed 's/^## .*//' | sed 's/^$//' | head -30)" git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}" echo -e "${GREEN}✓ Commit & Tag erstellt${NC}" echo "" echo -e "${BLUE}Pushe zu Remote...${NC}" # Push mit --follow-tags (pusht Commit + zugehörige Tags) if git push --follow-tags; then echo -e "${GREEN}✓ Erfolgreich gepusht${NC}" else echo -e "${RED}⚠ Push fehlgeschlagen - bitte manuell pushen:${NC}" echo " git push --follow-tags" fi echo "" echo -e "${GREEN}✅ Release v${NEW_VERSION} fertig!${NC}"