# Cuts a release: moves CHANGELOG.md's [Unreleased] section under a new # version heading, commits it to main, then creates and pushes the version tag. # Trigger manually via workflow_dispatch, entering the semver to release. # The pushed tag can then be built with docker-publish.yml. name: Create Release Tag on: workflow_dispatch: inputs: version: description: "Version to release (semver, e.g. 1.2.3)" required: true type: string jobs: tag: runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Validate version and Unreleased section run: | if ! [[ "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Error: '${{ inputs.version }}' is not a valid semver (e.g. 1.2.3)." exit 1 fi if git rev-parse "refs/tags/${{ inputs.version }}" >/dev/null 2>&1; then echo "Error: tag '${{ inputs.version }}' already exists." exit 1 fi awk '/^## \[Unreleased\]/{f=1;next}/^## \[/{f=0}f' CHANGELOG.md > /tmp/unreleased.md if ! grep -q '[^[:space:]]' /tmp/unreleased.md; then echo "Error: CHANGELOG.md's [Unreleased] section is empty — nothing to release." exit 1 fi - name: Move Unreleased entries under the new version heading run: | today=$(date +%Y-%m-%d) awk -v ver="${{ inputs.version }}" -v date="$today" ' /^## \[Unreleased\]/ { print; print ""; print "## [" ver "] - " date; next } { print } ' CHANGELOG.md > /tmp/CHANGELOG.md mv /tmp/CHANGELOG.md CHANGELOG.md - name: Commit and tag run: | git config user.name "gitea-actions" git config user.email "actions@noreply.git.arthurerlich.de" git add CHANGELOG.md git commit -m "chore(release): ${{ inputs.version }}" git tag "${{ inputs.version }}" git push origin HEAD:main git push origin "${{ inputs.version }}"