Merge pull request #116 from DigitalHarborFoundation/docs/fix-peewee-… #33
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 package to PyPI and TestPyPI | |
| on: | |
| push: | |
| branches: ["main"] | |
| tags: ["v*"] | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| name: Build distribution | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version-file: ".python-version" | |
| - name: Build a binary wheel and a source tarball | |
| run: >- | |
| uv build | |
| - name: Store the distribution packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-package-distributions | |
| path: dist/ | |
| detect-version-change: | |
| name: Detect package version change | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.detect.outputs.version }} | |
| changed: ${{ steps.detect.outputs.changed }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| # Need the parent commit so we can diff the version against it. | |
| fetch-depth: 2 | |
| persist-credentials: false | |
| - name: Detect whether the version bumped vs. the parent commit | |
| id: detect | |
| run: | | |
| current=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' src/flexeval/__about__.py | head -n1) | |
| echo "version=$current" >> "$GITHUB_OUTPUT" | |
| if git show HEAD~1:src/flexeval/__about__.py > /tmp/prev_about.py 2>/dev/null; then | |
| previous=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' /tmp/prev_about.py | head -n1) | |
| else | |
| previous="" | |
| fi | |
| if [ "$current" != "$previous" ]; then | |
| echo "changed=true" >> "$GITHUB_OUTPUT" | |
| echo "Version changed: '${previous}' -> '${current}'" | |
| else | |
| echo "changed=false" >> "$GITHUB_OUTPUT" | |
| echo "Version unchanged at '${current}'" | |
| fi | |
| publish-to-pypi: | |
| name: >- | |
| Publish Python distribution to PyPI | |
| if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes | |
| needs: | |
| - build | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/python-flexeval | |
| permissions: | |
| id-token: write # IMPORTANT: mandatory for trusted publishing | |
| steps: | |
| - name: Download all the dists | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-package-distributions | |
| path: dist/ | |
| - name: Publish distribution to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| smoke-test-pypi: | |
| name: Smoke-test the PyPI release | |
| # Runs only on tags, inherited transitively from publish-to-pypi. | |
| needs: | |
| - publish-to-pypi | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version-file: ".python-version" | |
| - name: Read package version | |
| id: version | |
| run: | | |
| version=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' src/flexeval/__about__.py | head -n1) | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "Smoke-testing python-flexeval==$version" | |
| - name: Install just-published build from PyPI into a clean venv | |
| # Install into a fresh venv (NOT the repo's env) so we exercise the | |
| # published wheel, not the source tree. The PyPI index can lag a few | |
| # seconds behind publish, so retry the install. --refresh-package forces | |
| # uv to re-fetch python-flexeval's index metadata on each attempt; | |
| # otherwise uv caches the pre-publish listing and every retry sees the | |
| # same stale "no such version" result. | |
| run: | | |
| uv venv /tmp/smoke-env | |
| version="${{ steps.version.outputs.version }}" | |
| for attempt in 1 2 3 4 5 6; do | |
| if uv pip install --python /tmp/smoke-env \ | |
| --refresh-package python-flexeval \ | |
| "python-flexeval==${version}"; then | |
| break | |
| fi | |
| if [ "$attempt" -eq 6 ]; then | |
| echo "::error::python-flexeval==${version} still not installable from PyPI after $attempt attempts" | |
| exit 1 | |
| fi | |
| echo "Install attempt $attempt failed (PyPI index may not have propagated yet); retrying in 15s..." | |
| sleep 15 | |
| done | |
| - name: Run smoke test | |
| # Run from the repo root so --run-vignettes can find vignettes/*.py and | |
| # the data files they reference. The vignettes import the *installed* | |
| # flexeval (there is no flexeval package at the repo root, only src/). | |
| run: | | |
| /tmp/smoke-env/bin/python scripts/smoke_test.py \ | |
| --expect-version "${{ steps.version.outputs.version }}" \ | |
| --run-vignettes | |
| publish-to-testpypi: | |
| name: Publish Python distribution to TestPyPI | |
| # Publish to TestPyPI only when the version actually bumped on a main push, | |
| # or on manual dispatch. TestPyPI (like PyPI) rejects re-uploading an | |
| # existing version, so publishing on every commit fails on the duplicate. | |
| # We deliberately do NOT publish on tags: the version was already validated | |
| # on TestPyPI when the bump landed on main, and re-uploading it would 400. | |
| if: >- | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && | |
| github.ref == 'refs/heads/main' && | |
| needs.detect-version-change.outputs.changed == 'true') | |
| needs: | |
| - build | |
| - detect-version-change | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: testpypi | |
| url: https://test.pypi.org/p/python-flexeval | |
| permissions: | |
| id-token: write # IMPORTANT: mandatory for trusted publishing | |
| steps: | |
| - name: Download all the dists | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-package-distributions | |
| path: dist/ | |
| - name: Publish distribution to TestPyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| # Belt-and-suspenders: don't hard-fail if this exact version was already | |
| # uploaded (e.g. a re-run of the same commit). | |
| skip-existing: true | |
| smoke-test-testpypi: | |
| name: Smoke-test the TestPyPI release | |
| needs: | |
| - publish-to-testpypi | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version-file: ".python-version" | |
| - name: Read package version | |
| id: version | |
| run: | | |
| version=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' src/flexeval/__about__.py | head -n1) | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "Smoke-testing python-flexeval==$version" | |
| - name: Install just-published build from TestPyPI into a clean venv | |
| # Install into a fresh venv (NOT the repo's env) so we exercise the | |
| # published wheel, not the source tree. Deps come from real PyPI; only | |
| # python-flexeval itself comes from TestPyPI. The TestPyPI simple index | |
| # can lag a few seconds behind publish, so retry the install. | |
| # --refresh-package forces uv to re-fetch python-flexeval's index metadata | |
| # on each attempt; otherwise uv caches the pre-publish listing and every | |
| # retry sees the same stale "no such version" result. | |
| run: | | |
| uv venv /tmp/smoke-env | |
| version="${{ steps.version.outputs.version }}" | |
| for attempt in 1 2 3 4 5 6; do | |
| if uv pip install --python /tmp/smoke-env \ | |
| --refresh-package python-flexeval \ | |
| --index-url https://test.pypi.org/simple/ \ | |
| --extra-index-url https://pypi.org/simple/ \ | |
| --index-strategy unsafe-best-match \ | |
| "python-flexeval==${version}"; then | |
| break | |
| fi | |
| if [ "$attempt" -eq 6 ]; then | |
| echo "::error::python-flexeval==${version} still not installable from TestPyPI after $attempt attempts" | |
| exit 1 | |
| fi | |
| echo "Install attempt $attempt failed (TestPyPI index may not have propagated yet); retrying in 15s..." | |
| sleep 15 | |
| done | |
| - name: Run smoke test | |
| # Run from the repo root so --run-vignettes can find vignettes/*.py and | |
| # the data files they reference. The vignettes import the *installed* | |
| # flexeval (there is no flexeval package at the repo root, only src/). | |
| run: | | |
| /tmp/smoke-env/bin/python scripts/smoke_test.py \ | |
| --expect-version "${{ steps.version.outputs.version }}" \ | |
| --run-vignettes |