From decf735b67e404618fc604eee165e1f84e7278a3 Mon Sep 17 00:00:00 2001 From: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> Date: Tue, 4 Aug 2026 19:04:40 +0000 Subject: [PATCH] ci(release): honor dry_run=false on manual dispatch; correct a download-artifact pin The attest and publish steps were conditioned on github.ref_type == 'tag' in addition to DRY_RUN, so a manual dispatch with dry_run=false built everything but uploaded nothing. The workflow's only triggers are tag pushes and manual dispatch, and DRY_RUN already evaluates to false on tag pushes, so the ref_type clause is redundant there and only prevented the documented dry_run=false path from working. Removing it lets a manual dispatch (still gated by the release environment approval) publish; all registry legs skip already-existing files and versions, so such a run is idempotent and can add newly supported platform wheels to 0.1.0-alpha.4 (PR #57) on PyPI. Also correct the actions/download-artifact pin in the python job to the actual v8.0.1 commit 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c (resolved from the upstream repository via the GitHub API; it is the same pin the typescript and dotnet jobs use). The previously merged SHA does not exist upstream, which would make the python job fail at action resolution. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> --- .github/workflows/release.yml | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8046cb3..216ab30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,13 @@ # Tag-driven release pipeline. # # Trigger: push a tag `v*` (e.g. v0.1.0-alpha.2) — one tag releases the -# spec + all five SDKs together (VERSIONING.md). Or run manually with -# dry_run=true to build everything and skip every upload. +# spec + all five SDKs together (VERSIONING.md). Or run manually: +# dry_run=true builds everything and skips attestation and every +# upload; dry_run=false performs a real publish from the selected ref +# (gated by the release environment). Every registry leg skips files +# and versions that already exist, so a non-dry dispatch is idempotent +# and can append artifacts to an already-published version (e.g. new +# platform wheels). # # Publishing setup (one-time, per registry): # PyPI — trusted publishing (OIDC): add this repo/workflow as a @@ -36,7 +41,7 @@ on: workflow_dispatch: inputs: dry_run: - description: Build and attest everything, skip all uploads + description: Build everything, skip attestation and all uploads type: boolean default: true @@ -120,7 +125,7 @@ jobs: attestations: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/download-artifact@3e5f45b2cfb9172054f4087a40e8e0b5a5461e7c # v8.0.1 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: python-* path: dist @@ -146,12 +151,12 @@ jobs: path: sdk/python artifact-name: sbom-python.spdx.json - name: Attest build provenance - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v2 with: subject-path: dist/* - name: Publish to PyPI (trusted publishing) - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1 with: packages-dir: dist @@ -179,16 +184,16 @@ jobs: path: sdk/rust artifact-name: sbom-rust.spdx.json - name: Attest build provenance - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v2 with: subject-path: sdk/rust/target/package/*.crate - name: Authenticate to crates.io (trusted publishing) - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' id: cratesio-auth uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1 - name: Publish to crates.io - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' # Idempotent: skip when this version already exists (sparse index). run: | V=$(cargo pkgid -p agent-hooks-sdk | sed 's/.*[#@]//') @@ -265,14 +270,14 @@ jobs: path: sdk/typescript artifact-name: sbom-typescript.spdx.json - name: Attest build provenance - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v2 with: subject-path: | sdk/typescript/*.tgz sdk/typescript/npm/**/*.node - name: Publish to npm (platform packages, then the loader package) - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' # OIDC trusted publishing: no token. Each package (the four # platform packages and the loader) has its own trusted # publisher on npmjs.com (repo responsibleai/agent-hooks, @@ -389,18 +394,18 @@ jobs: path: sdk/dotnet artifact-name: sbom-dotnet.spdx.json - name: Attest build provenance - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v2 with: subject-path: sdk/dotnet/dist/*.nupkg - name: Authenticate to NuGet (trusted publishing) - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' id: nuget-login uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 with: user: ${{ secrets.NUGET_USER }} - name: Publish to NuGet - if: env.DRY_RUN != 'true' && github.ref_type == 'tag' + if: env.DRY_RUN != 'true' run: dotnet nuget push dist/*.nupkg --api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate working-directory: sdk/dotnet