Dashboard › craft › Distillation
6bf44c04-caee-4b39-aa98-7b0d985363b9["lore_tm_v1_27DfduczD9-ci2im6ZSW4Sb4fFXoL85Fws4bQNHTjTM","lore_tm_v1_MrnwSOdJ3ffhASa7wXXpIE8kZ1JD2QuhyXPRtYV3_l0","lore_tm_v1_vunWgXweekaK584Ub_PVKjYS4TkWZgAh15fvbJeLvFs","lore_tm_v1_KMWTHLj8hyZ7x9XZSdRPqvk_7N8VmQKjDPNn3J4KSC0","lore_tm_v1_3OvbSTI_5bVDTa-xsPuura_1LHJboPxjcG3HPRJtdMY","lore_tm_v1_4GhIQumiziWs3QGH9lmg69sO8pcM2ktwqUaNVzX09hU","lore_tm_v1_0tC5ZHaGQtrQ01U8MUhYrbFrdHAa38gkUd3Q7MzNIK4","lore_tm_v1_dJNNcjTeoqyYCb4tIZJijmDXksd0JRJy04mrBxk6JOc","lore_tm_v1_pCixeCzXh-vP_1f2fNLYpr7jPh1LEEGUq4uKl3gBPL8","lore_tm_v1_Qr-hyiyNzfhZvW2vEtt0gGdduOD6xMxTCd71Q8dg9NY","lore_tm_v1_qzIbVG4PrAtv0zgmmWJ3Z-mf5DTdNidfkfLKEBLtSac"]
Date: Aug 27, 2026
publish-workspace-acceptance/src/modules/details-from-context.js parses GitHub publish-issue titles with titleParser: ^publish: (?:getsentry\/)?(?<repo>[A-Za-z0-9_.-]+)(?<path>\/[\w./-]+)?(?: \[workspace: (?<workspace>"(?:[^"\\]|\\.)*")\] )?@(?<version>[\w.+-]+)$. It accepts an optional JSON-quoted [workspace: "..."] segment immediately before @version, sets path to "." + titleDetails.path, and rejects paths whose slash-separated segments include "..".detailsFromContext() validates a parsed workspace by JSON.parse(workspaceJson) and rejects invalid JSON with Invalid publish workspace JSON in title; it also rejects empty names and Unicode control (\p{Cc}), format (\p{Cf}), line-separator (\p{Zl}), or paragraph-separator (\p{Zp}) characters with Workspace names must be nonempty and cannot contain Unicode control, format, or separator characters.detailsFromContext() sets dry_run to "1" only if context.payload.issue.labels.some((l) => l.name === "dry-run"); parses Merge target: <[\w.\-/]+> into merge_target (leaving it "" for (default)); and uses TARGETS_SECTION_PARSER_REGEX, TARGETS_PARSER_REGEX, and CHECKED_TARGETS_PARSER_REGEX to return only checked target IDs..github/workflows/release.yml supports both workflow_dispatch and workflow_call. Dispatch inputs are required version (default 'auto'), optional force, and optional workspace; callable inputs additionally include merge_target, blocker_label (default 'release-blocker'), publish_repo, git_user_name, git_user_email, path (default '.'), workspace, and craft_config_from_merge_target (default 'false')..github/workflows/release.yml has a build job only when github.repository == 'getsentry/craft'; the release job requires the build result to be either 'success' or 'skipped', uses actions/checkout@v6 with fetch-depth: 0, and outputs version, branch, sha, previous_tag, and changelog..github/workflows/release.yml obtains an app token via actions/create-github-app-token@v3 using vars.SENTRY_RELEASE_BOT_CLIENT_ID and secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY, then invokes local action ./ with dispatch version, force, and workspace. External repositories invoke getsentry/craft@v2 with all callable release inputs, including workspace and craft_config_from_merge_target, using github.token.src/config.ts:getVersioningPolicy() returns explicitly configured config.versioning.policy when present; otherwise it defaults to VersioningPolicy.Auto if minVersion >= '2.14.0' (AUTO_VERSION_MIN_VERSION) and VersioningPolicy.Manual otherwise for backward compatibility. Documented policies: 'auto' analyzes commits, 'manual' requires an explicit version, and 'calver' uses calendar versioning.src/config.ts:getGlobalGitHubConfig(clearCache = false) caches resolved GitHubGlobalConfig in _globalGitHubConfigCache; if config has no github, it checks Git remotes, preferring origin then the first remote, parses the push/fetch URL with GitUrlParse, and adopts { owner, repo } only when remoteUrl.source === 'github.com'. It freezes the cached result and throws ConfigurationError('GitHub configuration not found in the config file and cannot be determined from Git') when cached resolution is null.src/config.ts:getGitTagPrefix() uses the first active-config target named 'github' and its tagPrefix (default ''). If multiple GitHub targets have differing prefixes, it warns that the first is being used and recommends top-level workspaces entries per independently versioned monorepo product, or separate .craft.yml files, each with one GitHub target and its own prefix.src/config.ts:getArtifactProviderFromConfig() defaults artifactProviderName to ArtifactProviderName.GitHub, combines configured artifact settings with repoName/repoOwner from getGlobalGitHubConfig(), and supports NoneArtifactProvider, GCSArtifactProvider, and GitHubArtifactProvider; other values throw ConfigurationError('Invalid artifact provider'). getStatusProviderFromConfig() defaults to StatusProviderName.GitHub, creates GitHubStatusProvider, and rejects other status providers with ConfigurationError('Invalid status provider').src/commands/prepare.ts:prepareMain() supports argv.configFrom: it fetches [argv.remote, argv.configFrom], loads ${argv.remote}/${argv.configFrom}:${CONFIG_FILE_NAME} via git.show, and warns that the remote branchβs .craft.yml preReleaseCommand will execute and therefore the branch must be trusted. Fetch/load failure becomes ConfigurationError('Failed to load ${CONFIG_FILE_NAME} from branch "${argv.configFrom}": ${error.message}').prepareMain() resolves the release revision as argv.rev || repoStatus.current || defaultBranch; unless argv.noGitChecks, it calls checkGitStatus(repoStatus, rev); resolves a version through resolveVersion(git, { versionArg: argv.newVersion, calverOffset: argv.calverOffset }); emits it as GitHub Actions output version; prompts for confirmation when no explicit rev is given and the current revision is not the default branch.prepareMain() creates dry-run isolation with createDryRunIsolation(git, rev), then creates a release branch, obtains the prior tag only after branch creation via getLatestTag(git, getGitTagPrefix()), prepares/stages changelog changes, runs runPreReleaseCommand, commits changes, previews the dry-run diff, pushes unless argv.noPush, and emits branch, sha, and previous_tag outputs.@-mentions with bold formatting, avoiding contributor notifications; committed CHANGELOG.md content retains original mentions.src/commands/prepare.ts:927-942, CalVer is detected when argv.newVersion === 'calver' or getVersioningPolicy() === VersioningPolicy.CalVer; then disableChangelogMentions(changelogBody) produces issueChangelog, otherwise the original changelog is used. writeGitHubActionsFile('changelog', issueChangelog) writes it to a file to avoid E2BIG when action.yml would expand large changelogs into an environment variable; documentation cites a roughly 2 MB Linux ARG_MAX limit.src/__tests__/action.test.ts creates temporary fake craft and git executables, then verifies Craft Prepare and Read Craft Targets pass option-like workspace '--config-from=untrusted' inline as prepare --workspace=--config-from=untrusted and targets --workspace=--config-from=untrusted, preventing it from being interpreted as a separate option.src/__tests__/action.test.ts verifies both Craft Prepare and Read Craft Targets set WORKSPACE to '${{ inputs.workspace }}'; requires Validate workspace to be the first action step; verifies invalid workspace characters ('cli\tnext', 'cli\u202enext', 'cli\u2028next', 'cli\u2029next') fail before any fake git or craft side effects; and accepts '' plus 'cli-ζ₯ζ¬θͺ'.publish-workspace-acceptance/src/modules/__tests__/details-from-context.js tests ordinary parsing of publish: getsentry/sentry@21.3.1 into repo: 'sentry', version: '21.3.1', path: '.', merge_target: 'custom-branch', dry_run: '', and checked targets ['github', 'npm[@sentry/node]', 'docker[latest]']; it also accepts versions containing +, e.g. '4.2.6+sentry1'.details-from-context.js tests workspace-title parsing for 'publish: getsentry/toolkit [workspace: "cli/v2"] @1.2.3', escaped workspace 'cli [preview] "next"', and safe Unicode 'cli-ζ₯ζ¬θͺ'; it rejects legacy unexpected spacing before the version ('publish: getsentry/toolkit @1.2.3'), invalid JSON escape \\q, empty workspace, newline/NUL/tab/bidi/line-separator/paragraph-separator workspace content, target-checkout-escaping path 'getsentry/toolkit/../other@1.2.3', and missing issue context.path examples in docs/src/content/docs/targets/gcs.md (release/{{version}}/download, release/{{revision}}/platform/package), a path example in docs/src/content/docs/getting-started.md:271, and path: HomebrewFormula in docs/src/content/docs/targets/brew.md:44.