Dashboard › publish › Distillation
357305f5-875d-4e8f-8ce8-794ddead27f7["lore_tm_v1_yIRZNC-ynTRhXQktqCsQAocVdjiM50WigymeTewrwlE","lore_tm_v1_QUVyBnF7_PEDEv0WS1xuyIoOeZFiPXcor3sJk1uYNJ0","lore_tm_v1_OSEMuAOGbgEi-txDirlloG9Ctd2KGOAi1OoXY0CvM9k","lore_tm_v1_ZrPMrSzNjhnyx_AR7tsHhLNfKHDAfsqRGrSRlsG0w7c","lore_tm_v1_-iMFp9DBe1TsgxzB7G3xzWTmKTih2fXSe2wydms8SI4","lore_tm_v1_0uIftO6L-6lv-Tijw5s148u-UOBfBF4Nkcz2WezURuI","lore_tm_v1_QmpHJIJqsBpM6Li-veDftqSC90CN00wJwTbo_AQwkuE"]
Date: Aug 27, 2026
/home/byk/Code/getsentry/publish, with no edits permitted.MUST-FIX, HIGH, MEDIUM, LOW, CONCERN, or PASS, each with file:line, evidence, and remediation; required the report to end exactly MERGE or DO-NOT-MERGE..github/workflows/publish.yml, .github/workflows/ci-poller.yml, new approval scripts/modules, and tests, specifically auditing event/title/label binding; job/step if semantics including always(); bot identity/provenance; token availability/permissions; cleanup on all failures; issue-comment provenance; title grammar; pagination/event-ID handling; and workflow_dispatch./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/ci-poller.yml, .github/workflows/publish.yml, AGENTS.md, src/libs/__tests__/github.js, src/libs/github.js, src/modules/details-from-context.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 files include .lore.md and src/modules/approval-attestation.js..github/workflows/publish.yml has packages: write permissions and workflow logic/comments indicating the poller flips ci-pending to ci-ready; its issue-event guard includes github.event.issue.state == 'open'..github/workflows/publish.yml approval flow includes steps named Get release bot auth token, Authorize approval (id: authorization), an attestation step (id: attestation), an approval-validation step (id: approval-validation), and Reject invalid approval; validation receives APPROVAL_ISSUE_REPOSITORY: ${{ github.repository }}, APPROVAL_ISSUE_NUMBER: ${{ github.event.issue.number }}, and approval title input APPROVAL_ISSUE_TITLE: ${{ github.event.issue.title }}..github/workflows/publish.yml uses continue-on-error: true for an approval-related step and rejects approval if validation or attestation outcomes are not success; rejection edits the triggering issue with gh issue edit "${{ github.event.issue.number }}" and exits 1..github/workflows/publish.yml contains a cleanup/rejection condition if: always() && steps.approval-validation.outcome != 'success'..github/workflows/publish.yml comments indicate a label event can be missed if waiting-for-ci is added on the same event, and that the poller always adds ci-ready, guaranteeing publish.yml triggers on the happy path.src/libs/__tests__/github.js expectation was changed to exact message 'No "GITHUB_TOKEN" environment variable found.' (removed trailing comma from the expected string).src/publish/post-result.js changed module imports to double-quoted style: const processEndState = require("../modules/process-end-state");, const { getGitHubToken } = require("../libs/github");, and const github = require("@actions/github");..github/workflows/publish.yml:382-387 runs node .__publish__/src/publish/update-issue.js in step Update completed targets and remove label when if: ${{ cancelled() || failure() }}, passing PUBLISH_ARGS: ${{ steps.inputs.outputs.result }} and GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}..github/workflows/publish.yml:389-394 posts cancellation result through node .__publish__/src/publish/post-result.js cancelled when if: ${{ cancelled() }}; .github/workflows/publish.yml:396-401 posts failure through post-result.js failure when if: ${{ failure() }}; .github/workflows/publish.yml:403-408 closes on success through post-result.js success when if: ${{ success() }}. All pass PUBLISH_ARGS: ${{ steps.inputs.outputs.result }} and GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}..github/workflows/ci-poller.yml declares workflow_dispatch, sets environment: production, and has a job condition/comment explicitly allowing workflow_dispatch for manual recovery..github/workflows/ci-poller.yml creates a GitHub App token with actions/create-github-app-token@v3; comments state the sentry-internal-app token is used for label changes and that GITHUB_TOKEN cannot perform these operations..github/workflows/ci-poller.yml comments state the release bot sees all target repositories and authorizes the actorβs approval, while the poller selects issues bearing both ci-pending and accepted labels to avoid polling abandoned unapproved releases..github/workflows/ci-poller.yml:101 implements the stated invariant, βNever move a release to ci-ready after either value changes,β using APPROVAL_TOKEN="$GH_TOKEN" and approval-attestation validation before a label transition..github/workflows/ci-poller.yml parses issue titles using grammar "publish: owner/repo[/path]@version" and extracts repository and version; malformed titles with absent repo or version are handled as invalid..github/workflows/ci-poller.yml extracts an original issue commit SHA from the issue body using grep -oP '(?<=commit/)[0-9a-f]{40}(?=/checks)' || true, resolves the release branch from original-commit check data, and can retain issue_sha..github/workflows/ci-poller.yml fetches paginated check runs and explicitly flattens them because --paginate --jq applies filtering per page; it calculates pending checks with jq -s '[.[] | select(.status != "completed")] | length'..github/workflows/ci-poller.yml evaluates commit status and check completion; on success with pending_checks == "0" and unsuccessful_checks == "0", it proceeds toward ci-ready. On failure, it swaps ci-pending to ci-failed, removes accepted to stop polling, and posts a comment including failed status contexts, a View check runs URL, and instructions to re-add accepted after CI is fixed..github/workflows/ci-poller.yml updates a poller variable to match actual open issue count, uses a poller-token step, and has a variable-update condition if: always() && steps.poller-token.outcome == 'success'..github/workflows/ci-poller.yml has concurrency intended to prevent accumulation, allowing 1 running and 1 queued run, and includes retry logic using attempt=$((ATTEMPT + 1)).src/modules/approval-authorizer.js defines ALLOWED_ROLE_NAMES = new Set(["write", "maintain", "admin"]), AUTO_APPROVER = "getsantry[bot]", and imports PUBLISH_TITLE_REGEX from ./details-from-context.js.authorizeApproval({ actor, issueTitle, getPermission, autoApprovedRepositories = new Set() }) in src/modules/approval-authorizer.js:5-35 matches issueTitle against PUBLISH_TITLE_REGEX; invalid titles return { authorized: false, repository: null }.src/modules/approval-authorizer.js:17-25 constructs repository as getsentry/${title.groups.repo} and releasePath as ${repository}${title.groups.path || ""}; getsantry[bot] is authorized only if autoApprovedRepositories.has(releasePath), otherwise it is denied.src/modules/approval-authorizer.js:28-34 calls getPermission({ owner: "getsentry", repository: title.groups.repo, username: actor }) for non-bot actors, and authorizes only when returned role_name is write, maintain, or admin.