Dashboard › publish › Distillation
382e6952-8fd1-454e-929a-bdb3fd4e9c8f["lore_tm_v1_tindQzpVpFu1kqLBF9GvuqNolBYgDnqYNvfXEMZwNcA","lore_tm_v1_5yGBUyg-dfTt90TD4yFZLZNrXAUc--UlKtCgU3Rds1c"]
.github/workflows/ci-poller-dispatch.yml relay rather than direct workflow_dispatch in .github/workflows/ci-poller.yml..github/workflows/ci-poller.yml checks out ${{ github.event.repository.default_branch }} in the Get publish code step with persist-credentials: false before obtaining secret-backed app tokens..github/workflows/ci-poller.yml revalidates the approval after final CI checks and again immediately before adding ci-ready..github/workflows/publish.yml first removes any existing ci-ready during the Mark ci-pending step so the poller’s later addition creates a fresh labeled event..github/workflows/auto-approve.yml now grants issues: write, places job auto-approve in environment: production, and pins actions/checkout to 11d5960a326750d5838078e36cf38b85af677262 and actions/create-github-app-token to bcd2ba49218906704ab6c1aa796996da409d3eb1..github/workflows/auto-approve.yml now runs node src/publish/record-auto-approval-attestation.js with APPROVAL_TOKEN, APPROVAL_ISSUE_NUMBER, APPROVAL_ISSUE_REPOSITORY, APPROVAL_ISSUE_TITLE, and AUTO_APPROVER; it posts ${{ steps.attestation.outputs.auto_approval_attestation }} using ${{ github.token }} before adding accepted using ${{ steps.token.outputs.token }}..github/workflows/ci-poller.yml replaced direct workflow_dispatch with repository_dispatch type [ci-poller] and completed workflow_run events from [Run CI Status Poller]; the check-ci job runs for pending work, repository dispatch, or a successful relay run whose head_branch is the repository default branch..github/workflows/ci-poller.yml changed permissions from issues: read to issues: write and keeps job check-ci in environment: production..github/workflows/ci-poller.yml validates repository-dispatch ATTEMPT before obtaining app tokens using regex ^(0|[1-5][0-9])$; invalid values emit repository_dispatch attempt must be an integer from 0 through 59 and exit 1..github/workflows/ci-poller.yml added the trusted checkout actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803, targeting ${{ github.event.repository.default_branch }} with persist-credentials: false.actions/create-github-app-token uses in .github/workflows/ci-poller.yml were pinned to bcd2ba49218906704ab6c1aa796996da409d3eb1..github/workflows/ci-poller.yml now calls src/publish/current-accepted-event.js before inspecting CI and extracts .actor and .eventId; inability to bind the current event removes 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..github/workflows/ci-poller.yml validates approval through src/publish/validate-approval-attestation.js using APPROVAL_ATTESTATION_AUTHOR="github-actions[bot]", the current issue number/repository/title, and the bound EXPECTED_ACCEPTED_ACTOR and EXPECTED_ACCEPTED_EVENT_ID; invalid approval removes ci-pending and accepted and posts the retry guidance.sed; it imports parsePublishTitle from ./src/modules/details-from-context.js, constructs the repository as "getsentry/" + .repo, and reads .version, ensuring CI and publication interpret titles consistently..github/workflows/ci-poller.yml revalidates the original accepted event; if the issue was renamed, altered, or re-approved during CI, it removes ci-pending and accepted instead of adding ci-ready.ci-ready, .github/workflows/ci-poller.yml invokes src/publish/record-ci-ready-attestation.js with the bound accepted actor/event ID, captures output through a temporary GITHUB_OUTPUT file, requires the output to begin ci_ready_attestation=, and posts the proof using ${{ github.token }}..github/workflows/ci-poller.yml to remove ci-pending and accepted, post the standard retry guidance, and continue without adding ci-ready..github/workflows/ci-poller.yml performs one final validate-approval-attestation.js call after posting the CI-ready proof and immediately before label promotion; changed approval removes ci-pending and accepted.ATTEMPT from ${{ github.event_name == 'repository_dispatch' && steps.dispatch-attempt.outputs.value || '0' }}, increments with attempt=$((10#$ATTEMPT + 1)), caps the chain at 60 attempts, and sends {event_type: "ci-poller", client_payload: {attempt: $attempt}} via gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -; cron remains the fallback after approximately 30 minutes..github/workflows/publish.yml job waiting-for-ci now checks out publish code at actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 with persist-credentials: false before obtaining app tokens..github/workflows/publish.yml job waiting-for-ci now gets a Sentry Release Bot token for owner getsentry, runs node src/publish/authorize-approval.js with the issue actor/number/repository/title, posts the returned approval attestation with ${{ github.token }}, and validates it through node src/publish/validate-approval-attestation.js..github/workflows/publish.yml, failed authorization, unauthorized output, failed attestation posting, or failed validation triggers Reject invalid approval, which 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..github/workflows/publish.yml triggers the CI poller through gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" -f event_type=ci-poller instead of gh workflow run ci-poller.yml..github/workflows/publish.yml job publish runs only for an open issue’s fresh ci-ready label event when both accepted and ci-ready are present and neither ci-pending nor ci-failed is present; the job has timeout-minutes: 90 and environment: production..github/workflows/publish.yml lines 191–220, the publish job checks out the repository into .__publish__ using actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803, then validates approval with REQUIRE_CI_READY_ATTESTATION: "true"; failure removes accepted, posts the retry guidance, and exits 1..github/workflows/publish.yml pins actions/setup-node to 249970729cb0ef3589644e2896645e5dc5ba9c38, uses Node 24 with Yarn caching, and pins all shown checkout steps to d23441a48e516b6c34aea4fa41551a30e30af803..github/workflows/publish.yml lines 328–351, Revalidate approval attestation runs after Set targets and immediately before Craft with REQUIRE_CI_READY_ATTESTATION: "true"; Reject revoked approval removes accepted, posts the standard retry guidance, and exits 1 if final validation fails..github/workflows/publish.yml pins Craft to docker://getsentry/craft@sha256:9a4a5d5efa44a00c2215078ead39800d4aaa5a97908b94f45a64d7d506d6e14b instead of docker://getsentry/craft:latest.README.md now states that secret-bearing jobs use the protected production environment, which permits only main deployments and disallows administrator bypass, protecting environment-scoped credentials from arbitrary workflow refs.README.md now states that SENTRY_INTERNAL_APP_PRIVATE_KEY and SENTRY_RELEASE_BOT_PRIVATE_KEY are organization-level secrets whose availability to other repositories is an organization-wide security concern; Security must manage that boundary separately.src/modules/details-from-context.js added PUBLISH_TITLE_REGEX = /^publish: (?:getsentry\/)?(?<repo>[^/@]+)(?<path>\/[\w./-]+)?@(?<version>[\w.+-]+)$/ and exported parsePublishTitle(title) plus PUBLISH_TITLE_REGEX.detailsFromContext() now uses parsePublishTitle() and throws Invalid publish issue title: ${context.payload.issue.title} when parsing fails, replacing the prior unconditional .groups access.src/modules/__tests__/details-from-context.js added coverage showing parsePublishTitle("publish: getsentry/sentry-javascript/packages/core@10.0.0") returns { path: "/packages/core", repo: "sentry-javascript", version: "10.0.0" }, while parsePublishTitle("publish: sentry-javascript@10.0.0") returns { path: undefined, repo: "sentry-javascript", version: "10.0.0" }.src/modules/update-issue.js now tolerates absent publish inputs: it only calls updateTargets() when inputs?.version exists, while always removing the accepted label.src/modules/__tests__/update-issue.js added removes accepted without parsed publish inputs, verifying that undefined inputs do not call fs.existsSync, issues.get, or issues.update, but do call issues.removeLabel for issue "211" in getsentry/publish with label accepted.src/publish/update-issue.js now wraps execution in async main(), conditionally parses process.env.PUBLISH_ARGS, warns Could not parse publish inputs; skipping target update on malformed JSON, awaits updateIssue({ context, octokit, inputs }), exports { main }, and sets process.exitCode = 1 on uncaught main errors.