name: Release — Semantic Versioning & Desktop Packaging # --------------------------------------------------------------- # Trigger: Manuell ODER automatisch wenn version.properties # auf main/master geändert wird. # --------------------------------------------------------------- on: push: branches: [ main, master ] paths: - 'version.properties' workflow_dispatch: inputs: dry_run: description: 'Dry-Run (kein Tag, kein Upload)' required: false default: 'false' jobs: # ============================================================= # JOB 1: Version lesen & Git-Tag setzen # ============================================================= tag-release: name: 🏷️ Git-Tag setzen # Für Plan-B-Builds überspringen: Commit-Message enthält [planb] if: ${{ !contains(github.event.head_commit.message, '[planb]') }} runs-on: ubuntu-latest outputs: version: ${{ steps.read-version.outputs.version }} tag: ${{ steps.read-version.outputs.tag }} already_tagged: ${{ steps.check-tag.outputs.already_tagged }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Version aus version.properties lesen id: read-version run: | source <(grep -v '^#' version.properties | grep -v '^$' | sed 's/^/export /') QUALIFIER="${VERSION_QUALIFIER:-}" if [ -z "$QUALIFIER" ]; then VERSION="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" else VERSION="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${QUALIFIER}" fi TAG="v${VERSION}" echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "📦 Version: ${VERSION} | Tag: ${TAG}" - name: Prüfen ob Tag bereits existiert id: check-tag run: | TAG="${{ steps.read-version.outputs.tag }}" if git rev-parse "$TAG" >/dev/null 2>&1; then echo "already_tagged=true" >> $GITHUB_OUTPUT echo "⚠️ Tag $TAG existiert bereits — überspringe Tagging" else echo "already_tagged=false" >> $GITHUB_OUTPUT echo "✅ Tag $TAG ist neu" fi - name: Git-Tag erstellen & pushen if: steps.check-tag.outputs.already_tagged == 'false' && github.event.inputs.dry_run != 'true' run: | TAG="${{ steps.read-version.outputs.tag }}" VERSION="${{ steps.read-version.outputs.version }}" git config user.name "Gitea CI" git config user.email "ci@mo-code.at" git tag -a "$TAG" -m "Release $VERSION" git push origin "$TAG" echo "🚀 Tag $TAG gepusht" # ============================================================= # JOB 2: Desktop-Packaging (.deb — Linux) # ============================================================= package-linux: name: 📦 Linux .deb Packaging # Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(github.event.head_commit.message, '[planb]') }} runs-on: ubuntu-latest needs: tag-release steps: - name: Checkout uses: actions/checkout@v4 - name: Setup JDK 21 (Temurin) uses: actions/setup-java@v4 with: distribution: temurin java-version: '21' - name: Gradle cache uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper .gradle key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'gradle.properties') }} restore-keys: | ${{ runner.os }}-gradle- - name: Make gradlew executable run: chmod +x ./gradlew - name: Linux .deb bauen env: _JAVA_OPTIONS: -Djava.awt.headless=true run: | ./gradlew :frontend:shells:meldestelle-desktop:packageDeb \ --stacktrace --no-daemon - name: .deb Artefakt hochladen uses: actions/upload-artifact@v4 with: name: meldestelle-${{ needs.tag-release.outputs.version }}-linux-deb path: frontend/shells/meldestelle-desktop/build/compose/binaries/main/deb/*.deb if-no-files-found: warn # ============================================================= # JOB 3: Desktop-Packaging (.msi — Windows) # ============================================================= package-windows: name: 📦 Windows .msi Packaging # Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(github.event.head_commit.message, '[planb]') }} runs-on: windows-latest needs: tag-release steps: - name: Checkout uses: actions/checkout@v4 - name: Setup JDK 21 (Temurin) uses: actions/setup-java@v4 with: distribution: temurin java-version: '21' - name: Gradle cache uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper .gradle key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'gradle.properties') }} restore-keys: | ${{ runner.os }}-gradle- - name: Windows .msi bauen env: _JAVA_OPTIONS: -Djava.awt.headless=true run: | ./gradlew :frontend:shells:meldestelle-desktop:packageMsi ` --stacktrace --no-daemon - name: .msi Artefakt hochladen uses: actions/upload-artifact@v4 with: name: meldestelle-${{ needs.tag-release.outputs.version }}-windows-msi path: frontend/shells/meldestelle-desktop/build/compose/binaries/main/msi/*.msi if-no-files-found: warn # ============================================================= # JOB 4: Release-Summary # ============================================================= release-summary: name: 📋 Release-Summary runs-on: ubuntu-latest needs: [ tag-release, package-linux, package-windows ] if: always() steps: - name: Summary ausgeben run: | echo "## 🚀 Release ${{ needs.tag-release.outputs.version }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Artefakt | Status |" >> $GITHUB_STEP_SUMMARY echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY echo "| Linux .deb | ${{ needs.package-linux.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Windows .msi | ${{ needs.package-windows.result }} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Git-Tag:** \`${{ needs.tag-release.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY