release #2
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: release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Release version (e.g. 0.3.0)' | |
| required: true | |
| type: string | |
| # Minimal default; individual jobs declare only what they need. | |
| permissions: | |
| contents: read | |
| jobs: | |
| test: | |
| name: Test (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12"] | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| run: uv python install ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: uv sync --dev --python ${{ matrix.python-version }} | |
| - name: Run tests | |
| run: uv run --python ${{ matrix.python-version }} pytest tests/ -v | |
| build: | |
| name: Build distribution | |
| needs: test | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # required to push the release tag | |
| outputs: | |
| version: ${{ steps.normalize.outputs.version }} | |
| steps: | |
| # Strip a leading 'v' once here; all downstream steps use the output. | |
| - name: Normalize version | |
| id: normalize | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| VERSION="${VERSION#v}" | |
| echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 # required: hatch-vcs derives the package version from git tags | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Create the tag locally so hatch-vcs can derive the package version during | |
| # `uv build`. The tag is pushed to origin only AFTER a successful build to | |
| # avoid leaving a dangling remote tag if the build fails. | |
| - name: Create local release tag | |
| run: git tag "v${{ steps.normalize.outputs.version }}" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5 | |
| - name: Build wheel and sdist | |
| run: uv build | |
| # Fail fast if the tag already exists on origin (e.g. re-running the workflow | |
| # for the same version) before attempting to push, to surface a clear error | |
| # rather than a confusing "already exists" git message. | |
| - name: Push release tag | |
| run: | | |
| if git ls-remote --exit-code --tags origin \ | |
| "refs/tags/v${{ steps.normalize.outputs.version }}" > /dev/null 2>&1; then | |
| echo "ERROR: tag v${{ steps.normalize.outputs.version }} already exists on origin" >&2 | |
| exit 1 | |
| fi | |
| git push origin "v${{ steps.normalize.outputs.version }}" | |
| - name: Upload dist artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: dist | |
| path: dist/ | |
| if-no-files-found: error | |
| # IMPORTANT: The PyPI and TestPyPI Trusted Publisher configurations must reference | |
| # this workflow file (`.github/workflows/release.yml`). If they still point to the | |
| # former `publish.yml`, OIDC token exchange will be rejected by PyPI/TestPyPI. | |
| # Update both configs at https://pypi.org and https://test.pypi.org before running | |
| # this workflow for the first time. | |
| publish-testpypi: | |
| name: Publish → TestPyPI | |
| needs: build | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: testpypi | |
| url: https://test.pypi.org/p/starfix | |
| permissions: | |
| id-token: write # required for OIDC trusted publishing | |
| steps: | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5 | |
| - name: Download dist artifact | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Publish to TestPyPI | |
| run: uv publish --publish-url https://test.pypi.org/legacy/ dist/* | |
| publish-pypi: | |
| name: Publish → PyPI | |
| needs: [build, publish-testpypi] | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/starfix | |
| permissions: | |
| id-token: write # required for OIDC trusted publishing | |
| contents: write # required for creating the GitHub Release | |
| steps: | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5 | |
| - name: Download dist artifact | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Publish to PyPI | |
| run: uv publish dist/* | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2 | |
| with: | |
| tag_name: "v${{ needs.build.outputs.version }}" | |
| generate_release_notes: true | |
| files: dist/* |