Skip to content

Merge pull request #9 from securebitsorg/feature/github-releases-docu… #24

Merge pull request #9 from securebitsorg/feature/github-releases-docu…

Merge pull request #9 from securebitsorg/feature/github-releases-docu… #24

name: Auto Release on Push
on:
push:
branches: [ main ]
paths-ignore:
- 'README.md'
- 'docs/**'
- '*.md'
permissions:
contents: write # Needed to create releases and push tags
actions: read # Needed to read workflow artifacts
packages: write # Needed for package publishing
id-token: write # Needed for PyPI trusted publishing (optional)
jobs:
check-for-release:
name: Check for Release Triggers
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
release_type: ${{ steps.check.outputs.release_type }}
version: ${{ steps.check.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check commit message for release triggers
id: check
run: |
COMMIT_MSG="${{ github.event.head_commit.message }}"
echo "Commit message: $COMMIT_MSG"
# Aktuelle Version lesen
CURRENT_VERSION=$(cat VERSION 2>/dev/null || echo "0.0.0")
echo "Current version: $CURRENT_VERSION"
# Letzten Git-Tag abrufen
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
LAST_TAG_VERSION=${LAST_TAG#v}
echo "Last tag version: $LAST_TAG_VERSION"
# Höchste Version verwenden
if [[ "$LAST_TAG_VERSION" > "$CURRENT_VERSION" ]]; then
CURRENT_VERSION="$LAST_TAG_VERSION"
echo "Using tag version as base: $CURRENT_VERSION"
fi
# Release-Typ bestimmen basierend auf Commit-Message
SHOULD_RELEASE="false"
RELEASE_TYPE=""
NEW_VERSION=""
if [[ "$COMMIT_MSG" =~ ^(feat|feature)(\(.+\))?!: ]] || [[ "$COMMIT_MSG" =~ BREAKING[[:space:]]CHANGE ]]; then
# Major release (breaking change)
SHOULD_RELEASE="true"
RELEASE_TYPE="major"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1+1".0.0"}')
elif [[ "$COMMIT_MSG" =~ ^(feat|feature)(\(.+\))?: ]]; then
# Minor release (new feature)
SHOULD_RELEASE="true"
RELEASE_TYPE="minor"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1"."$2+1".0"}')
elif [[ "$COMMIT_MSG" =~ ^(fix|bugfix)(\(.+\))?: ]]; then
# Patch release (bug fix)
SHOULD_RELEASE="true"
RELEASE_TYPE="patch"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1"."$2"."$3+1}')
elif [[ "$COMMIT_MSG" =~ \[release\] ]]; then
# Manueller Release-Trigger
SHOULD_RELEASE="true"
RELEASE_TYPE="patch"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1"."$2"."$3+1}')
elif [[ "$COMMIT_MSG" =~ \[major\] ]]; then
SHOULD_RELEASE="true"
RELEASE_TYPE="major"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1+1".0.0"}')
elif [[ "$COMMIT_MSG" =~ \[minor\] ]]; then
SHOULD_RELEASE="true"
RELEASE_TYPE="minor"
NEW_VERSION=$(echo $CURRENT_VERSION | awk -F. '{print $1"."$2+1".0"}')
fi
# Überprüfen ob der berechnete Tag bereits existiert
if [[ "$SHOULD_RELEASE" == "true" ]] && git rev-parse "v$NEW_VERSION" >/dev/null 2>&1; then
echo "Tag v$NEW_VERSION already exists, skipping release"
SHOULD_RELEASE="false"
fi
echo "should_release=$SHOULD_RELEASE" >> $GITHUB_OUTPUT
echo "release_type=$RELEASE_TYPE" >> $GITHUB_OUTPUT
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "Should release: $SHOULD_RELEASE"
echo "Release type: $RELEASE_TYPE"
echo "New version: $NEW_VERSION"
create-release:
name: Create Automatic Release
needs: check-for-release
runs-on: ubuntu-latest
if: needs.check-for-release.outputs.should_release == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Configure Git
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
- name: Update version files
run: |
NEW_VERSION="${{ needs.check-for-release.outputs.version }}"
# VERSION-Datei aktualisieren
echo "$NEW_VERSION" > VERSION
# __version__.py aktualisieren
cat > __version__.py << EOF
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Version information for Bash-Script-Maker
"""
__version__ = "$NEW_VERSION"
__version_info__ = ($(echo $NEW_VERSION | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1, \2, \3/'))
EOF
# pyproject.toml aktualisieren
sed -i "s/^version = .*/version = \"$NEW_VERSION\"/" pyproject.toml
- name: Generate release notes
id: release_notes
run: |
NEW_VERSION="${{ needs.check-for-release.outputs.version }}"
RELEASE_TYPE="${{ needs.check-for-release.outputs.release_type }}"
COMMIT_MSG="${{ github.event.head_commit.message }}"
# Basis Release-Notes erstellen
cat > release_notes.txt << EOF
## Version $NEW_VERSION
**Release-Typ:** $RELEASE_TYPE
### Änderungen
$COMMIT_MSG
### Installation
\`\`\`bash
# Via pip
pip install bash-script-maker==$NEW_VERSION
# Aus Quellcode
git clone https://github.com/securebitsorg/bash-script-maker.git
cd bash-script-maker
git checkout v$NEW_VERSION
./install.sh
\`\`\`
### Artefakte
- Python Wheel (.whl)
- Source Distribution (.tar.gz)
- Flatpak Bundle (.flatpak)
- Vollständiger Quellcode
EOF
echo "Release-Notes erstellt für Version $NEW_VERSION"
- name: Commit version changes
run: |
NEW_VERSION="${{ needs.check-for-release.outputs.version }}"
git add VERSION __version__.py pyproject.toml
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
- name: Create and push tag
run: |
NEW_VERSION="${{ needs.check-for-release.outputs.version }}"
# Überprüfen ob Tag bereits existiert
if git rev-parse "v$NEW_VERSION" >/dev/null 2>&1; then
echo "Tag v$NEW_VERSION already exists, skipping tag creation"
exit 0
fi
git tag -a "v$NEW_VERSION" -m "Automatic release v$NEW_VERSION"
git push origin main
git push origin "v$NEW_VERSION"
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ needs.check-for-release.outputs.version }}
name: Release ${{ needs.check-for-release.outputs.version }}
body_path: release_notes.txt
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-and-upload:
name: Build and Upload Assets
needs: [check-for-release, create-release]
runs-on: ubuntu-latest
if: needs.check-for-release.outputs.should_release == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: v${{ needs.check-for-release.outputs.version }}
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install twine wheel setuptools
- name: Build Python packages
run: |
python setup.py sdist bdist_wheel
- name: Create source archive
run: |
VERSION=${{ needs.check-for-release.outputs.version }}
git archive --format=tar.gz --prefix=bash-script-maker-$VERSION/ HEAD > bash-script-maker-$VERSION-source.tar.gz
- name: Upload to release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ needs.check-for-release.outputs.version }}
files: |
dist/*.whl
dist/*.tar.gz
bash-script-maker-${{ needs.check-for-release.outputs.version }}-source.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-pypi:
name: Publish to PyPI
needs: [check-for-release, build-and-upload]
runs-on: ubuntu-latest
if: needs.check-for-release.outputs.should_release == 'true' && !contains(needs.check-for-release.outputs.version, '-')
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: v${{ needs.check-for-release.outputs.version }}
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install twine wheel setuptools
- name: Build packages
run: python setup.py sdist bdist_wheel
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
skip-existing: true
publish-github-packages:
name: Publish to GitHub Packages
needs: [check-for-release, build-and-upload]
runs-on: ubuntu-latest
if: needs.check-for-release.outputs.should_release == 'true'
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: v${{ needs.check-for-release.outputs.version }}
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/bash-script-maker
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}},value=v${{ needs.check-for-release.outputs.version }}
type=semver,pattern={{major}}.{{minor}},value=v${{ needs.check-for-release.outputs.version }}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max