@@ -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,252 @@ 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"
120-
121- if [ -f "$CSPROJ_FILE" ]; then
122- echo "Updating version in $CSPROJ_FILE to $VERSION_CSPROJ"
115+ CSPROJ="TFMAudioApp/TFMAudioApp.csproj"
123116
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+ > 4. Sync \`develop\` branch with \`main\`")
179+
180+ echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
181+ echo "✅ PR created: $PR_URL"
186182
187- - name : ' ✅ Close issue with success comment '
183+ - name : ' 💬 Comment on issue '
188184 env :
189185 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
190186 run : |
191- TAG="${{ steps.version.outputs.version_tag }}"
187+ VERSION_TAG="${{ steps.version.outputs.version_tag }}"
188+ PR_URL="${{ steps.create_pr.outputs.pr_url }}"
192189
193- gh issue comment ${{ github.event.issue.number }} --body "## ✅ Release Created Successfully!
190+ gh issue comment ${{ github.event.issue.number }} --body "## 📋 Release PR Created
194191
195- - **Version:** $TAG
196- - **CSPROJ Version:** ${{ steps.version.outputs.version_csproj }}
197- - **Release:** https://github.com/${{ github.repository }}/releases/tag/$TAG
192+ A pull request has been created to bump the version to **$VERSION_TAG**:
198193
199- The build workflow has been triggered and will upload the binaries shortly.
200-
201- ---
202- *This issue was automatically processed by the release workflow.*"
194+ 👉 $PR_URL
203195
204- gh issue close ${{ github.event.issue.number }} --reason completed
196+ **Next steps:**
197+ 1. Review and approve the PR
198+ 2. Merge the PR to \`main\`
199+ 3. The release will be created automatically after merge
205200
206- echo "✅ Issue closed"
201+ ---
202+ *This comment was automatically generated.*"
207203
208204 - name : ' ❌ Comment on failure'
209205 if : failure()
210206 env :
211207 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
212208 run : |
213- gh issue comment ${{ github.event.issue.number }} --body "## ❌ Release Failed
209+ gh issue comment ${{ github.event.issue.number }} --body "## ❌ Release PR Creation Failed
214210
215- The release process encountered an error. Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details .
211+ Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
216212
217213 Common issues:
218- - Version format incorrect (use: v3.5.0 or 3.5.0 )
214+ - Version format incorrect (use: v3.5.0)
219215 - Tag already exists
220216 - User not authorized
221217
222218 ---
223219 *This comment was automatically generated.*"
220+
221+ # ===========================================
222+ # JOB 2: Create tag and release after PR merge
223+ # ===========================================
224+ create-release-after-merge :
225+ name : Create Release After Merge
226+ runs-on : ubuntu-latest
227+
228+ # Only run when a release PR is merged
229+ if : |
230+ github.event_name == 'pull_request' &&
231+ github.event.pull_request.merged == true &&
232+ startsWith(github.event.pull_request.head.ref, 'release/')
233+
234+ steps :
235+ - name : ' 📋 Extract version from branch name'
236+ id : version
237+ run : |
238+ BRANCH="${{ github.event.pull_request.head.ref }}"
239+ # Extract version from branch name (release/3.5.0 -> 3.5.0)
240+ VERSION=${BRANCH#release/}
241+ VERSION_TAG="v${VERSION}"
242+
243+ echo "version=$VERSION" >> $GITHUB_OUTPUT
244+ echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
245+ echo "✅ Version: $VERSION | Tag: $VERSION_TAG"
246+
247+ - name : ' 📄 Checkout main'
248+ uses : actions/checkout@v4
249+ with :
250+ ref : main
251+ fetch-depth : 0
252+
253+ - name : ' 🏷️ Create and push tag'
254+ run : |
255+ TAG="${{ steps.version.outputs.version_tag }}"
256+
257+ git config user.name "github-actions[bot]"
258+ git config user.email "github-actions[bot]@users.noreply.github.com"
259+
260+ git tag -a "$TAG" -m "Release $TAG"
261+ git push origin "$TAG"
262+
263+ echo "✅ Tag '$TAG' created and pushed"
264+
265+ - name : ' 🚀 Create GitHub Release'
266+ env :
267+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
268+ run : |
269+ TAG="${{ steps.version.outputs.version_tag }}"
270+ PR_BODY="${{ github.event.pull_request.body }}"
271+
272+ gh release create "$TAG" \
273+ --title "Release $TAG" \
274+ --notes "$PR_BODY" \
275+ --target main
276+
277+ echo "✅ GitHub Release created"
278+
279+ - name : ' 🗑️ Delete release branch'
280+ env :
281+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
282+ run : |
283+ BRANCH="${{ github.event.pull_request.head.ref }}"
284+ gh api -X DELETE "repos/${{ github.repository }}/git/refs/heads/$BRANCH" || true
285+ echo "✅ Branch '$BRANCH' deleted"
286+
287+ - name : ' 🔄 Sync develop with main'
288+ run : |
289+ git config user.name "github-actions[bot]"
290+ git config user.email "github-actions[bot]@users.noreply.github.com"
291+
292+ # Fetch all branches
293+ git fetch origin develop:develop || true
294+
295+ # Check if develop branch exists
296+ if git show-ref --verify --quiet refs/heads/develop; then
297+ git checkout develop
298+ git merge main -m "Sync develop with main after release ${{ steps.version.outputs.version_tag }}"
299+ git push origin develop
300+ echo "✅ develop branch synced with main"
301+ else
302+ echo "ℹ️ develop branch does not exist, skipping sync"
303+ fi
0 commit comments