chore(release): bfabric 1.21.0, bfabric_scripts 1.17.0, bfabric_app_runner 0.8.0 #59
Workflow file for this run
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: PR Release Preview | |
| on: | |
| pull_request: | |
| branches: | |
| - release | |
| # `edited` is required to catch PR base-branch retargeting (e.g. a PR first | |
| # opened against `main` and later retargeted to `release`); GitHub fires | |
| # `edited` rather than `synchronize` for that. See #409. | |
| types: [opened, synchronize, reopened, edited] | |
| jobs: | |
| preview-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| packages_to_release: ${{ steps.check-versions.outputs.packages-to-release }} | |
| version_info: ${{ steps.check-versions.outputs.version-info }} | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install hatch | |
| run: pip install hatch | |
| - name: Check which packages will be released | |
| id: check-versions | |
| uses: ./.github/actions/check-package-versions | |
| with: | |
| packages: "bfabric,bfabric_scripts,bfabric_app_runner" | |
| pypi-url: "https://pypi.org" | |
| priority-order: "bfabric,bfabric_scripts,bfabric_app_runner" | |
| include-versions: "true" | |
| - name: Build version table | |
| id: build-table | |
| run: | | |
| packages='${{ steps.check-versions.outputs.packages-to-release }}' | |
| version_info='${{ steps.check-versions.outputs.version-info }}' | |
| # Build table with current PyPI and new versions | |
| table="| Package | Current (PyPI) | New Version |\n|---------|----------------|-------------|" | |
| for pkg in $(echo $packages | jq -r '.[]'); do | |
| current_version=$(echo $version_info | jq -r ".$pkg.current_version") | |
| new_version=$(echo $version_info | jq -r ".$pkg.local_version") | |
| table="$table\n| $pkg | $current_version | $new_version |" | |
| done | |
| echo "table<<TABLE_EOF" >> $GITHUB_OUTPUT | |
| echo -e "$table" >> $GITHUB_OUTPUT | |
| echo "TABLE_EOF" >> $GITHUB_OUTPUT | |
| - name: Create or update PR comment | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const packages = JSON.parse('${{ steps.check-versions.outputs.packages-to-release }}'); | |
| const table = `${{ steps.build-table.outputs.table }}`; | |
| let commentBody; | |
| if (packages.length === 0) { | |
| commentBody = `## π Release Preview | |
| No packages will be released - all versions already exist on PyPI.`; | |
| } else { | |
| commentBody = `## π Release Preview | |
| The following packages will be released when this PR is merged: | |
| ${table} | |
| --- | |
| *This comment is automatically updated when the PR changes.*`; | |
| } | |
| // Find existing comment | |
| const comments = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existingComment = comments.data.find(comment => | |
| comment.user.login === 'github-actions[bot]' && | |
| comment.body.includes('π Release Preview') | |
| ); | |
| if (existingComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existingComment.id, | |
| body: commentBody | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: commentBody | |
| }); | |
| } | |
| validate-and-test-release: | |
| needs: preview-release | |
| # Skip the (expensive) build/test matrix on title/body edits; only re-run it | |
| # for real changes β i.e. anything except an `edited` event whose `changes` | |
| # don't include the base branch. | |
| if: ${{ needs.preview-release.outputs.packages_to_release != '[]' && (github.event.action != 'edited' || github.event.changes.base != null) }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.11", "3.13"] | |
| resolution: ["highest", "lowest-direct"] | |
| exclude: | |
| # Only test lowest-direct on Python 3.11 | |
| - python-version: "3.13" | |
| resolution: "lowest-direct" | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install build and test tools | |
| run: pip install hatch nox uv | |
| - name: Build distributions | |
| id: build | |
| run: | | |
| packages='${{ needs.preview-release.outputs.packages_to_release }}' | |
| wheels="" | |
| for pkg in $(echo $packages | jq -r '.[]'); do | |
| echo "Building $pkg..." | |
| cd $pkg | |
| hatch build | |
| cd .. | |
| # Find the wheel file | |
| wheel=$(ls $pkg/dist/*.whl | head -1) | |
| wheel_abs=$(realpath $wheel) | |
| # Add to wheels list | |
| if [ -z "$wheels" ]; then | |
| wheels="--wheels $wheel_abs" | |
| else | |
| wheels="$wheels --wheels $wheel_abs" | |
| fi | |
| done | |
| echo "wheels_args=$wheels" >> $GITHUB_OUTPUT | |
| echo "Built wheels: $wheels" | |
| - name: Verify package contents | |
| if: ${{ matrix.python-version == '3.11' && matrix.resolution == 'highest' }} | |
| run: | | |
| packages='${{ needs.preview-release.outputs.packages_to_release }}' | |
| for pkg in $(echo $packages | jq -r '.[]'); do | |
| echo "Verifying $pkg..." | |
| wheel=$(ls $pkg/dist/*.whl | head -1) | |
| # List wheel contents | |
| echo "Contents of $wheel:" | |
| unzip -l $wheel | |
| # Check for py.typed in bfabric | |
| if [ "$pkg" = "bfabric" ]; then | |
| if ! unzip -l $wheel | grep -q "py.typed"; then | |
| echo "β py.typed missing from bfabric wheel" | |
| exit 1 | |
| fi | |
| echo "β py.typed found in bfabric wheel" | |
| fi | |
| # Check for resources in bfabric_app_runner | |
| if [ "$pkg" = "bfabric_app_runner" ]; then | |
| if ! unzip -l $wheel | grep -q "resources/.*\.mk"; then | |
| echo "β .mk resources missing from bfabric_app_runner wheel" | |
| exit 1 | |
| fi | |
| echo "β Resources found in bfabric_app_runner wheel" | |
| fi | |
| done | |
| - name: Test distributions | |
| run: | | |
| # This will install the built wheels and run tests | |
| # If version constraints are incompatible, installation will fail naturally | |
| nox -s test_distributions-${{ matrix.python-version }} -- \ | |
| ${{ steps.build.outputs.wheels_args }} \ | |
| --resolution ${{ matrix.resolution }} | |
| comment-test-results: | |
| needs: [preview-release, validate-and-test-release] | |
| # Mirror the guard on validate-and-test-release so we don't post a stale | |
| # "tests failed" comment when the matrix was intentionally skipped. | |
| if: always() && needs.preview-release.outputs.packages_to_release != '[]' && (github.event.action != 'edited' || github.event.changes.base != null) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| - uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const packages = JSON.parse('${{ needs.preview-release.outputs.packages_to_release }}'); | |
| // Determine overall status | |
| const testResult = '${{ needs.validate-and-test-release.result }}'; | |
| const allPassed = testResult === 'success'; | |
| const emoji = allPassed ? 'β ' : 'β'; | |
| // Get current timestamp | |
| const timestamp = new Date().toISOString(); | |
| const commentBody = `## ${emoji} Release Distribution Testing | |
| **Packages to release:** ${packages.join(', ')} | |
| **Test Results:** | |
| - Python 3.11 (highest): ${testResult === 'success' ? 'β passed' : 'β failed'} | |
| - Python 3.11 (lowest-direct): ${testResult === 'success' ? 'β passed' : 'β failed'} | |
| - Python 3.13 (highest): ${testResult === 'success' ? 'β passed' : 'β failed'} | |
| ${allPassed ? | |
| '**Status:** All tests passed with built distributions. The packages are ready for release.' : | |
| `**Status:** Tests failed. Please check the [workflow logs](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) for details.`} | |
| *Last updated: ${timestamp}* | |
| `; | |
| // Find existing comment | |
| const comments = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existingComment = comments.data.find(comment => | |
| comment.user.login === 'github-actions[bot]' && | |
| comment.body.includes('Release Distribution Testing') | |
| ); | |
| if (existingComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existingComment.id, | |
| body: commentBody | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: commentBody | |
| }); | |
| } |