1+ name : Tag and Release
2+
3+ on :
4+ workflow_dispatch :
5+ inputs :
6+ version :
7+ description : ' Version to release (e.g., v1.0.0, v1.2.3)'
8+ required : true
9+ type : string
10+ action_type :
11+ description : ' What to create'
12+ required : true
13+ default : ' tag_and_release'
14+ type : choice
15+ options :
16+ - tag_only
17+ - tag_and_release
18+ release_type :
19+ description : ' Type of release (if creating release)'
20+ required : false
21+ default : ' release'
22+ type : choice
23+ options :
24+ - release
25+ - prerelease
26+ draft :
27+ description : ' Create as draft release (if creating release)'
28+ required : false
29+ default : false
30+ type : boolean
31+ tag_message :
32+ description : ' Custom tag message (optional)'
33+ required : false
34+ type : string
35+
36+ permissions :
37+ contents : write
38+ actions : read
39+
40+ jobs :
41+ validate-version :
42+ runs-on : ubuntu-latest
43+ outputs :
44+ version : ${{ steps.validate.outputs.version }}
45+ tag_exists : ${{ steps.check_tag.outputs.exists }}
46+ steps :
47+ - name : Checkout
48+ uses : actions/checkout@v4
49+ with :
50+ fetch-depth : 0
51+
52+ - name : Validate version format
53+ id : validate
54+ run : |
55+ VERSION="${{ github.event.inputs.version }}"
56+
57+ # Remove 'v' prefix if present for validation
58+ VERSION_NUMBER=${VERSION#v}
59+
60+ # Validate semantic version format
61+ if [[ ! $VERSION_NUMBER =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?(\+[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?$ ]]; then
62+ echo "❌ Invalid version format: $VERSION"
63+ echo "Please use semantic versioning format (e.g., v1.0.0, v1.2.3-beta.1)"
64+ exit 1
65+ fi
66+
67+ # Ensure version starts with 'v'
68+ if [[ ! $VERSION =~ ^v ]]; then
69+ VERSION="v$VERSION"
70+ fi
71+
72+ echo "✅ Valid version: $VERSION"
73+ echo "version=$VERSION" >> $GITHUB_OUTPUT
74+
75+ - name : Check if tag already exists
76+ id : check_tag
77+ run : |
78+ VERSION="${{ steps.validate.outputs.version }}"
79+ if git rev-parse "$VERSION" >/dev/null 2>&1; then
80+ echo "exists=true" >> $GITHUB_OUTPUT
81+ echo "⚠️ Tag $VERSION already exists!"
82+ else
83+ echo "exists=false" >> $GITHUB_OUTPUT
84+ echo "✅ Tag $VERSION is available"
85+ fi
86+
87+ create-tag :
88+ needs : validate-version
89+ runs-on : ubuntu-latest
90+ if : needs.validate-version.outputs.tag_exists == 'false'
91+ outputs :
92+ tag_created : ${{ steps.create_tag.outputs.tag_created }}
93+ tag_name : ${{ steps.create_tag.outputs.tag }}
94+ steps :
95+ - name : Checkout
96+ uses : actions/checkout@v4
97+ with :
98+ fetch-depth : 0
99+ token : ${{ secrets.GITHUB_TOKEN }}
100+
101+ - name : Configure Git
102+ run : |
103+ git config --local user.email "action@github.com"
104+ git config --local user.name "GitHub Action"
105+
106+ - name : Create and push tag
107+ id : create_tag
108+ run : |
109+ VERSION="${{ needs.validate-version.outputs.version }}"
110+ TAG_MESSAGE="${{ github.event.inputs.tag_message }}"
111+
112+ if [ -n "$TAG_MESSAGE" ]; then
113+ echo "🏷️ Creating tag: $VERSION with message: $TAG_MESSAGE"
114+ git tag -a "$VERSION" -m "$TAG_MESSAGE"
115+ else
116+ echo "🏷️ Creating tag: $VERSION"
117+ git tag -a "$VERSION" -m "Release $VERSION"
118+ fi
119+
120+ echo "📤 Pushing tag to repository"
121+ git push origin "$VERSION"
122+
123+ echo "✅ Tag $VERSION created and pushed successfully"
124+ echo "tag=$VERSION" >> $GITHUB_OUTPUT
125+ echo "tag_created=true" >> $GITHUB_OUTPUT
126+
127+ create-release :
128+ needs : [validate-version, create-tag]
129+ runs-on : ubuntu-latest
130+ if : |
131+ needs.validate-version.outputs.tag_exists == 'false' &&
132+ needs.create-tag.outputs.tag_created == 'true' &&
133+ github.event.inputs.action_type == 'tag_and_release'
134+ steps :
135+ - name : Checkout
136+ uses : actions/checkout@v4
137+ with :
138+ fetch-depth : 0
139+
140+ - name : Create release artifacts
141+ run : |
142+ VERSION="${{ needs.create-tag.outputs.tag_name }}"
143+
144+ echo "📦 Creating release artifacts for $VERSION"
145+
146+ # Create comprehensive archive
147+ tar -czf "support-tools-${VERSION}.tar.gz" \
148+ --exclude='.git' \
149+ --exclude='.github' \
150+ --exclude='*.tar.gz' \
151+ --exclude='node_modules' \
152+ --exclude='.DS_Store' \
153+ *.sh \
154+ helm/ \
155+ scanner/ \
156+ scripts/ \
157+ README.md \
158+ CHANGELOG.md \
159+ LICENSE
160+
161+ # Create checksums
162+ sha256sum "support-tools-${VERSION}.tar.gz" > "support-tools-${VERSION}.tar.gz.sha256"
163+
164+ echo "✅ Created artifacts:"
165+ echo " - support-tools-${VERSION}.tar.gz"
166+ echo " - support-tools-${VERSION}.tar.gz.sha256"
167+
168+ - name : Create GitHub Release
169+ uses : softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
170+ with :
171+ tag_name : ${{ needs.create-tag.outputs.tag_name }}
172+ name : Release ${{ needs.create-tag.outputs.tag_name }}
173+ body : ' Release ${{ needs.create-tag.outputs.tag_name }} created via GitHub Actions workflow.'
174+ draft : ${{ github.event.inputs.draft }}
175+ prerelease : ${{ github.event.inputs.release_type == 'prerelease' }}
176+ files : |
177+ support-tools-${{ needs.create-tag.outputs.tag_name }}.tar.gz
178+ support-tools-${{ needs.create-tag.outputs.tag_name }}.tar.gz.sha256
179+ fail_on_unmatched_files : true
180+ env :
181+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
182+
183+ summary :
184+ needs : [validate-version, create-tag, create-release]
185+ runs-on : ubuntu-latest
186+ if : always() && needs.validate-version.outputs.tag_exists == 'false'
187+ steps :
188+ - name : Generate summary
189+ run : |
190+ VERSION="${{ needs.create-tag.outputs.tag_name }}"
191+ ACTION_TYPE="${{ github.event.inputs.action_type }}"
192+
193+ if [ "$ACTION_TYPE" = "tag_only" ]; then
194+ echo "## 🏷️ Tag Created Successfully!" >> $GITHUB_STEP_SUMMARY
195+ echo "" >> $GITHUB_STEP_SUMMARY
196+ echo "- **Tag**: $VERSION" >> $GITHUB_STEP_SUMMARY
197+ echo "- **Message**: ${{ github.event.inputs.tag_message || 'Release ' }}$VERSION" >> $GITHUB_STEP_SUMMARY
198+ echo "- **Commit**: $(git rev-parse HEAD 2>/dev/null || echo 'Unknown')" >> $GITHUB_STEP_SUMMARY
199+ echo "" >> $GITHUB_STEP_SUMMARY
200+ echo "### 📋 Next Steps" >> $GITHUB_STEP_SUMMARY
201+ echo "1. Create a release from this tag if needed using the same workflow" >> $GITHUB_STEP_SUMMARY
202+ echo "2. Update any documentation that references the new version" >> $GITHUB_STEP_SUMMARY
203+ else
204+ RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/$VERSION"
205+
206+ echo "## 🎉 Tag and Release Created Successfully!" >> $GITHUB_STEP_SUMMARY
207+ echo "" >> $GITHUB_STEP_SUMMARY
208+ echo "- **Version**: $VERSION" >> $GITHUB_STEP_SUMMARY
209+ echo "- **Type**: ${{ github.event.inputs.release_type }}" >> $GITHUB_STEP_SUMMARY
210+ echo "- **Draft**: ${{ github.event.inputs.draft }}" >> $GITHUB_STEP_SUMMARY
211+ echo "- **Release URL**: [$VERSION]($RELEASE_URL)" >> $GITHUB_STEP_SUMMARY
212+ echo "" >> $GITHUB_STEP_SUMMARY
213+ echo "### 📦 Artifacts" >> $GITHUB_STEP_SUMMARY
214+ echo "- support-tools-${VERSION}.tar.gz" >> $GITHUB_STEP_SUMMARY
215+ echo "- support-tools-${VERSION}.tar.gz.sha256" >> $GITHUB_STEP_SUMMARY
216+ echo "" >> $GITHUB_STEP_SUMMARY
217+ echo "### 📋 Next Steps" >> $GITHUB_STEP_SUMMARY
218+ echo "1. Review the release at $RELEASE_URL" >> $GITHUB_STEP_SUMMARY
219+ echo "2. Update any documentation that references the new version" >> $GITHUB_STEP_SUMMARY
220+ echo "3. Announce the release to your team/community" >> $GITHUB_STEP_SUMMARY
221+
222+ tag-exists-error :
223+ needs : validate-version
224+ runs-on : ubuntu-latest
225+ if : needs.validate-version.outputs.tag_exists == 'true'
226+ steps :
227+ - name : Tag already exists
228+ run : |
229+ echo "❌ Cannot create release: Tag ${{ needs.validate-version.outputs.version }} already exists"
230+ echo ""
231+ echo "Options:"
232+ echo "1. Choose a different version number"
233+ echo "2. Delete the existing tag if it was created in error:"
234+ echo " git push --delete origin ${{ needs.validate-version.outputs.version }}"
235+ echo " git tag -d ${{ needs.validate-version.outputs.version }}"
236+ echo ""
237+ exit 1
0 commit comments