Dashboard › publish › Distillation
7919da0b-7e57-411e-bf24-01602e4a9a28["lore_tm_v1_enhUsjaGhxPssOm_bJTGz1ExotiRls2hd_cSKhN5WrI","lore_tm_v1_tt7lHxfs238Fw0aIWnnisgTTCGb9aCR2A-Uotg7JCQI","lore_tm_v1_LsfqlSwLctHVYX0yqtiP42VYOgInNUXoNPu9-HuR8Jc","lore_tm_v1_GqoCBCcGTBieqVQ7W7Od5u54-q1BflTQiffeZfybX2s","lore_tm_v1_LYFDM9_EHXD0urfayEH2TTZp3uRrA0oD4kJVw8RRzKQ","lore_tm_v1_DPizoQLrx4hHR5Honl9UbhHl_54FEOzSDlvyJRZWtVE","lore_tm_v1_KGGj_Xtx6TWw_rMwTaDFUpf8kd60aIZkaEzq2xTXLps","lore_tm_v1_C4qXAtj8bruWk-JQpongIQU8EmPHsGI-ibBP1IhAiBQ"]
src/publish/validate-approval-attestation.js showed validateApprovalAttestation() fetches the issue, all issue events, and all comments; requires the issue to remain open with the exact issueTitle, requestDigest(issue) === expectedRequestDigest, an accepted label, a non-null currentAcceptedEvent(events), an optional exact expectedAcceptedEvent actor/event-ID match, and a matching approval attestation. When requireCiReadyAttestation is true, it additionally requires a non-null currentCiReadyEvent(events), a ci-ready label, and hasCiReadyAttestation().src/publish/validate-approval-attestation.js uses GitHub API version 2026-03-10, paginates issue events/comments with per_page=100, and requires environment variables APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, APPROVAL_ATTESTATION_AUTHOR, and EXPECTED_REQUEST_DIGEST; optional binding uses EXPECTED_ACCEPTED_ACTOR, EXPECTED_ACCEPTED_EVENT_ID, and REQUIRE_CI_READY_ATTESTATION === "true".accepted and ci-pending; failure of the final ci-ready label addition must restore ci-pending so manual or scheduled polling can retry.src/modules/__tests__/approval-attestation.js and src/modules/__tests__/ci-poller-workflow.js.yarn vitest run src/modules/__tests__/approval-attestation.js src/modules/__tests__/ci-poller-workflow.js --printConsoleTrace with Vitest v4.1.0; result was 2 failed test files, 5 failed tests, and 19 passed tests out of 24, duration 2.48s, exit code 1.rejects an accepted label after a newer unlabeled event failed at src/modules/__tests__/approval-attestation.js:87: expected null but received { actor: 'contractor', eventId: '200' }, confirming a newer revocation was ignored.fails closed on malformed accepted-label event IDs failed at src/modules/__tests__/approval-attestation.js:106: expected null but received { actor: 'contractor', eventId: '200' }, confirming malformed relevant event IDs did not invalidate the current accepted event.does not check CI when check-suite lookup fails failed at src/modules/__tests__/ci-poller-workflow.js:359: after the check-suite lookup, the workflow still invoked commit /status, paginated check-runs, created the proof comment, removed labels, added ci-ready, and posted the publication-starting comment.does not check CI when branch-head lookup fails failed at src/modules/__tests__/ci-poller-workflow.js:359: after gh api repos/getsentry/toolkit/git/ref/heads/release/1.2.3 --jq .object.sha failed, the workflow still fell back to SHA aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, queried /status and check-runs, created the proof comment, transitioned labels, and posted the publication-starting comment.restores ci-pending when the final ci-ready add fails failed at src/modules/__tests__/ci-poller-workflow.js:371: workflow status was 1 instead of expected 0, showing no successful recovery path after the failed final --add-label ci-ready.src/modules/update-issue.js showed updateIssue() runs updateTargets() and removal of the accepted label concurrently through Promise.all(). Consequently, a target-restoration failure can reject the combined operation even though authorization cleanup is intended to proceed independently.src/modules/update-issue.js function updateTargets() returns without reading or updating the issue when stateFilePath is absent or does not exist; otherwise it concurrently fetches the issue and parses the JSON state file, transforms target checkboxes using transformIssueBody(), and updates the issue body.src/modules/__tests__/update-issue.js coverage uses CRAFT_STATE_FILE_PATH=.craft-state/craft/publish-state-getsentry-sentry-c232c383e26f-21.3.1.json; verifies target restoration including - [x] github, - [ ] pypi, added - [x] lol, and added - [ ] hey; verifies no issue-body modification when the state file is absent; and verifies accepted removal still occurs without parsed publish inputs.transformIssueBody() regression in src/modules/__tests__/update-issue.js verifies target states become, in order, npm[@sentry/node] checked, aws-lambda checked, github unchecked, and previously unlisted foo checked.src/publish/__tests__/publish-workflow.js showed existing workflow invariants: 1. approval/publication is bound to the triggering issue snapshot via node src/publish/request-digest-from-event.js and exactly 4 EXPECTED_REQUEST_DIGEST references; 2. approval is revalidated after Set targets and before Publish using Craft with REQUIRE_CI_READY_ATTESTATION: "true"; 3. Craft is pinned to docker://getsentry/craft@sha256: plus a 64-character lowercase hexadecimal digest.src/publish/__tests__/publish-workflow.js activation-order test requires Mark ci-pending → Trigger CI poller → Comment on issue → Enable cron poller → Revoke stranded approval; trigger, comment, and enable steps use continue-on-error: true; revocation runs when both trigger and enable outcomes are not success, removing ci-pending and accepted.Publish using Craft → Reconcile publish issue → Report publish result → Verify publish issue reconciliation; both reconciliation sections must use if: always(), derive state from ${{ steps.publish.outcome }}, remove accepted, ci-pending, and ci-ready, close the issue with --state closed, and avoid Node.Report publish result step, if: always(), and exact outcome mapping success) status=success ;;, cancelled) status=cancelled ;;, and *) status=failure ;;, followed by node .__publish__/src/publish/post-result.js "$status"; it rejects use of cancelled().