@@ -4,22 +4,32 @@ name: Auto Release from Issue
44on :
55 issues :
66 types : [opened, labeled]
7+ # Also trigger when PR is merged (to create tag after merge)
8+ pull_request :
9+ types : [closed]
10+ branches : [main]
711
812permissions :
913 contents : write
1014 issues : write
15+ pull-requests : write
1116
1217env :
1318 # Only these users can trigger releases (comma-separated GitHub usernames)
1419 ALLOWED_USERS : " mateof"
1520
1621jobs :
17- create-release :
18- name : Create Release from Issue
22+ # ===========================================
23+ # JOB 1: Create PR with version bump
24+ # ===========================================
25+ create-version-pr :
26+ name : Create Version Bump PR
1927 runs-on : ubuntu-latest
2028
21- # Only run if issue has 'release' label
22- if : contains(github.event.issue.labels.*.name, 'release')
29+ # Only run on issue events with 'release' label
30+ if : |
31+ github.event_name == 'issues' &&
32+ contains(github.event.issue.labels.*.name, 'release')
2333
2434 steps :
2535 - name : ' 🔐 Verify user authorization'
@@ -29,13 +39,10 @@ jobs:
2939 echo "Issue author: $ISSUE_AUTHOR"
3040 echo "Allowed users: $ALLOWED_USERS"
3141
32- # Check if author is in allowed list
3342 if [[ ! ",$ALLOWED_USERS," == *",$ISSUE_AUTHOR,"* ]]; then
3443 echo "❌ User '$ISSUE_AUTHOR' is not authorized to create releases"
35- echo " Only these users can create releases: $ALLOWED_USERS"
3644 exit 1
3745 fi
38-
3946 echo "✅ User '$ISSUE_AUTHOR' is authorized"
4047
4148 - name : ' 📋 Extract version from issue title'
@@ -45,179 +52,233 @@ jobs:
4552 run : |
4653 echo "Issue title: $ISSUE_TITLE"
4754
48- # Extract version from title (supports: v3.5.0, 3.5.0, v3.5.0.0, 3 .5.0.0)
55+ # Extract version (supports: v3.5.0, 3.5.0, v3.5.0.0)
4956 VERSION=$(echo "$ISSUE_TITLE" | grep -oE '[vV]?[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1)
5057
5158 if [ -z "$VERSION" ]; then
5259 echo "❌ No version found in issue title"
53- echo " Title should contain a version like: v3.5.0 or 3.5.0"
5460 exit 1
5561 fi
5662
57- # Remove 'v' prefix if present
63+ # Remove 'v' prefix
5864 VERSION=${VERSION#v}
5965 VERSION=${VERSION#V}
6066
61- # Ensure 4-part version for csproj (3.5.0 -> 3.5.0.0)
67+ # 4-part version for csproj
6268 PARTS=$(echo "$VERSION" | tr '.' '\n' | wc -l)
6369 if [ "$PARTS" -eq 3 ]; then
6470 VERSION_CSPROJ="${VERSION}.0"
6571 else
6672 VERSION_CSPROJ="$VERSION"
6773 fi
6874
69- # Tag version (without trailing .0 if it's 0)
7075 VERSION_TAG="v${VERSION}"
76+ BRANCH_NAME="release/${VERSION}"
7177
7278 echo "version=$VERSION" >> $GITHUB_OUTPUT
7379 echo "version_csproj=$VERSION_CSPROJ" >> $GITHUB_OUTPUT
7480 echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
81+ echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
7582
76- echo "✅ Extracted versions:"
77- echo " Version: $VERSION"
78- echo " CSPROJ: $VERSION_CSPROJ"
79- echo " Tag: $VERSION_TAG"
83+ echo "✅ Version: $VERSION | CSPROJ: $VERSION_CSPROJ | Tag: $VERSION_TAG"
8084
8185 - name : ' 📄 Checkout main branch'
8286 uses : actions/checkout@v4
8387 with :
8488 ref : main
8589 fetch-depth : 0
86- token : ${{ secrets.GITHUB_TOKEN }}
8790
8891 - name : ' 🔍 Check if tag already exists'
89- id : check_tag
9092 run : |
9193 TAG="${{ steps.version.outputs.version_tag }}"
9294 if git rev-parse "$TAG" >/dev/null 2>&1; then
9395 echo "❌ Tag '$TAG' already exists!"
94- echo "exists=true" >> $GITHUB_OUTPUT
9596 exit 1
9697 fi
97- echo "✅ Tag '$TAG' does not exist yet"
98- echo "exists=false" >> $GITHUB_OUTPUT
98+ echo "✅ Tag '$TAG' does not exist"
99+
100+ - name : ' 🌿 Create release branch'
101+ run : |
102+ BRANCH="${{ steps.version.outputs.branch_name }}"
103+ git checkout -b "$BRANCH"
99104
100105 - name : ' 📝 Update version in TelegramDownloader.csproj'
101106 run : |
102107 VERSION_CSPROJ="${{ steps.version.outputs.version_csproj }}"
103- CSPROJ_FILE="TelegramDownloader/TelegramDownloader.csproj"
104-
105- echo "Updating version in $CSPROJ_FILE to $VERSION_CSPROJ"
106-
107- # Update <Version> tag
108- sed -i "s|<Version>[^<]*</Version>|<Version>$VERSION_CSPROJ</Version>|g" "$CSPROJ_FILE"
109-
110- # Verify the change
111- echo "Updated content:"
112- grep -n "Version" "$CSPROJ_FILE" | head -5
113-
114- echo "✅ Version updated to $VERSION_CSPROJ"
108+ sed -i "s|<Version>[^<]*</Version>|<Version>$VERSION_CSPROJ</Version>|g" "TelegramDownloader/TelegramDownloader.csproj"
109+ echo "✅ TelegramDownloader version updated to $VERSION_CSPROJ"
115110
116111 - name : ' 📝 Update version in TFMAudioApp.csproj (if exists)'
117112 run : |
113+ VERSION="${{ steps.version.outputs.version }}"
118114 VERSION_CSPROJ="${{ steps.version.outputs.version_csproj }}"
119- CSPROJ_FILE ="TFMAudioApp/TFMAudioApp.csproj"
115+ CSPROJ ="TFMAudioApp/TFMAudioApp.csproj"
120116
121- if [ -f "$CSPROJ_FILE" ]; then
122- echo "Updating version in $CSPROJ_FILE to $VERSION_CSPROJ"
123-
124- # Update <ApplicationDisplayVersion> if exists
125- if grep -q "ApplicationDisplayVersion" "$CSPROJ_FILE"; then
126- sed -i "s|<ApplicationDisplayVersion>[^<]*</ApplicationDisplayVersion>|<ApplicationDisplayVersion>${{ steps.version.outputs.version }}</ApplicationDisplayVersion>|g" "$CSPROJ_FILE"
117+ if [ -f "$CSPROJ" ]; then
118+ if grep -q "ApplicationDisplayVersion" "$CSPROJ"; then
119+ sed -i "s|<ApplicationDisplayVersion>[^<]*</ApplicationDisplayVersion>|<ApplicationDisplayVersion>$VERSION</ApplicationDisplayVersion>|g" "$CSPROJ"
127120 fi
128-
129- # Update <Version> if exists
130- if grep -q "<Version>" "$CSPROJ_FILE"; then
131- sed -i "s|<Version>[^<]*</Version>|<Version>$VERSION_CSPROJ</Version>|g" "$CSPROJ_FILE"
121+ if grep -q "<Version>" "$CSPROJ"; then
122+ sed -i "s|<Version>[^<]*</Version>|<Version>$VERSION_CSPROJ</Version>|g" "$CSPROJ"
132123 fi
133-
134124 echo "✅ TFMAudioApp version updated"
135- else
136- echo "ℹ️ TFMAudioApp.csproj not found, skipping"
137125 fi
138126
139- - name : ' 💾 Commit version changes'
127+ - name : ' 💾 Commit and push changes'
140128 run : |
141129 VERSION="${{ steps.version.outputs.version }}"
130+ BRANCH="${{ steps.version.outputs.branch_name }}"
142131
143132 git config user.name "github-actions[bot]"
144133 git config user.email "github-actions[bot]@users.noreply.github.com"
145134
146135 git add -A
147136
148- # Check if there are changes to commit
149137 if git diff --staged --quiet; then
150- echo "ℹ️ No version changes to commit (version may already be set) "
138+ echo "ℹ️ No changes to commit"
151139 else
152140 git commit -m "Bump version to $VERSION"
153- git push origin main
154- echo "✅ Version changes committed and pushed "
141+ git push origin "$BRANCH"
142+ echo "✅ Changes pushed to $BRANCH "
155143 fi
156144
157- - name : ' 🏷️ Create and push tag'
158- run : |
159- TAG="${{ steps.version.outputs.version_tag }}"
160-
161- git tag -a "$TAG" -m "Release $TAG"
162- git push origin "$TAG"
163-
164- echo "✅ Tag '$TAG' created and pushed"
165-
166- - name : ' 🚀 Create GitHub Release'
145+ - name : ' 🔀 Create Pull Request'
146+ id : create_pr
167147 env :
168148 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
169149 run : |
170- TAG="${{ steps.version.outputs.version_tag }}"
171150 VERSION="${{ steps.version.outputs.version }}"
151+ VERSION_TAG="${{ steps.version.outputs.version_tag }}"
152+ BRANCH="${{ steps.version.outputs.branch_name }}"
153+ ISSUE_NUMBER="${{ github.event.issue.number }}"
172154 ISSUE_BODY="${{ github.event.issue.body }}"
173155
174- # Create release with issue body as release notes
175- gh release create "$TAG" \
176- --title "Release $TAG" \
177- --notes "## What's Changed
156+ PR_URL=$(gh pr create \
157+ --base main \
158+ --head "$BRANCH" \
159+ --title "Release $VERSION_TAG" \
160+ --body "## 🚀 Release $VERSION_TAG
178161
162+ This PR bumps the version to **$VERSION** and will trigger a release when merged.
163+
164+ ### Changes
165+ - Updated \`TelegramDownloader.csproj\` version to \`${{ steps.version.outputs.version_csproj }}\`
166+ - Updated \`TFMAudioApp.csproj\` version (if applicable)
167+
168+ ### Release Notes
179169 $ISSUE_BODY
180170
181171 ---
182- *Release created automatically from issue #${{ github.event.issue.number }}*" \
183- --target main
172+ Closes #$ISSUE_NUMBER
184173
185- echo "✅ GitHub Release created"
174+ > ⚠️ **After merging**, the release workflow will automatically:
175+ > 1. Create tag \`$VERSION_TAG\`
176+ > 2. Create GitHub Release
177+ > 3. Build and upload binaries")
178+
179+ echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
180+ echo "✅ PR created: $PR_URL"
186181
187- - name : ' ✅ Close issue with success comment '
182+ - name : ' 💬 Comment on issue '
188183 env :
189184 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
190185 run : |
191- TAG="${{ steps.version.outputs.version_tag }}"
192-
193- gh issue comment ${{ github.event.issue.number }} --body "## ✅ Release Created Successfully!
186+ VERSION_TAG="${{ steps.version.outputs.version_tag }}"
187+ PR_URL="${{ steps.create_pr.outputs.pr_url }}"
194188
195- - **Version:** $TAG
196- - **CSPROJ Version:** ${{ steps.version.outputs.version_csproj }}
197- - **Release:** https://github.com/${{ github.repository }}/releases/tag/$TAG
189+ gh issue comment ${{ github.event.issue.number }} --body "## 📋 Release PR Created
198190
199- The build workflow has been triggered and will upload the binaries shortly.
191+ A pull request has been created to bump the version to **$VERSION_TAG**:
200192
201- ---
202- *This issue was automatically processed by the release workflow.*"
193+ 👉 $PR_URL
203194
204- gh issue close ${{ github.event.issue.number }} --reason completed
195+ **Next steps:**
196+ 1. Review and approve the PR
197+ 2. Merge the PR to \`main\`
198+ 3. The release will be created automatically after merge
205199
206- echo "✅ Issue closed"
200+ ---
201+ *This comment was automatically generated.*"
207202
208203 - name : ' ❌ Comment on failure'
209204 if : failure()
210205 env :
211206 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
212207 run : |
213- gh issue comment ${{ github.event.issue.number }} --body "## ❌ Release Failed
208+ gh issue comment ${{ github.event.issue.number }} --body "## ❌ Release PR Creation Failed
214209
215- The release process encountered an error. Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details .
210+ Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
216211
217212 Common issues:
218- - Version format incorrect (use: v3.5.0 or 3.5.0 )
213+ - Version format incorrect (use: v3.5.0)
219214 - Tag already exists
220215 - User not authorized
221216
222217 ---
223218 *This comment was automatically generated.*"
219+
220+ # ===========================================
221+ # JOB 2: Create tag and release after PR merge
222+ # ===========================================
223+ create-release-after-merge :
224+ name : Create Release After Merge
225+ runs-on : ubuntu-latest
226+
227+ # Only run when a release PR is merged
228+ if : |
229+ github.event_name == 'pull_request' &&
230+ github.event.pull_request.merged == true &&
231+ startsWith(github.event.pull_request.head.ref, 'release/')
232+
233+ steps :
234+ - name : ' 📋 Extract version from branch name'
235+ id : version
236+ run : |
237+ BRANCH="${{ github.event.pull_request.head.ref }}"
238+ # Extract version from branch name (release/3.5.0 -> 3.5.0)
239+ VERSION=${BRANCH#release/}
240+ VERSION_TAG="v${VERSION}"
241+
242+ echo "version=$VERSION" >> $GITHUB_OUTPUT
243+ echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
244+ echo "✅ Version: $VERSION | Tag: $VERSION_TAG"
245+
246+ - name : ' 📄 Checkout main'
247+ uses : actions/checkout@v4
248+ with :
249+ ref : main
250+ fetch-depth : 0
251+
252+ - name : ' 🏷️ Create and push tag'
253+ run : |
254+ TAG="${{ steps.version.outputs.version_tag }}"
255+
256+ git config user.name "github-actions[bot]"
257+ git config user.email "github-actions[bot]@users.noreply.github.com"
258+
259+ git tag -a "$TAG" -m "Release $TAG"
260+ git push origin "$TAG"
261+
262+ echo "✅ Tag '$TAG' created and pushed"
263+
264+ - name : ' 🚀 Create GitHub Release'
265+ env :
266+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
267+ run : |
268+ TAG="${{ steps.version.outputs.version_tag }}"
269+ PR_BODY="${{ github.event.pull_request.body }}"
270+
271+ gh release create "$TAG" \
272+ --title "Release $TAG" \
273+ --notes "$PR_BODY" \
274+ --target main
275+
276+ echo "✅ GitHub Release created"
277+
278+ - name : ' 🗑️ Delete release branch'
279+ env :
280+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
281+ run : |
282+ BRANCH="${{ github.event.pull_request.head.ref }}"
283+ gh api -X DELETE "repos/${{ github.repository }}/git/refs/heads/$BRANCH" || true
284+ echo "✅ Branch '$BRANCH' deleted"
0 commit comments