1+ name : Nightly Release (Alpha)
2+
3+ on :
4+ schedule :
5+ # Monday-Thursday at 2 AM UTC (after dev work typically done)
6+ - cron : ' 0 2 * * 1-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+ steps :
27+ - uses : actions/checkout@v4
28+ with :
29+ fetch-depth : 0
30+ ref : dev
31+
32+ - name : Check for changes since last alpha release
33+ id : changes
34+ run : |
35+ # Get last alpha release tag
36+ LAST_ALPHA=$(git tag -l "*alpha*" --sort=-version:refname | head -n1)
37+
38+ if [ -z "$LAST_ALPHA" ]; then
39+ echo "No previous alpha release found, checking last 24 hours"
40+ SINCE="24 hours ago"
41+ COMMIT_COUNT=$(git rev-list --count --since="$SINCE" dev)
42+ else
43+ echo "Last alpha release: $LAST_ALPHA"
44+ COMMIT_COUNT=$(git rev-list --count ${LAST_ALPHA}..dev)
45+ fi
46+
47+ echo "Commits since last alpha: $COMMIT_COUNT"
48+ echo "commit_count=$COMMIT_COUNT" >> $GITHUB_OUTPUT
49+
50+ if [ "$COMMIT_COUNT" -gt 0 ] || [ "${{ github.event.inputs.force_build }}" = "true" ]; then
51+ echo "has_changes=true" >> $GITHUB_OUTPUT
52+ echo "✅ Changes detected, proceeding with nightly build"
53+ else
54+ echo "has_changes=false" >> $GITHUB_OUTPUT
55+ echo "ℹ️ No changes since last alpha, skipping build"
56+ fi
57+
58+ nightly-release :
59+ needs : check-changes
60+ if : needs.check-changes.outputs.has_changes == 'true'
61+ runs-on : ubuntu-latest
62+ steps :
63+ - uses : actions/checkout@v4
64+ with :
65+ fetch-depth : 0
66+ ref : dev
67+ token : ${{ secrets.GITHUB_TOKEN }}
68+
69+ - name : Set up Python
70+ uses : actions/setup-python@v5
71+ with :
72+ python-version : ' 3.11'
73+
74+ - name : Install dependencies
75+ run : |
76+ python -m pip install --upgrade pip
77+ pip install bump2version build twine
78+ pip install -e ".[dev]"
79+
80+ - name : Configure git
81+ run : |
82+ git config --local user.email "action@github.com"
83+ git config --local user.name "GitHub Action"
84+
85+ - name : Generate alpha version
86+ id : version
87+ run : |
88+ # Get current version
89+ CURRENT_VERSION=$(python -c "from datafog.__about__ import __version__; print(__version__)")
90+ echo "Current version: $CURRENT_VERSION"
91+
92+ # Generate alpha version with timestamp
93+ DATE_STAMP=$(date +"%Y%m%d")
94+ TIME_STAMP=$(date +"%H%M")
95+ COMMIT_SHORT=$(git rev-parse --short HEAD)
96+
97+ # If current version already has alpha, increment it
98+ if [[ $CURRENT_VERSION == *"alpha"* ]]; then
99+ BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'a' -f1)
100+ else
101+ # Bump patch version for alpha
102+ BASE_VERSION=$(python -c "
103+ import re
104+ version = '$CURRENT_VERSION'
105+ parts = version.split('.')
106+ parts[2] = str(int(parts[2]) + 1)
107+ print('.'.join(parts))
108+ " )
109+ fi
110+
111+ ALPHA_VERSION=" ${BASE_VERSION}a${DATE_STAMP}.${TIME_STAMP}.${COMMIT_SHORT}"
112+ echo "Alpha version : $ALPHA_VERSION"
113+ echo "alpha_version=$ALPHA_VERSION" >> $GITHUB_OUTPUT
114+
115+ # Update version in files
116+ sed -i "s/__version__ = \".*\"/__version__ = \"$ALPHA_VERSION\"/" datafog/__about__.py
117+ sed -i "s/version=\".*\"/version=\"$ALPHA_VERSION\"/" setup.py
118+
119+ - name : Generate changelog for alpha
120+ run : |
121+ python scripts/generate_changelog.py --alpha --output ALPHA_CHANGELOG.md
122+
123+ - name : Build package
124+ run : |
125+ python -m build
126+
127+ # Verify wheel size
128+ python scripts/check_wheel_size.py
129+
130+ - name : Create alpha release
131+ env :
132+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
133+ run : |
134+ ALPHA_VERSION="${{ steps.version.outputs.alpha_version }}"
135+
136+ # Create and push tag
137+ git add datafog/__about__.py setup.py
138+ git commit -m "chore: bump version to $ALPHA_VERSION for nightly release"
139+ git tag -a "v$ALPHA_VERSION" -m "Alpha release $ALPHA_VERSION"
140+ git push origin "v$ALPHA_VERSION"
141+
142+ # Create GitHub release
143+ gh release create "v$ALPHA_VERSION" \
144+ --title "🌙 Nightly Alpha $ALPHA_VERSION" \
145+ --notes-file ALPHA_CHANGELOG.md \
146+ --prerelease \
147+ --target dev \
148+ dist/*
149+
150+ - name : Publish to PyPI (Alpha)
151+ if : github.event.inputs.dry_run != 'true'
152+ env :
153+ TWINE_USERNAME : __token__
154+ TWINE_PASSWORD : ${{ secrets.PYPI_API_TOKEN }}
155+ run : |
156+ echo "🚀 Publishing alpha release to PyPI..."
157+ python -m twine upload dist/* --verbose
158+
159+ - name : Dry run summary
160+ if : github.event.inputs.dry_run == 'true'
161+ run : |
162+ echo "🏃♂️ DRY RUN COMPLETED"
163+ echo "Would have published: ${{ steps.version.outputs.alpha_version }}"
164+ echo "Package contents:"
165+ ls -la dist/
166+
167+ - name : Cleanup old alpha releases
168+ env :
169+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
170+ run : |
171+ echo "🧹 Cleaning up old alpha releases (keep last 7)..."
172+
173+ # Get all alpha releases, sorted by creation date
174+ ALPHA_RELEASES=$(gh release list --limit 50 | grep alpha | tail -n +8 | cut -f3)
175+
176+ for release in $ALPHA_RELEASES; do
177+ echo "Deleting old alpha release: $release"
178+ gh release delete "$release" --yes || true
179+ git push --delete origin "$release" || true
180+ done
181+
182+ notify-alpha :
183+ needs : [check-changes, nightly-release]
184+ if : needs.check-changes.outputs.has_changes == 'true' && success()
185+ runs-on : ubuntu-latest
186+ steps :
187+ - name : Alpha release notification
188+ run : |
189+ echo "🌙 Nightly alpha release completed!"
190+ echo "📦 New alpha version available for testing"
191+ echo "💡 Install with: pip install datafog==${{ needs.nightly-release.outputs.alpha_version }}"
192+ echo "📊 Commits included: ${{ needs.check-changes.outputs.commit_count }}"
0 commit comments