Beta Release (Thursday) #46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Beta Release (Thursday) | |
on: | |
schedule: | |
- cron: '0 2 * * 4' # Thursday at 2 AM UTC | |
workflow_dispatch: | |
inputs: | |
dry_run: | |
description: 'Dry run (skip PyPI publish)' | |
required: false | |
default: 'false' | |
type: boolean | |
force_build: | |
description: 'Force build even if no changes' | |
required: false | |
default: 'false' | |
type: boolean | |
jobs: | |
check-changes: | |
runs-on: ubuntu-latest | |
outputs: | |
has_changes: ${{ steps.changes.outputs.has_changes }} | |
commit_count: ${{ steps.changes.outputs.commit_count }} | |
last_beta: ${{ steps.changes.outputs.last_beta }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: dev | |
- name: Check for changes since last beta release | |
id: changes | |
run: | | |
LAST_BETA=$(git tag -l "*b*" --sort=-version:refname | head -n1) | |
if [ -z "$LAST_BETA" ]; then | |
echo "No previous beta release found" | |
COMMIT_COUNT=$(git rev-list --count --since="1 week ago" dev) | |
else | |
echo "Last beta release: $LAST_BETA" | |
COMMIT_COUNT=$(git rev-list --count ${LAST_BETA}..dev) | |
fi | |
echo "commit_count=$COMMIT_COUNT" >> $GITHUB_OUTPUT | |
echo "last_beta=$LAST_BETA" >> $GITHUB_OUTPUT | |
if [ "$COMMIT_COUNT" -gt 0 ] || [ "${{ github.event.inputs.force_build }}" = "true" ]; then | |
echo "has_changes=true" >> $GITHUB_OUTPUT | |
else | |
echo "has_changes=false" >> $GITHUB_OUTPUT | |
fi | |
beta-release: | |
needs: check-changes | |
if: needs.check-changes.outputs.has_changes == 'true' | |
runs-on: ubuntu-latest | |
outputs: | |
beta_version: ${{ steps.version.outputs.beta_version }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: dev | |
token: ${{ secrets.GH_PAT }} | |
- name: Set up Python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install bump2version build twine psutil | |
pip install -e ".[all,dev]" | |
# Install memory monitoring tools | |
pip install memory_profiler | |
- name: Configure git | |
run: | | |
git config --local user.email "[email protected]" | |
git config --local user.name "GitHub Action" | |
- name: Generate beta version | |
id: version | |
run: | | |
set -e | |
# Fetch all tags to ensure we have the complete tag history | |
git fetch --tags | |
CURRENT_VERSION=$(python -c "from datafog.__about__ import __version__; print(__version__)") | |
echo "Current version: $CURRENT_VERSION" | |
# Extract base version (remove any alpha/beta suffix) | |
if [[ $CURRENT_VERSION == *"b"* ]]; then | |
BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'b' -f1) | |
elif [[ $CURRENT_VERSION == *"a"* ]]; then | |
BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'a' -f1) | |
else | |
BASE_VERSION=$CURRENT_VERSION | |
fi | |
echo "Base version: $BASE_VERSION" | |
# Find the next available beta version by checking existing tags | |
BETA_NUM=1 | |
while git tag -l "v${BASE_VERSION}b${BETA_NUM}" | grep -q "v${BASE_VERSION}b${BETA_NUM}"; do | |
echo "Tag v${BASE_VERSION}b${BETA_NUM} already exists" | |
BETA_NUM=$((BETA_NUM + 1)) | |
done | |
BETA_VERSION="${BASE_VERSION}b${BETA_NUM}" | |
echo "Next available beta version: $BETA_VERSION" | |
echo "beta_version=$BETA_VERSION" >> $GITHUB_OUTPUT | |
sed -i "s/__version__ = \".*\"/__version__ = \"$BETA_VERSION\"/" datafog/__about__.py | |
- name: Generate changelog | |
run: | | |
python scripts/generate_changelog.py --beta --output BETA_CHANGELOG.md | |
- name: Run tests with segfault protection | |
env: | |
# Memory optimization environment variables (set by run_tests.py) | |
CI: true | |
GITHUB_ACTIONS: true | |
run: | | |
# Print system memory info | |
free -h || echo "free command not available" | |
# Use our robust test runner that handles segfaults | |
echo "Running main tests with segfault protection..." | |
python run_tests.py tests/ -k "not benchmark and not integration" --no-header | |
# Run integration tests separately with segfault protection | |
echo "Running integration tests..." | |
python run_tests.py -m integration --no-header | |
# Run simple performance validation (no pytest-benchmark dependency) | |
echo "Running simple performance validation..." | |
OMP_NUM_THREADS=4 MKL_NUM_THREADS=4 OPENBLAS_NUM_THREADS=4 python tests/simple_performance_test.py | |
- name: Build package | |
run: | | |
python -m build | |
python scripts/check_wheel_size.py | |
- name: Create GitHub release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GH_PAT }} | |
run: | | |
BETA_VERSION="${{ steps.version.outputs.beta_version }}" | |
git add datafog/__about__.py | |
git commit -m "chore: bump version to $BETA_VERSION for beta release" | |
git tag -a "v$BETA_VERSION" -m "Beta release $BETA_VERSION" | |
git push origin "v$BETA_VERSION" | |
gh release create "v$BETA_VERSION" \ | |
--title "🚧 Beta Release $BETA_VERSION" \ | |
--notes-file BETA_CHANGELOG.md \ | |
--prerelease \ | |
--target dev \ | |
dist/* | |
- name: Publish to PyPI | |
if: github.event.inputs.dry_run != 'true' | |
env: | |
TWINE_USERNAME: __token__ | |
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} | |
run: | | |
python -m twine upload dist/* --verbose | |
- name: Dry run summary | |
if: github.event.inputs.dry_run == 'true' | |
run: | | |
echo "🏃 DRY RUN COMPLETE" | |
echo "Would have published: ${{ steps.version.outputs.beta_version }}" | |
ls -la dist/ | |
- name: Cleanup old betas | |
env: | |
GITHUB_TOKEN: ${{ secrets.GH_PAT }} | |
run: | | |
BETA_RELEASES=$(gh release list --limit 30 | grep b | tail -n +6 | cut -f3) | |
for release in $BETA_RELEASES; do | |
echo "Deleting $release" | |
gh release delete "$release" --yes || true | |
git push --delete origin "$release" || true | |
done | |
notify-beta: | |
needs: [check-changes, beta-release] | |
if: needs.check-changes.outputs.has_changes == 'true' && success() | |
runs-on: ubuntu-latest | |
steps: | |
- name: Beta release notification | |
run: | | |
echo "🚧 Beta release completed!" | |
echo "Install: pip install datafog==${{ needs.beta-release.outputs.beta_version }}" | |
echo "Commits since last beta: ${{ needs.check-changes.outputs.commit_count }}" |