Merge pull request #4 from Harperbot/ci/auto-github-release #2
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: Publish to PyPI | |
| on: | |
| # Publishes to PyPI on any `v*` tag push, via Trusted Publishing (OIDC). | |
| # | |
| # PREREQUISITE: a PyPI pending publisher must be registered on pypi.org | |
| # for this repo + this workflow file + environment `pypi` BEFORE the | |
| # first `v*` tag is pushed. Without it the `publish` job fails (the | |
| # `build` job still succeeds). See https://docs.pypi.org/trusted-publishers/ | |
| # | |
| # `workflow_dispatch` runs build-only — the version-check step and the | |
| # publish job are tag-gated — so it can smoke-test the build safely. | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| name: Build sdist + wheel | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install build | |
| run: python -m pip install --upgrade build | |
| - name: Build distributions | |
| run: python -m build | |
| - name: Verify version matches tag | |
| if: startsWith(github.ref, 'refs/tags/') | |
| run: | | |
| PKG_VERSION=$(python -c "import metal_guard; print(metal_guard.__version__)") | |
| TAG_VERSION="${GITHUB_REF_NAME#v}" | |
| if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then | |
| echo "::error::__version__ ($PKG_VERSION) != tag ($TAG_VERSION)" | |
| exit 1 | |
| fi | |
| echo "Version match: $PKG_VERSION" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| publish: | |
| name: Publish to PyPI (Trusted Publisher / OIDC) | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/project/metal-guard/ | |
| permissions: | |
| id-token: write # required for OIDC trusted publishing | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| # No password / token needed — OIDC token issued automatically | |
| # to the configured trusted publisher on pypi.org. | |
| packages-dir: dist/ | |
| github-release: | |
| # Creates the GitHub Release automatically on every `v*` tag, so the | |
| # Releases page never lags behind the tags. Runs only after a | |
| # successful PyPI publish, keeping GitHub Releases and PyPI in sync. | |
| name: Create GitHub Release | |
| needs: [build, publish] | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # required to create the release | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Extract release notes from CHANGELOG | |
| id: notes | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| awk -v ver="$VERSION" ' | |
| /^## \[/ { if (found) exit; if (index($0, "[" ver "]")) { found=1; next } } | |
| found { print } | |
| ' CHANGELOG.md > release-notes.md | |
| if [ -s release-notes.md ]; then | |
| echo "have_notes=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "have_notes=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| if [ "${{ steps.notes.outputs.have_notes }}" = "true" ]; then | |
| gh release create "$GITHUB_REF_NAME" dist/* \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "$GITHUB_REF_NAME" \ | |
| --notes-file release-notes.md \ | |
| --verify-tag --latest | |
| else | |
| gh release create "$GITHUB_REF_NAME" dist/* \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "$GITHUB_REF_NAME" \ | |
| --generate-notes \ | |
| --verify-tag --latest | |
| fi |