Dashboard › publish › Distillation
23681b0e-664c-4b88-bde7-c45d6642e1e9["lore_tm_v1_UngR32NDI94BcKZ5H6HLKUZc9taBeoMnCSfg2dvCYPw","lore_tm_v1_4f6MScqnh-h7MS7z3VOOgDUK_KXnzvzzBdLQf6nGj9Q","lore_tm_v1_rWr7FvrkcPQhkJxd4WzQJCP0dfGRgxHAr5f3A6OJKbI","lore_tm_v1_s6HS6m47S05UqCaxzKgKUQZ3aIAVlQ-_OXnSd282iYs","lore_tm_v1_eoGEx7It0OUk55qsoGekzKt7NiWO35Gd05jisFMNpes","lore_tm_v1_Xbt3XRf9w3XN34Bp07J7z98ePfq4-aTFo9d_iMNlvdo","lore_tm_v1_G2A6Lpn3g3HZSWKNwOjBlMKBhIXA1fHU-OLrr-HNDyo","lore_tm_v1_6s-52d6ZS1ntFdIbu3Iz89H81mucAf5kP64c3yPaIqM","lore_tm_v1_YqTJvY_l8pKeQn67A5WTk7kcnIthWMoXwZfqcbvOGeM","lore_tm_v1_dnwEEjcTw9QXfMRi66x7-oGwXuaW4q8b4stsBC5TUE8"]
/home/byk/Code/getsentry/publish/.github/workflows/publish.yml, the publish job requires an open issue, a ci-ready label event, both accepted and ci-ready currently present, and neither ci-pending nor ci-failed; timeout is 90 minutes and SENTRY_DSN is configured.waiting-for-ci first removes any existing ci-ready, so a fresh labeled event fires and the publish gate is guaranteed to trigger on the happy path.publish job checks out trusted workflow contents into .__publish__ with actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 and persist-credentials: false.Validate approval attestation runs node .__publish__/src/publish/validate-approval-attestation.js with REQUIRE_CI_READY_ATTESTATION: "true" and is continue-on-error: true; failure removes accepted, posts Approval is invalid or could not be verified. Re-add the accepted label to retry after resolving the issue., and exits 1.actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 with Node 24 and Yarn caching keyed by .__publish__/yarn.lock, installs via yarn install --cwd ".__publish__", and parses inputs using node .__publish__/src/publish/inputs.js.Set target repo checkout branch allowlist requires protected target branches and currently recognizes: sentry-migr8/tmp-merge-target; sentry-javascript/v10, v9, v8, v7, or master; sentry-python/alpha; and sentry-wizard/1.x.actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1, vars.SENTRY_RELEASE_BOT_CLIENT_ID, secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY, and owner: getsentry, then checks out getsentry/${{ fromJSON(steps.inputs.outputs.result).repo }} into __repo__ with fetch-depth: 0.Set targets step creates Craft’s already-published JSON as {"published": ...} and writes it outside __repo__/ under $GITHUB_WORKSPACE/.craft-state/craft; the filename is publish-state-${owner_sanitised}-${repo_sanitised}-${cwd_hash}-${version_sanitised}.json./github/workspace/__repo__, monorepo paths map below it, and sanitise() lowercases values and replaces characters outside [a-z0-9._-] with _.getsentry/craft#797, released in Craft 2.26.0, and sets XDG_STATE_HOME: /github/workspace/.craft-state so target-repository contents cannot pre-populate publish state.Revalidate approval attestation reruns node .__publish__/src/publish/validate-approval-attestation.js with REQUIRE_CI_READY_ATTESTATION: "true"; failure is treated as revoked approval, removes accepted, posts the invalid-approval retry message, and exits 1.docker://getsentry/craft@sha256:9a4a5d5efa44a00c2215078ead39800d4aaa5a97908b94f45a64d7d506d6e14b, changes to __repo__/${{ fromJSON(steps.inputs.outputs.result).path }}, and executes craft publish ${{ fromJSON(steps.inputs.outputs.result).version }}.CRAFT_MERGE_TARGET, CRAFT_LOG_LEVEL defaulting to Info, CRAFT_DRY_RUN, release-bot Git author/committer identity, GITHUB_TOKEN, DOCKER_GHCR_IO_USERNAME, DOCKER_GHCR_IO_PASSWORD, GITHUB_API_TOKEN, CLOUDFLARE_API_TOKEN, COCOAPODS_TRUNK_TOKEN, CRAFT_GCS_TARGET_CREDS_JSON, CRAFT_GCS_STORE_CREDS_JSON, CRATES_IO_TOKEN, DOCKER_USERNAME, DOCKER_PASSWORD, HEX_API_KEY, TWINE_USERNAME, TWINE_PASSWORD, TWINE_VERBOSE: "1", NPM_TOKEN, GEM_HOST_API_KEY, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, NUGET_API_TOKEN, POWERSHELL_API_KEY, GPG_PRIVATE_KEY, GPG_PASSPHRASE, OSSRH_USERNAME, OSSRH_PASSWORD, PUBDEV_ACCESS_TOKEN, PUBDEV_REFRESH_TOKEN, VERCEL_ORG_ID, and VERCEL_TOKEN.node .__publish__/src/publish/update-issue.js; it then reports cancelled or failure through node .__publish__/src/publish/post-result.js, while success runs node .__publish__/src/publish/post-result.js success./home/byk/Code/getsentry/publish/.github/workflows/ci-poller.yml defines CI Status Poller, triggered by cron */5 * * * *, repository_dispatch type ci-poller, and successful completion of the Run CI Status Poller workflow.production environment when vars.CI_POLLER_HAS_PENDING == 'true', on repository_dispatch, or after a successful workflow_run whose head_branch equals the repository default branch; concurrency group is ci-status-poller with cancel-in-progress: false.attempt is validated against ^(0|[1-5][0-9])$, allowing only integers 0 through 59 before app tokens are requested.Get publish code step checks out github.event.repository.default_branch before requesting app tokens, using actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 with persist-credentials: false.publish.yml, and the sentry-release-bot token for cross-repository check-suites, status, and check-runs APIs because sentry-internal-app returns 404 for private repositories including sentry-xbox, sentry-playstation, sentry-switch, and service-registry.gh_api_release() helper scopes GH_TOKEN="$RELEASE_TOKEN" to a subshell-style command invocation, captures stderr/stdout, warns and returns nonzero on API failures including 404s, and avoids leaking the token override to other calls.ci-pending and accepted; this excludes abandoned releases that nobody approved.node src/publish/current-accepted-event.js, retaining its .actor and .eventId.ci-pending and accepted, comments Approval is invalid or could not be verified. Re-add the accepted label to retry after resolving the issue., and skips that issue.EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID using node src/publish/validate-approval-attestation.js; invalid approval removes ci-pending and accepted, posts the retry message, and skips the issue.parsePublishTitle from src/modules/details-from-context.js, ensuring CI and publishing target the same repository and version.https://github.com/{owner}/{repo}/commit/{SHA}/checks/ link, resolves the release branch from the original commit’s first check suite, then resolves branch HEAD to account for auto-fix or skill-regeneration bot pushes.success, neutral, or skipped pass; failure, cancelled, timed_out, action_required, stale, and startup_failure are unsuccessful.success or there are no commit statuses, all check runs are completed, and no check run has an unsuccessful conclusion.ci-ready; changed approval removes ci-pending and accepted and requires re-approval.ci-ready, the poller runs node src/publish/record-ci-ready-attestation.js to create proof tied to the current accepted actor and event; the output must begin ci_ready_attestation=, and the proof is posted by github-actions[bot] using ${{ github.token }}.ci-pending and accepted, posts the invalid-approval retry message, and prevents progression.ci-pending, adds ci-ready, and comments CI checks passed for ${repo}@${version}. Publishing is starting now.ci-pending and accepted, adds ci-failed, reports exact failed check names and a check-runs link, and tells the author to re-add accepted after fixing CI.failure, the poller similarly moves the issue to ci-failed, removes accepted, and lists commit-status contexts in the failure comment with target links where available.ci-pending and accepted; using a token from vars.CI_POLLER_APP_CLIENT_ID and secrets.CI_POLLER_APP_PRIVATE_KEY, it sets CI_POLLER_HAS_PENDING to "false" when none remain and "true" otherwise.*/5 cron can drift to 30–40 minutes under load; concurrency limits accumulation to 1 running plus 1 queued run.attempt with attempt=$((10#$ATTEMPT + 1)), stops at 60 attempts (approximately 30 minutes), then relies on cron fallback; dispatch uses jq to send {event_type: "ci-poller", client_payload: {attempt: $attempt}} to repos/$GITHUB_REPOSITORY/dispatches./home/byk/Code/getsentry/publish/src/publish/__tests__/ci-poller-workflow.js contains 3 Vitest tests: 1. trusted default-branch code is checked out before app tokens; 2. manual recovery uses a protected workflow-dispatch relay; 3. repository-dispatch attempts are validated before app tokens.ci-poller.yml to have repository_dispatch, workflow_run, successful/default-branch relay checks, and no direct workflow_dispatch; .github/workflows/ci-poller-dispatch.yml must have workflow_dispatch, permissions: {}, environment: production, no secrets., and no repository_dispatch./home/byk/Code/getsentry/publish/.github/workflows/ci-poller-dispatch.yml defines Run CI Status Poller as a no-permission workflow_dispatch relay with a production environment job whose only command is ":".production environment reports deployment branch main, can_admins_bypass: false, custom branch policies enabled, protected-branch matching disabled, and one branch_policy protection rule with ID 42720759..github/workflows/auto-approve.yml now grants issues: write, runs the auto-approve job in environment: production, pins checkout to actions/checkout@11d5960a326750d5838078e36cf38b85af677262, and pins app-token creation to actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1.sentry-release-bot[bot] or getsantry[bot] whose titles start with publish: , and sparse-checks out auto-approve-repos.txt with sparse-checkout-cone-mode: false..github/workflows/auto-approve.yml runs node src/publish/record-auto-approval-attestation.js with APPROVAL_TOKEN, issue number/repository/title, and AUTO_APPROVER; it posts steps.attestation.outputs.auto_approval_attestation as an issue comment using ${{ github.token }}.accepted label is added only if automated-attestation generation succeeded and the repository parsed from publish: <repo>@... exactly matches a line in auto-approve-repos.txt./home/byk/Code/getsentry/publish/src/publish/authorize-approval.js imports createApprovalAttestation, currentAcceptedEvent, and hasAutoApprovalAttestation from ../modules/approval-attestation.js, plus AUTO_APPROVAL_LABELER, AUTO_APPROVERS, authorizeApproval, and isAutoApprovedRepository from ../modules/approval-authorizer.js.authorize-approval.js loads nonempty lines from auto-approve-repos.txt into a Set, queries collaborator permission at repos/{owner}/{repository}/collaborators/{username}/permission, and sends GitHub API requests with media type application/vnd.github+json and API version 2026-03-10.getIssueEvents() and getIssueComments() paginate with per_page=100, increasing page until a response contains fewer than 100 entries.actor === AUTO_APPROVAL_LABELER, authorization requires the live issue to remain open with the same title; its requester must be a string in AUTO_APPROVERS; isAutoApprovedRepository() must pass; the current accepted event actor must equal the labeler; and a github-actions[bot] comment must contain a valid auto-approval attestation for that requester and live issue.authorize-approval.js calls authorizeApproval() with the actor, issue title, getPermission, and the auto-approved repository set.authorized=true and approval_attestation=... to GITHUB_OUTPUT; failed authorization writes authorized=false.