Dashboard › publish › Distillation
8416c59b-4d14-40b0-8ba8-ddcf85b7a2c4["lore_tm_v1_ObvEdwpsIuuK-88dC3PbZCNC3jOHme83YH5giW7F-Lw","lore_tm_v1_kRkwgrqFDuEajrO3XRMUegrSq1r99z3I7_CsOjnnmUs","lore_tm_v1_ltd0yRgB9xebKmGZNp9vp_CNBKjZKFOUV-B0YXOxgzw","lore_tm_v1_nne-QpCeZn6ulMSBHRN_VN_eTh6VPH6mSBRa6OXj3YQ","lore_tm_v1_A3E31cpBy8cBK8wRo1-MB4hTBtC8nMg1Vrg5uZDwJX4","lore_tm_v1_-X27LKbyS7y3sARtrORM9h0un-m4S72FZ0DXpO3f9D0","lore_tm_v1_rv1JUo6V4J2zs_gUDWZf8HVODaD_QN14YN0GDdpfmJo","lore_tm_v1_QRK1JMVW5eJtNBT9W4oiIx-UCaPS5qehc-9yfmkW-BU","lore_tm_v1_x-YJefqhosm605zI8rjYGdZPuxYBjGuzoHcXOGd7ACs","lore_tm_v1_lj_rNxveSU25GuGmyl9ayrb5InhjfwwlD0vQGegLgVo","lore_tm_v1_BDtbYJnTcYKqEfZRmEx922AtLZrQFQxl6d6xRKGyFVg","lore_tm_v1_opcoQPmDHAx9l2K5JTYVy--C7mAhrDV1HF8Z9mGB1fo","lore_tm_v1_trxQrn5l1VLN1QJwAOYI4l_4weuPpzUjC_44VL6xqos","lore_tm_v1_bFgQCmtTIJrtRyUBqKfsM9tIQarf8EHPUUVltr4PoXs","lore_tm_v1_Z7_nx_jKbLYvoBcZym8ZPgxOnbtZ-CPhVkwAmyXxQaU"]
Date: Aug 27, 2026
src/modules/approval-attestation.js initially defined ATTESTATION_PREFIX = "<!-- publish-approval " and ATTESTATION_SUFFIX = " -->"; createApprovalAttestation({ actor, eventId, title }) base64url-encodes JSON { actor, eventId: String(eventId), title } inside an HTML comment.src/modules/approval-attestation.js initially defined parseApprovalAttestation(body), returning null if the prefix/suffix is absent, JSON/base64url decoding fails, or decoded actor, eventId, or title is not a string.src/modules/approval-attestation.js initially defined currentAcceptedEvent(events): filters events whose label name is accepted, selects the greatest event ID using BigInt, requires event.event === "labeled" and event.actor?.login, and returns { actor, eventId: String(event.id) }; otherwise returns null.src/modules/approval-attestation.js initially defined hasApprovalAttestation({ comments, event, title, attestationAuthor }): accepts an attestation only when the comment author matches attestationAuthor and decoded actor, eventId, and title exactly match the current event and title.src/modules/__tests__/approval-authorizer.js was modified and src/modules/__tests__/approval-attestation.js was added.accepted label event, actor, and title; a later label re-addition or title mutation invalidates it, causing CI and publication to stop and remove accepted.src/modules/approval-attestation.js, src/modules/__tests__/approval-attestation.js, and src/publish/authorize-approval.js were modified; src/publish/validate-approval-attestation.js was added.accepted events invalidate approval.src/modules/approval-attestation.js was hardened: currentAcceptedEvent(events) now filters only events with event.event === "labeled", event.label?.name === "accepted", typeof event.id === "string", and event.actor?.login.src/modules/approval-attestation.js was hardened: the BigInt reduction and return in currentAcceptedEvent(events) are wrapped in try/catch, returning null for invalid/non-BigInt event IDs rather than throwing.ci-ready.src/publish/authorize-approval.js imports createApprovalAttestation and currentAcceptedEvent from ../modules/approval-attestation.js, and authorizeApproval from ../modules/approval-authorizer.js.src/publish/authorize-approval.js defines getAutoApprovedRepositories(), reading auto-approve-repos.txt as UTF-8, splitting by /\r?\n/, filtering empty lines, and returning a Set.src/publish/authorize-approval.js defines getPermission({ owner, repository, username }), calling repos/${encodeURIComponent(owner)}/${encodeURIComponent(repository)}/collaborators/${encodeURIComponent(username)}/permission; non-OK responses throw Could not retrieve ${username}'s permission for ${owner}/${repository}: GitHub returned ${response.status}.src/publish/authorize-approval.js defines getGitHubResponse(path), fetching https://api.github.com/${path} with headers Accept: "application/vnd.github+json", Authorization: Bearer ${process.env.APPROVAL_TOKEN}, and X-GitHub-Api-Version: "2026-03-10".src/publish/authorize-approval.js defines getIssue({ repository, issueNumber }) for repos/${repository}/issues/${issueNumber} and getIssueEvents({ repository, issueNumber }), which paginates repos/${repository}/issues/${issueNumber}/events?per_page=100&page=${page} until a page has fewer than 100 events.src/publish/authorize-approval.js main() requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY; missing values throw explicit errors.src/publish/authorize-approval.js calls authorizeApproval({ actor: process.env.APPROVAL_ACTOR, issueTitle: process.env.APPROVAL_ISSUE_TITLE, getPermission, autoApprovedRepositories: getAutoApprovedRepositories() }); if unauthorized, it appends authorized=false\n to GITHUB_OUTPUT.src/publish/authorize-approval.js concurrently retrieves the live issue title and all issue events, finds currentAcceptedEvent(events), and rejects authorization (authorized=false) if the live title differs from APPROVAL_ISSUE_TITLE, no valid accepted event exists, or the accepted-event actor differs from APPROVAL_ACTOR.src/publish/authorize-approval.js creates an approval attestation bound to event.actor, event.eventId, and live title, then appends authorized=true\napproval_attestation=${attestation}\n to GITHUB_OUTPUT.src/publish/authorize-approval.js executes main() only when require.main === module; errors are logged via console.error(error) and set process.exitCode = 1; exports are getAutoApprovedRepositories, getGitHubResponse, getIssue, getIssueEvents, getPermission, and main..github/workflows/auto-approve.yml, .github/workflows/ci-poller.yml, and .github/workflows/publish.yml; all three use vars.SENTRY_INTERNAL_APP_ID and secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY, while publish.yml additionally contains Authorize approval, node src/publish/authorize-approval.js, and Reject unauthorized approval or failed authorization.