diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7527ac9..0d32f28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,24 @@ on: push: workflow_dispatch: +permissions: {} + +# Cancel superseded runs on PR branches; never cancel main, since a +# mid-flight publish would orphan the tag from the PyPI upload and the +# next run would skip publish because the tag already exists. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + PYTHON_VERSION: "3.10" + POETRY_VERSION: "1.5.1" + jobs: compile: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout repo @@ -15,11 +30,11 @@ jobs: - name: Set up python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.10" + python-version: ${{ env.PYTHON_VERSION }} - name: Bootstrap poetry run: | - curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 + curl -sSL https://install.python-poetry.org | python - -y --version "${{ env.POETRY_VERSION }}" - name: Install dependencies run: poetry install @@ -30,6 +45,9 @@ jobs: test: needs: [ compile ] runs-on: ubuntu-latest + permissions: + contents: read + steps: - name: Checkout repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -37,11 +55,11 @@ jobs: - name: Set up python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.10" + python-version: ${{ env.PYTHON_VERSION }} - name: Bootstrap poetry run: | - curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 + curl -sSL https://install.python-poetry.org | python - -y --version "${{ env.POETRY_VERSION }}" - name: Install dependencies run: poetry install @@ -68,7 +86,7 @@ jobs: # version tagged but unpublished, and subsequent runs would skip # publish because the tag already exists. - name: Verify bundled OpenAPI spec - uses: PhenoML/sdk-shared-actions/verify-openapi-spec@1.0.2 + uses: PhenoML/sdk-shared-actions/verify-openapi-spec@1.0.3 with: spec-path: src/phenoml/openapi/openapi.json @@ -94,12 +112,11 @@ jobs: --title "${{ steps.check.outputs.version }}" \ --generate-notes - publish: - needs: [ compile, test, tag ] + build-artifact: + needs: [ tag ] if: needs.tag.outputs.should_publish == 'true' runs-on: ubuntu-latest permissions: - id-token: write contents: read steps: @@ -109,14 +126,44 @@ jobs: - name: Set up python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: - python-version: "3.10" + python-version: ${{ env.PYTHON_VERSION }} - name: Bootstrap poetry run: | - curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 + curl -sSL https://install.python-poetry.org | python - -y --version "${{ env.POETRY_VERSION }}" - name: Build distribution run: poetry build + - name: Upload artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: python-dist + path: dist/ + if-no-files-found: error + retention-days: 1 + + publish: + needs: [ tag, build-artifact ] + if: needs.tag.outputs.should_publish == 'true' + runs-on: ubuntu-latest + # Environment-scoped OIDC: the environment's deployment branch rule + # restricts this job to refs/heads/main, and the PyPI Trusted Publisher + # binding requires this environment name — so a publish from any other + # ref or workflow is rejected end-to-end. + environment: pypi-production + permissions: + id-token: write + contents: read + + steps: + # download-artifact verifies the downloaded bundle against GitHub's + # recorded digest by default (digest-mismatch: error). + - name: Download artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: python-dist + path: dist + - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 diff --git a/.github/workflows/sync-fern-artifacts.yml b/.github/workflows/sync-fern-artifacts.yml index 301b0a1..0a4a39b 100644 --- a/.github/workflows/sync-fern-artifacts.yml +++ b/.github/workflows/sync-fern-artifacts.yml @@ -20,6 +20,6 @@ jobs: sync: permissions: contents: write - uses: PhenoML/sdk-shared-actions/.github/workflows/sync-fern-artifacts.yml@1.0.2 + uses: PhenoML/sdk-shared-actions/.github/workflows/sync-fern-artifacts.yml@1.0.3 with: spec-path: src/phenoml/openapi/openapi.json