chore(release): pact-python-ffi v0.5.4.2 #606
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
| --- | |
| # Release workflow for pact-python (core package). | |
| # | |
| # This workflow handles the full release lifecycle in three stages: | |
| # | |
| # Stage 1: Prepare (trigger: push to main) | |
| # The `prepare` job runs `scripts/release.py prepare core`, which uses | |
| # git-cliff to compute the next semver from conventional commits, updates | |
| # pyproject.toml and CHANGELOG.md, and force-pushes those changes to the | |
| # fixed branch `release/pact-python`. It then creates (or updates the title | |
| # and body of) the release PR targeting main. | |
| # | |
| # Stage 2: Tag (trigger: release PR merged → `closed` event, merged == true) | |
| # When the release PR on `release/pact-python` is merged, the `tag` job runs | |
| # `scripts/release.py tag core`, which reads the version from pyproject.toml | |
| # and pushes a git tag of the form `pact-python/X.Y.Z`. | |
| # | |
| # Stage 3: Publish (trigger: tag push matching `pact-python/*`) | |
| # The `build` and `publish` jobs build the sdist and wheel, create a GitHub | |
| # release with the changelog, and publish the artifacts to PyPI. | |
| # | |
| # Additional: the `build` job also runs on open/updated PRs (not closed) so | |
| # that release PRs can be verified to build correctly before merging. | |
| # | |
| # The `closed` PR type is listed in the trigger so that Stage 2 fires on merge. | |
| # All jobs except `tag` guard against closed-but-not-merged events with | |
| # explicit `if` conditions. | |
| name: release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - pact-python/* | |
| pull_request: | |
| branches: | |
| - main | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| - closed | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }} | |
| env: | |
| # Bump to 3.11 to access tomllib, otherwise, we would use the oldest supported Python version | |
| STABLE_PYTHON_VERSION: '311' | |
| HATCH_VERBOSE: '1' | |
| FORCE_COLOR: '1' | |
| jobs: | |
| complete: | |
| name: Release completion check | |
| if: always() | |
| runs-on: ubuntu-latest | |
| needs: | |
| - prepare | |
| - tag | |
| - build | |
| - publish | |
| steps: | |
| - name: Failed | |
| run: exit 1 | |
| if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') | |
| prepare: | |
| name: Update release PR | |
| if: >- | |
| github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: release-pr | |
| steps: | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| app-id: ${{ vars.PACT_FOUNDATION_BOT_APP_ID }} | |
| private-key: ${{ secrets.PACT_FOUNDATION_BOT_PRIVATE_KEY }} | |
| - name: Checkout code | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| # Need full history for git-cliff to determine the next version and | |
| # generate the changelog | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Configure git identity | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]" | |
| git config user.email "$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq '.id')+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com" | |
| - name: Install git-cliff and typos | |
| uses: taiki-e/install-action@07b4745e0c39a41822af610387492e3e53aa222b # v2.83.4 | |
| with: | |
| tool: git-cliff,typos | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 | |
| - name: Install Python | |
| run: uv python install ${{ env.STABLE_PYTHON_VERSION }} | |
| - name: Update release PR | |
| run: uv run python scripts/release.py prepare core | |
| env: | |
| # Use the GitHub App token instead of GITHUB_TOKEN so that the PR can | |
| # itself trigger workflows | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| tag: | |
| name: Create release tag | |
| if: >- | |
| github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.head.ref | |
| == 'release/pact-python' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: release-pr | |
| steps: | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| app-id: ${{ vars.PACT_FOUNDATION_BOT_APP_ID }} | |
| private-key: ${{ secrets.PACT_FOUNDATION_BOT_PRIVATE_KEY }} | |
| - name: Checkout main | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| ref: main | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Configure git identity | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]" | |
| git config user.email "$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq '.id')+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com" | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 | |
| - name: Install Python | |
| run: uv python install ${{ env.STABLE_PYTHON_VERSION }} | |
| - name: Create and push release tag | |
| run: uv run python scripts/release.py tag core | |
| env: | |
| # Use the GitHub App token instead of GITHUB_TOKEN so that the tag can | |
| # itself trigger workflows | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| build: | |
| name: Build source distribution | |
| # Prepare the wheels for upload, and also verify that the build works on | |
| # release PRs before merging. | |
| if: >- | |
| ( | |
| github.event_name == 'push' && | |
| startsWith(github.ref, 'refs/tags/pact-python/') | |
| ) || ( | |
| github.event_name == 'pull_request' && | |
| github.event.action != 'closed' && | |
| github.event.pull_request.head.ref == 'release/pact-python' | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 | |
| - name: Install Python | |
| run: uv python install ${{ env.STABLE_PYTHON_VERSION }} | |
| - name: Install hatch | |
| run: uv tool install hatch | |
| - name: Build source distribution and wheel | |
| run: hatch build | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: wheels-sdist | |
| path: ./dist/*.tar* | |
| if-no-files-found: error | |
| compression-level: 0 | |
| - name: Upload wheel | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: wheels-whl | |
| path: ./dist/*.whl | |
| if-no-files-found: error | |
| compression-level: 0 | |
| publish: | |
| name: Publish wheel and sdist | |
| if: >- | |
| github.event_name == 'push' && startsWith(github.ref, 'refs/tags/pact-python/') | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/pact-python | |
| needs: | |
| - build | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Extract release changelog | |
| run: | | |
| version="${{ github.ref_name }}" | |
| version="${version#*/}" | |
| out="${{ runner.temp }}/release-changelog.md" | |
| awk -v ver="$version" ' | |
| /^## / { if (found) exit; if (index($0, ver)) found=1; next } | |
| found { print } | |
| ' CHANGELOG.md > "$out" | |
| if [ ! -s "$out" ]; then | |
| printf '> [!WARNING]\n>\n> No changelog entry found for %s.\n' "$version" > "$out" | |
| fi | |
| - name: Find previous release tag | |
| id: previous-tag | |
| run: | | |
| git fetch --tags --quiet | |
| previous=$(git tag --list 'pact-python/*' --sort=-version:refname \ | |
| | grep -v "^${{ github.ref_name }}$" | head -1) | |
| echo "tag=${previous}" >> "$GITHUB_OUTPUT" | |
| - name: Download wheels and sdist | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: wheelhouse | |
| merge-multiple: true | |
| - name: Create GitHub release | |
| uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 | |
| with: | |
| files: wheelhouse/* | |
| body_path: ${{ runner.temp }}/release-changelog.md | |
| previous_tag: ${{ steps.previous-tag.outputs.tag }} | |
| draft: false | |
| prerelease: false | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1 | |
| with: | |
| skip-existing: true | |
| packages-dir: wheelhouse |