Dashboard › craft › Distillation
e42ca1f7-b15c-4bf0-a1e3-b5ac7100d4c0["lore_tm_v1_qLkojcH_ZQZY4_EwNGbhHRKaGInUVXOrs0JMExnGrD0","lore_tm_v1_CbMYJFlV620zX9aYZiTN_5051UokxkJN3tTmDckN00E","lore_tm_v1_epoHK-JOBpgSf_i--M-uyKf4-Jy-ml1xkg3LsMjnVvE","lore_tm_v1_YB9oXOIwqgT-OVH4nqiFtYHRoCV638F9GgiKWPWWlU8","lore_tm_v1_PKlbAa3gOO-VcRa4PJoVEeYyyHT4ntWkFGTmY8n_wfo","lore_tm_v1_Xn-22jBOiIE1p9tpqPRSZfc5cDUhH5kuoYth1Q5JpTU","lore_tm_v1_zp0w66TnKZN-MdDEd_cxgtIXCHutAR8yvj4l44m9uaA","lore_tm_v1_5404aAp6SzM4dQz7cVg2G-nW8iV47gGT7i2QLS024LE","lore_tm_v1_tMfDhXos8JzOWvveuB8R641VJjVbJu_vPROp5P9iZzk","lore_tm_v1_yFvKm2EwL4pNQuAU4A_hFgqtq2aYy-2sdB8NKgBgdqQ","lore_tm_v1_UQwsHO2Gm0tchwLTaNbYMk-G65sgSAVi-5ad44U5jjw","lore_tm_v1_jL-2wfMJmcb8odcrsvS9grQaVRQTsL9yBOemp3dGiLs","lore_tm_v1_yun-SH-1n9WoSLq2KS46cXe2NWJiU8W4lgg812cnbWg","lore_tm_v1_HGIwojx8XXhwiKL4_MgCe93oy5ALN6_rPYuPbelB4B0","lore_tm_v1_R2WD83MvtWVphzVqCie-zRq_TXmeBm6pCRiItoEKqkA","lore_tm_v1_F6r3rHZz7GwtymIfYWy5SM8lnG68QUztkvKSgJdJwWk","lore_tm_v1_n3tHhD2F9WZ9WlpJ7GgoUV74r_dyNzTFZZ0AZyf51Mc","lore_tm_v1_pQfcywhnTBkzQW35j0yd8aW_OyC-wCbi4XihREDgDW8","lore_tm_v1_uwpyTAalexkx47rpZ73Kr_fw9cI0z-H0Au2bLHB29wc","lore_tm_v1_0trvtGyMiS3LUgD7YkZD4fj9F5PANbKQc13xF6SiYgw","lore_tm_v1_pPe6SyuLdpWjyIEWS8N3dAOlNn6JrhoaFMYO4ZUacFw"]
Date: Aug 29, 2026
latest Craft-image contract, retain the CI-pinned --rev execution path, and apply review fixes without an image-availability gate.getsentry/craft:latest for Publish, replacing the semver-pin plan; stated Craft must release first so latest includes workspace list and CI-pinned --rev. It identified the real review gaps as rejection of legacy workspace-plus-path titles and generated-parser freshness.src/modules/publish-issue-title.peggy defines canonical PublishIssueTitle grammar: publish: , optional getsentry/, Repository, optional slash-delimited Path, optional legacy workspace syntax [workspace: <JsonString>], @, and Version; repository/path characters are [A-Za-z0-9_.-], versions allow [A-Za-z0-9_.+-], and JSON escape validation is delegated to JSON.parse.latest for discovery and publishing; reject explicit workspaces outside the checkout root; add a non-mutating generated-parser freshness check to the test script.test("preserves a legacy workspace", () => { was absent from src/modules/__tests__/publish-location.js.test("preserves the legacy explicit workspace", () => {, and it would apply narrow changes against the current tree.src/modules/__tests__/publish-location.js from /home/byk/Code/getsentry/publish-workspace-acceptance/. Existing tests specified: discovery is required only for a one-segment path such as ./cli with no explicit workspace; exact workspace matching preserves case (./CLI resolves to { path: ".", workspace: "CLI" } when names include "CLI"); non-workspace suffixes and multi-segment paths remain checkout paths; root remains "."; explicit legacy "cli/v2" workspace at root is preserved without discovery validation; invalid discovered workspace "cli-日本語" throws Craft workspace discovery returned an invalid workspace list.../publish-workspace-acceptance/: .github/workflows/publish.yml, src/modules/details-from-context.js, src/modules/publish-location.js, scripts/generate-publish-issue-title-parser.js, package.json, src/modules/__tests__/publish-workflow.js, src/modules/__tests__/details-from-context.js, and src/modules/__tests__/publish-location.js.yarn 1.22.22 successfully ran node scripts/generate-publish-issue-title-parser.js and node scripts/generate-publish-issue-title-parser.js --check (0.48s and 0.47s respectively). Direct vitest invocation failed because vitest: command not found.yarn check:generated && vitest run src/modules/__tests__/details-from-context.js src/modules/__tests__/publish-location.js src/modules/__tests__/release-revision.js src/modules/__tests__/publish-workflow.js; 4 test files and 32 tests passed under Vitest 4.1.0. eslint src .github --ignore-pattern '!.github' also passed.pnpm-lock.yaml.yarn check:generated && vitest run produced 8 passing test files and 45 passing tests; lint passed via eslint src .github --ignore-pattern '!.github'.publish: + optional getsentry/ + repository + optional path + optional legacy workspace + @ version. New root releases use publish: getsentry/sentry@21.3.1; root workspace releases use one trailing path segment, e.g. publish: getsentry/toolkit/cli@1.2.3.^[A-Za-z0-9_.-]+$ and retain exact spelling. After checkout of the exact CI-approved revision from the View check runs link, a root .craft.yml enables craft workspace list; a one-segment suffix exactly matching a listed workspace key becomes a workspace, otherwise it remains a checkout path. Missing root .craft.yml always yields checkout-path behavior; discovery errors when root config exists fail release.publish: getsentry/toolkit [workspace: "cli/v2"] @1.2.3 and publish: getsentry/toolkit [workspace: "cli [preview] \"next\""] @1.2.3. The JSON string must decode to a nonempty name with no Unicode Cc, Cf, Zl, or Zp characters; legacy titles require one space between ] and @; unqualified titles require no space before @; optional getsentry/ remains parseable for existing issues; paths cannot include ...Merge target uses <branch-or-(default)>, with (default) meaning the target repository default branch; allowed explicit branch characters are letters, digits, _, ., /, and -. Checked - [x] <target-id> entries in ### Targets are read as skipped targets and preserved by Craft on refresh; secure Craft publish-state updates checkboxes after failed release; retry requires manual unchecking. The accepted label starts publishing and dry-run enables dry-run mode.package.json scripts now include "generate": "node scripts/generate-publish-issue-title-parser.js" and "check:generated": "node scripts/generate-publish-issue-title-parser.js --check"; "test" is "yarn check:generated && vitest run". Dev dependencies include peggy 5.1.0, vitest ^4.1.0, prettier ^2.2.1, and ESLint 8.9.0.scripts/generate-publish-issue-title-parser.js reads src/modules/publish-issue-title.peggy, generates CommonJS parser source using Peggy, formats it with Prettier into src/modules/publish-issue-title.js, and under --check compares generated output byte-for-byte; drift throws The generated publish issue title parser is stale. Run \yarn generate`.`.src/modules/details-from-context.js now parses titles with parsePublishIssueTitle; validates JSON legacy workspaces; rejects empty workspace names and Unicode control/format/line/paragraph separators; rejects .. path segments; and throws A publish workspace must use the repository root path. when an explicit workspace has any path other than ".".src/modules/__tests__/details-from-context.js cover version 4.2.6+sentry1; legacy workspace cli/v2; rejection of legacy title publish: getsentry/toolkit/packages/cli [workspace: "cli/v2"] @1.2.3; escaped workspace cli [preview] "next"; safe Unicode workspace cli-日本語; unexpected space before @; invalid JSON escape \q; empty/newline/NUL/tab/bidi U+202E/line-separator U+2028/paragraph-separator U+2029 workspaces; path escape ../other; and missing issue context.src/modules/publish-location.js implements needsWorkspaceDiscovery({ path, workspace }) only for no-workspace paths matching ^\.\/[A-Za-z0-9_.-]+$; resolvePublishLocation() rejects explicit workspaces unless path === ".", validates every discovered workspace via isWorkspaceName(), exact-matches a one-segment suffix with workspaceNames.includes() without normalization, and otherwise retains the path. isWorkspaceName() requires a string matching ^[A-Za-z0-9_.-]+$ and rejects "__proto__".src/modules/__tests__/publish-location.js test that an explicit workspace "cli/v2" with path "./packages/cli" throws A publish workspace must use the repository root path..src/modules/release-revision.js parses only a View check runs URL matching https://github.com/getsentry/<repo>/commit/<40 lowercase hex chars>/checks/, requires the URL repository to exactly equal the publish repository, and otherwise throws Expected a View check runs link for getsentry/<repo> in the publish issue body. Added tests cover valid standard and CRLF bodies, wrong repository, missing revision, and uppercase SHA rejection.src/publish/resolve-location.js reads PUBLISH_ARGS, invokes workspace discovery only when needsWorkspaceDiscovery() is true, reads discovered names from CRAFT_WORKSPACE_NAMES, validates that value is an array, and sets the result output. src/publish/resolve-release-revision.js reads repo from PUBLISH_ARGS, parses PUBLISH_ISSUE_BODY via getReleaseRevision(), and sets the revision output.src/modules/__tests__/publish-workflow.js verifies workflow order: checkout target repository, resolve publish location, set targets, publish using Craft. It requires checkout ref ${{ steps.release-revision.outputs.revision }}, getsentry/craft:latest workspace list, conditional workspace discovery, publication craft publish <version> --rev ${{ steps.release-revision.outputs.revision }}, and absence of getsentry/craft:2.31.0. It also verifies Craft publish-state filenames for root Sentry 21.3.1 and Toolkit workspace cli 1.2.3.latest image contract, keeps the exact CI-approved revision through checkout and --rev, rejects legacy workspace-plus-path ambiguity, and detects stale generated parsers; it planned final intended-file inspection and remaining formatting checks.No files found.All matched files use Prettier code style!. Modified tracked files were .github/workflows/publish.yml, docs/publish-issue-format.md, package.json, src/modules/__tests__/details-from-context.js, src/modules/__tests__/publish-workflow.js, src/modules/details-from-context.js, src/modules/post-workflow-details.js, src/publish/inputs.js, and yarn.lock. Untracked files/directories included pnpm-lock.yaml, scripts/, parser/location/revision modules and tests, src/modules/publish-issue-title.{js,peggy}, src/publish/resolve-location.js, and src/publish/resolve-release-revision.js.src/modules/post-workflow-details.js and src/publish/inputs.js had only final-newline changes. Tracked intended diff summary: 9 files changed, 166 insertions and 63 deletions.