TagRelease #10
This file contains 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: TagRelease | |
on: | |
workflow_dispatch: | |
inputs: | |
tagType: | |
description: 'TagType' | |
required: true | |
default: 'pre-tag' | |
type: choice | |
options: | |
- normal | |
- pre-tag | |
tag: | |
description: 'Tag version number (Eg: v0.1.0)' | |
required: true | |
type: string | |
message: | |
description: 'Tag message' | |
required: true | |
permissions: | |
contents: write | |
packages: write | |
jobs: | |
# * Step 0: Pre-Check | |
pre-check: | |
runs-on: ubuntu-latest | |
outputs: | |
TAG_NAME: ${{ steps.set-tag.outputs.TAG_NAME }} | |
PRERELEASE: ${{ steps.set-tag.outputs.PRERELEASE }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.PAT }} | |
# ! TODO add check if tag format is valid (semver) | |
- name: Check if tag is valid | |
run : | | |
# Check if the tag start with 'v', if not, add it | |
if [[ ! ${{ github.event.inputs.tag }} =~ ^v.* ]]; then | |
echo "Error tag format is invalid. The format is vx.x.x" >> "$GITHUB_OUTPUT" | |
exit 1 | |
fi | |
- name: Construct Tag for Pre-Release | |
id: set-tag | |
run: | | |
# Construct the tag name | |
if [ "${{ github.event.inputs.tagType }}" == "pre-tag" ]; then | |
echo "TAG_NAME=$(echo ${{ github.event.inputs.tag }}-alpha$(date +%Y%m%d%H%M))" >> "$GITHUB_OUTPUT" | |
echo "PRERELEASE=true" >> "$GITHUB_OUTPUT" | |
else | |
echo "TAG_NAME=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT" | |
fi | |
# * Step 1: Check if everything is ok | |
tag-already-exist: | |
needs: [pre-check] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.PAT }} | |
- name: Check if tag not already exists | |
run: | | |
if git rev-parse ${{ needs.pre-check.outputs.TAG_NAME }} >/dev/null 2>&1; then | |
echo "Tag ${{ needs.pre-check.outputs.TAG_NAME }} already exists" >> "$GITHUB_OUTPUT" | |
exit 1 | |
fi | |
golangci-lint: | |
needs: [pre-check] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.PAT }} | |
- uses: actions/setup-go@v5 | |
with: | |
go-version-file: 'go.mod' | |
- run: go mod download | |
- name: golangci-lint | |
uses: golangci/golangci-lint-action@v6 | |
with: | |
version: latest | |
# TODO add tests | |
# * Step 2: Create a new tag | |
tag: | |
needs: [golangci-lint, pre-check, tag-already-exist] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.PAT }} | |
- uses: rickstaa/action-create-tag@v1 | |
id: "tag_create" | |
with: | |
tag: ${{ needs.pre-check.outputs.TAG_NAME }} | |
tag_exists_error: true | |
message: ${{ github.event.inputs.message }} | |
release-notes: | |
runs-on: ubuntu-latest | |
needs: [tag, pre-check] | |
steps: | |
- uses: actions/checkout@v4 # v3.5.3 | |
with: | |
fetch-depth: 0 | |
ref: ${{ needs.pre-check.outputs.TAG_NAME }} | |
- name: Generate Release Notes | |
run: | | |
echo "" > release-notes.txt | |
if [ ${{ needs.pre-check.outputs.PRERELEASE }} == "true" ]; then | |
echo "## :construction: Prerelease" >> release-notes.txt | |
export PREV_TAG=$(git tag --list 'v*' --sort=-version:refname | grep -E "v[0-9]+\.[0-9]+\.[0-9]+$" | head -n 1) | |
export PREV_VERSION=${PREV_TAG//v} | |
else | |
export PREV_TAG=$(git tag --list 'v*' --sort=-version:refname | grep -E "v[0-9]+\.[0-9]+\.[0-9]+$" | head -n 2 | tail -n 1) | |
export PREV_VERSION=${PREV_TAG//v} | |
fi | |
sed -n -e "1{/# /d;}" -e "2{/^$/d;}" -e "/# $PREV_VERSION/q;p" CHANGELOG.md >> release-notes.txt | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: release-notes | |
path: release-notes.txt | |
retention-days: 1 | |
release-app: | |
runs-on: ubuntu-latest | |
needs: [release-notes, golangci-lint, pre-check] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: ${{ needs.pre-check.outputs.TAG_NAME }} | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version-file: 'go.mod' | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- id: release-notes-download | |
name: Release Notes Download | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: release-notes | |
path: /tmp | |
- name: Run GoReleaser | |
uses: goreleaser/goreleaser-action@v6 | |
if: success() | |
with: | |
distribution: goreleaser | |
version: latest | |
args: release --clean -f .goreleaser.yaml --release-notes=${{ steps.release-notes-download.outputs.download-path }}/release-notes.txt | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
trigger-doc-update: | |
needs: [release-app, pre-check] | |
runs-on: ubuntu-latest | |
if: needs.pre-check.outputs.PRERELEASE == 'false' | |
steps: | |
- name: Repository Dispatch | |
uses: peter-evans/repository-dispatch@v3 | |
with: | |
event-type: update-doc | |
highest-version-tag: | |
needs: [pre-check,release-app] | |
runs-on: ubuntu-latest | |
if: needs.pre-check.outputs.PRERELEASE == 'false' | |
outputs: | |
tag: ${{ steps.highest-version-tag.outputs.tag }} | |
steps: | |
- uses: actions/checkout@v4 # v3.5.3 | |
with: | |
ref: ${{ needs.pre-check.outputs.TAG_NAME }} | |
fetch-depth: 0 | |
- name: Output highest version tag | |
id: highest-version-tag | |
run: | | |
HIGHEST=$(git tag | sort -V | tail -1) | |
echo "tag=$HIGHEST" >> "$GITHUB_OUTPUT" | |
changelog-newversion: | |
needs: [release-app, highest-version-tag, pre-check] | |
# write new changelog header only if release tag is the $HIGHEST i.e. exists on main | |
# and not a backport release branch (e.g. release/3.x). This results in | |
# manually updating the CHANGELOG header if releasing from the non-default branch. | |
# TODO: find a more deterministic way to determine release branch from tag commit | |
if: github.ref_name == needs.highest-version-tag.outputs.tag && needs.pre-check.outputs.PRERELEASE == 'false' | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 # v3.5.3 | |
with: | |
token: ${{ secrets.PAT }} | |
fetch-depth: 0 | |
ref: main | |
- name: Update Changelog Header | |
run: | | |
CHANGELOG_FILE_NAME="CHANGELOG.md" | |
PREVIOUS_RELEASE_TAG=${{ github.ref_name }} | |
# Add Release Date | |
RELEASE_DATE=`date +%B' '%e', '%Y` | |
sed -i -e "1 s/.*Unreleased.*/## ${PREVIOUS_RELEASE_TAG#v} ($RELEASE_DATE)/" $CHANGELOG_FILE_NAME | |
# Prepend next release line | |
echo Previous release is: $PREVIOUS_RELEASE_TAG | |
NEW_RELEASE_LINE=$(echo $PREVIOUS_RELEASE_TAG | awk -F. '{ | |
$1 = substr($1,2) | |
$2 += 1 | |
printf("%s.%01d.0\n\n", $1, $2); | |
}') | |
echo New minor version is: v$NEW_RELEASE_LINE | |
echo -e "## $NEW_RELEASE_LINE (Unreleased)\n$(cat $CHANGELOG_FILE_NAME)" > $CHANGELOG_FILE_NAME | |
- uses: stefanzweifel/git-auto-commit-action@v5 | |
with: | |
commit_message: "chore: Update CHANGELOG.md after ${{ github.ref_name }}" | |
commit_options: '--no-verify --signoff' | |
file_pattern: CHANGELOG.md | |
commit_user_name: Changelog[bot] | |
commit_user_email: changelog-bot@azrod.me | |
commit_author: Changelog Bot <changelog-bot@azrod.me> | |