From ea10e62b545ec091d52b8bf204fe41aafd51d8d3 Mon Sep 17 00:00:00 2001 From: vvillait88 Date: Fri, 4 Sep 2026 20:42:47 -0400 Subject: [PATCH] publish: resumable by workflow_dispatch on a tag A publish that dies after the npm step (a transient Sigstore POST failure on v0.5.3 did exactly that) leaves the version on npm with no signed binaries, no release and no tap update, and a re-run of the tag's job fails at npm publish before reaching them. The workflow now takes a tag by dispatch, skips the npm step when that version is already published, uploads assets to an existing release instead of failing to create it, and reads the tag from one variable in every step. --- .github/workflows/publish.yml | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 13529f0..ddd5b71 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,6 +3,17 @@ name: Publish on: push: tags: ["v*"] + # Resume a publish that died after the npm step (a transient Sigstore or + # GitHub failure leaves the version on npm with no signed binaries, no + # release and no tap update, and a re-run of the tag's job would fail at + # `npm publish` before reaching them). Every step below is idempotent on + # what already exists, so dispatching the tag finishes what the push started. + workflow_dispatch: + inputs: + tag: + description: "Release tag to publish or resume (vX.Y.Z)" + required: true + type: string permissions: contents: write @@ -16,8 +27,12 @@ jobs: publish: runs-on: ubuntu-latest timeout-minutes: 20 + env: + RELEASE_TAG: ${{ inputs.tag || github.ref_name }} steps: - uses: actions/checkout@v7 + with: + ref: ${{ inputs.tag || github.ref_name }} - uses: oven-sh/setup-bun@v2 @@ -27,14 +42,18 @@ jobs: registry-url: "https://registry.npmjs.org" - name: Set version from tag - run: npm version "${GITHUB_REF_NAME#v}" --no-git-tag-version --allow-same-version + run: npm version "${RELEASE_TAG#v}" --no-git-tag-version --allow-same-version - run: bun install --frozen-lockfile - run: bun run build - name: Publish to npm (with provenance) run: | - VERSION="${GITHUB_REF_NAME#v}" + VERSION="${RELEASE_TAG#v}" + if [ "$(npm view "@agent-score/pay@${VERSION}" version 2>/dev/null)" = "$VERSION" ]; then + echo "@agent-score/pay@${VERSION} is already on npm; skipping publish (resumed run)" + exit 0 + fi if [[ "$VERSION" == *-* ]]; then DIST_TAG="${VERSION#*-}" DIST_TAG="${DIST_TAG%%.*}" @@ -60,7 +79,12 @@ jobs: - name: Create GitHub Release run: | - gh release create "$GITHUB_REF_NAME" --generate-notes \ + if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then + echo "release $RELEASE_TAG exists; uploading any missing assets" + gh release upload "$RELEASE_TAG" --clobber dist/bin/agentscore-pay-* + exit 0 + fi + gh release create "$RELEASE_TAG" --generate-notes \ dist/bin/agentscore-pay-darwin-arm64 \ dist/bin/agentscore-pay-darwin-arm64.bundle \ dist/bin/agentscore-pay-darwin-x64 \ @@ -77,7 +101,7 @@ jobs: - name: Update Homebrew tap env: GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} - VERSION: ${{ github.ref_name }} + VERSION: ${{ inputs.tag || github.ref_name }} if: env.GH_TOKEN != '' run: | set -euo pipefail