This repository was archived by the owner on May 14, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 409
441 lines (353 loc) · 16.1 KB
/
release.yml
File metadata and controls
441 lines (353 loc) · 16.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# Automated Release Workflow for AI Studio Proxy API
# Creates GitHub releases with source code archives when version tags are pushed,
# on pushes to main (nightly builds), or manually triggered via workflow_dispatch.
#
# Release Types:
# - Stable: Push a tag (git tag v0.1.0 && git push origin v0.1.0)
# - Nightly: Automatic on every push to main branch (rolling release)
# - Manual: Actions -> Release -> Run workflow -> Enter version (e.g., v0.2.0)
# The tag will be auto-created on the current HEAD if it doesn't exist.
name: Release
on:
# Trigger on pushes to main branch for nightly builds
push:
branches:
- main
tags:
- 'v*.*.*' # Matches v1.0.0, v2.1.3, etc.
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., v0.1.0 or 0.1.0)'
required: true
type: string
# Ensure only one release workflow runs at a time
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write # Required for creating releases
jobs:
# ===========================================================================
# Stable Release Job
# ===========================================================================
# Runs on tag pushes (v*.*.*) or manual workflow_dispatch
# Creates versioned, stable releases
release:
name: Create Release
runs-on: ubuntu-latest
# Only run on tag pushes or manual triggers (not on main branch pushes)
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
steps:
- name: Validate version format (manual trigger)
if: github.event_name == 'workflow_dispatch'
run: |
VERSION_RAW="${{ github.event.inputs.version }}"
if [[ "$VERSION_RAW" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
VERSION="v$VERSION_RAW"
else
VERSION="$VERSION_RAW"
fi
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "::error::Invalid version format '$VERSION_RAW'. Expected format: v1.2.3, 1.2.3, or pre-release variants like v1.2.3-beta.1"
exit 1
fi
echo "Version format validated: $VERSION"
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog generation
# For workflow_dispatch, checkout default branch first, then verify/checkout tag
# For tag pushes, checkout the tag directly
ref: ${{ github.event_name == 'workflow_dispatch' && '' || github.ref }}
- name: Determine version
id: version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
VERSION_RAW="${{ github.event.inputs.version }}"
if [[ "$VERSION_RAW" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
VERSION="v$VERSION_RAW"
else
VERSION="$VERSION_RAW"
fi
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "version_number=${VERSION#v}" >> $GITHUB_OUTPUT
echo "Release version: $VERSION"
- name: Setup Git for tagging (manual trigger)
if: github.event_name == 'workflow_dispatch'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Create or verify tag (manual trigger)
if: github.event_name == 'workflow_dispatch'
run: |
VERSION="${{ steps.version.outputs.version }}"
# Fetch all tags to ensure we have the latest
git fetch --tags --force
if git rev-parse "refs/tags/$VERSION" >/dev/null 2>&1; then
echo "✓ Tag $VERSION already exists"
echo "Checking out existing tag..."
git checkout "refs/tags/$VERSION"
else
echo "Tag $VERSION does not exist, creating it on current HEAD..."
CURRENT_SHA=$(git rev-parse HEAD)
echo "Creating tag $VERSION at commit $CURRENT_SHA"
# Create the tag locally
git tag -a "$VERSION" -m "Release $VERSION"
# Push the tag to remote
git push origin "$VERSION"
echo "✓ Tag $VERSION created and pushed successfully"
fi
- name: Generate changelog
id: changelog
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.version.outputs.version }}"
# Find the previous tag for comparison
PREVIOUS_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | grep -v "^$VERSION$" | head -n 1)
if [ -n "$PREVIOUS_TAG" ]; then
echo "Generating changelog from $PREVIOUS_TAG to $VERSION"
# Generate commit log grouped by type
CHANGELOG=$(cat << 'CHANGELOG_EOF'
## What's Changed
CHANGELOG_EOF
)
TEMP_FILE=$(mktemp)
while IFS= read -r commit_sha || [ -n "$commit_sha" ]; do
if [ -z "$commit_sha" ]; then
continue
fi
commit_msg=$(git log -1 --pretty=format:"%s" "$commit_sha")
short_sha=$(git rev-parse --short "$commit_sha")
git_author=$(git log -1 --pretty=format:"%an" "$commit_sha")
api_response=$(gh api "repos/${{ github.repository }}/commits/$commit_sha" 2>/dev/null || echo '{}')
github_username=$(echo "$api_response" | jq -r '.author.login // empty')
if [ -n "$github_username" ]; then
echo "- ${commit_msg} by @${github_username} (${short_sha})" >> "$TEMP_FILE"
else
echo "- ${commit_msg} by ${git_author} (${short_sha})" >> "$TEMP_FILE"
fi
done < <(git log --pretty=format:"%H" "$PREVIOUS_TAG..$VERSION" 2>/dev/null || true)
if [ -s "$TEMP_FILE" ]; then
CHANGELOG="$CHANGELOG
$(cat "$TEMP_FILE")"
else
CHANGELOG="$CHANGELOG
- Various improvements and updates"
fi
rm -f "$TEMP_FILE"
CHANGELOG="$CHANGELOG
**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$VERSION"
else
echo "No previous tag found, this appears to be the first release"
CHANGELOG="## What's Changed
This is the first automated release in this repository.
See the commit history for details."
fi
# Write to file for use in release
echo "$CHANGELOG" > CHANGELOG.md
echo "Changelog generated successfully"
- name: Build release body
id: release_body
run: |
VERSION="${{ steps.version.outputs.version }}"
VERSION_NUMBER="${{ steps.version.outputs.version_number }}"
cat > RELEASE_BODY.md << 'EOF'
${{ steps.version.outputs.version }} brings improvements and updates to the AI Studio Proxy API.
EOF
# Append the generated changelog
cat CHANGELOG.md >> RELEASE_BODY.md
cat >> RELEASE_BODY.md << 'EOF'
---
## Installation
### Quick Start
```bash
# Clone the repository
git clone https://github.com/${{ github.repository }}.git
cd AIstudioProxyAPI
# Install dependencies with Poetry
poetry install
# Run the server
poetry run python server.py
```
### Docker
```bash
docker-compose -f docker/docker-compose.yml up -d
```
For full installation and configuration details, see the [README](https://github.com/${{ github.repository }}/blob/main/README.md).
## Source Code
Source code archives (zip and tar.gz) are automatically attached below.
---
**Thank you to all contributors!**
EOF
echo "Release body generated successfully"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "AI Studio Proxy API ${{ steps.version.outputs.version }}"
tag_name: ${{ steps.version.outputs.version }}
body_path: RELEASE_BODY.md
draft: false
prerelease: ${{ contains(steps.version.outputs.version, '-') }}
generate_release_notes: false # We generate our own
make_latest: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Release summary
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "## Release Created Successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version:** $VERSION" >> $GITHUB_STEP_SUMMARY
echo "**Release URL:** https://github.com/${{ github.repository }}/releases/tag/$VERSION" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Included Assets" >> $GITHUB_STEP_SUMMARY
echo "- Source code (zip)" >> $GITHUB_STEP_SUMMARY
echo "- Source code (tar.gz)" >> $GITHUB_STEP_SUMMARY
# ===========================================================================
# Nightly Release Job
# ===========================================================================
# Runs on every push to main branch (not on tags)
# Creates/updates a rolling "nightly" release with the latest development code
nightly:
name: Create Nightly Release
runs-on: ubuntu-latest
# Only run on pushes to main branch, NOT on tag pushes
if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog generation
- name: Get build info
id: build_info
run: |
# Get short commit SHA and date for versioning
SHORT_SHA=$(git rev-parse --short HEAD)
BUILD_DATE=$(date +'%Y-%m-%d')
BUILD_TIME=$(date +'%H:%M:%S UTC')
COMMIT_MSG=$(git log -1 --pretty=format:"%s")
echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "build_date=$BUILD_DATE" >> $GITHUB_OUTPUT
echo "build_time=$BUILD_TIME" >> $GITHUB_OUTPUT
echo "commit_msg=$COMMIT_MSG" >> $GITHUB_OUTPUT
echo "Build info: $SHORT_SHA @ $BUILD_DATE $BUILD_TIME"
- name: Generate recent changes
id: changes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Build nightly changelog from latest stable tag to HEAD
echo "## What's Changed" > NIGHTLY_CHANGES.md
echo "" >> NIGHTLY_CHANGES.md
LATEST_STABLE_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)
if [ -n "$LATEST_STABLE_TAG" ]; then
echo "_Changes since ${LATEST_STABLE_TAG}_" >> NIGHTLY_CHANGES.md
echo "" >> NIGHTLY_CHANGES.md
echo "Using commit range: ${LATEST_STABLE_TAG}..HEAD"
else
echo "_No stable release tag found. Showing last 20 commits (first release scenario)._" >> NIGHTLY_CHANGES.md
echo "" >> NIGHTLY_CHANGES.md
echo "No stable tag found; falling back to last 20 commits"
fi
TEMP_FILE=$(mktemp)
while IFS= read -r commit_sha || [ -n "$commit_sha" ]; do
if [ -z "$commit_sha" ]; then
continue
fi
commit_msg=$(git log -1 --pretty=format:"%s" "$commit_sha")
short_sha=$(git rev-parse --short "$commit_sha")
git_author=$(git log -1 --pretty=format:"%an" "$commit_sha")
api_response=$(gh api "repos/${{ github.repository }}/commits/$commit_sha" 2>/dev/null || echo '{}')
github_username=$(echo "$api_response" | jq -r '.author.login // empty')
if [ -n "$github_username" ]; then
echo "- ${commit_msg} by @${github_username} (${short_sha})" >> "$TEMP_FILE"
else
echo "- ${commit_msg} by ${git_author} (${short_sha})" >> "$TEMP_FILE"
fi
done < <(
if [ -n "$LATEST_STABLE_TAG" ]; then
git log --pretty=format:"%H" "${LATEST_STABLE_TAG}..HEAD" 2>/dev/null || true
else
git log --pretty=format:"%H" -20 2>/dev/null || true
fi
)
if [ -s "$TEMP_FILE" ]; then
cat "$TEMP_FILE" >> NIGHTLY_CHANGES.md
else
if [ -n "$LATEST_STABLE_TAG" ]; then
echo "- No commits found since ${LATEST_STABLE_TAG}" >> NIGHTLY_CHANGES.md
else
echo "- Various improvements and updates" >> NIGHTLY_CHANGES.md
fi
fi
rm -f "$TEMP_FILE"
echo "" >> NIGHTLY_CHANGES.md
echo "Recent changes generated"
- name: Build nightly release body
run: |
cat > NIGHTLY_BODY.md << 'EOF'
## ⚠️ Nightly Build (Development Version)
**This is an automated nightly build from the `main` branch.**
> **Warning**: This release may contain untested features, breaking changes, or bugs.
> For stable releases, please use a [versioned release](https://github.com/${{ github.repository }}/releases?q=v&expanded=true).
### Build Information
- **Commit**: `${{ steps.build_info.outputs.short_sha }}`
- **Date**: ${{ steps.build_info.outputs.build_date }} ${{ steps.build_info.outputs.build_time }}
- **Latest Change**: ${{ steps.build_info.outputs.commit_msg }}
EOF
cat NIGHTLY_CHANGES.md >> NIGHTLY_BODY.md
cat >> NIGHTLY_BODY.md << 'EOF'
---
## Quick Start
```bash
# Clone the repository
git clone https://github.com/${{ github.repository }}.git
cd AIstudioProxyAPI
# Install dependencies
poetry install
# Run the server
poetry run python server.py
```
---
*This nightly release is automatically updated on every push to the main branch.*
**Thank you to all contributors!**
EOF
echo "Nightly release body generated"
- name: Delete existing nightly release
run: |
# Delete existing nightly release if it exists (to avoid accumulation)
echo "Checking for existing nightly release..."
if gh release view nightly &>/dev/null; then
echo "Deleting existing nightly release..."
gh release delete nightly --yes --cleanup-tag
echo "Existing nightly release deleted"
else
echo "No existing nightly release found"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create nightly release
uses: softprops/action-gh-release@v2
with:
name: "Nightly Build (Latest)"
tag_name: nightly
body_path: NIGHTLY_BODY.md
draft: false
prerelease: true # Mark as prerelease since it's development code
generate_release_notes: false
make_latest: false # Don't mark nightly as "latest" - reserve that for stable releases
target_commitish: ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Nightly release summary
run: |
echo "## Nightly Release Updated!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ steps.build_info.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "**Build Date:** ${{ steps.build_info.outputs.build_date }}" >> $GITHUB_STEP_SUMMARY
echo "**Release URL:** https://github.com/${{ github.repository }}/releases/tag/nightly" >> $GITHUB_STEP_SUMMARY