name: Release on: workflow_dispatch: inputs: version: description: "Version tag (e.g. v0.1, v1.0.0)" required: true type: string env: REGISTRY: ghcr.io jobs: release: name: Build, Push & Release runs-on: ubuntu-latest permissions: contents: write packages: write attestations: write id-token: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set image name run: echo "IMAGE_NAME=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/tanken" >> "$GITHUB_ENV" - name: Validate version format run: | if [[ ! "${{ inputs.version }}" =~ ^v[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then echo "::error::Version must match vX.Y or vX.Y.Z (e.g. v0.1, v1.0.0)" exit 1 fi - name: Check tag doesn't already exist run: | if git rev-parse "${{ inputs.version }}" >/dev/null 2>&1; then echo "::error::Tag ${{ inputs.version }} already exists" exit 1 fi - name: Generate changelog id: changelog run: | PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -z "$PREVIOUS_TAG" ]; then ALL_COMMITS=$(git log --pretty=format:"%s (%h)" --no-merges) COMPARE_TEXT="Initial release" else ALL_COMMITS=$(git log "${PREVIOUS_TAG}..HEAD" --pretty=format:"%s (%h)" --no-merges) COMPARE_TEXT="**Full changelog**: [\`${PREVIOUS_TAG}...${{ inputs.version }}\`](https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...${{ inputs.version }})" fi FEATURES="" FIXES="" CHORES="" OTHER="" while IFS= read -r line; do [ -z "$line" ] && continue # Strip prefix for the display text clean=$(echo "$line" | sed -E 's/^(feat|fix|chore)(\(.+\))?:\s*//') if echo "$line" | grep -qE '^feat(\(.+\))?:'; then FEATURES="${FEATURES}- ${clean}"$'\n' elif echo "$line" | grep -qE '^fix(\(.+\))?:'; then FIXES="${FIXES}- ${clean}"$'\n' elif echo "$line" | grep -qE '^chore(\(.+\))?:'; then CHORES="${CHORES}- ${clean}"$'\n' else OTHER="${OTHER}- ${line}"$'\n' fi done <<< "$ALL_COMMITS" { echo "body<> "$GITHUB_OUTPUT" - name: Create and push tag run: | git tag "${{ inputs.version }}" git push origin "${{ inputs.version }}" - uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push image uses: docker/build-push-action@v6 with: context: . file: Dockerfile push: true tags: | ${{ env.IMAGE_NAME }}:${{ inputs.version }} ${{ env.IMAGE_NAME }}:latest no-cache: true - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ inputs.version }} name: ${{ inputs.version }} body: ${{ steps.changelog.outputs.body }} generate_release_notes: false