docs(release): finalize v0.6 contract wording #8
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 | |
| # Triggers: | |
| # - Pushing any tag matching `v*` auto-publishes that ref to PyPI. | |
| # - `workflow_dispatch` lets you (re)publish an existing tag manually, | |
| # useful for backfilling a tag that shipped before this workflow | |
| # existed (e.g. v0.2.1) or for retrying a failed publish. | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Existing tag to publish (e.g. v0.5.0). Required for manual publish." | |
| required: true | |
| type: string | |
| jobs: | |
| build: | |
| name: Build sdist + wheel | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| # workflow_dispatch may override with a specific tag; otherwise | |
| # use the ref that triggered the workflow (tag push = that tag). | |
| ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref }} | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| - name: Install dependencies | |
| run: uv sync --dev | |
| - name: Run tests | |
| run: uv run python -m pytest tests/ -q | |
| - name: Build distributions | |
| run: uv build | |
| - name: Sanity-check version matches tag | |
| # Ensure pyproject.toml version matches the tag name for both automatic | |
| # tag publishes and manual retries. | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG_NAME="${{ github.event.inputs.tag }}" | |
| else | |
| TAG_NAME="${GITHUB_REF_NAME}" | |
| fi | |
| case "$TAG_NAME" in | |
| v*) ;; | |
| *) | |
| echo "::error::Release tag must start with v (got ${TAG_NAME})" | |
| exit 1 | |
| ;; | |
| esac | |
| TAG_VERSION="${TAG_NAME#v}" | |
| PKG_VERSION=$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/') | |
| echo "Tag: v${TAG_VERSION} pyproject: ${PKG_VERSION}" | |
| if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then | |
| echo "::error::Tag v${TAG_VERSION} does not match pyproject version ${PKG_VERSION}" | |
| exit 1 | |
| fi | |
| - name: Check distributions | |
| run: uvx twine check dist/* | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: dist | |
| path: dist/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| publish: | |
| name: Publish to PyPI (OIDC) | |
| needs: build | |
| runs-on: ubuntu-latest | |
| # `environment` is required by PyPI's Trusted Publisher if one was | |
| # configured with an environment name. We use `pypi` as the | |
| # convention. If you set a different name on PyPI, update it here. | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/project/seeklink/ | |
| permissions: | |
| # Required for PyPI Trusted Publishing (OIDC) — the action exchanges | |
| # this for a short-lived PyPI upload token, so no long-lived API | |
| # secret is ever stored in GitHub. | |
| id-token: write | |
| steps: | |
| - name: Download artifacts | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 | |
| # No `password:` input — Trusted Publishing via OIDC. | |
| with: | |
| packages-dir: dist/ |