2-publish-pypi-stage #29
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: CI, TestPyPI Deploy, and Manual PyPI Release | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| # Run on PRs targeting main | |
| types: [opened, synchronize, reopened] # Be explicit about PR event types | |
| branches: [ main ] | |
| # Allows manual triggering for publishing steps | |
| workflow_dispatch: | |
| jobs: | |
| # --- Test Job (Runs on push/pr/workflow_dispatch) --- | |
| test: | |
| runs-on: ubuntu-latest | |
| # No 'if' condition needed here, controlled by top-level 'on:' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image with Cache | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| target: dev | |
| tags: my-test-image:latest | |
| load: true | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Run tests with dFBA extra | |
| run: | | |
| docker run --rm \ | |
| -v "$(pwd):/app" \ | |
| -w /app \ | |
| my-test-image:latest \ | |
| uv run --with dfba --with pytest --with pytest-cov coverage run --parallel-mode -m pytest ./tests/extras --junitxml=test-report-dfba.xml | |
| - name: Run tests without dFBA extra | |
| run: | | |
| docker run --rm \ | |
| -v "$(pwd):/app" \ | |
| -w /app \ | |
| my-test-image:latest \ | |
| uv run --with pytest --with pytest-cov coverage run --parallel-mode -m pytest ./tests/core --junitxml=test-report-core.xml | |
| - name: Combine and Report Coverage | |
| if: success() | |
| run: | | |
| docker run --rm \ | |
| -v "$(pwd):/app" \ | |
| -w /app \ | |
| my-test-image:latest \ | |
| sh -c '\ | |
| echo "Combining coverage data..." && \ | |
| uv run --with pytest --with pytest-cov coverage combine && \ | |
| echo "Generating coverage summary..." && \ | |
| uv run --with pytest --with pytest-cov coverage report -m > /app/coverage_summary.txt && \ | |
| echo "Generating HTML coverage report..." && \ | |
| uv run --with pytest --with pytest-cov coverage html -d htmlcov \ | |
| ' | |
| echo "--- Coverage Summary ---" | |
| cat coverage_summary.txt | |
| echo "------------------------" | |
| - name: Format Coverage Comment Body | |
| if: success() && github.event_name == 'pull_request' | |
| run: | | |
| echo '### :test_tube: Coverage Report' > coverage_comment.md | |
| echo '' >> coverage_comment.md | |
| echo '```text' >> coverage_comment.md | |
| cat coverage_summary.txt >> coverage_comment.md | |
| echo '' >> coverage_comment.md | |
| echo '```' >> coverage_comment.md | |
| - name: Post or Update Coverage Comment | |
| if: success() && github.event_name == 'pull_request' | |
| uses: marocchino/sticky-pull-request-comment@v2 | |
| with: | |
| path: coverage_comment.md | |
| # --- Job: Publish to TestPyPI (Runs automatically on PRs after tests pass) --- | |
| publish-testpypi: | |
| name: Publish dev build to TestPyPI | |
| # Run after tests succeed, for PRs to main OR manual triggers | |
| needs: test | |
| # No specific 'if' here, runs if 'test' succeeded for a triggering event | |
| # Implicitly runs on pull_request targeting main (from top-level 'on:') | |
| # Implicitly runs on workflow_dispatch (from top-level 'on:') | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: testpypi | |
| url: https://test.pypi.org/pypi | |
| permissions: | |
| id-token: write # For trusted publishing | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Needed for accurate versioning if using git tags | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install build dependencies | |
| run: python -m pip install build twine | |
| - name: Generate development version suffix | |
| id: version_suffix | |
| # Use PR number/SHA for PRs, timestamp for manual triggers | |
| run: | | |
| if [ "${{ github.event_name }}" == "pull_request" ]; then | |
| # Suffix for PR builds: .dev<PR_NUMBER>+<SHA> | |
| echo "suffix=dev${{ github.event.number }}+${GITHUB_SHA::7}" >> $GITHUB_OUTPUT | |
| else | |
| # Suffix for other builds (like manual): .dev<TIMESTAMP> | |
| echo "suffix=dev$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Update version in pyproject.toml for TestPyPI | |
| run: | | |
| # Add the generated .dev suffix to the version line | |
| # This assumes version = "X.Y.Z" format | |
| VERSION_SUFFIX="${{ steps.version_suffix.outputs.suffix }}" | |
| # Use a temporary file for sed compatibility on different OS (though runner is ubuntu) | |
| sed -i.bak "s/^\(version\s*=\s*\"\)\([^\"]*\)\"/\1\2.${VERSION_SUFFIX}\"/" pyproject.toml | |
| rm pyproject.toml.bak # Remove backup file | |
| echo "Updated pyproject.toml with version suffix:" | |
| grep "^version" pyproject.toml | |
| - name: Build package | |
| run: python -m build | |
| - name: Publish package distributions to TestPyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| # skip-existing: true # Recommended for dev builds to avoid conflicts | |
| # --- Job: Publish to PyPI (Manual Trigger ONLY on main branch) --- | |
| publish-pypi: | |
| name: Publish to PyPI | |
| # Run ONLY when manually triggered AND on the main branch | |
| if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' | |
| needs: publish-testpypi # Depends on the testpypi build (which runs first on manual trigger) | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/pypi | |
| permissions: | |
| id-token: write # For trusted publishing | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| # Ensure we check out the 'main' branch explicitly for the release build | |
| ref: 'main' | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install build dependencies | |
| run: python -m pip install build twine | |
| - name: Build package | |
| run: | | |
| echo "Building package with version:" | |
| grep "^version" pyproject.toml | |
| python -m build | |
| # This builds using the clean version string from the checked-out main branch code | |
| - name: Publish package distributions to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| # Defaults to PyPI, uses trusted publishing |