Dashboard › craft › Distillation
49241b04-23ff-40b6-a74e-bb054ad99577["lore_tm_v1_94s72aV5d0pEjY6JkxC2ST3zXvVzFqHHfEdP4-tKCts","lore_tm_v1_9L4YK9b_wO3KLNSn_OP--4upq_Q8Rb4tFaSeMEEZEdU","lore_tm_v1_lMSPRCR0aUCCFyLZVm2Yr_J867QP0SZWM98775p3byc","lore_tm_v1_o2YDZ3yY5mpWrnp3-cJ8L4KI10FgpzitIOQ_PvTdB_M","lore_tm_v1_6o6C2lHJSJXwSkdU0zP8E2R_V3OB8l0j3AtHYVCZypQ","lore_tm_v1_ty53yeO1KmzTngF983IVz8MBa5g_CMbn0xsUCPAOqLU","lore_tm_v1_dz-5P_P4SeQGkqR2NJfc7_g8BQSVkcYWppRN1IM_sdA","lore_tm_v1_QtGms4GLB4GDpBjCppkSo78oBsdnzYxK9PgKslO4Ebc","lore_tm_v1_ftBBvXK062N8ynOGi86GXBnplmYfy0Iwkf-Bez1o9uI","lore_tm_v1_1CywOarbsRXk_SqsCHphZK7ps1FWKILoHnx_LiCZPRM","lore_tm_v1_NLh6MnnJqEI8nTQRCjqSKb0jyt0qVWPhWMqwTzIlpug","lore_tm_v1_QIWC9C2KAR35zWr330xML1Q-bA5HLSl-eoewbY21_wA","lore_tm_v1_mo0DmPposC693UYsCvoOUsaYzSLHbC0eCfGiRplD-EA","lore_tm_v1_IO8q0IP2tQTgVfRYbWfijeQz_ggtj_ExO0GIxIRbHp8"]
Date: Sep 8, 2026
src/modules/__tests__/release-revision.js defines REVISION = "7e5ca7ed5581552de066e2a8bc295b8306be38ac" and helpers requestBody(quickLinks) and canonicalQuickLinks(revision = REVISION), whose canonical links are https://github.com/getsentry/toolkit/compare/1.2.2...release/1.2.3 and https://github.com/getsentry/toolkit/commit/${revision}/checks/.getReleaseRevision() returns REVISION from a request header for repo: "toolkit" and accepts CRLF bodies; it rejects a check-runs URL for getsentry/other with "Expected a View check runs link for getsentry/toolkit"."Expected exactly one View check runs link in Quick links"; reject a standalone Quick links block and a complete request header preceded by ### Changelog with "Expected a View check runs link for getsentry/toolkit".updateReleaseRevision({ issueBody, repo: "toolkit", revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }) updates the canonical request-header check-runs link to /commit/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/checks/.src/modules/ci-poller-input.js implements getCiPollerInput({ title, issueBody, revision }): parses titles with parsePublishIssueTitle(), rejects invalid title/repository/version/path with respectively Invalid publish issue title: '${title}', Invalid publish issue repository: '${repo}', Invalid publish issue version: '${version}', and Invalid publish issue path: '${path}'; validates repo via isPublishRepository(), version via isReleaseVersion(), and .${parsedTitle.path} via isPublishPath().getCiPollerInput() obtains currentRevision through getReleaseRevision({ issueBody, repo }); returns { repo: \getsentry/${repo}`, revision: currentRevision, version }, and when a truthy revisionis supplied, additionally returnsissueBody: updateReleaseRevision({ issueBody, repo, revision })`.src/publish/resolve-ci-poller-input.js writes JSON to stdout from getCiPollerInput({ issueBody: process.env.PUBLISH_ISSUE_BODY || "", title: process.env.PUBLISH_TITLE || "", revision: process.env.PUBLISH_REVISION || "" })..github/workflows/ci-poller.yml has cron schedule "*/5 * * * *", a check-ci job, concurrency group ci-status-poller, actions/create-github-app-token@v3, and actions/checkout@v7; its comments state workflow_dispatch is always allowed for manual recovery.ci-pending and accepted labels, calls node .__publish__/src/publish/resolve-ci-poller-input.js, updates the request body through PUBLISH_ISSUE_BODY="$body" PUBLISH_REVISION="$sha" PUBLISH_TITLE="$title" node .__publish__/src/publish/resolve-ci-poller-input.js | jq -r '.issueBody', and evaluates combined commit statuses and check runs.ci-pending and comments CI checks passed for ${repo}@${version}. Publishing is starting now.; on failed checks/statuses it blocks publishing, removes ci-pending, adds failure handling, links https://github.com/${repo}/commit/${sha}/checks/, and tells users to re-add accepted once CI is fixed to retry.src/publish/inputs.js imports @actions/github, @actions/core, and detailsFromContext from ../modules/details-from-context; inputs() awaits detailsFromContext({ context: github.context }) and sets GitHub output result to JSON.stringify(result).scripts/generate-publish-issue-title-parser.js reads src/modules/publish-issue-title.peggy, generates CommonJS source parser src/modules/publish-issue-title.js with Peggy allowed start rules PublishIssueTitle, ReleaseRevision, and CheckRunsLinkCount, formats it with Prettier, and regenerates the title-grammar block in docs/publish-issue-format.md.--check mode compares generated parser and documentation to current files and throws respectively "The generated publish issue title parser is stale. Run \yarn generate`."or"The generated publish issue title documentation is stale. Run `yarn generate`."; without --check`, it writes both generated files.src/modules/__tests__/publish-workflow.js reads .github/workflows/publish.yml, extracts the Set targets Bash script using a regex bounded by - name: Set targets and - uses: docker://getsentry/craft:latest, and executes it with bash -e -c in a temporary directory.uses the CI-approved revision for checkout, location resolution, and publishing enforces ordering: Resolve CI-approved release revision before Inform start, Check out target repo, Resolve publish location, Set targets, and Publish using Craft; it requires checkout ref ${{ steps.release-revision.outputs.revision }}, location discovery command node .__publish__/src/publish/discover-location.js, PUBLISH_REPOSITORY_DIRECTORY: __repo__, Craft latest rather than getsentry/craft:2.31.0, and craft publish ${{ fromJSON(steps.inputs.outputs.result).version }} --rev ${{ steps.release-revision.outputs.revision }}.ci-ready label event on issues that contain accepted and ci-ready, and do not contain ci-pending or ci-failed..craft-state/craft/publish-state-getsentry-sentry-c232c383e26f-21.3.1.json for root sentry@21.3.1, containing {"published":{"github":true}}../packages/cli against workspace ["packages/cli"], then requires .craft-state/craft/publish-state-getsentry-toolkit-c232c383e26f-workspace-cGFja2FnZXMvY2xp-1.2.3.json for toolkit@1.2.3, containing {"published":{"github":true}}.4.2.6+sentry1 must end in -version-NC4yLjYrc2VudHJ5MQ.json, while 4.2.6+Sentry1 must end in -version-NC4yLjYrU2VudHJ5MQ.json.src/modules/__tests__/ci-poller-input.js verifies titles publish: getsentry/toolkit/cli@1.2.3 and publish: toolkit/packages/cli/v2@1.2.3 both resolve to { repo: "getsentry/toolkit", revision: REVISION, version: "1.2.3" }..github/workflows/ci-poller.yml to contain name: Check out publish controller, path: .__publish__, and node .__publish__/src/publish/resolve-ci-poller-input.js, and not contain grep -oP '(?<=commit/.-toolkit, ., .., and __proto__ before CI API calls; reject invalid versions --config and 1.2; reject malformed titles publish: getsentry/@1.2.3 and publish: getsentry/toolkit$@1.2.3; and reject unsafe paths containing .., ., __proto__, or --config.src/modules/publish-location.js: resolvePublishLocation({ path, workspaceNames }) validates path and every workspace name, returns { path } for root ., returns { path: ".", workspace } only when non-root path.slice(2) exactly occurs in workspaceNames, otherwise returns { path }..craft.yml always means checkout-path behavior.isPublishPath() accepts only "." or "./" paths whose slash-separated segments pass isSafeWorkspaceSegment(); isWorkspaceName() requires every slash-separated segment to pass the same validator. Safe segments match /^[A-Za-z0-9_.-]+$/, cannot be ., .., or __proto__, and cannot start with -.docs/publish-issue-format.md documents canonical title grammar: publish: followed by optional getsentry/, a repository token, optional path suffix, @, and a version; repository/path token characters are [A-Za-z0-9_.-], version characters are [A-Za-z0-9_.+-].publish: getsentry/sentry@21.3.1 and publish: getsentry/toolkit/packages/cli@1.2.3; getsentry/ remains optional when parsing existing issues, and 4.2.6+sentry1 is a valid version build metadata example.View check runs link, the controller uses craft workspace list only when root .craft.yml exists; a title suffix exactly matching a concrete workspace path is a workspace, all other suffixes remain checkout paths, and workspace discovery errors with root configuration fail the release.Requested by and Merge target, with exactly one View changes line followed by exactly one checkout-repository View check runs line; controller and CI poller treat that check-runs revision as release authority.accepted label starts CI waiting; publishing begins only after the CI poller adds a fresh ci-ready label to an open accepted issue without ci-pending or ci-failed; dry-run requests dry-run mode.