Dashboard › publish › Distillation
1c90c193-a229-440b-a3ec-21e0cf1045bd["lore_tm_v1_Zclw1FzLuQ-mfeSZsDRNsDgwRHFt3nFNOzuL_zZXxos","lore_tm_v1_UTKnhriIFBEy8mUo7CWEO47tYnA86Am6mkX9XZadHvE","lore_tm_v1_G1nIvoPb4x7MBMZ1qwnHdfKmrn29xzmT0qNAgJPvXrA","lore_tm_v1_PiHTz61B8wG-ZVGO2VdZ-yg0tZl49RlxWmqv75zeH2Q","lore_tm_v1_MG0cUqF3qbRN1OacO7EyHrnAD67LvHLt2H7LCdGA8v8","lore_tm_v1_2Ey5C7vzzJLoRK3REmmI594ESpuOTwr1Giocbu_3hLE","lore_tm_v1_itBK74rtZ0JuNnDAffbeJmzApPwlynci4l1XykBrY9s","lore_tm_v1_o2UATFtiBLQ2hZ2b9ayfo7iLH32nvcmBLu6HfjwJ5r4","lore_tm_v1_0S0NL2wW0nJIyP6K79KCVH-Uw9Aq0Bnb3DArTvqAoRM","lore_tm_v1_XOR-1RaFj29IBDpvbnnpM4Ff2ko1doGPbm0JWVSicgE","lore_tm_v1_k3STuk_r-hahtDI2WmK5bbEU8Z1Ax3hFhJqPgnIT7Xc","lore_tm_v1_FwfmwGntC22wpVHBFW4hu3JJa-8icHbreDTIa_IrsZQ","lore_tm_v1__zv162_EVdhH6ZWblaZV4dei4DdkHuRx_1Sqa2h-I7E"]
Date: Aug 27, 2026
/home/byk/Code/getsentry/publish, focused on correctness, GitHub Actions event semantics, workflow failure/cleanup paths, supported title parsing, and tests. Requested severity plus exact file:line for every finding; each finding classified PASS/CONCERN/MUST-FIX; requested the review end exactly MERGE or DO-NOT-MERGE.write, maintain, or admin access to the target getsentry repository; getsantry[bot] auto-approval is allowed only for exact entries in auto-approve-repos.txt; failed checks must fail closed and remove the accepted label.trimRight() was replaced with trimEnd() in commit 4da4a25 chore: replace deprecated trimRight() with trimEnd() (#9012)./home/byk/Code/getsentry/publish contains .eslintrc.js, .git/, .github/, .gitignore, .lore.md, AGENTS.md, auto-approve-repos.txt, docs/, LICENSE, node_modules/, package.json, README.md, src/, vitest.config.js, and yarn.lock (15 entries)..github/workflows/publish.yml, AGENTS.md, src/libs/__tests__/github.js, src/libs/github.js, src/modules/post-workflow-details.js, src/modules/process-end-state.js, src/modules/update-issue.js, src/publish/inputs.js, src/publish/post-result.js, src/publish/post-workflow-details.js, and src/publish/update-issue.js; untracked .lore.md, src/modules/__tests__/approval-authorizer.js, src/modules/approval-authorizer.js, src/publish/__tests__/, and src/publish/authorize-approval.js..github/workflows/publish.yml adds actions/checkout@v6 with persist-credentials: false before authorization, creates a release-bot GitHub App token with actions/create-github-app-token@v3 using continue-on-error: true, and runs an authorization step with continue-on-error: true; the workflow is intended to remove accepted if authorization fails or steps.authorization.outputs.authorized != 'true'.src/modules/approval-authorizer.js:1-34 defines ALLOWED_ROLE_NAMES = new Set(["write", "maintain", "admin"]), AUTO_APPROVER = "getsantry[bot]", and PUBLISH_TITLE_REGEX = /^publish: (?:getsentry\/)?(?<repository>[^/@]+)(?<path>\/[^@]+)?@[^@]+$/. authorizeApproval() parses qualified or unqualified publish titles, maps them to getsentry/${repository}, permits getsantry[bot] only when exact releasePath is in autoApprovedRepositories, otherwise calls getPermission({ owner: "getsentry", repository, username: actor }), and authorizes only allowed role_name values. Malformed titles return { authorized: false, repository: null } without a lookup.src/publish/authorize-approval.js:4-10 reads auto-approve-repos.txt as UTF-8, splits on CRLF/LF, filters blank lines, and returns exact entries as a Set.src/publish/authorize-approval.js:13-35 queries GET https://api.github.com/repos/${owner}/${repository}/collaborators/${username}/permission, URL-encodes owner/repository/username, sends Accept: application/vnd.github+json, Authorization: Bearer ${process.env.APPROVAL_TOKEN}, and X-GitHub-Api-Version: 2026-03-10; non-OK responses throw Could not retrieve ${username}'s permission for ${owner}/${repository}: GitHub returned ${status}.src/publish/authorize-approval.js:38-64 requires GITHUB_OUTPUT and APPROVAL_TOKEN, invokes authorizeApproval() with APPROVAL_ACTOR, APPROVAL_ISSUE_TITLE, getPermission, and the allowlist, then appends authorized=${authorized}\n to GITHUB_OUTPUT; when executed directly, main() logs failures and sets process.exitCode = 1.auto-approve-repos.txt has 46 exact allowlist entries: getsentry/arroyo, getsentry/auto-type-annotate, getsentry/devenv, getsentry/infra-event-notifier, getsentry/jest-sentry-environment, getsentry/json-schema-diff, getsentry/js-source-scopes, getsentry/objectstore/clients, getsentry/ophio, getsentry/pdb, getsentry/pyo3-python-tracing-subscriber, getsentry/pytest-sentry, getsentry/relay/py, getsentry/responses, getsentry/rust-proguard, getsentry/rust-sourcemap, getsentry/rust-usage-accountant, getsentry/script-runner, getsentry/sentry-api-schema, getsentry/sentry-forked-djangorestframework-stubs, getsentry/sentry-forked-django-stubs, getsentry/sentry-forked-jsonnet, getsentry/sentry-infra-tools, getsentry/sentry-kafka-management, getsentry/sentry-kafka-schemas, getsentry/sentry-protos, getsentry/sentry-redis-tools, getsentry/service-registry, getsentry/skrooge, getsentry/snuba-sdk, getsentry/statsdproxy, getsentry/status-page-list, getsentry/streams/sentry_streams, getsentry/symbolic, getsentry/taskbroker/clients, getsentry/usage-accountant, getsentry/watto, getsentry/sentry, getsentry/snuba, getsentry/vroom, getsentry/relay, getsentry/symbolicator, getsentry/taskbroker, getsentry/uptime-checker, getsentry/launchpad, and getsentry/self-hosted.src/modules/__tests__/approval-authorizer.js:8-147 tests: allowlisted getsantry[bot] approval without calling getPermission; bot rejection outside allowlist with a role_name: "none" lookup; human authorization for write, maintain, and admin; unqualified publish: sentry-javascript/packages/core@10.0.0 mapped to getsentry/sentry-javascript; rejection for none, read, triage, Elevated Bot, and undefined; malformed-title rejection without GitHub queries; and permission-lookup error propagation.src/publish/__tests__/authorize-approval.js:34-86 tests exact parsing of getsentry/sentry-javascript and getsentry/objectstore/clients from the allowlist; a successful collaborator-permission lookup using Authorization: Bearer release-bot-token and output authorized=true\n; and fail-closed behavior for GitHub 404, with no output written.src/modules/details-from-context.js:24-30 currently parses publish titles with /^publish: (?:getsentry\/)?(?<repo>[^/@]+)(?<path>\/[\w./-]+)?@(?<version>[\w.+-]+)$/, supporting optional getsentry/ qualification and optional paths restricted to [\w./-]+; it derives path as "." + (titleMatch.path || "").ci-ready after passing CI, even if the label already exists, because re-adding it deliberately emits the label event that starts publishing after the waiting-for-ci race; an idempotence optimization would strand accepted releases.workflow_dispatch must always remain allowed for manual recovery, independently of the pending-work repository variable..lore.md records the intended approval-cleanup design: create the internal-app token before authorization; execute the authorizer with continue-on-error; remove accepted whenever authorizer outcome fails or authorized is not true; then fail the job. It also records that the release-bot-token step fails softly so cleanup remains possible..github/workflows/auto-approve.yml:1-35 triggers on opened issues; its auto-approve job runs only when github.actor is sentry-release-bot[bot] or getsantry[bot] and title starts publish: . It checks out auto-approve-repos.txt via actions/checkout@v4 sparse checkout, obtains an internal-app token with actions/create-github-app-token@v3, parses REPO from ISSUE_TITLE using sed -n 's/^publish: \(.*\)@.*/\1/p', and adds accepted with gh issue edit "$ISSUE_URL" --add-label accepted only if grep -qxF "$REPO" auto-approve-repos.txt matches exactly.