From f5ce8d702faf59a0c8f68ca06cb96f241d31222b Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Thu, 16 Jul 2026 20:32:37 -0700 Subject: [PATCH] fix: support exact prepublication recovery claims (#3131) --- .github/workflows/prepublication-publish-checks.yml | 6 ++++++ .../security/prepublication-worker-workflow.test.ts | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/.github/workflows/prepublication-publish-checks.yml b/.github/workflows/prepublication-publish-checks.yml index 13bb1562..58b11c26 100644 --- a/.github/workflows/prepublication-publish-checks.yml +++ b/.github/workflows/prepublication-publish-checks.yml @@ -15,6 +15,10 @@ on: description: "Stop claiming new attempts after this many minutes" required: true default: "8" + attempt-id: + description: "Optional exact publish attempt ID for targeted recovery" + required: false + default: "" kind: description: "Optional targeted recovery kind: skill or package" required: false @@ -61,6 +65,7 @@ jobs: PREPUBLICATION_CHECK_LIMIT: ${{ inputs['batch-limit'] || '2' }} PREPUBLICATION_CHECK_MAX_JOBS: ${{ inputs['max-jobs'] || '' }} PREPUBLICATION_CHECK_MAX_RUNTIME_MINUTES: ${{ inputs['max-runtime-minutes'] || '8' }} + PREPUBLICATION_CHECK_ATTEMPT_ID: ${{ inputs['attempt-id'] || '' }} PREPUBLICATION_CHECK_KIND: ${{ inputs.kind || '' }} PREPUBLICATION_CHECK_SLUG: ${{ inputs.slug || '' }} PREPUBLICATION_CHECK_VERSION: ${{ inputs.version || '' }} @@ -88,6 +93,7 @@ jobs: --batch-limit "$PREPUBLICATION_CHECK_LIMIT" \ --max-jobs "$PREPUBLICATION_CHECK_MAX_JOBS" \ --max-runtime-minutes "$PREPUBLICATION_CHECK_MAX_RUNTIME_MINUTES" \ + --attempt-id "$PREPUBLICATION_CHECK_ATTEMPT_ID" \ --kind "$PREPUBLICATION_CHECK_KIND" \ --slug "$PREPUBLICATION_CHECK_SLUG" \ --version "$PREPUBLICATION_CHECK_VERSION" diff --git a/scripts/security/prepublication-worker-workflow.test.ts b/scripts/security/prepublication-worker-workflow.test.ts index df9cc969..d938f075 100644 --- a/scripts/security/prepublication-worker-workflow.test.ts +++ b/scripts/security/prepublication-worker-workflow.test.ts @@ -39,6 +39,10 @@ describe("pre-publication publish worker workflow", () => { schedule?: Array<{ cron?: string }>; workflow_dispatch?: { inputs?: { + "attempt-id"?: { + default?: string; + required?: boolean; + }; kind?: { default?: string; required?: boolean; @@ -76,6 +80,10 @@ describe("pre-publication publish worker workflow", () => { required: false, default: "", }); + expect(workflow.on?.workflow_dispatch?.inputs?.["attempt-id"]).toMatchObject({ + required: false, + default: "", + }); expect(workflow.on?.workflow_dispatch?.inputs?.slug).toMatchObject({ required: false, default: "", @@ -94,6 +102,7 @@ describe("pre-publication publish worker workflow", () => { "${{ vars.CONVEX_URL || vars.VITE_CONVEX_URL || 'https://wry-manatee-359.convex.cloud' }}", PREPUBLICATION_CLAWSCAN_TIMEOUT_MS: "${{ vars.PREPUBLICATION_CLAWSCAN_TIMEOUT_MS || '240000' }}", + PREPUBLICATION_CHECK_ATTEMPT_ID: "${{ inputs['attempt-id'] || '' }}", PREPUBLICATION_CHECK_LIMIT: "${{ inputs['batch-limit'] || '2' }}", PREPUBLICATION_CHECK_KIND: "${{ inputs.kind || '' }}", PREPUBLICATION_CHECK_SLUG: "${{ inputs.slug || '' }}", @@ -108,6 +117,7 @@ describe("pre-publication publish worker workflow", () => { const runStep = steps.find((step) => step.name === "Run pre-publication publish worker"); expect(runStep?.run).toContain("bun run publish:prepublication-worker"); + expect(runStep?.run).toContain('--attempt-id "$PREPUBLICATION_CHECK_ATTEMPT_ID"'); expect(runStep?.run).toContain('--kind "$PREPUBLICATION_CHECK_KIND"'); expect(runStep?.run).toContain('--slug "$PREPUBLICATION_CHECK_SLUG"'); expect(runStep?.run).toContain('--version "$PREPUBLICATION_CHECK_VERSION"');