Dashboard › craft › Distillation
6131eb57-d988-41ad-8cc6-fbc135dd84e4["lore_tm_v1_Qx76StAhWxSMHdV2VlZKkPjZvaS7Ril7w837hLnAUJM","lore_tm_v1_OkevLdRf26BO4QRhNyerKS9WysLwmwq62DRZScuNVik"]
Date: Sep 3, 2026
ci-ready after checking CI; waiting-for-ci first removes an existing ci-ready label so that the pollerβs fresh add emits a labeled event and reliably triggers publishing..github/workflows/publish.yml has an issue-title concurrency group ${{ github.event.issue.title }} with cancel-in-progress: false, so duplicate issues for the same repo@version share a group..github/workflows/publish.yml waiting-for-ci job runs on ubuntu-latest in production only when an open issue receives accepted and its title starts with publish: . It creates a GitHub App token via actions/create-github-app-token@v3, removes ci-failed and ci-ready, adds ci-pending using gh issue edit, comments either "Retrying β CI was previously failed. Checking CI status now." or "Approved. Checking CI status on the release branch. Publishing will start automatically when CI passes.", best-effort enables CI_POLLER_HAS_PENDING=true using a dedicated poller app token, and immediately dispatches ci-poller.yml with the internal app token..github/workflows/publish.yml publish job runs only for an open issueβs ci-ready label event when the issue has accepted and ci-ready, and lacks ci-pending and ci-failed; it has timeout-minutes: 90. This prevents an accepted-event race with waiting-for-ci and prevents publishing without CI verification..__publish__, uses actions/setup-node@v6 with Node 24 and Yarn cache keyed by .__publish__/yarn.lock, runs yarn install --cwd ".__publish__", parses inputs with node .__publish__/src/publish/inputs.js, and resolves the CI-approved release revision through node .__publish__/src/publish/resolve-release-revision.js using PUBLISH_ARGS and PUBLISH_ISSUE_BODY.getsentry/${{ fromJSON(steps.inputs.outputs.result).repo }} into __repo__ at ${{ steps.release-revision.outputs.revision }}, with fetch-depth: 0 and a Release Bot GitHub App token scoped to owner getsentry.publish.yml, Resolve publish location initializes workspace_names='[]', computes requires_workspace_discovery using needsWorkspaceDiscovery(input), and only runs getsentry/craft:latest workspace list when discovery is required and __repo__/.craft.yml exists. The Docker command mounts $GITHUB_WORKSPACE/__repo__ at /github/workspace/__repo__ and uses that path as its working directory; CRAFT_WORKSPACE_NAMES is passed to node .__publish__/src/publish/resolve-location.js.Set targets runs only when fromJSON(steps.inputs.outputs.result).targets is truthy. It builds payload as {"published": {<target>: true, ...}} via jq, uses resolved path and optional workspace, and writes Craft publish state outside the target checkout at $GITHUB_WORKSPACE/.craft-state/craft.container_cwd with realpath -m "/github/workspace/__repo__/$CRAFT_PUBLISH_PATH" and rejects any path other than /github/workspace/__repo__ or its descendants with ::error::Publish path must remain inside the target checkout. It derives a 12-character SHA-1 cwd_hash, sanitizes owner/repo/version to lowercase [a-z0-9._-], and prefixes workspace state files with URL-safe base64 workspace-${workspace_encoded}-; resulting filename is publish-state-${owner_sanitised}-${repo_sanitised}-${cwd_hash}-${workspace_prefix}${version_sanitised}.json.cd __repo__/${{ fromJSON(steps.location.outputs.result).path }} then craft publish <version> --rev <CI-approved revision>. It pins XDG_STATE_HOME=/github/workspace/.craft-state, passes resolved workspace through CRAFT_WORKSPACE, keeps CRAFT_PUBLISH_STATE_GITHUB_REPO bound to the issue checkout identity getsentry/<repo> rather than any workspace release-repository override, and invokes node .__publish__/src/publish/update-issue.js on cancellation or failure to update completed targets and remove the relevant label.src/modules/__tests__/details-from-context.js verifies ordinary title parsing for publish: getsentry/sentry@21.3.1: result { dry_run: "", merge_target: "custom-branch", path: ".", repo: "sentry", targets: ["github", "npm[@sentry/node]", "docker[latest]"], version: "21.3.1" }; verifies versions may contain +, e.g. 4.2.6+sentry1; and verifies Merge target: (default) becomes merge_target: "".details-from-context.js tests legacy human-readable workspace title syntax publish: getsentry/toolkit [workspace: "cli/v2"] @1.2.3, expecting repo: "toolkit", version: "1.2.3", and workspace: "cli/v2"; it rejects the same workspace suffix paired with toolkit/packages/cli using "A publish workspace must use the repository root path.".cli [preview] \"next\" to cli [preview] "next" and Unicode cli-ζ₯ζ¬θͺ; a title with an unexpected space before a version (publish: getsentry/toolkit @1.2.3) is rejected as Invalid publish issue title, and invalid JSON escape cli\qnext is rejected as Invalid publish workspace JSON in title."", newline escape cli\nnext, NUL \u0000, tab escape cli\tnext, bidirectional-format character cli\u202enext, line separator cli\u2028next, and begins coverage for paragraph-separator workspace input in the continuation beyond line 300.