🎫 Auto Release #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🎫 Auto Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # Trigger bei: v1.0.0, v1.2.3, etc. | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Tag, der released werden soll (z. B. v1.2.3)' | |
| required: true | |
| type: string | |
| create_tag: | |
| description: 'Neuen Tag erstellen, falls er noch nicht existiert' | |
| required: false | |
| type: boolean | |
| default: false | |
| ref: | |
| description: 'Branch/Commit für den neuen Tag (nur falls oben aktiviert)' | |
| required: false | |
| type: string | |
| default: main | |
| # Verhindert, dass sich zwei Release-Läufe für denselben Tag überschneiden | |
| concurrency: | |
| group: release-${{ inputs.tag || github.ref_name }} | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| # Tag ermitteln — funktioniert sowohl bei Tag-Push als auch bei manueller Ausführung | |
| - name: Tag ermitteln | |
| id: tag | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG="${{ inputs.tag }}" | |
| else | |
| TAG="${GITHUB_REF_NAME}" | |
| fi | |
| if [[ ! "$TAG" =~ ^v ]]; then | |
| echo "::error::Tag '$TAG' entspricht nicht dem erwarteten Muster 'v*'." | |
| exit 1 | |
| fi | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| # Checkout des Tags (falls vorhanden) bzw. des angegebenen Branches (für neue Tags). | |
| # fetch-depth: 0 holt komplette History + alle Tags. | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref || github.ref }} | |
| fetch-depth: 0 | |
| # Prüft, ob der Tag existiert. Falls nicht: | |
| # - create_tag aktiviert → Tag wird aus 'ref' erstellt und gepusht | |
| # - create_tag deaktiviert → Abbruch mit Hinweis | |
| - name: Tag prüfen & ggf. erstellen | |
| run: | | |
| set -euo pipefail | |
| TAG="${{ steps.tag.outputs.tag }}" | |
| if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then | |
| echo "✅ Tag '$TAG' existiert bereits." | |
| exit 0 | |
| fi | |
| if [ "${{ inputs.create_tag }}" != "true" ]; then | |
| echo "::error::Tag '$TAG' existiert nicht. Workflow erneut ausführen und die Option 'Neuen Tag erstellen' aktivieren — der Tag wird dann aus '${{ inputs.ref }}' erstellt." | |
| exit 1 | |
| fi | |
| echo "🏷️ Tag '$TAG' existiert nicht — wird aus '${{ inputs.ref }}' erstellt." | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git tag -a "$TAG" -m "Release $TAG" | |
| git push origin "refs/tags/$TAG" | |
| echo "✅ Tag '$TAG' erstellt und gepusht." | |
| - name: Modified files & Commits ermitteln | |
| run: | | |
| set -euo pipefail | |
| CURR_TAG="${{ steps.tag.outputs.tag }}" | |
| PREV_TAG=$(git describe --tags --abbrev=0 "${CURR_TAG}^" 2>/dev/null || echo "") | |
| REPO="${GITHUB_REPOSITORY}" | |
| if [ -z "$PREV_TAG" ]; then | |
| RANGE="$CURR_TAG" | |
| printf '> ⚠️ First Release – no comparison with previous tag possible.\n\n' > release_body.md | |
| else | |
| RANGE="$PREV_TAG..$CURR_TAG" | |
| printf '> 🔍 Comparison: [`%s` → `%s`](https://github.com/%s/compare/%s...%s)\n\n' \ | |
| "$PREV_TAG" "$CURR_TAG" "$REPO" "$PREV_TAG" "$CURR_TAG" > release_body.md | |
| fi | |
| # Commits | |
| # Use --pretty=format:"...%n" so every line (including the last) ends | |
| # with a newline. The previous `while read` loop silently dropped the | |
| # most recent commit, because `read` returns non-zero on a final line | |
| # without a trailing newline — the loop body was skipped for it. | |
| echo "## 📝 Commits" >> release_body.md | |
| git log "$RANGE" \ | |
| --pretty=format:"- [\`%h\`](https://github.com/$REPO/commit/%H) %s (%an)%n" \ | |
| >> release_body.md | |
| # Modified files | |
| printf '\n\n## 📂 Modified files\n' >> release_body.md | |
| echo '```' >> release_body.md | |
| git diff --name-status "$RANGE" \ | |
| | sed 's/^A\t/✅ NEW /;s/^M\t/✏️ CHANGED /;s/^D\t/🗑️ DELETED /' \ | |
| >> release_body.md | |
| echo '```' >> release_body.md | |
| # Statistics | |
| STATS=$(git diff --shortstat "$RANGE" 2>/dev/null || echo "First Release") | |
| printf '\n---\n📊 **%s**\n' "$STATS" >> release_body.md | |
| - name: GitHub Release erstellen | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.tag }} | |
| body_path: release_body.md | |
| generate_release_notes: true | |
| token: ${{ secrets.GITHUB_TOKEN }} |