11name : Release
22
33on :
4+ push :
5+ tags :
6+ - ' v*'
47 workflow_dispatch :
58 inputs :
69 version :
1417jobs :
1518 create-release :
1619 runs-on : ubuntu-latest
20+ permissions :
21+ contents : write
1722 steps :
1823 - uses : actions/checkout@v4
1924 with :
2025 fetch-depth : 0
26+
27+ - name : Get version from tag or input
28+ id : get_version
29+ run : |
30+ if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
31+ # Extract version from the tag (remove 'v' prefix)
32+ VERSION="${GITHUB_REF#refs/tags/v}"
33+ echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
34+ echo "Using version from tag: ${VERSION}"
35+ else
36+ # For manual workflow dispatch
37+ VERSION="${{ github.event.inputs.version }}"
38+ echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
39+ echo "Using provided version: ${VERSION}"
40+ fi
2141
2242 - name : Validate version format
43+ if : github.event_name == 'workflow_dispatch'
2344 run : |
24- echo "Validating version format: ${{ github.event.inputs.version }}"
25- if ! [[ ${{ github.event.inputs.version }} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
45+ echo "Validating version format: ${{ steps.get_version.outputs.VERSION }}"
46+ if ! [[ ${{ steps.get_version.outputs.VERSION }} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
2647 echo "::error::Version must be in the format X.Y.Z"
2748 exit 1
2849 fi
2950
3051 - name : Check tag doesn't already exist
52+ if : github.event_name == 'workflow_dispatch'
3153 run : |
32- if git rev-parse "v${{ github.event.inputs.version }}" >/dev/null 2>&1; then
33- echo "::error::Tag v${{ github.event.inputs.version }} already exists"
54+ if git rev-parse "v${{ steps.get_version.outputs.VERSION }}" >/dev/null 2>&1; then
55+ echo "::error::Tag v${{ steps.get_version.outputs.VERSION }} already exists"
3456 exit 1
3557 fi
3658
3759 - name : Generate changelog
3860 id : changelog
3961 run : |
40- # Generate changelog from git history
41- CHANGELOG=$(git log --pretty=format:"* %s (%an)" $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~50)..HEAD)
62+ if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
63+ # For tag pushes, extract from CHANGELOG.md if it exists
64+ VERSION="${{ steps.get_version.outputs.VERSION }}"
65+ if grep -q "## \[${VERSION}\]" CHANGELOG.md; then
66+ echo "Extracting changelog for v${VERSION} from CHANGELOG.md"
67+ CHANGELOG_CONTENT=$(awk -v ver="## [${VERSION}]" '
68+ BEGIN { printing = 0; content = ""; }
69+ $0 ~ ver { printing = 1; next; }
70+ /^## \[/ { if (printing == 1) { printing = 0; } }
71+ { if (printing == 1) content = content $0 "\n"; }
72+ END { print content; }
73+ ' CHANGELOG.md)
74+ else
75+ # Fallback to git log if not in CHANGELOG.md
76+ echo "No entry found in CHANGELOG.md, generating from git log"
77+ CHANGELOG_CONTENT=$(git log --pretty=format:"* %s (%an)" $(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo HEAD~50)..HEAD)
78+ fi
79+ else
80+ # For manual workflow, use git log from previous tag to HEAD
81+ echo "Generating changelog from git log"
82+ CHANGELOG_CONTENT=$(git log --pretty=format:"* %s (%an)" $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~50)..HEAD)
83+ fi
4284
4385 # Format for GitHub Actions output
4486 echo "changelog<<EOF" >> $GITHUB_OUTPUT
45- echo "$CHANGELOG " >> $GITHUB_OUTPUT
87+ echo "$CHANGELOG_CONTENT " >> $GITHUB_OUTPUT
4688 echo "EOF" >> $GITHUB_OUTPUT
4789
4890 - name : Create changelog file
4991 run : |
50- echo "# Changelog for v${{ github.event.inputs.version }}" > CHANGELOG.md
92+ echo "# Changelog for v${{ steps.get_version.outputs.VERSION }}" > CHANGELOG.md
5193 echo "" >> CHANGELOG.md
5294 echo "${{ steps.changelog.outputs.changelog }}" >> CHANGELOG.md
5395
96+ - name : Determine if prerelease
97+ id : prerelease
98+ run : |
99+ if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
100+ # Check if tag contains 'alpha', 'beta', 'rc', etc.
101+ if [[ "${{ github.ref_name }}" =~ -alpha|-beta|-rc|dev|test ]]; then
102+ echo "IS_PRERELEASE=true" >> $GITHUB_OUTPUT
103+ else
104+ echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT
105+ fi
106+ else
107+ echo "IS_PRERELEASE=${{ github.event.inputs.prerelease }}" >> $GITHUB_OUTPUT
108+ fi
109+
54110 - name : Create Release
55111 uses : softprops/action-gh-release@v1
56112 with :
57- tag_name : v ${{ github.event.inputs.version }}
58- name : v${{ github.event.inputs.version }}
113+ tag_name : ${{ github.event_name == 'push' && github.ref_type == 'tag' && github.ref_name || format('v{0}', steps.get_version.outputs.VERSION) }}
114+ name : v${{ steps.get_version.outputs.VERSION }}
59115 body_path : CHANGELOG.md
60- prerelease : ${{ github.event.inputs.prerelease }}
116+ prerelease : ${{ steps.prerelease.outputs.IS_PRERELEASE }}
61117 token : ${{ secrets.GITHUB_TOKEN }}
0 commit comments