Dashboard › publish › Distillation
977d69af-090c-48ef-85d5-65e6bc320541["lore_tm_v1_bTBOqnCoSWE7gGNrnlOvX-1EYg9MHmJxtWq6S6dYEP0","lore_tm_v1_-0SjO_JqP-Vi9plsz6yz3OJRurd5ieng7AkW-sr_hk4","lore_tm_v1_n6b6ZK0tG6VPfLhe3Qk1cKMoatFhabMkpsL8Senlz-8","lore_tm_v1_lP-TCn58OUx-9g39rRF8Cl2eIDYQc6j8IuFRdMe1OS8","lore_tm_v1_wGrJnyuU_-z46IiMgvRjMusPhC36P1ffsYyU9XdDSHk","lore_tm_v1_toL4d2IVY1FF6wVjdCj1BxFMkWOwpnlJy_Szu8OyLII","lore_tm_v1_GN2hA7eAloZr8OiMJVa6ub6wLWxolr4lgh56d0rUXfI","lore_tm_v1_1q06MfSizjslT7j-axyQPfGp02OZOAmWURJqJmAdthc","lore_tm_v1_7JfYczZP_BGCGuyRc1Q5onlyj2_LdyrH91Ju2ZPm1QY","lore_tm_v1_6uFZjnsYU2qj3xVrJbef1QE5mjDj_50sW62rzJ5LLkc","lore_tm_v1_PgfCAACyIn_YxSDXUIG6RUAKCjmxSMxH-bXvgzFYYpg"]
src/publish/validate-approval-attestation.js defines getGitHubResponse(path), which fetches https://api.github.com/${path} with Accept: application/vnd.github+json, Authorization: Bearer ${process.env.APPROVAL_TOKEN}, and X-GitHub-Api-Version: 2026-03-10.src/publish/validate-approval-attestation.js, getIssue({ repository, issueNumber }) retrieves repos/${repository}/issues/${issueNumber} and throws Could not retrieve issue #${issueNumber}: GitHub returned ${response.status} on a non-OK response.src/publish/validate-approval-attestation.js, getAllPages({ repository, issueNumber, resource }) requests repos/${repository}/issues/${issueNumber}/${resource}?per_page=100&page=${page}, accumulates records, stops when a page contains fewer than 100 records, and throws an error naming the resource, issue number, and GitHub status on failure.validateApprovalAttestation() in src/publish/validate-approval-attestation.js concurrently fetches the live issue, all issue events, and all issue comments, then derives event with currentAcceptedEvent(events) and ciReadyEvent with currentCiReadyEvent(events).validateApprovalAttestation() requires the issue to be open, retain the exact expected title, currently have an accepted label, have a non-null current accepted event, match both actor and eventId when expectedAcceptedEvent is supplied, and satisfy hasApprovalAttestation({ attestationAuthor, comments, event, issue }).requireCiReadyAttestation is false, validateApprovalAttestation() immediately returns the base approval result.requireCiReadyAttestation is true, validateApprovalAttestation() additionally requires a non-null current CI-ready event, a live ci-ready label, and hasCiReadyAttestation({ acceptedEvent: event, attestationAuthor, comments, ciReadyEvent, issue }).src/publish/validate-approval-attestation.js requires APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, and APPROVAL_ATTESTATION_AUTHOR; a missing value throws No "<NAME>" environment variable found.src/publish/validate-approval-attestation.js, expectedAcceptedEvent is constructed only when both EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID are present, preserving their exact string values as { actor, eventId }; requireCiReadyAttestation is enabled only when REQUIRE_CI_READY_ATTESTATION === "true".validateApprovalAttestation() returns false, main() throws The current accepted label has no matching approval attestation.src/publish/validate-approval-attestation.js exports getAllPages, getGitHubResponse, getIssue, main, and validateApprovalAttestation; direct execution logs errors with console.error() and sets process.exitCode = 1.src/modules/__tests__/approval-attestation.js tests that currentAcceptedEvent() chooses the latest accepted label event (eventId: "200" over "100") and that a matching attestation authored by github-actions[bot] is trusted.src/modules/__tests__/approval-attestation.js tests that numeric GitHub issue-event ID 29503999078 is normalized to string eventId: "29503999078".src/modules/__tests__/approval-attestation.js tests CI-ready attestation binding: an attestation for accepted event { actor: "contractor", eventId: "200" } and ciReadyActor: "sentry-internal-app[bot]" validates against a CI-ready event by that bot, but fails for accepted event ID "201" or CI-ready actor "contractor".src/modules/__tests__/approval-attestation.js tests rejection of attestations with an untrusted comment author, stale event/request data, or malformed payload <!-- publish-approval not-base64 -->.src/modules/__tests__/approval-attestation.js tests that changing a request from non-dry-run to a dry-run-labeled issue changes requestDigest() and invalidates the prior approval attestation.src/modules/__tests__/approval-authorizer.js tests that direct approvals by getsantry[bot] and sentry-release-bot[bot] are rejected without a target-repository permission lookup.src/modules/__tests__/approval-authorizer.js tests that getsantry[bot] is rejected when getsentry/sentry-javascript is absent from the auto-approval allowlist, even if a permission lookup mock would return role_name: "write"; the lookup must not run.src/modules/__tests__/approval-authorizer.js tests that target-repository roles write, maintain, and admin authorize contractor, while none, read, triage, Elevated Bot, and undefined do not.src/modules/__tests__/approval-authorizer.js tests that title publish: getsentry/sentry-javascript@10.0.0 resolves to getsentry/sentry-javascript and calls getPermission({ owner: "getsentry", repository: "sentry-javascript", username: "contractor" }).src/modules/__tests__/approval-authorizer.js tests that unqualified title publish: sentry-javascript/packages/core@10.0.0 resolves against getsentry/sentry-javascript.src/modules/__tests__/approval-authorizer.js tests that malformed titles publish: @1.0.0 and publish: getsentry/sentry-javascript return { authorized: false, repository: null } without querying GitHub, and that a getPermission() failure such as Not Found propagates.src/publish/__tests__/authorize-approval.js tests exact auto-approval allowlist entries getsentry/sentry-javascript and getsentry/objectstore/clients.src/publish/__tests__/authorize-approval.js tests successful manual authorization for contractor with role_name: "write" against getsentry/sentry-javascript, including the API URL https://api.github.com/repos/getsentry/sentry-javascript/collaborators/contractor/permission, token Bearer release-bot-token, and output matching authorized=true\napproval_attestation=<!-- publish-approval .+ -->\n.src/publish/__tests__/authorize-approval.js tests that requester contractor cannot approve their own release and produces exactly authorized=false\n.src/publish/__tests__/authorize-approval.js tests that an allowlisted automated request opened by getsantry[bot] can be approved by sentry-internal-app[bot] when a github-actions[bot] comment contains createAutoApprovalAttestation() proof; no collaborator lookup occurs.src/publish/__tests__/authorize-approval.js tests that the same automated approval is rejected with exactly authorized=false\n when the request-proof comment is absent.src/publish/__tests__/authorize-approval.js tests that direct approval by automated opener sentry-release-bot[bot] is rejected without any GitHub request.src/publish/__tests__/authorize-approval.js tests fail-closed behavior for a GitHub permission response with status 404: main() rejects with Could not retrieve contractor's permission for getsentry/sentry-javascript: GitHub returned 404 and writes nothing to GITHUB_OUTPUT.src/publish/__tests__/auto-approval-workflow.js verifies .github/workflows/auto-approve.yml runs node src/publish/record-auto-approval-attestation.js before --add-label accepted.src/publish/__tests__/auto-approval-workflow.js verifies the automated proof is posted using GH_TOKEN: ${{ github.token }} before the internal app adds the label using GH_TOKEN: ${{ steps.token.outputs.token }}.src/publish/__tests__/ci-poller-workflow.js verifies .github/workflows/ci-poller.yml checks out trusted code from ${{ github.event.repository.default_branch }} using a 40-character immutable actions/checkout commit before Get auth token.src/publish/__tests__/ci-poller-workflow.js verifies manual CI-poller recovery uses a protected relay: the main workflow supports repository_dispatch type [ci-poller] and successful workflow_run events from the repository default branch, but not workflow_dispatch; .github/workflows/ci-poller-dispatch.yml supports workflow_dispatch, has permissions: {}, uses environment: production, and contains neither secrets. nor repository_dispatch:.src/publish/__tests__/ci-poller-workflow.js verifies repository-dispatch attempts are validated before app-token creation using [[ "$ATTEMPT" =~ ^(0|[1-5][0-9])$ ]], default attempt '0', increment expression attempt=$((10#$ATTEMPT + 1)), and gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -.src/publish/__tests__/current-accepted-event.js tests that getCurrentAcceptedEvent() returns the latest accepted-label event { actor: "contractor", eventId: "200" } and rejects an empty event list with The issue has no current accepted label event.src/publish/__tests__/publish-workflow.js verifies .github/workflows/publish.yml places Revalidate approval attestation after Set targets and immediately before Publish using Craft, with REQUIRE_CI_READY_ATTESTATION: "true".src/publish/__tests__/publish-workflow.js verifies Craft is pinned to an immutable 64-hex-character digest matching uses: docker://getsentry/craft@sha256:[a-f0-9]{64}.src/publish/__tests__/record-auto-approval-attestation.js tests that recordAutoApprovalAttestation() binds requester getsantry[bot] to the live request publish: getsentry/sentry-javascript@10.0.0, yielding parsed fields autoApprover, requestDigest, and title.src/publish/__tests__/record-auto-approval-attestation.js tests rejection with The automated approval request changed before approval when the live author is contractor instead of getsantry[bot].src/publish/__tests__/record-ci-ready-attestation.js tests that recordCiReadyAttestation() binds accepted event { actor: "contractor", eventId: "100" } and authenticated actor sentry-internal-app[bot] to request publish: getsentry/sentry-javascript@10.0.0, producing parsed fields acceptedActor, acceptedEventId, ciReadyActor, requestDigest, and title.src/publish/__tests__/record-ci-ready-attestation.js tests rejection with The approval changed before CI could be marked ready when the live request title/current accepted event is invalid.src/publish/__tests__/record-ci-ready-attestation.js tests rejection of a re-approval when the poller expected accepted event ID "100" but the current accepted event ID is "200".validateApprovalAttestation() include rejection after the issue body changes, demonstrating that approval validation is bound to the live request digest rather than only its title/event.