Dashboard › publish › Distillation
3c1d9c87-a386-4009-b60d-9794391895bd["lore_tm_v1_3UgC_9BatrhBK2mCOmfhUBfjdT7vsd3bUqG5J15ankU","lore_tm_v1_VmmMs-2l81P7E3kYYZAIPFuRVGoMQ8mGop4Lbnx3JAk","lore_tm_v1_9m-y_u70GujraEIiYPlT26b-Fe5s2uJIUDkflSSwQck","lore_tm_v1_p2lX0VfSQ_fiqBOiFclX0J7nnKNAlQtjykcue4gTz8E","lore_tm_v1_83bNzcgt05k_WP9pfS7x9VbcMbgtunl88zBfS4xCCZI","lore_tm_v1_5Ov6KtwHob3kvROZC02TtOmp3BcOcWmXV6_ACQBOPWE","lore_tm_v1_vgqc2eZpTS0Ob00NtTcxnKSu_Wo8e8exQr9hB1la6h8","lore_tm_v1_pzivqn6ZdGny7fu1hfvn6UzekND9PXTOu3EYR2hXheo","lore_tm_v1_IwEaSM0l23-hWshoKslt7hfMbXY6zjwbPOFNfKs05Bg","lore_tm_v1_cZ77tOKCeBkCcq_p0i0Sf-4hsW7RVvkuZgMFc2U8PsM","lore_tm_v1_x10c52OOfydS3hcA75Urc1yV37ep-FuPc4T3Pv14z3s","lore_tm_v1_ePkeDdusmWSUh87KZssIpn3FInEwisGnKnFv9GPpL6Y","lore_tm_v1_45jILywDDzW1c4gM3kaYo3JnOroNvPKQ6ljoREGyMuM","lore_tm_v1_3yI2jypbp2Ea_Rw3gnc-GImWvVB58-K12ZA_G76gThA","lore_tm_v1_juZ4WezN1lxasSjv8adaM0F_iREim_KqxoR6gSpzcig"]
2026-09-10
/home/byk/Code/getsentry/publish/src/modules/__tests__/ci-poller-workflow.js, a 228-line Vitest integration-style test file that extracts the shell script between "Check CI status for ci-pending issues" and "Check for remaining pending issues" from .github/workflows/ci-poller.yml./home/byk/Code/getsentry/publish/src/modules/__tests__/ci-poller-workflow.js defines INITIAL_REVISION = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and UPDATED_REVISION = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" and runs the extracted poller with stub executables for node, mktemp, and gh in a temporary PATH.node stub in ci-poller-workflow.js returns {"actor":"approver","eventId":"1"} for current-accepted-event.js, succeeds silently for validate-approval-attestation.js, and makes resolve-ci-poller-input.js return initial output, update output, or a configured nonzero exit depending on PUBLISH_REVISION and NODE_INITIAL_EXIT.gh stub in ci-poller-workflow.js logs all arguments, returns issues from GH_ISSUES, "release/1.2.3" for /check-suites, UPDATED_REVISION for /git/ref/heads/, {"state":"success","total_count":0} for /status, and {"status":"completed","conclusion":"success"} for /check-runs; for issue edit, it copies the --body-file content to CAPTURED_BODY.runPoller() in ci-poller-workflow.js supplies issue #1 titled publish: getsentry/toolkit@1.2.3, initial resolver output { repo: "getsentry/toolkit", revision: INITIAL_REVISION, version: "1.2.3" }, repository getsentry/publish, and invokes Bash as bash -e -o pipefail -c <poller script>.ci-poller-workflow.js verifies that an initial resolver exit status of 1 causes the poller to exit successfully, perform no issue edit, and create no temporary files.ci-poller-workflow.js verifies rewrite outputs with no issueBody, an empty issueBody, malformed JSON "not JSON", or non-object JSON "[]" are skipped without --body-file edits or temporary files, while the poller itself exits successfully.ci-poller-workflow.js verifies rewrite-body byte preservation using "canonical issue body\n\n": the captured body must match exactly; the issue edit must remove ci-pending and accepted; it must not add ci-ready, query /status, or leave temporary files./home/byk/Code/getsentry/publish/auto-approve-repos.txt, containing exactly 46 auto-approved entries in order: 1. getsentry/arroyo; 2. getsentry/auto-type-annotate; 3. getsentry/devenv; 4. getsentry/infra-event-notifier; 5. getsentry/jest-sentry-environment; 6. getsentry/json-schema-diff; 7. getsentry/js-source-scopes; 8. getsentry/objectstore/clients; 9. getsentry/ophio; 10. getsentry/pdb; 11. getsentry/pyo3-python-tracing-subscriber; 12. getsentry/pytest-sentry; 13. getsentry/relay/py; 14. getsentry/responses; 15. getsentry/rust-proguard; 16. getsentry/rust-sourcemap; 17. getsentry/rust-usage-accountant; 18. getsentry/script-runner; 19. getsentry/sentry-api-schema; 20. getsentry/sentry-forked-djangorestframework-stubs; 21. getsentry/sentry-forked-django-stubs; 22. getsentry/sentry-forked-jsonnet; 23. getsentry/sentry-infra-tools; 24. getsentry/sentry-kafka-management; 25. getsentry/sentry-kafka-schemas; 26. getsentry/sentry-protos; 27. getsentry/sentry-redis-tools; 28. getsentry/service-registry; 29. getsentry/skrooge; 30. getsentry/snuba-sdk; 31. getsentry/statsdproxy; 32. getsentry/status-page-list; 33. getsentry/streams/sentry_streams; 34. getsentry/symbolic; 35. getsentry/taskbroker/clients; 36. getsentry/usage-accountant; 37. getsentry/watto; 38. getsentry/sentry; 39. getsentry/snuba; 40. getsentry/vroom; 41. getsentry/relay; 42. getsentry/symbolicator; 43. getsentry/taskbroker; 44. getsentry/uptime-checker; 45. getsentry/launchpad; 46. getsentry/self-hosted./home/byk/Code/getsentry/publish/src/publish/record-auto-approval-attestation.js, a 66-line CommonJS module exporting main and recordAutoApprovalAttestation.recordAutoApprovalAttestation() fetches the live issue and rejects with "The automated approval request changed before approval" unless the issue remains open, its title equals issueTitle, requestDigest(issue) equals expectedRequestDigest, and the requester login case-insensitively equals autoApprover; on success it calls createAutoApprovalAttestation({ autoApprover, issue }).record-auto-approval-attestation.js requires environment variables GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, AUTO_APPROVER, and EXPECTED_REQUEST_DIGEST; it appends auto_approval_attestation=${attestation}\n to GITHUB_OUTPUT./home/byk/Code/getsentry/publish/src/modules/approval-authorizer.js, a 57-line CommonJS module defining allowed repository roles "write", "maintain", and "admin"; AUTO_APPROVAL_LABELER = "sentry-internal-app[bot]"; and AUTO_APPROVERS = new Set(["getsantry[bot]", "sentry-release-bot[bot]"]).isAutoApprovedRepository() returns false unless actor is in AUTO_APPROVERS and parsePublishTitle(issueTitle) succeeds; it then checks membership of getsentry/${title.repo}${title.path || ""} in autoApprovedRepositories.authorizeApproval() returns { authorized: false, repository: null } for an invalid title; returns unauthorized for actors in AUTO_APPROVERS or actor sentry-internal-app[bot]; otherwise requests the actorβs permission for owner getsentry and authorizes only role_name values "write", "maintain", or "admin"./home/byk/Code/getsentry/publish/src/publish/authorize-approval.js, a 249-line CommonJS authorization entry point.getAutoApprovedRepositories() reads auto-approve-repos.txt, splits on /\r?\n/, removes empty lines, and returns a Set.getGitHubResponse(path) calls https://api.github.com/${path} with Accept: "application/vnd.github+json", bearer token APPROVAL_TOKEN, and "X-GitHub-Api-Version": "2026-03-10".getPermission() queries repos/<owner>/<repository>/collaborators/<username>/permission with URL-encoded components and throws Could not retrieve ${username}'s permission for ${owner}/${repository}: GitHub returned ${response.status} on failure.getIssue() queries repos/${repository}/issues/${issueNumber}; getIssueEvents() paginates /events?per_page=100&page=${page}; and getIssueComments() paginates /comments?per_page=100&page=${page}, stopping when a page has fewer than 100 entries.authorize-approval.js requires GITHUB_OUTPUT, APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, and EXPECTED_REQUEST_DIGEST; it reads the actor from APPROVAL_ACTOR and title from APPROVAL_ISSUE_TITLE.AUTO_APPROVAL_LABELER, authorize-approval.js concurrently fetches the live issue, events, and comments, then authorizes only when the issue is open, title and request digest match the bound snapshot, requester is one of AUTO_APPROVERS, the title resolves to an entry in auto-approve-repos.txt, the current accepted event actor is the labeler, and hasAutoApprovalAttestation() validates an attestation by github-actions[bot] for that requester and issue.authorize-approval.js delegates to authorizeApproval({ actor, issueTitle, getPermission, autoApprovedRepositories }); if authorization fails, it appends authorized=false\n to GITHUB_OUTPUT.authorize-approval.js revalidates that the issue remains open, its title and request digest match, requester is a string, an ordinary actor is not the requester case-insensitively, a current accepted event exists, and its actor equals the approving actor; failure appends authorized=false\n.createApprovalAttestation({ actor: event.actor, eventId: event.eventId, issue }) and appends authorized=true\napproval_attestation=${attestation}\n to GITHUB_OUTPUT./home/byk/Code/getsentry/publish/src/modules/post-workflow-details.js, a 19-line module whose postWorkflowDetails({ context, octokit }) fetches the current workflow run and comments on the triggering issue with Publishing: [run#${run_id}](${workflowInfo.html_url})./home/byk/Code/getsentry/publish/src/modules/process-end-state.js, a 119-line module that posts a final issue comment, closes the issue only for status "success", and reports the release session to Sentry.githubIssueComment() in process-end-state.js maps "failure" to Failed to publish. and "cancelled" to Publish workflow cancelled., each linking to ${workflowInfo.html_url}?check_suite_focus=true#step:8 and offering a branch-deletion link at https://github.com/getsentry/${repo}/branches/all?query=${encodeURIComponent(version)}; "success" produces Published successfully: [run#${run_id}](${workflowInfo.html_url}); unknown statuses throw Unknown status: '${status}'.reportSession() initializes Sentry with dsn: process.env.SENTRY_DSN and release ${details.repo}@${details.version}, tags repository, stores issue_number and full inputs in release context, captures a status-specific message/severity, starts and ends a session, and awaits Sentry.close().sentryInfoFromDetails() maps statuses as follows: "failure" β message Release failed: ${repo}, severity "error", session status "crashed"; "cancelled" β Release cancelled: ${repo}, severity "warn", status "crashed"; "success" β Release succeeded: ${repo}, severity "info", status "ok"; unknown statuses throw./home/byk/Code/getsentry/publish/src/publish/post-workflow-details.js, an 8-line entry point that obtains github.context, creates an Octokit client using getGitHubToken(), and calls postWorkflowDetails({ context, octokit })./home/byk/Code/getsentry/publish/src/publish/post-result.js, an 11-line entry point that parses process.env.PUBLISH_ARGS, takes status from process.argv.slice(2)[0], and calls processEndState({ context, octokit, inputs, status })./home/byk/Code/getsentry/publish/src/libs/github.js, a 19-line module whose getGitHubToken() returns process.env.GITHUB_TOKEN or throws No "GITHUB_TOKEN" environment variable found. Please ensure the workflow is configured correctly./home/byk/Code/getsentry/publish/src/publish/__tests__/resolve-release-revision.js, a 20-line Vitest file that runs resolve-release-revision.js with PUBLISH_ARGS: "" and PUBLISH_ISSUE_BODY: ""; it expects a nonzero exit and stderr containing "Publish input must define a repository." but not "Unexpected end of JSON input"..github/workflows/publish.yml showing immutable action pinning and approval hardening: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 was added for publish code, and actions/create-github-app-token@v3 was replaced by actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1..github/workflows/publish.yml diff adds a "Bind request snapshot" step with id request-digest running node src/publish/request-digest-from-event.js, a release-bot token step using SENTRY_RELEASE_BOT_CLIENT_ID and SENTRY_RELEASE_BOT_PRIVATE_KEY with owner getsentry, authorization and attestation handling, approval validation/rejection, and "Revalidate approval attestation" before publication with APPROVAL_ATTESTATION_AUTHOR: github-actions[bot].getCiPollerInput({ title, issueBody, revision }) to getCiPollerInput({ title, issueBody, labels, revision }) and computes resolvedIssueBody as updateReleaseRevision({ issueBody, repo, revision }) when revision is present, otherwise retaining issueBody./home/byk/Code/getsentry/publish/src/publish/resolve-location.js, a 25-line entry point that parses PUBLISH_ARGS || "{}" and CRAFT_WORKSPACE_NAMES || "[]", rejects non-array workspace discovery with "Craft workspace discovery returned an invalid workspace list.", and writes output "result" as JSON from resolvePublishLocation({ path: input.path, workspaceNames }).(?!...); the error recommended enabling PCRE2 with --pcre2.uses: references: .github/workflows/test.yml lines 19 actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803, 20 actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38, and 23 actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830; .github/workflows/publish.yml lines 36 checkout d23441a48e516b6c34aea4fa41551a30e30af803, 42/56/155/262 create-github-app-token bcd2ba49218906704ab6c1aa796996da409d3eb1, 198/268 checkout 3d3c42e5aac5ba805825da76410c181273ba90b1, 234 setup-node 249970729cb0ef3589644e2896645e5dc5ba9c38, and 367 docker://getsentry/craft@sha256:9a4a5d5efa44a00c2215078ead39800d4aaa5a97908b94f45a64d7d506d6e14b; .github/workflows/ci-poller.yml line 49 checkout d23441a48e516b6c34aea4fa41551a30e30af803 and lines 61/72/435 create-github-app-token bcd2ba49218906704ab6c1aa796996da409d3eb1; .github/workflows/auto-approve.yml line 18 checkout 11d5960a326750d5838078e36cf38b85af677262 and line 23 create-github-app-token bcd2ba49218906704ab6c1aa796996da409d3eb1.