1
+ name : Beta Release (Thursday)
2
+
3
+ on :
4
+ schedule :
5
+ # Thursday at 2 AM UTC - consolidate week's alpha changes into beta
6
+ - cron : ' 0 2 * * 4'
7
+ workflow_dispatch :
8
+ inputs :
9
+ dry_run :
10
+ description : ' Dry run (skip PyPI publish)'
11
+ required : false
12
+ default : ' false'
13
+ type : boolean
14
+ force_build :
15
+ description : ' Force build even if no changes'
16
+ required : false
17
+ default : ' false'
18
+ type : boolean
19
+
20
+ jobs :
21
+ check-changes :
22
+ runs-on : ubuntu-latest
23
+ outputs :
24
+ has_changes : ${{ steps.changes.outputs.has_changes }}
25
+ commit_count : ${{ steps.changes.outputs.commit_count }}
26
+ last_beta : ${{ steps.changes.outputs.last_beta }}
27
+ steps :
28
+ - uses : actions/checkout@v4
29
+ with :
30
+ fetch-depth : 0
31
+ ref : dev
32
+
33
+ - name : Check for changes since last beta release
34
+ id : changes
35
+ run : |
36
+ # Get last beta release tag
37
+ LAST_BETA=$(git tag -l "*b*" --sort=-version:refname | head -n1)
38
+
39
+ if [ -z "$LAST_BETA" ]; then
40
+ echo "No previous beta release found, checking last week"
41
+ SINCE="1 week ago"
42
+ COMMIT_COUNT=$(git rev-list --count --since="$SINCE" dev)
43
+ else
44
+ echo "Last beta release: $LAST_BETA"
45
+ COMMIT_COUNT=$(git rev-list --count ${LAST_BETA}..dev)
46
+ fi
47
+
48
+ echo "Commits since last beta: $COMMIT_COUNT"
49
+ echo "commit_count=$COMMIT_COUNT" >> $GITHUB_OUTPUT
50
+ echo "last_beta=$LAST_BETA" >> $GITHUB_OUTPUT
51
+
52
+ if [ "$COMMIT_COUNT" -gt 0 ] || [ "${{ github.event.inputs.force_build }}" = "true" ]; then
53
+ echo "has_changes=true" >> $GITHUB_OUTPUT
54
+ echo "✅ Changes detected, proceeding with beta build"
55
+ else
56
+ echo "has_changes=false" >> $GITHUB_OUTPUT
57
+ echo "ℹ️ No changes since last beta, skipping build"
58
+ fi
59
+
60
+ beta-release :
61
+ needs : check-changes
62
+ if : needs.check-changes.outputs.has_changes == 'true'
63
+ runs-on : ubuntu-latest
64
+ outputs :
65
+ beta_version : ${{ steps.version.outputs.beta_version }}
66
+ steps :
67
+ - uses : actions/checkout@v4
68
+ with :
69
+ fetch-depth : 0
70
+ ref : dev
71
+ token : ${{ secrets.GITHUB_TOKEN }}
72
+
73
+ - name : Set up Python
74
+ uses : actions/setup-python@v5
75
+ with :
76
+ python-version : ' 3.11'
77
+
78
+ - name : Install dependencies
79
+ run : |
80
+ python -m pip install --upgrade pip
81
+ pip install bump2version build twine
82
+ pip install -e ".[dev]"
83
+
84
+ - name : Configure git
85
+ run : |
86
+ git config --local user.email "action@github.com"
87
+ git config --local user.name "GitHub Action"
88
+
89
+ - name : Generate beta version
90
+ id : version
91
+ run : |
92
+ # Get current version
93
+ CURRENT_VERSION=$(python -c "from datafog.__about__ import __version__; print(__version__)")
94
+ echo "Current version: $CURRENT_VERSION"
95
+
96
+ # Generate beta version
97
+ if [[ $CURRENT_VERSION == *"b"* ]]; then
98
+ # If already beta, increment beta number
99
+ BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'b' -f1)
100
+ BETA_NUM=$(echo $CURRENT_VERSION | cut -d'b' -f2)
101
+ BETA_VERSION="${BASE_VERSION}b$((BETA_NUM + 1))"
102
+ elif [[ $CURRENT_VERSION == *"a"* ]]; then
103
+ # If alpha, convert to beta
104
+ BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'a' -f1)
105
+ BETA_VERSION="${BASE_VERSION}b1"
106
+ else
107
+ # If stable, bump minor and add beta (4.1.1 -> 4.2.0)
108
+ BASE_VERSION=$(python -c "import re; version = '$CURRENT_VERSION'; parts = version.split('.'); parts[1] = str(int(parts[1]) + 1); parts[2] = '0'; print('.'.join(parts))")
109
+ BETA_VERSION="${BASE_VERSION}b1"
110
+ fi
111
+
112
+ echo "Beta version: $BETA_VERSION"
113
+ echo "beta_version=$BETA_VERSION" >> $GITHUB_OUTPUT
114
+
115
+ # Update version in files
116
+ sed -i "s/__version__ = \".*\"/__version__ = \"$BETA_VERSION\"/" datafog/__about__.py
117
+ sed -i "s/version=\".*\"/version=\"$BETA_VERSION\"/" setup.py
118
+
119
+ - name : Generate changelog for beta
120
+ run : |
121
+ python scripts/generate_changelog.py --beta --output BETA_CHANGELOG.md
122
+
123
+ - name : Run comprehensive tests
124
+ run : |
125
+ echo "🧪 Running comprehensive test suite for beta release..."
126
+
127
+ # Run core tests
128
+ python -m pytest tests/ -v --tb=short
129
+
130
+ # Run integration tests
131
+ python -m pytest -m integration -v
132
+
133
+ # Run benchmarks to ensure performance
134
+ python -m pytest tests/benchmark_text_service.py -v
135
+
136
+ echo "✅ All tests passed for beta release"
137
+
138
+ - name : Build package
139
+ run : |
140
+ python -m build
141
+
142
+ # Verify wheel size
143
+ python scripts/check_wheel_size.py
144
+
145
+ echo "📦 Beta package built successfully"
146
+
147
+ - name : Create beta release
148
+ env :
149
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
150
+ run : |
151
+ BETA_VERSION="${{ steps.version.outputs.beta_version }}"
152
+
153
+ # Create and push tag
154
+ git add datafog/__about__.py setup.py
155
+ git commit -m "chore: bump version to $BETA_VERSION for beta release"
156
+ git tag -a "v$BETA_VERSION" -m "Beta release $BETA_VERSION"
157
+ git push origin "v$BETA_VERSION"
158
+
159
+ # Create GitHub release
160
+ gh release create "v$BETA_VERSION" \
161
+ --title "🚧 Beta Release $BETA_VERSION" \
162
+ --notes-file BETA_CHANGELOG.md \
163
+ --prerelease \
164
+ --target dev \
165
+ dist/*
166
+
167
+ - name : Publish to PyPI (Beta)
168
+ if : github.event.inputs.dry_run != 'true'
169
+ env :
170
+ TWINE_USERNAME : __token__
171
+ TWINE_PASSWORD : ${{ secrets.PYPI_API_TOKEN }}
172
+ run : |
173
+ echo "🚀 Publishing beta release to PyPI..."
174
+ python -m twine upload dist/* --verbose
175
+
176
+ - name : Dry run summary
177
+ if : github.event.inputs.dry_run == 'true'
178
+ run : |
179
+ echo "🏃♂️ DRY RUN COMPLETED"
180
+ echo "Would have published: ${{ steps.version.outputs.beta_version }}"
181
+ echo "Package contents:"
182
+ ls -la dist/
183
+ echo "Test results: All tests would be run"
184
+
185
+ - name : Cleanup old beta releases
186
+ env :
187
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
188
+ run : |
189
+ echo "🧹 Cleaning up old beta releases (keep last 5)..."
190
+
191
+ # Get all beta releases, sorted by creation date
192
+ BETA_RELEASES=$(gh release list --limit 30 | grep "🚧.*b[0-9]" | tail -n +6 | cut -f3)
193
+
194
+ for release in $BETA_RELEASES; do
195
+ echo "Deleting old beta release: $release"
196
+ gh release delete "$release" --yes || true
197
+ git push --delete origin "$release" || true
198
+ done
199
+
200
+ notify-beta :
201
+ needs : [check-changes, beta-release]
202
+ if : needs.check-changes.outputs.has_changes == 'true' && success()
203
+ runs-on : ubuntu-latest
204
+ steps :
205
+ - name : Beta release notification
206
+ run : |
207
+ echo "🚧 Thursday beta release completed!"
208
+ echo "📦 Beta version ready for final testing"
209
+ echo "💡 Install with: pip install datafog==${{ needs.beta-release.outputs.beta_version }}"
210
+ echo "📊 Commits included: ${{ needs.check-changes.outputs.commit_count }}"
211
+ echo "🗓️ Stable release scheduled for Friday"
212
+ echo ""
213
+ echo "🧪 Beta Testing Checklist:"
214
+ echo " ✅ All automated tests passed"
215
+ echo " ⏳ Manual testing recommended"
216
+ echo " ⏳ Performance validation"
217
+ echo " ⏳ Integration testing"
218
+
219
+ prepare-friday-release :
220
+ needs : [beta-release]
221
+ if : success()
222
+ runs-on : ubuntu-latest
223
+ steps :
224
+ - name : Prepare Friday stable release
225
+ run : |
226
+ echo "🎯 Preparing for Friday stable release..."
227
+ echo "Current beta: ${{ needs.beta-release.outputs.beta_version }}"
228
+
229
+ # Extract base version for Friday
230
+ BETA_VERSION="${{ needs.beta-release.outputs.beta_version }}"
231
+ STABLE_VERSION=$(echo $BETA_VERSION | cut -d'b' -f1)
232
+
233
+ echo "Planned stable version: $STABLE_VERSION"
234
+ echo "📋 Friday Release Checklist:"
235
+ echo " ⏳ Final beta testing"
236
+ echo " ⏳ Update CHANGELOG.md"
237
+ echo " ⏳ Run weekly release workflow"
238
+ echo " ⏳ Social media announcement"
0 commit comments