Dashboard › publish › Distillation
c87828af-d213-4991-b557-a4ee2b8e26c2["lore_tm_v1_pgM_Ld4WkZwo9_D5eAyeD7PxFysvXDUY9QGFf3cQWKs","lore_tm_v1_hZt_qOD_Yi2nUQPwRbHW5cXd3kOZOloJu9i-9dalPvg","lore_tm_v1_8iPqq6FdgCAmtUMqHyqnybHmrxq0eOz-WIR5y7Me_q8","lore_tm_v1_Nl6QR4_MC8caF1xBWZ13dDBN4CU0BZGL1AWmi8O7yKY","lore_tm_v1_ms--aLi0aGvAAyYkWJ7jp79pfN1Bd2IDBz-bpaJKkLE","lore_tm_v1_YyjQCNSeVl8XLrsBhpz4Oz_Rr7YKgra_ufpjIQ4GiVQ","lore_tm_v1_6Ld7Sau5z_XpEXTsupTp-I4ZEaLKeRwf7r-eLKNWwrc","lore_tm_v1_yCQKxqecSIRI1fXxsVKj-CxbYQdhCwrGeSYHnmu9lQA"]
/home/byk/Code/getsentry/publish/.github/workflows/ci-poller-dispatch.yml defines the manual Run CI Status Poller relay with only a workflow_dispatch trigger, permissions: {}, and one dispatch job in the protected production environment on ubuntu-latest; its sole step runs ":"..github/workflows/ci-poller-dispatch.yml; protected environment secrets enforce that an arbitrary dispatched ref cannot add them. The workflow contains no secret references./home/byk/Code/getsentry/publish/src/modules/update-issue.js defines updateTargets({ octokit, version, publishRepo, issue_number }), which reads ${process.env.GITHUB_WORKSPACE}/__repo__/.craft-publish-${version}.json; it returns without modification if that Craft state file does not exist.updateTargets() concurrently fetches the issue and reads/parses the Craft state JSON, transforms issue.body with transformIssueBody(craftState, issue.body), then updates the issue body through octokit.rest.issues.update().transformIssueBody() uses TARGETS_SECTION_PARSER_REGEX and TARGETS_PARSER_REGEX from ./details-from-context; it preserves declared target order, marks each target - [x] when craftState.published[targetId] is truthy and - [ ] otherwise, tracks declared IDs in a Set, and appends every unlisted key from craftState.published with the corresponding checkbox state.updateIssue({ context, octokit, inputs }) derives publishRepo from context.repo and issue_number from context.payload.issue.number; via Promise.all(), it conditionally calls updateTargets() when inputs?.version exists and always removes the accepted label with octokit.rest.issues.removeLabel()./home/byk/Code/getsentry/publish/src/publish/update-issue.js gets the GitHub Actions context from @actions/github, constructs Octokit with getGitHubToken(), parses process.env.PUBLISH_ARGS as JSON when present, warns Could not parse publish inputs; skipping target update on parse failure, and invokes updateIssue({ context, octokit, inputs }); top-level failures set process.exitCode = 1./home/byk/Code/getsentry/publish/src/publish/authorize-approval.js reads auto-approve-repos.txt as UTF-8, splits on /\r?\n/, removes empty lines, and returns the repository names as a Set from getAutoApprovedRepositories().getGitHubResponse(path) requests 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.getPermission() queries repos/<owner>/<repository>/collaborators/<username>/permission with each path component passed through encodeURIComponent(); non-OK responses throw Could not retrieve ${username}'s permission for ${owner}/${repository}: GitHub returned ${response.status}.getIssue() queries repos/${repository}/issues/${issueNumber} and throws on a non-OK response; getIssueEvents() and getIssueComments() paginate their respective endpoints with per_page=100&page=${page}, accumulating pages until one contains fewer than 100 records and throwing endpoint-specific errors on non-OK responses.authorize-approval.js requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, and APPROVAL_ISSUE_REPOSITORY; absence of any one throws an explicit No "<VARIABLE>" environment variable found error.actor === AUTO_APPROVAL_LABELER, approval authorization concurrently retrieves the live issue, all issue events, and all comments. Authorization requires: the issue is open; its live title equals APPROVAL_ISSUE_TITLE; its requester login is a string and belongs to AUTO_APPROVERS; isAutoApprovedRepository() accepts the requester, repository set, and title; the current accepted-label event actor equals AUTO_APPROVAL_LABELER; and hasAutoApprovalAttestation() validates a comment authored by github-actions[bot].authorize-approval.js delegates initial authorization to authorizeApproval({ actor, issueTitle, getPermission, autoApprovedRepositories }); if unauthorized, it appends authorized=false to GITHUB_OUTPUT and returns.authorize-approval.js obtains the live issue and current accepted event if they were not already loaded, then rejects authorization unless the issue remains open, its title still equals APPROVAL_ISSUE_TITLE, the requester is a string, a non-auto approver is not also the requester under case-insensitive comparison, an accepted event exists, and that eventβs actor equals the approving actor.createApprovalAttestation({ actor: event.actor, eventId: event.eventId, issue }) and appends exactly authorized=true plus approval_attestation=${attestation} to GITHUB_OUTPUT. The module exports getAutoApprovedRepositories, getGitHubResponse, getIssue, getIssueComments, getIssueEvents, getPermission, and main./home/byk/Code/getsentry/publish/src/publish/__tests__/record-ci-ready-attestation.js tests that recordCiReadyAttestation() binds the current approval to the app that will add ci-ready: for issue 123, title publish: getsentry/sentry-javascript@10.0.0, accepted actor contractor, event ID "100", and authenticated login sentry-internal-app[bot], parseCiReadyAttestation() must return acceptedActor: "contractor", acceptedEventId: "100", ciReadyActor: "sentry-internal-app[bot]", the same title, and a string requestDigest.The approval changed before CI could be marked ready: (1) the live issue title is publish: getsentry/sentry-python@10.0.0 while the expected title is publish: getsentry/sentry-javascript@10.0.0 and there is no accepted event; (2) the poller expected { actor: "contractor", eventId: "100" }, but the current accepted event has ID "200"./home/byk/Code/getsentry/publish/src/publish/__tests__/publish-workflow.js verifies that .github/workflows/publish.yml places Revalidate approval attestation after Set targets and immediately before Publish using Craft, with the remaining workflow containing REQUIRE_CI_READY_ATTESTATION: "true".publish-workflow.js also requires Craft to be pinned to an immutable image digest matching uses: docker://getsentry/craft@sha256:[a-f0-9]{64}./home/byk/Code/getsentry/publish/src/publish/__tests__/ci-poller-workflow.js verifies Get publish code uses actions/checkout@ followed by an exact 40-character lowercase hexadecimal revision, checks out ${{ github.event.repository.default_branch }}, and occurs before Get auth token.ci-poller-workflow.js verifies manual recovery is isolated to .github/workflows/ci-poller-dispatch.yml: the main poller must use repository_dispatch type ci-poller and successful default-branch workflow_run events from Run CI Status Poller, must not contain workflow_dispatch:, while the relay must contain workflow_dispatch:, permissions: {}, and environment: production but no secrets. or repository_dispatch:.ci-poller-workflow.js verifies Validate dispatch attempt appears before Get auth token, checks attempts using [[ "$ATTEMPT" =~ ^(0|[1-5][0-9])$ ]], defaults non-repository-dispatch ATTEMPT to '0', increments with attempt=$((10#$ATTEMPT + 1)), and self-dispatches via gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -./home/byk/Code/getsentry/publish/src/publish/__tests__/workflow-action-pinning.js enumerates every .yml file under .github/workflows and requires every actions/<name>@<revision> reference to use an exact 40-character lowercase hexadecimal revision.workflow-action-pinning.js rejects workflow_dispatch: in every workflow except .github/workflows/ci-poller-dispatch.yml, and separately verifies that only this protected relay contains workflow_dispatch:, permissions: {}, and environment: production while containing no secrets. reference.workflow-action-pinning.js defines protected secret-bearing jobs and requires environment: production within each named job: 1. .github/workflows/auto-approve.yml job auto-approve; 2. .github/workflows/ci-poller.yml job check-ci; 3. .github/workflows/cocoapods-keepalive.yml job keepalive; 4. .github/workflows/publish.yml jobs waiting-for-ci and publish.