Dashboard › publish › Distillation
f1d892f7-5d27-4929-8cfa-198b20b71f18["lore_tm_v1_abJmbDyU-s7VcH4mLibio_yf_KuApU_fGI5kXIkdPaY","lore_tm_v1_mz_9HBQaJe-I7MvIyJyxRh8xhb8FanrC1FYhCPINZ6o","lore_tm_v1_kJhW3GvXQ2hI_kHmV3369KPXJerPfrmNlwJS8jfd6GA","lore_tm_v1_cl3pYg1xVqPVhTswaucG5-QBUw4gEOxJMPrhSmN50rs","lore_tm_v1_-jujj2Rl50kLLhBL2ZfNJYEhA44vmNAAmtC7T_4UVeY","lore_tm_v1_SwvPA6p5UGSHF01Y9GCKhvMPq0AXx8eFthIenZGmXsA"]
Date: Sep 9, 2026
src/modules/approval-attestation.js defines three base64url-encoded HTML-comment attestations: <!-- publish-approval … -->, <!-- publish-auto-approval … -->, and <!-- publish-ci-ready … -->. requestDigest({ body, labels, title }) computes SHA-256 over JSON containing the exact body, title, and dryRun status derived from a dry-run label (src/modules/approval-attestation.js:3-29).createApprovalAttestation({ actor, eventId, issue }) binds actor, stringified eventId, requestDigest, and title; createAutoApprovalAttestation({ autoApprover, issue }) binds autoApprover, requestDigest, and title; createCiReadyAttestation({ acceptedEvent, ciReadyActor, issue }) binds the accepted actor/event ID, CI-ready actor, request digest, and title (src/modules/approval-attestation.js:31-56).parseAttestation(body, prefix) finds the first matching prefix and subsequent " -->", base64url-decodes and JSON-parses the payload, and returns null for absent/malformed content. parseApprovalAttestation, parseAutoApprovalAttestation, and parseCiReadyAttestation require their respective fields to be strings (src/modules/approval-attestation.js:58-127).compareEventIds(left, right) normalizes leading zeroes, rejects nondecimal IDs with Invalid issue event ID, then compares numeric-string length and lexicographic order. currentLabeledEvent(events, labelName) selects the greatest valid event ID among matching labeled events with an actor login, returning { actor, eventId }; malformed IDs cause it to return null. currentAcceptedEvent() and currentCiReadyEvent() specialize it for accepted and ci-ready (src/modules/approval-attestation.js:129-174).src/modules/approval-attestation.js accepts only comments authored by the supplied attestationAuthor: hasApprovalAttestation() matches the live event actor/event ID plus request digest/title; hasAutoApprovalAttestation() matches autoApprover plus request digest/title; hasCiReadyAttestation() matches accepted actor/event ID, CI-ready actor, request digest, and title (src/modules/approval-attestation.js:176-242).src/modules/approval-authorizer.js allows repository permission roles write, maintain, and admin. It defines AUTO_APPROVAL_LABELER = "sentry-internal-app[bot]" and AUTO_APPROVERS = new Set(["getsantry[bot]", "sentry-release-bot[bot]"]) (src/modules/approval-authorizer.js:1-5).isAutoApprovedRepository({ actor, autoApprovedRepositories, issueTitle }) requires an actor in AUTO_APPROVERS, a title accepted by parsePublishTitle(), and an exact allowlist match for getsentry/${title.repo}${title.path || ""}. authorizeApproval({ actor, issueTitle, getPermission }) rejects malformed titles, auto-approver bots, and sentry-internal-app[bot]; otherwise it queries collaborator permission for owner getsentry and authorizes only write, maintain, or admin (src/modules/approval-authorizer.js:7-50).src/publish/authorize-approval.js loads auto-approve-repos.txt into a Set, dropping empty lines. GitHub requests use APPROVAL_TOKEN, Accept: application/vnd.github+json, and API version 2026-03-10; getPermission() queries repos/{owner}/{repository}/collaborators/{username}/permission, while getIssueEvents() and getIssueComments() paginate at per_page=100 until a page has fewer than 100 records (src/publish/authorize-approval.js:14-107).authorize-approval.js requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY. For an acceptance event by sentry-internal-app[bot], it concurrently fetches the live issue, all issue events, and all comments, then requires: an open issue; unchanged title; requester in AUTO_APPROVERS; exact auto-approved repository/path; current accepted event actor equal to sentry-internal-app[bot]; and a matching auto-approval attestation authored by github-actions[bot] (src/publish/authorize-approval.js:109-172).authorize-approval.js calls authorizeApproval() using APPROVAL_ACTOR and APPROVAL_ISSUE_TITLE. Before producing proof, it refetches the live issue/events when needed and rejects unless the issue remains open with the exact title, has a string requester, is not case-insensitively self-approved by the actor, has a current accepted event, and that event’s actor equals the approval actor. Success writes authorized=true and approval_attestation=… to GITHUB_OUTPUT; rejection writes authorized=false (src/publish/authorize-approval.js:173-223).src/publish/current-accepted-event.js defines getCurrentAcceptedEvent(), which fetches all issue events, derives currentAcceptedEvent(), and throws The issue has no current accepted label event when absent. Its CLI requires APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY, uses getAllPages({ resource: "events" }), and writes the event as JSON to stdout (src/publish/current-accepted-event.js:1-48).src/publish/record-auto-approval-attestation.js fetches the live issue and requires it to remain open, retain the exact expected title, and have a requester login case-insensitively equal to autoApprover; otherwise it throws The automated approval request changed before approval. Success creates an auto-approval attestation. The CLI requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, and AUTO_APPROVER, then writes auto_approval_attestation=… to GITHUB_OUTPUT (src/publish/record-auto-approval-attestation.js:7-51).src/publish/record-ci-ready-attestation.js obtains the authenticated App login from GitHub’s user endpoint and rejects a failed response or a non-string login. recordCiReadyAttestation() concurrently fetches the live issue, all events, and authenticated login; it requires the issue to remain open with the exact title, currently contain the accepted label, and have a current accepted-label event. When expectedAcceptedEvent is supplied, both actor and event ID must exactly match; otherwise it throws The approval changed before CI could be marked ready (src/publish/record-ci-ready-attestation.js:12-59).record-ci-ready-attestation.js CLI requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, and APPROVAL_ISSUE_TITLE. It constructs expectedAcceptedEvent only when both EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID are present, fetches all event pages via getAllPages({ resource: "events" }), and writes ci_ready_attestation=… to GITHUB_OUTPUT (src/publish/record-ci-ready-attestation.js:61-95).