Dashboard › publish › Distillation
78f4356a-182b-4941-9773-ae212cc31ef8["lore_tm_v1_oUXgWyZMnVyJFWckHkBRsfQ1WmyKGkR0HaPyx-Io65A","lore_tm_v1_dis31niXXC2ZByYEDqBjrMmRvyMnKdTx35jSBHokjSQ","lore_tm_v1_oQxO-mzQils_EORx-I3kJALRlGxymHUkVpy54JJNA_0","lore_tm_v1_GWZk3KHuJW8NME6CoRJWw4YeLQUyCJEahOTEr8HZSAE","lore_tm_v1_Jw6CeIw8rmMYVMns6TWH8dY_bjfMHsaqzM03auGlCiA","lore_tm_v1_VePKdeCGUb9nuS1cFtjODpGPKwcZba_raL5USX62YY4","lore_tm_v1_qJRMfaUAD8fN_9gZq2Dz9kPhrJsHYX38IgONpXg51Ow","lore_tm_v1_XjAddS0v9DQ1-JxySRWg9EDXphnDHrTy33-VAlGVGzA","lore_tm_v1_7rQOTjau7K-FepE4Vm0OmGdIREcj9_CgMNzcHYz79GU","lore_tm_v1_4CP9PZZgoFxZNzjEVD0F2VfM_Ynmd2EJheJfZeXgFXE","lore_tm_v1_hDGIIiWb73T3pjBYNLgTlat4nOqzTTZoHlXdLjO2YQA","lore_tm_v1_ITN1VvIHKKVMXMmOQ_V_omLt6xvsjcol7-WmrOqIhx4","lore_tm_v1_pRCwfnWQQhgKSy_J-lAotkotmN0v7DTB9xa876HCXxk","lore_tm_v1_8L4V3yJuAR-T1XOzEQeEoU4bGb45XSVDPSobPK1wTB8","lore_tm_v1_ANkvTP9jXpY3b_0ZJ8wA_uGSzYBXhuIhzFZxrXV-u6I","lore_tm_v1_n9JEHwf6phQqNRxzk42arei7Ct3xNzu_2lmWiZTjUYE","lore_tm_v1_DVqvx8_AXyxRnNtddZVJFE_3h6pd1zgngUMhxGYqPjw","lore_tm_v1_bSCtT_S1nuSIlGNdRAHvnaiMrcZZ5dF6zdvRZ9FrOJI","lore_tm_v1_qxu2b-AxOEe5E8x_LYALulmcceZGU_YxlKBV9gF0zig","lore_tm_v1_GF0zpS2RwrSKVP1HZSSS_XBUa2isWsxrVc56EnZFRGw"]
Date: Aug 27, 2026
ses_fbc2027dbfferQZUN0ETLQ4agz completed DO-NOT-MERGE. Critical: authorization reads the immutable accepted-label event title but only persists authorized; it never binds that title or repository to later stages. .github/workflows/ci-poller.yml and Publish then consume the mutable current issue title, enabling authorization for repository A followed by retitling and publication of repository B. Affected: .github/workflows/publish.yml:62-65,90-98,174-176, .github/workflows/ci-poller.yml:80,90-100, src/publish/authorize-approval.js:46-53.success() condition; the rejection step also relies on the possibly failed app token, leaving accepted attached. Affected .github/workflows/publish.yml:35-45,67-80..github/workflows/auto-approve.yml permits both sentry-release-bot[bot] and getsantry[bot], but labels using the internal-app token; the later labeled event identifies the app rather than the originating bot. This either rejects legitimate allowlisted automation or authorizes from the app’s repository role instead of exact trusted provenance. Affected .github/workflows/auto-approve.yml:13,20-34, .github/workflows/publish.yml:62-65, src/modules/approval-authorizer.js:2,17-21.src/modules/approval-authorizer.js:3-4, src/modules/details-from-context.js:24-26.write, maintain, or admin; triage, read, unknown, and custom roles fail closed.getsantry[bot].yarn test passed with 33 tests. Existing tests do not cover workflow-level cleanup, provenance, or title-mutation paths.workflow_dispatch must always be allowed for manual recovery..github/workflows/ci-poller.yml context: scheduled every 5 minutes (cron: "*/5 * * * *"), has check-ci, concurrency group ci-status-poller, checks only issues with both ci-pending and accepted, parses repo from current title via sed -n 's|^publish: \([^/]*/[^/@]*\).*@.*|\1|p', checks commit status and paginated check runs using a cross-repo sentry-release-bot token, adds ci-ready after CI passes, removes ci-pending, and handles CI failure by removing accepted/changing labels and commenting.joshuarli, created at 2026-08-25T20:47:45Z.src/modules/details-from-context.js parses publish titles with PUBLISH_TITLE_REGEX equivalent to /^publish: (?:getsentry\/)?(?<repo>[^/@]+)(?<path>\/[\w./-]+)?@(?<version>[\w.+-]+)$/; it derives path as "." + (titleMatch.path || ""), sets dry_run to "1" when the issue has dry-run, parses Merge target: <[\w.\-/]+>, and parses checked target IDs from the Targets section.getsantry[bot], created at 2026-08-15T17:06:41Z, with issue_author: null.chadwhitacre mentioned and subscribed at 2026-08-15T17:06:33Z; getsantry[bot] added accepted at 17:06:41Z, added ci-pending at 17:06:52Z, removed ci-pending and added ci-ready at 17:16:07Z; github-actions[bot] closed the issue at 17:18:55Z.accepted event and exact validated title; publishing will reject if that event, title, actor, or attestation no longer match, requiring fresh approval after a rename.src/modules/approval-attestation.js; modified src/modules/details-from-context.js and src/modules/approval-authorizer.js..github/workflows/publish.yml waiting-for-ci runs only for an open issue where github.event.label.name == 'accepted' and the title starts publish: . It checks out with actions/checkout@v6 and persist-credentials: false; obtains a sentry-internal-app token with actions/create-github-app-token@v3; attempts a getsentry release-bot token with continue-on-error: true; invokes node src/publish/authorize-approval.js with APPROVAL_TOKEN, APPROVAL_ACTOR: ${{ github.actor }}, and APPROVAL_ISSUE_TITLE: ${{ github.event.issue.title }}..github/workflows/publish.yml rejects when authorization does not succeed or authorized != 'true': using the internal-app GH_TOKEN, it removes accepted, comments that the actor cannot approve and must have write, maintain, or admin, then exits 1. This cleanup currently follows checkout and token creation and is vulnerable to prior-step implicit-success() skipping..github/workflows/publish.yml resets approved issues by removing ci-failed and ci-ready and adding ci-pending; it optionally enables CI_POLLER_HAS_PENDING=true with a dedicated poller app because sentry-internal-app lacks actions_variables:write, then triggers ci-poller.yml through the internal-app token.ci-ready after CI passes; waiting-for-ci removes any existing ci-ready so the fresh labeled event triggers Publish..github/workflows/publish.yml publish job runs only for an open issue on a ci-ready label event when labels include accepted and ci-ready but exclude ci-pending and ci-failed; it has timeout-minutes: 90 and SENTRY_DSN: "https://303a687befb64dc2b40ce4c96de507c5@o1.ingest.sentry.io/6183838".src/modules/approval-authorizer.js: ALLOWED_ROLE_NAMES = new Set(["write", "maintain", "admin"]); AUTO_APPROVER = "getsantry[bot]"; it imports PUBLISH_TITLE_REGEX from details-from-context.js, rejects unmatched titles with { authorized: false, repository: null }, computes repository = getsentry/<repo> and releasePath = repository + path, approves getsantry[bot] only for exact allowlisted release paths without a permission lookup, explicitly rejects non-allowlisted getsantry[bot], and otherwise calls getPermission({ owner: "getsentry", repository: title.groups.repo, username: actor }).src/publish/authorize-approval.js: getAutoApprovedRepositories() reads auto-approve-repos.txt, splits on line endings, filters blank lines, and returns a Set; getPermission() fetches https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repository)}/collaborators/${encodeURIComponent(username)}/permission with Authorization: Bearer ${process.env.APPROVAL_TOKEN} and GitHub API version "2026-03-10", throwing on non-OK responses. main() requires GITHUB_OUTPUT and APPROVAL_TOKEN, calls authorizeApproval() with APPROVAL_ACTOR and APPROVAL_ISSUE_TITLE, and appends authorized=<boolean>\n.src/modules/__tests__/approval-authorizer.js coverage: allowlisted getsantry[bot] release getsentry/sentry-javascript authorizes without lookup; non-allowlisted bot test expects rejection for allowlist getsentry/sentry-python but incorrectly expects getPermission to be called with bot username; human collaborators with write, maintain, and admin authorize; unqualified publish: sentry-javascript/packages/core@10.0.0 maps to getsentry/sentry-javascript; none, read, triage, "Elevated Bot", and undefined reject; malformed titles reject without lookup; lookup errors propagate.src/publish/__tests__/authorize-approval.js verifies exact allowlist release paths getsentry/sentry-javascript and getsentry/objectstore/clients; verifies successful contractor permission lookup against https://api.github.com/repos/getsentry/sentry-javascript/collaborators/contractor/permission with Bearer release-bot-token writes authorized=true\n; verifies a 404 permission response throws and writes no output..github/workflows/auto-approve.yml runs on opened issues only when github.actor is either sentry-release-bot[bot] or getsantry[bot] and title starts publish: . It sparse-checks out auto-approve-repos.txt, creates a sentry-internal-app token, extracts REPO with sed -n 's/^publish: \(.*\)@.*/\1/p', and adds accepted when that exact string exists in auto-approve-repos.txt.