Skip to content

Commit 24c9708

Browse files
committed
feat(ci): add nightly alpha builds for Monday-Thursday
- Add automated nightly release workflow for dev branch - Support alpha versioning with timestamp and commit hash - Include smart change detection to skip empty builds - Auto-cleanup old alpha releases (keep last 7) - Update bump2version config for alpha support - Add dry run and force build options for testing - Exclude GitHub Actions YAML from prettier formatting
1 parent 20a2e7d commit 24c9708

File tree

3 files changed

+209
-2
lines changed

3 files changed

+209
-2
lines changed

.bumpversion.cfg

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ commit = True
44
tag = True
55
tag_name = v{new_version}
66
message = Bump version: {current_version} → {new_version}
7+
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(a(?P<alpha>\d+))?
8+
serialize =
9+
{major}.{minor}.{patch}a{alpha}
10+
{major}.{minor}.{patch}
11+
12+
[bumpversion:part:alpha]
13+
values =
14+
release
15+
alpha
16+
17+
[bumpversion:part:release]
718

819
[bumpversion:file:datafog/__about__.py]
920
search = __version__ = "{current_version}"
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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 }}"

.pre-commit-config.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@ repos:
3232
rev: v4.0.0-alpha.8
3333
hooks:
3434
- id: prettier
35-
files: '.*\.(md|markdown|json|yaml|yml|js|jsx|css|html)$'
36-
exclude: .venv
35+
files: '.*\.(md|markdown|json|js|jsx|css|html)$'
36+
exclude: |
37+
(?x)^(
38+
.venv|
39+
.*\.github/workflows/.*\.ya?ml$
40+
)$

0 commit comments

Comments
 (0)