Beta Release (Thursday) #30
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 "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| - name: Generate beta version | |
| id: version | |
| run: | | |
| set -e | |
| CURRENT_VERSION=$(python -c "from datafog.__about__ import __version__; print(__version__)") | |
| echo "Current version: $CURRENT_VERSION" | |
| if [[ $CURRENT_VERSION == *"b"* ]]; then | |
| # Already a beta, increment beta number | |
| BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'b' -f1) | |
| BETA_NUM=$(echo $CURRENT_VERSION | cut -d'b' -f2) | |
| BETA_VERSION="${BASE_VERSION}b$((BETA_NUM + 1))" | |
| elif [[ $CURRENT_VERSION == *"a"* ]]; then | |
| # Alpha version, convert to beta | |
| BASE_VERSION=$(echo $CURRENT_VERSION | cut -d'a' -f1) | |
| BETA_VERSION="${BASE_VERSION}b1" | |
| else | |
| # Stable version - create beta of current version for unreleased features | |
| # Don't auto-increment minor version; use current version for beta testing | |
| BETA_VERSION="${CURRENT_VERSION}b1" | |
| fi | |
| echo "beta_version=$BETA_VERSION" >> $GITHUB_OUTPUT | |
| sed -i "s/__version__ = \".*\"/__version__ = \"$BETA_VERSION\"/" datafog/__about__.py | |
| sed -i "s/version=\".*\"/version=\"$BETA_VERSION\"/" setup.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 setup.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 }}" |