Dashboard › craft › Distillation
3c24a2ba-c442-4af5-acb5-cbe5bf07d39a["lore_tm_v1_jpIFaJFkiKVfhgk_Rn_r4ic1c9XdzD0bfkJxu0tNI8M"]
Date: Sep 4, 2026
.craft.yml always means checkout-path behavior..github/workflows/publish.yml, docs/publish-issue-format.md, src/modules/__tests__/ci-poller-input.js, src/modules/__tests__/details-from-context.js, src/modules/__tests__/publish-location.js, src/modules/__tests__/publish-workflow.js, src/modules/ci-poller-input.js, src/modules/details-from-context.js, src/modules/publish-issue-title.js, src/modules/publish-issue-title.peggy, src/modules/publish-location.js, and src/publish/resolve-location.js; untracked src/modules/publish-issue-validation.js; diff totals shown as 291 insertions and 539 deletions across 12 tracked files.docs/publish-issue-format.md canonical title grammar was simplified to publish: , optional getsentry/, repository, optional slash-delimited path, @, and version; legacy [workspace: <json-string>] syntax is removed.publish: getsentry/toolkit/packages/cli@1.2.3, while root releases remain publish: getsentry/sentry@21.3.1.[A-Za-z0-9_.-]+, excluding ., .., __proto__, and segments beginning -; repository identities follow the same safe-token exclusions; exact spelling is preserved.4.2.6+sentry1 is valid.View check runs revision, the controller calls craft workspace list when root .craft.yml exists; an exact complete suffix match to a concrete listed workspace path resolves as a workspace, all other suffixes remain checkout paths, missing root .craft.yml uses checkout-path behavior, and workspace-discovery errors with root configuration fail the release.accepted starts CI waiting; publishing starts only from a fresh ci-ready label on an open accepted issue that has neither ci-pending nor ci-failed; dry-run enables dry-run mode..github/workflows/publish.yml now always discovers workspace names whenever __repo__/.craft.yml exists, rather than gating discovery through removed needsWorkspaceDiscovery(input)..github/workflows/publish.yml state-file naming now prevents version filename collisions: it uses version_sanitised unchanged only if identical to CRAFT_PUBLISH_VERSION; otherwise Base64URL-encodes the original version and uses version-${version_encoded}. Workspace state prefixes remain Base64URL workspace-${workspace_encoded}-..craft-state/craft/publish-state-getsentry-toolkit-c232c383e26f-workspace-cGFja2FnZXMvY2xp-1.2.3.json for workspace packages/cli, and distinct encoded version suffixes -version-NC4yLjYrc2VudHJ5MQ.json versus -version-NC4yLjYrU2VudHJ5MQ.json for 4.2.6+sentry1 versus 4.2.6+Sentry1.src/modules/publish-issue-title.peggy and generated src/modules/publish-issue-title.js removed parsing and output of LegacyWorkspace, JsonString, and JsonCharacter; parser output is now { repo, path: path || "", version }, with full path suffix syntactically parsed before @.src/modules/publish-location.js removed needsWorkspaceDiscovery() and legacy explicit-workspace handling. resolvePublishLocation({ path, workspaceNames }) now validates path, validates every discovered workspace name, returns { path: "." } for root, resolves an exact full suffix matchβe.g. ./packages/CLI against ["packages/cli", "packages/CLI"]βto { path: ".", workspace: "packages/CLI" }, and otherwise returns the checkout path unchanged.src/modules/publish-location.js added exported isPublishPath(path): permits only . or ./ plus slash-delimited safe workspace segments. isSafeWorkspaceSegment(segment) requires /^[A-Za-z0-9_.-]+$/, rejects ., .., __proto__, and leading -; isWorkspaceName(name) applies that segment validation to every slash-delimited segment.src/publish/resolve-location.js now always parses CRAFT_WORKSPACE_NAMES as JSON and passes it to resolvePublishLocation; it no longer conditionally discovers workspace names or passes input.workspace.src/modules/ci-poller-input.js and src/modules/details-from-context.js now use isPublishRepository and isReleaseVersion from new src/modules/publish-issue-validation.js, plus isPublishPath from publish-location, before CI API/context processing. They throw Invalid publish issue repository: '<repo>', Invalid publish issue version: '<version>', or Invalid publish issue path: '<path>' for invalid parsed values.src/modules/details-from-context.js removed legacy workspace JSON decoding, Unicode-control/format/separator workspace validation, and the root-only explicit-workspace restriction; it now preserves a parsed full suffix as path, prefixed with . (e.g. title suffix /packages/cli becomes path: "./packages/cli").-toolkit, ., .., and __proto__; malformed repositories getsentry/ and toolkit$; invalid versions --config and 1.2; unsafe paths containing ../, ./, __proto__, or --config; and invalid version path syntax 1.2.3/other.src/modules/__tests__/publish-location.js now verifies full concrete workspace path matching without normalization, root releases, nonmatching multi-segment checkout paths, invalid root discovery output packages/../cli, invalid publish paths ./., ./.., and ./packages/../other, and invalid discovered workspace names including ., .., packages/./cli, packages/../cli, packages/__proto__/cli, packages/-cli, packages/foo], packages/foo!, and packages/foo^.src/modules/__tests__/publish-workflow.js verifies the workflow checks if [[ -f __repo__/.craft.yml ]]; then, uses the CI-approved revision for checkout/location/publishing, invokes getsentry/craft:latest workspace list, and publishes only on github.event.label.name == 'ci-ready' with accepted and ci-ready labels present and ci-pending/ci-failed absent.