From d538d4682382191fd7a569143696b7f36e3dfe9c Mon Sep 17 00:00:00 2001 From: Michael D'Angelo Date: Fri, 18 Sep 2026 12:45:44 -0700 Subject: [PATCH] ci: isolate release checkouts and validate package builds --- .github/workflows/release-please.yml | 31 +++++++++++++++++++++------- AGENTS.md | 13 ++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index d9523eb..90edf0e 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -41,34 +41,48 @@ jobs: build: if: | - inputs.tag != '' || - needs.release-please.outputs.release_created == 'true' + !cancelled() && + (github.event_name == 'pull_request' || + (needs.release-please.result == 'success' && + (inputs.tag != '' || needs.release-please.outputs.release_created == 'true'))) needs: release-please runs-on: ubuntu-latest permissions: contents: read + defaults: + run: + working-directory: package-source steps: - name: Check out publishing tool requirements from the workflow revision uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: ref: ${{ github.workflow_sha }} + path: publishing-tools persist-credentials: false sparse-checkout: .github/requirements-twine.txt sparse-checkout-cone-mode: false - name: Save publishing tool requirements for historical tags - run: cp .github/requirements-twine.txt "$RUNNER_TEMP/requirements-twine.txt" + working-directory: ${{ github.workspace }} + run: cp publishing-tools/.github/requirements-twine.txt "$RUNNER_TEMP/requirements-twine.txt" - - name: Check out the release tag + - name: Check out the package source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: - ref: ${{ needs.release-please.outputs.tag_name }} + ref: ${{ github.event_name == 'pull_request' && github.sha || needs.release-please.outputs.tag_name }} + path: package-source persist-credentials: false + - name: Verify the package source and publishing tool requirements are available + run: | + test -f pyproject.toml + test -f "$RUNNER_TEMP/requirements-twine.txt" + - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0 with: version: "0.12.17" enable-cache: auto + working-directory: package-source - name: Pin Python version run: uv python pin 3.12 @@ -94,6 +108,7 @@ jobs: run: uvx --from twine --constraints "$RUNNER_TEMP/requirements-twine.txt" twine check --strict dist/* - name: Verify package version matches release tag + if: github.event_name != 'pull_request' env: TAG: ${{ needs.release-please.outputs.tag_name }} run: | @@ -112,13 +127,13 @@ jobs: uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: dist - path: dist/ + path: package-source/dist/ if-no-files-found: error publish-pypi: if: | - inputs.tag != '' || - needs.release-please.outputs.release_created == 'true' + github.event_name != 'pull_request' && + (inputs.tag != '' || needs.release-please.outputs.release_created == 'true') needs: [build, release-please] runs-on: ubuntu-latest environment: diff --git a/AGENTS.md b/AGENTS.md index e9496d2..569da0e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -147,16 +147,17 @@ Tests run on multiple Python versions (3.10, 3.14) and OSes (Ubuntu, Windows), w ### Release Workflow (`.github/workflows/release-please.yml`) -Triggered on push to main: +Triggered on pushes to main, manual tag republishing, and PRs that change the release workflow or its configuration: -1. **release-please job**: Creates/updates release PR -2. **build job**: (on release PR merge) - - Builds Python package with `uv build` - - Verifies package version matches release +1. **release-please job**: Creates or updates release PRs on pushes to main +2. **build job**: Runs for releases, manual republishing, and the matching PRs + - Runs unit tests and builds the Python package with `uv build` + - Checks distribution metadata and verifies the package version against the tag for releases - Uploads build artifacts -3. **publish-pypi job**: (on release PR merge) +3. **publish-pypi job**: Runs only for releases or manual tag republishing - Downloads build artifacts - Publishes to PyPI using OIDC (no tokens!) +4. **validate-action job**: Starts release-please in read-only mode on the matching PRs The required Python CI check must come from a `pull_request` run. If `RELEASE_PLEASE_TOKEN` is configured with access to create and update release PRs, GitHub starts those runs automatically.