Dashboard › publish › Distillation
49f319e9-d763-43e5-ba8d-5e4b44c8c811["lore_tm_v1_xvFkB2R-Bu9PpTjArOS_zvv3mPPXIcKkmNJUz_HzvaQ","lore_tm_v1__mA4oU0BKt6VAMTFQeV8lwm8pIxL7Pgvj6xEt7MGhms","lore_tm_v1_RYvGpWzp2LRXRflE2BKgf1h0IEJOOIKw1tTonokbipY","lore_tm_v1_NQpJUZWbMaL08carIoyaCgx4iBxJmPOVAPoxOFd0FAw","lore_tm_v1_57cKYmSNXLw0XdNHakTpknN1VP9izewtyQrR5cl8DmA","lore_tm_v1_lfzoQF-prVpl7EWo0HP6RBN7mEgKHVZ74xwoaVWsQNU","lore_tm_v1_1hjr3RaK7PePgHKgz93HnxQi-SN-omjNFgN6QkeuocY","lore_tm_v1_D166hvrFG3lgKAU15VKmnMfOBQ245Squtz3NrlWfLBg","lore_tm_v1_fEsYzfIdBVS0fy1U5w6Qs3uEK1B3YavwiVzKEit0Pb8","lore_tm_v1_4Fts06vd4teQccCPOX6L50Arb_Rl7Jr0u0j5NIwSwKE","lore_tm_v1_8dPTBVntuh7V3Uy8u4dbUqr2BAgmo_oHpr6nS5dlhtY","lore_tm_v1_WfjThzXjgO2dSV1j7FA4wAlTAirctcG7T2_o8xHLO-o","lore_tm_v1_x6YoZ1j3rW37q-1dwj8_gnLwVEqWaJ3HJu2w19bnVpY","lore_tm_v1_RCQM1xEfomOmYQ62J-jzBBX64zXlTXPTjOU4NAF3Ruk","lore_tm_v1_chyc733aLgaPvo94QD3pu6eHxb5E3DfL-PoDT4EsSOM","lore_tm_v1__tS02KEJDzDTAc2t6vh59HoKbvyns_9pjCCIgPI-gCY"]
Date: Sep 8, 2026
.github/workflows/auto-approve.yml runs on newly opened issues only, with contents: read and issues: write; its auto-approve job runs only when github.actor is sentry-release-bot[bot] or getsantry[bot] and the issue title begins publish: .auto-approve-repos.txt using actions/checkout@v4 with sparse-checkout-cone-mode: false, then creates an internal-app token via actions/create-github-app-token@v3 using vars.SENTRY_INTERNAL_APP_ID and secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY.accepted, .github/workflows/auto-approve.yml executes 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 AUTO_APPROVAL_ATTESTATION as a github-actions[bot] comment using gh issue comment "$ISSUE_URL" --body "$AUTO_APPROVAL_ATTESTATION".ISSUE_TITLE using sed -n 's/^publish: \(.*\)@.*/\1/p'; only an exact line match in auto-approve-repos.txt results in gh issue edit "$ISSUE_URL" --add-label accepted, authenticated with the internal-app token.src/modules/approval-attestation.js encodes three HTML-comment attestation types as base64url JSON: <!-- publish-approval ... -->, <!-- publish-auto-approval ... -->, and <!-- publish-ci-ready ... -->; malformed/missing data parses as null.requestDigest({body, labels, title}): SHA-256 of JSON containing the issue body, title, and dryRun, where dryRun is true exactly when a label named dry-run exists. Therefore changing the issue body, title, or dry-run state invalidates existing attestations.actor, stringified eventId, requestDigest, and title; auto-approval attestations contain autoApprover, requestDigest, and title; CI-ready attestations contain acceptedActor, stringified acceptedEventId, ciReadyActor, requestDigest, and title.currentLabeledEvent() in src/modules/approval-attestation.js considers only GitHub issue events with event === "labeled", matching label.name, a string/number id, and actor.login; it selects the greatest numeric ID. compareEventIds() normalizes leading zeroes, compares arbitrary-length decimal IDs by length then localeCompare, and throws Invalid issue event ID for non-decimal IDs. currentAcceptedEvent() and currentCiReadyEvent() respectively select the latest accepted and ci-ready label events.hasApprovalAttestation(), hasAutoApprovalAttestation(), and hasCiReadyAttestation() require a matching trusted comment author and exact identity/request-binding fields. CI-ready validation additionally binds both the latest accepted event and the latest ci-ready label actor, preventing a CI-ready proof from being reused after re-approval or relabeling by a different actor.src/modules/approval-authorizer.js permits human approvals only for target-repository roles write, maintain, or admin; none, read, triage, unrecognized roles, and malformed publish titles are unauthorized.getsantry[bot] and sentry-release-bot[bot] (AUTO_APPROVERS) and requires the parsed release path—including any package/path suffix—to exactly match an allowlisted auto-approve-repos.txt entry such as getsentry/sentry-javascript; it does not query repository permissions for these bots.sentry-internal-app[bot] is AUTO_APPROVAL_LABELER: authorizeApproval() always rejects it as a direct approver, while src/publish/authorize-approval.js authorizes its accepted label only after live verification that the issue is open and title-stable, requester is an allowed auto-approver, release path is allowlisted, the latest accepted event actor is the internal app, and github-actions[bot] posted a matching auto-approval attestation.src/publish/authorize-approval.js paginates issue events and comments in pages of 100 through GitHub API version 2026-03-10, authenticated by APPROVAL_TOKEN; errors retrieving issues, events, comments, or permissions throw with GitHub response status.authorize-approval.js checks parsed title and target-repository permission, then fetches the live issue and latest accepted event. It rejects closed or retitled issues, missing/non-string requester, self-approval case-insensitively, absent accepted event, or latest accepted label not authored by the acting approver. On authorization it writes authorized=true and request-bound approval_attestation to GITHUB_OUTPUT; otherwise it writes authorized=false.src/publish/current-accepted-event.js retrieves all events pages through getAllPages() and emits JSON {actor,eventId} for the latest valid accepted label; it errors The issue has no current accepted label event if none exists. Required environment variables are APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY.src/publish/record-auto-approval-attestation.js fetches the live issue before attesting and errors The automated approval request changed before approval unless it is open, title-stable, and its requester matches AUTO_APPROVER case-insensitively; it writes auto_approval_attestation to GITHUB_OUTPUT.src/publish/record-ci-ready-attestation.js obtains the authenticated GitHub login from GET /user, then creates a CI-ready proof only if the issue remains open and title-stable, still has the accepted label, has a valid latest accepted event, and—when supplied—matches EXPECTED_ACCEPTED_ACTOR plus EXPECTED_ACCEPTED_EVENT_ID. It otherwise errors The approval changed before CI could be marked ready.ciReadyActor, writes ci_ready_attestation to GITHUB_OUTPUT, and uses APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, and APPROVAL_ISSUE_TITLE; expected accepted-event inputs are optional.src/publish/validate-approval-attestation.js requires a live open, title-stable issue with accepted label; latest accepted event matching any expected actor/event ID; and a matching standard approval attestation by APPROVAL_ATTESTATION_AUTHOR. When REQUIRE_CI_READY_ATTESTATION === "true", it additionally requires current ci-ready label/event and matching CI-ready attestation bound to that accepted event and CI-ready actor.validate-approval-attestation.js fetches issues, events, and comments with complete pagination (per_page=100), GitHub API version 2026-03-10, and APPROVAL_TOKEN; invalid validation exits with The current accepted label has no matching approval attestation.src/modules/__tests__/approval-attestation.js cover: selecting accepted event "200" over "100"; accepting numeric GitHub event ID 29503999078; binding CI-ready proofs to accepted event and CI-ready label actor; rejecting malformed base64, untrusted comment authors, stale title/event proofs; and invalidating approval when dry-run state changes.src/modules/__tests__/approval-authorizer.js cover allowlisted getsantry[bot] authorization without permission lookup; rejection outside the allowlist; authorization for human write/maintain/admin collaborators; target-repository lookup for unqualified title publish: sentry-javascript/packages/core@10.0.0; rejection of none/read/triage/Elevated Bot/undefined roles and malformed titles; and propagation of GitHub permission lookup failure.src/publish/__tests__/publish-workflow.js asserts that Revalidate approval attestation occurs after Set targets and before Publish using Craft in .github/workflows/publish.yml, includes REQUIRE_CI_READY_ATTESTATION: "true", and pins Craft as docker://getsentry/craft@sha256:[a-f0-9]{64}.src/publish/__tests__/auto-approval-workflow.js asserts record-auto-approval-attestation.js runs before --add-label accepted, proof posting uses ${{ github.token }} before labeling, and label editing uses ${{ steps.token.outputs.token }} afterward.src/publish/__tests__/ci-poller-workflow.js asserts .github/workflows/ci-poller.yml checks out trusted default-branch code using actions/checkout@v6 in a Get publish code step before Get auth token.src/publish/__tests__/current-accepted-event.js verifies getCurrentAcceptedEvent() returns latest accepted event {actor:"contractor",eventId:"200"} and rejects an empty event list with The issue has no current accepted label event.src/publish/__tests__/record-auto-approval-attestation.js verifies an open request by getsantry[bot] with title publish: getsentry/sentry-javascript@10.0.0 produces a parseable auto-approval proof, and a request authored by contractor is rejected.src/publish/__tests__/record-ci-ready-attestation.js verifies CI-ready proof binds accepted event {actor:"contractor",eventId:"100"} to sentry-internal-app[bot]; it rejects changed approval/title and rejects re-approval from expected event "100" to latest event "200".