TestPyPI Publishing #76
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: TestPyPI Publishing | |
| # SECURITY NOTE: This workflow uses PyPI Trusted Publishing (OIDC) | |
| # No API tokens required - authentication is handled automatically via GitHub's OIDC token | |
| # | |
| # This workflow publishes to TestPyPI ONLY for development testing. | |
| # Production releases to PyPI are handled by prod-release.yml | |
| # | |
| # Prerequisites: | |
| # 1. Configure trusted publisher on TestPyPI: https://test.pypi.org/manage/account/publishing/ | |
| # 2. See docs/deployment/pypi-setup.md for detailed setup instructions | |
| env: | |
| # Comment trigger words for package publishing | |
| PUBLISH_TRIGGERS: "/package" | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'src/**' | |
| - 'pyproject.toml' | |
| - 'requirements*.txt' | |
| - 'uv.lock' | |
| workflow_run: | |
| workflows: ["Quality Checks", "Unit Tests"] | |
| types: [completed] | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| force: | |
| description: 'Force publish even if version exists' | |
| required: false | |
| default: false | |
| type: boolean | |
| concurrency: | |
| group: "pypi-publishing" | |
| cancel-in-progress: false | |
| jobs: | |
| config: | |
| name: Get Configuration | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' | |
| outputs: | |
| default-python-version: ${{ steps.config.outputs.default-python-version }} | |
| package-version: ${{ steps.config.outputs.package-version }} | |
| pypi-name: ${{ steps.config.outputs.pypi-name }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Get project configuration | |
| id: config | |
| uses: ./.github/actions/get-config | |
| publish: | |
| name: Build and Publish Package | |
| runs-on: ubuntu-latest | |
| needs: [config] | |
| environment: | |
| name: testpypi | |
| url: https://test.pypi.org/p/${{ needs.config.outputs.pypi-name }} | |
| permissions: | |
| id-token: write # IMPORTANT: mandatory for trusted publishing | |
| contents: read # needed to checkout code | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| with: | |
| ref: ${{ github.sha }} | |
| - name: Determine version and target | |
| run: | | |
| { | |
| echo "VERSION=${{ needs.config.outputs.package-version }}" | |
| echo "TARGET=testpypi" | |
| } >> "$GITHUB_ENV" | |
| echo "Publishing to: TestPyPI with version: $VERSION" | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'requirements*.txt') }} | |
| fail-on-cache-miss: false | |
| - name: Build package | |
| run: | | |
| make build-with-version | |
| - name: Check package | |
| run: | | |
| make test-install-only | |
| - name: Publish to Test PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| verbose: true | |
| skip-existing: true | |
| - name: Create deployment summary | |
| run: | | |
| { | |
| echo "## Package Published Successfully" | |
| echo "" | |
| echo "**Environment:** Test PyPI" | |
| echo "**Installation:** \`pip install --index-url https://test.pypi.org/simple/ ${{ needs.config.outputs.pypi-name }}\`" | |
| echo "" | |
| echo "**Version:** $VERSION" | |
| echo "**Commands:**" | |
| echo "- \`orb --help\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| generate-sbom: | |
| name: Generate SBOM | |
| runs-on: ubuntu-latest | |
| needs: [config, publish] | |
| permissions: | |
| contents: read | |
| actions: write | |
| security-events: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6.0.2 | |
| - name: Setup Python and UV | |
| uses: ./.github/actions/setup-uv-cached | |
| with: | |
| cache-key: deps-${{ needs.config.outputs.default-python-version }}-${{ hashFiles('.project.yml', 'pyproject.toml', 'requirements*.txt') }} | |
| fail-on-cache-miss: false | |
| - name: Generate SBOM files | |
| run: | | |
| make ci-build-sbom | |
| - name: Upload SBOM artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: reports-sbom-${{ needs.config.outputs.package-version }} | |
| path: | | |
| python-sbom-cyclonedx.json | |
| python-sbom-spdx.json | |
| retention-days: 180 | |
| - name: Upload SBOM to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: python-sbom-cyclonedx.json | |
| continue-on-error: true |