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 patch and add beta
108+ BASE_VERSION=$(python -c "
109+ import re
110+ version = '$CURRENT_VERSION'
111+ parts = version.split('.')
112+ parts[2] = str(int(parts[2]) + 1)
113+ print('.'.join(parts))
114+ " )
115+ BETA_VERSION=" ${BASE_VERSION}b1"
116+ fi
117+
118+ echo "Beta version : $BETA_VERSION"
119+ echo "beta_version=$BETA_VERSION" >> $GITHUB_OUTPUT
120+
121+ # Update version in files
122+ sed -i "s/__version__ = \".*\"/__version__ = \"$BETA_VERSION\"/" datafog/__about__.py
123+ sed -i "s/version=\".*\"/version=\"$BETA_VERSION\"/" setup.py
124+
125+ - name : Generate changelog for beta
126+ run : |
127+ python scripts/generate_changelog.py --beta --output BETA_CHANGELOG.md
128+
129+ - name : Run comprehensive tests
130+ run : |
131+ echo "🧪 Running comprehensive test suite for beta release..."
132+
133+ # Run core tests
134+ python -m pytest tests/ -v --tb=short
135+
136+ # Run integration tests
137+ python -m pytest -m integration -v
138+
139+ # Run benchmarks to ensure performance
140+ python -m pytest tests/benchmark_text_service.py -v
141+
142+ echo "✅ All tests passed for beta release"
143+
144+ - name : Build package
145+ run : |
146+ python -m build
147+
148+ # Verify wheel size
149+ python scripts/check_wheel_size.py
150+
151+ echo "📦 Beta package built successfully"
152+
153+ - name : Create beta release
154+ env :
155+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
156+ run : |
157+ BETA_VERSION="${{ steps.version.outputs.beta_version }}"
158+
159+ # Create and push tag
160+ git add datafog/__about__.py setup.py
161+ git commit -m "chore: bump version to $BETA_VERSION for beta release"
162+ git tag -a "v$BETA_VERSION" -m "Beta release $BETA_VERSION"
163+ git push origin "v$BETA_VERSION"
164+
165+ # Create GitHub release
166+ gh release create "v$BETA_VERSION" \
167+ --title "🚧 Beta Release $BETA_VERSION" \
168+ --notes-file BETA_CHANGELOG.md \
169+ --prerelease \
170+ --target dev \
171+ dist/*
172+
173+ - name : Publish to PyPI (Beta)
174+ if : github.event.inputs.dry_run != 'true'
175+ env :
176+ TWINE_USERNAME : __token__
177+ TWINE_PASSWORD : ${{ secrets.PYPI_API_TOKEN }}
178+ run : |
179+ echo "🚀 Publishing beta release to PyPI..."
180+ python -m twine upload dist/* --verbose
181+
182+ - name : Dry run summary
183+ if : github.event.inputs.dry_run == 'true'
184+ run : |
185+ echo "🏃♂️ DRY RUN COMPLETED"
186+ echo "Would have published: ${{ steps.version.outputs.beta_version }}"
187+ echo "Package contents:"
188+ ls -la dist/
189+ echo "Test results: All tests would be run"
190+
191+ - name : Cleanup old beta releases
192+ env :
193+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
194+ run : |
195+ echo "🧹 Cleaning up old beta releases (keep last 5)..."
196+
197+ # Get all beta releases, sorted by creation date
198+ BETA_RELEASES=$(gh release list --limit 30 | grep "🚧.*b[0-9]" | tail -n +6 | cut -f3)
199+
200+ for release in $BETA_RELEASES; do
201+ echo "Deleting old beta release: $release"
202+ gh release delete "$release" --yes || true
203+ git push --delete origin "$release" || true
204+ done
205+
206+ notify-beta :
207+ needs : [check-changes, beta-release]
208+ if : needs.check-changes.outputs.has_changes == 'true' && success()
209+ runs-on : ubuntu-latest
210+ steps :
211+ - name : Beta release notification
212+ run : |
213+ echo "🚧 Thursday beta release completed!"
214+ echo "📦 Beta version ready for final testing"
215+ echo "💡 Install with: pip install datafog==${{ needs.beta-release.outputs.beta_version }}"
216+ echo "📊 Commits included: ${{ needs.check-changes.outputs.commit_count }}"
217+ echo "🗓️ Stable release scheduled for Friday"
218+ echo ""
219+ echo "🧪 Beta Testing Checklist:"
220+ echo " ✅ All automated tests passed"
221+ echo " ⏳ Manual testing recommended"
222+ echo " ⏳ Performance validation"
223+ echo " ⏳ Integration testing"
224+
225+ prepare-friday-release :
226+ needs : [beta-release]
227+ if : success()
228+ runs-on : ubuntu-latest
229+ steps :
230+ - name : Prepare Friday stable release
231+ run : |
232+ echo "🎯 Preparing for Friday stable release..."
233+ echo "Current beta: ${{ needs.beta-release.outputs.beta_version }}"
234+
235+ # Extract base version for Friday
236+ BETA_VERSION="${{ needs.beta-release.outputs.beta_version }}"
237+ STABLE_VERSION=$(echo $BETA_VERSION | cut -d'b' -f1)
238+
239+ echo "Planned stable version: $STABLE_VERSION"
240+ echo "📋 Friday Release Checklist:"
241+ echo " ⏳ Final beta testing"
242+ echo " ⏳ Update CHANGELOG.md"
243+ echo " ⏳ Run weekly release workflow"
244+ echo " ⏳ Social media announcement"
0 commit comments