Prepare Release - Step 3 - Build artifacts and draft a release #3
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: Prepare Release - Step 3 - Build artifacts and draft a release | |
| on: | |
| workflow_call: | |
| inputs: | |
| sha: | |
| description: Full SHA of the commit to release from | |
| required: true | |
| type: string | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| name: Build package | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| attestations: write | |
| artifact-metadata: write | |
| outputs: | |
| attestation_artifact_id: ${{ steps.attestations_upload.outputs.artifact-id }} | |
| sums_artifact_id: ${{ steps.sums_upload.outputs.artifact-id }} | |
| sdist_artifact_id: ${{ steps.sdist_upload.outputs.artifact-id }} | |
| wheel_artifact_id: ${{ steps.wheel_upload.outputs.artifact-id }} | |
| attestation_url: ${{ steps.attest.outputs.attestation-url }} | |
| run_id: ${{ github.run_id }} | |
| run_attempt: ${{ github.run_attempt }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.sha || github.sha }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.8" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install --upgrade build twine | |
| - name: Build distributions | |
| run: | | |
| SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) | |
| python -m build | |
| - name: Check built distributions | |
| run: python -m twine check dist/* | |
| - name: Generate checksums | |
| working-directory: dist | |
| run: | | |
| sha256sum * | tee SHA256SUMS | |
| - name: Generate attestations | |
| id: attest | |
| uses: actions/attest@v4 | |
| with: | |
| subject-checksums: dist/SHA256SUMS | |
| - name: Upload attestations bundle | |
| id: attestations_upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: attestation.json | |
| path: ${{ steps.attest.outputs.bundle-path }} | |
| archive: false | |
| - name: Upload checksums | |
| id: sums_upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| path: ./dist/SHA256SUMS | |
| archive: false | |
| - name: Upload sdist | |
| id: sdist_upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| path: ./dist/*.tar.gz | |
| archive: false | |
| if-no-files-found: error | |
| - name: Upload built wheel | |
| id: wheel_upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| path: ./dist/*.whl | |
| archive: false | |
| if-no-files-found: error | |
| draft_release: | |
| name: Make a draft release | |
| runs-on: ubuntu-latest | |
| needs: build | |
| permissions: | |
| attestations: read | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.commit || github.sha }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.8" | |
| - name: Get version to release | |
| id: version_to_release | |
| run: | | |
| venv_dir=$(mktemp -d) | |
| python -m venv "$venv_dir" | |
| "$venv_dir"/bin/pip install -U packaging | |
| "$venv_dir"/bin/python .github/workflows/scripts/bump_version.py | |
| env: | |
| JUST_RETURN_VERSION: '1' | |
| - name: Download distributions | |
| uses: actions/download-artifact@v8 | |
| with: | |
| artifact-ids: >- | |
| ${{ needs.build.outputs.attestation_artifact_id }}, | |
| ${{ needs.build.outputs.sums_artifact_id }}, | |
| ${{ needs.build.outputs.sdist_artifact_id }}, | |
| ${{ needs.build.outputs.wheel_artifact_id }} | |
| path: dist/ | |
| merge-multiple: true | |
| # This is done solely to verify that the attestations work as expected, | |
| # not to actually verify the integrity since GitHub has control over | |
| # both the artifacts and attestations here. | |
| - name: Verify integrity of artifacts | |
| env: | |
| GH_REPO: ${{ github.repository }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BUILD_RUN_ID: ${{ needs.build.outputs.run_id }} | |
| BUILD_RUN_ATTEMPT: ${{ needs.build.outputs.run_attempt }} | |
| working-directory: dist | |
| run: | | |
| expected_run_invocation_uri=( | |
| "https://github.com/$GH_REPO/actions/runs/$BUILD_RUN_ID/attempts/$BUILD_RUN_ATTEMPT" | |
| ) | |
| for file in *; do | |
| if [[ "$file" == 'SHA256SUMS' || "$file" == 'attestation.json' ]]; then | |
| continue | |
| fi | |
| run_invocation_uri=$( | |
| GH_FORCE_TTY=1 gh attestation verify "$file" --repo "$GH_REPO" \ | |
| --format=json --jq '.[0].verificationResult.signature.certificate.runInvocationURI' | |
| ) | |
| if [[ "$run_invocation_uri" != "$expected_run_invocation_uri" ]]; then | |
| echo "Got unexpected invocation URI for file: $file" | |
| echo "Expected: $expected_run_invocation_uri" | |
| echo "Actual: $run_invocation_uri" | |
| exit 1 | |
| fi | |
| done | |
| - name: Create a draft release | |
| env: | |
| GH_REPO: ${{ github.repository }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VERSION: ${{ steps.version_to_release.outputs.version }} | |
| PRERELEASE_FLAG: |- | |
| ${{ | |
| steps.version_to_release.outputs.is_prerelease == '1' | |
| && '--prerelease' | |
| || '' | |
| }} | |
| RELEASE_NOTES: | | |
| TODO: UPDATE RELEASE DESCRIPTION | |
| Artifact attestations available at: | |
| ${{ needs.build.outputs.attestation_url }} | |
| RELEASE_TARGET: ${{ inputs.commit || github.sha }} | |
| run: | | |
| gh release create $PRERELEASE_FLAG "$VERSION" dist/* \ | |
| --draft \ | |
| --title "v$VERSION" \ | |
| --notes "$RELEASE_NOTES" \ | |
| --target $RELEASE_TARGET |