Dashboard › publish › Distillation
94824380-f63d-4553-9bba-e56c3bca42a3["lore_tm_v1_Ec4nGQ5kc2mNxkAxsgfGEah2Kzx9K2nAt-Yiia1HPKs","lore_tm_v1__-Y4AeHD6yxkPuqIoYmZ4PMyk-0YX2bwbXezc7sel7w","lore_tm_v1_UpkwUb2S6_AYW6irGWWQJOBjvVkHGo5RhA2hRmPrE4A","lore_tm_v1_LEoATA2QjNAluovmXh9vKKrjgSjWNiF4JDsXr6zqUE0","lore_tm_v1_jW99VZwQn-v85Gz_SBRpHIFY7N94GE6FrBA88sTjDCE","lore_tm_v1_phD17eWepD1AgJzhLDDwzJrlbKtsk0207EKmrl9XM9o","lore_tm_v1_Ubta7CyA8WZTcnLeB-h2Y7tMpO_3CB-M6pDBi47dEfk","lore_tm_v1_k9ztLTOVcKGP408AD1cNHEc0YUs-OFm7KFY83IwDFz0","lore_tm_v1_vJBE_CDAdlnAYMvDC6Wwgsv3c4XSokM8GRQOEmGCw7I","lore_tm_v1_HImYE0r72LBb4V0dggM33dlo4IU-XPZpQZr03M3MCsg","lore_tm_v1__p2hVInwKk2MGJ0Gug7tH6wNgULPYT-S-R2j6ENc_CM","lore_tm_v1_b8YwyBoXY0HlSyR2vyM5cDe60jZREJoD9bHxBVfs0eM","lore_tm_v1_Z_hX3i0_McL_7B4HqdmV7vCrNCyOhJvaqj7uRXuUXbc","lore_tm_v1_V5GhD-Anz6Uj5mHqtZR9XPZwdK-5grnD53Xc-zvTC2I","lore_tm_v1__DrDNDFv5dl4zT3DIeRYpweaujWKmSIQypcApHFDAkc","lore_tm_v1_ioMjyzBJkhSvcVVFvzDvia4QPNt504jqVCwtHdl_fQo"]
Date: Sep 10, 2026
.github/workflows/ci-poller-dispatch.yml must never use repository secrets; the protected production environment must enforce that an arbitrary dispatched ref cannot add those secrets..github/workflows/ci-poller-dispatch.yml defines workflow Run CI Status Poller, triggered only by workflow_dispatch, with permissions: {}; job dispatch uses environment: production, runs on ubuntu-latest, and has one no-op step: run: ":".src/modules/approval-attestation.js defines three base64url-encoded HTML comment attestations ending in -->: approval prefix <!-- publish-approval , automatic-approval prefix <!-- publish-auto-approval , and CI-ready prefix <!-- publish-ci-ready .requestDigest({ body, labels, title }) in src/modules/approval-attestation.js rejects a non-string body or non-array labels with Invalid publish request; it computes a SHA-256 hex digest over JSON containing exact body, title, and dryRun, where dryRun is true when a label is named dry-run.actor, stringified eventId, requestDigest, and title; automatic-approval attestations record autoApprover, requestDigest, and title; CI-ready attestations record acceptedActor, stringified acceptedEventId, ciReadyActor, requestDigest, and title.parseAttestation(body, prefix) in src/modules/approval-attestation.js locates an attestation inside arbitrary comment text, base64url-decodes and JSON-parses it, and returns null for a missing prefix/suffix or malformed payload. parseApprovalAttestation(), parseAutoApprovalAttestation(), and parseCiReadyAttestation() additionally require every expected field to be a string.compareEventIds(left, right) in src/modules/approval-attestation.js compares arbitrarily large decimal issue-event IDs without numeric conversion: it stringifies values, strips leading zeros, validates digits, compares normalized lengths, then uses localeCompare; invalid IDs throw Invalid issue event ID.currentLabeledEvent(events, labelName) filters for valid labeled events matching labelName, requiring string/number id and actor.login, then returns the event with the greatest ID as { actor, eventId }; malformed IDs or no matching events return null. currentAcceptedEvent() selects accepted, and currentCiReadyEvent() selects ci-ready.hasApprovalAttestation(), hasAutoApprovalAttestation(), and hasCiReadyAttestation() in src/modules/approval-attestation.js only trust comments authored by the supplied attestationAuthor and require attested identities/events, current request digest, and exact issue title to match; CI-ready validation binds both the accepted event and the actor who added ci-ready.src/modules/approval-authorizer.js allows manual approval only for GitHub repository roles write, maintain, or admin. AUTO_APPROVAL_LABELER is sentry-internal-app[bot]; AUTO_APPROVERS are exactly getsantry[bot] and sentry-release-bot[bot].isAutoApprovedRepository() in src/modules/approval-authorizer.js requires the actor to belong to AUTO_APPROVERS, requires a valid publish title, and checks getsentry/${title.repo}${title.path || ""} against autoApprovedRepositories. authorizeApproval() rejects invalid titles, automatic approvers, and sentry-internal-app[bot]; other actors are checked through getPermission({ owner: "getsentry", repository: title.repo, username: actor }).src/modules/details-from-context.js parses titles with PUBLISH_TITLE_REGEX: ^publish: (?:getsentry\/)?(?<repo>[^/@]+)(?<path>\/[\w./-]+)?@(?<version>[\w.+-]+)$. detailsFromContext() returns parsed title groups plus dry_run ("1" when labeled dry-run, otherwise ""), path prefixed with ., optional merge_target parsed by ^Merge target: (?<merge_target>[\w.\-/]+)$, and checked targets from the initial checklist block.detailsFromContext() throws Issue context is not defined when issue context is absent and Invalid publish issue title: ${context.payload.issue.title} when the title does not match. Target parsing uses TARGETS_SECTION_PARSER_REGEX, TARGETS_PARSER_REGEX, and CHECKED_TARGETS_PARSER_REGEX, accepting checklist markers case-insensitively while extracting checked targets.src/modules/update-issue.js reads ${process.env.GITHUB_WORKSPACE}/__repo__/.craft-publish-${version}.json when present. transformIssueBody(craftState, issueBody) updates declared target checkboxes from craftState.published, appends any unlisted published targets, and preserves each target ID. updateIssue() optionally updates targets when inputs?.version exists and concurrently removes the accepted label.src/modules/post-workflow-details.js retrieves the current workflow run through octokit.rest.actions.getWorkflowRun() and comments Publishing: [run#${run_id}](${workflowInfo.html_url}) on the publish issue.src/modules/process-end-state.js posts end-state comments as follows: failure says Failed to publish, links run logs at ?check_suite_focus=true#step:8, and links the matching repository branch search for deletion; cancelled uses the same links with Publish workflow cancelled; success posts Published successfully: [run#${run_id}](${workflowInfo.html_url}). Unknown statuses throw Unknown status: '${status}', and successful publishing closes the issue.reportSession() in src/modules/process-end-state.js initializes Sentry with dsn: process.env.SENTRY_DSN and release ${repo}@${version}, tags repository, stores issue_number and inputs in release context, captures a message, records a session, and calls Sentry.close(). Status mappings are: failure β Release failed: ${repo}, severity error, session crashed; cancelled β Release cancelled: ${repo}, severity warn, session crashed; success β Release succeeded: ${repo}, severity info, session ok.src/publish/inputs.js calls detailsFromContext({ context: github.context }) and writes the result as GitHub Actions output result.src/publish/update-issue.js obtains Octokit with getGitHubToken(), parses process.env.PUBLISH_ARGS when present, warns Could not parse publish inputs; skipping target update on invalid JSON, and calls updateIssue({ context, octokit, inputs }); direct execution catches errors and sets process.exitCode = 1.src/publish/post-result.js parses process.env.PUBLISH_ARGS, takes publishing status from the first positional CLI argument, and invokes processEndState({ context, octokit, inputs, status }). src/publish/post-workflow-details.js invokes postWorkflowDetails({ context, octokit }).getGitHubToken() in src/libs/github.js returns process.env.GITHUB_TOKEN or throws No "GITHUB_TOKEN" environment variable found. Please ensure the workflow is configured correctly.src/publish/authorize-approval.js loads exact automatic-approval repository entries from nonempty lines of auto-approve-repos.txt. GitHub API requests use https://api.github.com/, Accept: application/vnd.github+json, bearer process.env.APPROVAL_TOKEN, and X-GitHub-Api-Version: 2026-03-10.getIssueEvents() and getIssueComments() in src/publish/authorize-approval.js paginate with per_page=100&page=${page} until a page contains fewer than 100 records. getPermission(), getIssue(), event retrieval, and comment retrieval throw status-specific errors when GitHub responses are not OK.src/publish/authorize-approval.js requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY. For actor sentry-internal-app[bot], authorization requires the live issue to remain open with the expected title, its requester to be one of AUTO_APPROVERS and allowed by auto-approve-repos.txt, the current accepted event actor to equal sentry-internal-app[bot], and a matching automatic-approval attestation authored by github-actions[bot].src/publish/authorize-approval.js re-fetches live issue/event state when necessary and rejects if the issue is closed, its title changed, requester is absent, a manual approver is also the requester case-insensitively, the current accepted event is absent, or its actor differs from the approval actor. Rejection appends authorized=false; success appends authorized=true and approval_attestation=${attestation} to GITHUB_OUTPUT.src/publish/current-accepted-event.js uses paginated issue events and currentAcceptedEvent(); it throws The issue has no current accepted label event if absent and otherwise writes the event JSON to stdout. Its CLI requires APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY.recordAutoApprovalAttestation() in src/publish/record-auto-approval-attestation.js re-fetches the issue and requires it to remain open, retain the expected title, and have a requester matching autoApprover case-insensitively; otherwise it throws The automated approval request changed before approval. Its CLI requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, and AUTO_APPROVER, then emits auto_approval_attestation.getAuthenticatedLogin() in src/publish/record-ci-ready-attestation.js requests GitHub API resource user, throws a status-specific error for a failed response, and requires a string login, otherwise throwing GitHub returned no authenticated user login.recordCiReadyAttestation() in src/publish/record-ci-ready-attestation.js concurrently retrieves the live issue, all issue events, and authenticated CI-ready actor. It requires the issue to remain open with the expected title and an accepted label, requires a current accepted event, andβwhen suppliedβrequires exact equality with expectedAcceptedEvent.actor and expectedAcceptedEvent.eventId; a mismatch throws The approval changed before CI could be marked ready.record-ci-ready-attestation.js CLI requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, and APPROVAL_ISSUE_TITLE. It constructs an expected accepted event only when both EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID are set, then emits ci_ready_attestation to GITHUB_OUTPUT.