2-publish-pypi-stage #23
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 - Run Unit Tests in Docker with Coverage | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| 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 # Assuming Dockerfile is at the root | |
| # Build the 'dev' target stage | |
| target: dev | |
| # Tag the image locally so subsequent steps can use it | |
| tags: my-test-image:latest | |
| # IMPORTANT: Load the image into the local Docker daemon | |
| load: true | |
| # Enable layer caching using GitHub Actions cache | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Run tests with dFBA extra | |
| run: | | |
| # Runs coverage collection via 'uv run' using --with pytest-cov. | |
| # Uses --parallel-mode for coverage data. | |
| # Generates uniquely named JUnit report. | |
| 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: | | |
| # Runs coverage collection via 'uv run' using --with pytest-cov. | |
| # Uses --parallel-mode for coverage data. | |
| # Generates uniquely named JUnit report. | |
| 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 | |
| # --- The step below only runs if BOTH test steps above succeeded --- | |
| - name: Combine and Report Coverage | |
| if: success() | |
| run: | | |
| # Runs combine, report, and html generation in a single container | |
| # Saves the console summary to /app/coverage_summary.txt within the container | |
| # which maps to coverage_summary.txt on the runner host via the volume mount. | |
| 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 \ | |
| ' | |
| # Also echo the summary to the main job log for easy viewing there | |
| echo "--- Coverage Summary ---" | |
| cat coverage_summary.txt | |
| echo "------------------------" | |
| - name: Format Coverage Comment Body | |
| # Prepare the content for the comment in a file | |
| # Only run on successful PR builds | |
| 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 # Ensure newline before closing fence | |
| echo '```' >> coverage_comment.md | |
| # Optional: Add a hidden HTML comment marker for extra safety/identification | |
| # echo "<!-- coverage-report-marker -->" >> coverage_comment.md | |
| - name: Post or Update Coverage Comment | |
| # Use the sticky comment action | |
| # Only run on successful PR builds | |
| if: success() && github.event_name == 'pull_request' | |
| uses: marocchino/sticky-pull-request-comment@v2 | |
| with: | |
| # Tell the action to read the comment body from the file we just created | |
| path: coverage_comment.md | |
| publish-to-testpypi: | |
| name: Publish to TestPyPI | |
| needs: test # Depends on test job succeeding | |
| if: github.event_name == 'workflow_dispatch' # Only runs on manual trigger | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: testpypi # Matches Trusted Publisher config on TestPyPI | |
| url: https://test.pypi.org/p/simulib # Replace YOUR_PACKAGE_NAME | |
| permissions: | |
| id-token: write # Needed for Trusted Publishing | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.x' | |
| - name: Install uv | |
| run: curl -LsSf https://astral.sh/uv/install.sh | sh | |
| - name: Install build dependency using uv | |
| run: uv pip install --system --upgrade build | |
| - name: Build package | |
| run: python -m build | |
| - name: Publish package to TestPyPI using uv and Trusted Publishing | |
| run: > | |
| uv publish --repository-url https://test.pypi.org/legacy/ dist/* | |
| # --- End of TestPyPI publish job --- | |
| publish-to-pypi: | |
| name: Publish to PyPI | |
| needs: publish-to-testpypi # Depends on TestPyPI publish job succeeding | |
| if: github.event_name == 'workflow_dispatch' # Also only runs on manual trigger (implicitly via needs) | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi # MUST MATCH the environment name configured in PyPI Trusted Publishers | |
| url: https://pypi.org/p/simulib # Replace YOUR_PACKAGE_NAME | |
| permissions: | |
| id-token: write # Needed for Trusted Publishing on PyPI | |
| steps: | |
| - name: Checkout code | |
| # Checkout code again for this job's environment | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.x' | |
| - name: Install uv | |
| run: curl -LsSf https://astral.sh/uv/install.sh | sh | |
| - name: Install build dependency using uv | |
| run: uv pip install --system --upgrade build | |
| - name: Build package | |
| # Re-build the package in this job's environment | |
| run: python -m build | |
| - name: Publish package to PyPI using uv and Trusted Publishing | |
| # No --repository-url needed, uv defaults to PyPI | |
| # Authentication happens via OIDC token automatically | |
| run: uv publish dist/* | |
| # --- End of PyPI publish job --- |