Dashboard › publish › Distillation
5d603196-8791-4ecb-9d88-9d29bc7634ce["lore_tm_v1_LvsKMbiVCUZXpekftkSy-Y0F0hd66sUvEnzRGPrsVdo","lore_tm_v1_Z5drMLBjDYv_4bFDB3W_cmeHJCKt1R_7P8Ckor9st3c","lore_tm_v1_lYbqWYI22qxJXvXR2osVSnlLkmBaYq3yAUFglXG-RYE","lore_tm_v1_NqK5UnbHLNt7d4bXw8NduKbsThrqTIAL3uFeLWbPr1k","lore_tm_v1_khaPZjK3Otei-VkQxihLpKwFVUijc056pkLH8e1b8VA","lore_tm_v1_Bc9snIrfXYniKUIPEu8o0tPiBCHAc8F13BMKVnywex8","lore_tm_v1_qsHJH6ddtLgJ_smWBL4sBnmzvL6WfZu_9ZZOKKqaZt8","lore_tm_v1_8elk_Rhu-V_8lVCBr9sTIJiu-ivgTJR4BvH5tIDdK5E","lore_tm_v1_iRLgytUq0q016lqWvuf_LHAZh2Gl6PDoraW3XwtttIA"]
src/publish/__tests__/ contains 9 test files: workflow-action-pinning.js, record-auto-approval-attestation.js, publish-workflow.js, auto-approval-workflow.js, ci-poller-workflow.js, current-accepted-event.js, record-ci-ready-attestation.js, validate-approval-attestation.js, and authorize-approval.js.src/modules/details-from-context.js defines PUBLISH_TITLE_REGEX as /^publish: (?:getsentry\/)?(?<repo>[^/@]+)(?<path>\/[\w./-]+)?@(?<version>[\w.+-]+)$/; parsePublishTitle(title) returns its named groups or null.detailsFromContext({ context }) rejects missing issue context with Issue context is not defined and invalid titles with Invalid publish issue title: ${context.payload.issue.title}; it returns repo, version, optional title-derived path normalized as "." + (titleMatch.path || ""), dry_run as "1" when the dry-run label exists or "" otherwise, merge_target, and checked targets.src/modules/details-from-context.js parses merge targets with /^Merge target: (?<merge_target>[\w.\-/]+)$/m; absent matches produce merge_target="".src/modules/details-from-context.js uses TARGETS_SECTION_PARSER_REGEX=/^(?!### Targets$\s)(?: *- \[[ xX]\] \S+\s*$(?:\r?\n)?)+/m, TARGETS_PARSER_REGEX=/^\s*- \[[ x]\] (\S+)/gim, and CHECKED_TARGETS_PARSER_REGEX=/^\s*- \[x\] (\S+)/gim; only checked target IDs are returned..github/workflows/auto-approve.yml runs auto-approve non-sdks on newly opened issues in the production environment only when the actor is sentry-release-bot[bot] or getsantry[bot] and the title starts with publish: ..github/workflows/auto-approve.yml checks out only auto-approve-repos.txt using actions/checkout@11d5960a326750d5838078e36cf38b85af677262, with sparse-checkout-cone-mode: false.actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1, SENTRY_INTERNAL_APP_ID, and protected secret SENTRY_INTERNAL_APP_PRIVATE_KEY.node src/publish/record-auto-approval-attestation.js with APPROVAL_TOKEN=${{ github.token }}, issue number/repository/title, and AUTO_APPROVER=${{ github.actor }}; on success it posts ${{ steps.attestation.outputs.auto_approval_attestation }} using gh issue comment..github/workflows/auto-approve.yml extracts REPO with sed -n 's/^publish: \(.*\)@.*/\1/p' and adds accepted only when the extracted value exactly matches a line in auto-approve-repos.txt via grep -qxF.src/publish/record-ci-ready-attestation.js gets the authenticated login from GitHub endpoint user; a non-OK response throws Could not retrieve the authenticated user: GitHub returned ${response.status}, and a non-string login throws GitHub returned no authenticated user login.recordCiReadyAttestation() concurrently retrieves the current issue, all issue events, and authenticated CI-ready actor; it rejects with The approval changed before CI could be marked ready if the issue is not open, its title changed, it lacks accepted, no current accepted event exists, or that event differs from optional expectedAcceptedEvent.actor/.eventId.src/publish/record-ci-ready-attestation.js requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, and APPROVAL_ISSUE_TITLE; optional EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID are used only when both exist.ci_ready_attestation=${attestation}\n to GITHUB_OUTPUT; exported functions are getAuthenticatedLogin, main, and recordCiReadyAttestation.src/publish/__tests__/record-ci-ready-attestation.js include binds the current approval to the app that will add ci-ready and rejects an approval that changes before ci-ready is recorded; src/publish/__tests__/validate-approval-attestation.js includes rejects a manually added ci-ready label.main...origin/main [behind 1]; two reported SHA-256-like values were e6dcd42feff3f4d6d1dbfb05e7a9dc15c86a1dc370b4f257cf5257a611b9a071 and eac73c8e8d90eab94d9a3fd039cadc5195233546e8ec92cd4e10cab5786b1101..github/workflows/ci-poller-dispatch.yml, .lore.md, src/modules/__tests__/approval-attestation.js, src/modules/__tests__/approval-authorizer.js, src/modules/approval-attestation.js, src/modules/approval-authorizer.js, src/publish/__tests__/, src/publish/authorize-approval.js, src/publish/current-accepted-event.js, src/publish/record-auto-approval-attestation.js, src/publish/record-ci-ready-attestation.js, and src/publish/validate-approval-attestation.js..github/workflows/publish.yml uses issue-title concurrency ${{ github.event.issue.title }} with cancel-in-progress: false, so duplicate issues for the same repo@version share a concurrency group.waiting-for-ci job runs on accepted label events for open issues whose titles begin publish: ; it checks out trusted publish code using actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 with persist-credentials: false.waiting-for-ci obtains a release-bot token with continue-on-error: true, then runs node src/publish/authorize-approval.js with that token as APPROVAL_TOKEN, ${{ github.actor }} as APPROVAL_ACTOR, and the issue number/repository/title.authorized == 'true', waiting-for-ci posts ${{ steps.authorization.outputs.approval_attestation }} as an issue comment, then runs src/publish/validate-approval-attestation.js with ${{ github.token }} and APPROVAL_ATTESTATION_AUTHOR=github-actions[bot].waiting-for-ci to remove accepted, comment Approval is invalid or could not be verified. Re-add the accepted label to retry after resolving the issue., and exit with failure.ci-failed and ci-ready and adding ci-pending; removing ci-ready ensures a later addition generates a new labeled event.Retrying β CI was previously failed. Checking CI status now. when the event payload already contains ci-failed; otherwise it is Approved. Checking CI status on the release branch. Publishing will start automatically when CI passes.waiting-for-ci best-effort creates a poller token using CI_POLLER_APP_CLIENT_ID and protected secret CI_POLLER_APP_PRIVATE_KEY; on token success it sets repository variable CI_POLLER_HAS_PENDING to true.waiting-for-ci immediately triggers the poller with gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" -f event_type=ci-poller, using the Sentry internal app token because GITHUB_TOKEN workflow-dispatch events are suppressed..github/workflows/auto-approve.yml +21/β2; .github/workflows/ci-poller.yml +172/β23; .github/workflows/cocoapods-keepalive.yml +1/β2; .github/workflows/publish.yml +131/β8; .github/workflows/test.yml +3/β3; AGENTS.md +6/β0; README.md +3/β1; docs/key_rotation_vault_changes.md +20/β20; docs/rfc.md +5/β4; src/libs/__tests__/github.js +1/β1; src/libs/github.js +4/β2; src/modules/__tests__/details-from-context.js +21/β1; src/modules/__tests__/update-issue.js +28/β0; src/modules/details-from-context.js +14/β3; src/modules/post-workflow-details.js +2/β2; src/modules/process-end-state.js +2/β2; src/modules/update-issue.js +23/β19; src/publish/inputs.js +8/β9; src/publish/post-result.js +4/β4; src/publish/post-workflow-details.js +4/β4; and src/publish/update-issue.js +26/β7. A separate output value was 33.src/modules/approval-attestation.js defines three HTML-comment proof formats: APPROVAL_ATTESTATION_PREFIX="<!-- publish-approval ", AUTO_APPROVAL_ATTESTATION_PREFIX="<!-- publish-auto-approval ", CI_READY_ATTESTATION_PREFIX="<!-- publish-ci-ready ", all ending in ATTESTATION_SUFFIX=" -->"; payloads are JSON encoded with Base64URL.requestDigest({ body, labels, title }) rejects a non-string body or non-array labels with Invalid publish request; otherwise it computes a SHA-256 hex digest over JSON containing exact body, boolean dryRun derived from the dry-run label, and title.createApprovalAttestation() binds actor, stringified eventId, requestDigest, and title; createAutoApprovalAttestation() binds autoApprover, requestDigest, and title; createCiReadyAttestation() binds acceptedActor, stringified acceptedEventId, ciReadyActor, requestDigest, and title.parseAttestation(body, prefix) finds the first matching prefix and following -->, Base64URL-decodes and JSON-parses the enclosed payload, and returns null for missing/malformed data; parseApprovalAttestation, parseAutoApprovalAttestation, and parseCiReadyAttestation additionally require every expected field to be a string.compareEventIds(left, right) stringifies IDs, removes leading zeros while preserving zero as "0", rejects non-decimal values with Invalid issue event ID, and compares arbitrary-length IDs first by normalized length and then with localeCompare.currentLabeledEvent(events, labelName) considers only labeled events for the requested label having a string/number id and actor.login; it selects the greatest event ID using compareEventIds() and returns { actor, eventId }, or null when no eligible event exists or ID comparison fails.currentAcceptedEvent(events) delegates to currentLabeledEvent(events, "accepted"); currentCiReadyEvent(events) delegates to currentLabeledEvent(events, "ci-ready").hasApprovalAttestation() accepts only a comment by the configured attestationAuthor whose parsed proof matches the current accepted eventβs actor and event ID plus the issueβs current digest and title.hasAutoApprovalAttestation() accepts only a comment by the configured attestationAuthor whose parsed proof matches autoApprover plus the issueβs current digest and title.hasCiReadyAttestation() accepts only a comment by the configured attestationAuthor whose parsed proof matches the current accepted actor/event ID, the actor of the current ci-ready event, and the issueβs current digest and title.src/modules/approval-attestation.js exports compareEventIds, createApprovalAttestation, createAutoApprovalAttestation, createCiReadyAttestation, currentAcceptedEvent, currentCiReadyEvent, currentLabeledEvent, hasApprovalAttestation, hasAutoApprovalAttestation, hasCiReadyAttestation, parseApprovalAttestation, parseAutoApprovalAttestation, parseCiReadyAttestation, and requestDigest.