Dashboard › craft › Distillation
b56c8765-a144-40bd-ba5b-4aa7335c0be2["lore_tm_v1_xmQDGDH-YhgFhsW4oPCnNbvyY_SaDDxBzvNyhm3mbo8","lore_tm_v1_CeKdJO2NJyprcIIGdoGrfMKIRJXX5Gfo_UuekbNukmQ","lore_tm_v1_kYgCYpQqRQu52zImZTcr2JhCBrCjHqwZkpPtxe1Y1vA","lore_tm_v1_URKFh-jx8o0PdG5zYVtLF6qFpAclXL-2wqKq9sEwgpw","lore_tm_v1_QG9HX8ttY_lTlkN_jH-3MMqifudJS125hI6mc4pcr34"]
Date: Sep 8, 2026
src/commands/workspace_cmds/list.ts defines the workspace list subcommand: command = ['list'], description 'List defined release workspaces as a JSON array', and handler() outputs formatJson(getWorkspaceNames()) with console.log.src/index.ts imports workspace from ./commands/workspace, registers it through .command(workspace), and defines global --workspace as a string option with description: 'Select a named workspace (release unit) from the configuration. Required when the config defines "workspaces". Env: CRAFT_WORKSPACE'.src/index.ts selects the active workspace before yargs parsing via setActiveWorkspace(extractWorkspaceSelection(argv)), because yargs command builders may read and validate workspace-resolved configuration before middleware executes; extractWorkspaceSelection is the single source of truth for CLI/env selection precedence.src/index.ts global boolean handling uses fixGlobalBooleanFlags(process.argv.slice(2)): standalone known flags from GLOBAL_BOOLEAN_FLAGS receive injected '1', allowing env-backed booleans and explicit --flag=no overrides while disallowing positional --flag no notation. GLOBAL_BOOLEAN_FLAGS includes no-input (default isCI) and dry-run (default process.env.DRY_RUN, TODO to deprecate in favor of CRAFT_DRY_RUN).--workspace --dry-run, must never be mistaken for a workspace name.extractWorkspaceSelection() in src/utils/helpers.ts uses Node built-in parseArgs() with { workspace: { type: 'string' } }, allowPositionals: true, strict: false, and tokens: true; it supports --workspace foo and --workspace=foo.extractWorkspaceSelection(): the last --workspace occurrence decides; an empty or bare final workspace flag clears an earlier CLI value and falls back to CRAFT_WORKSPACE; a CLI value wins over CRAFT_WORKSPACE only when it has a value; inline negative values such as --workspace=-foo are valid, while separated --workspace --foo is invalid because non-inline values beginning with - are rejected.src/utils/helpers.ts defines MAX_STEP_OUTPUT_BYTES = 64 * 1024 (64 KB) to truncate GitHub Actions step-output values and avoid E2BIG when subsequent steps expand outputs into environment variables; rationale notes this is below the approximately 2 MB ARG_MAX and GitHubβs approximately 65,536-character issue-body limit.envToBool() treats '', 'undefined', 'null', '0', 'false', and 'no' case-insensitively as false; all other values are true.setGitHubActionsOutput(name, value) is a no-op without GITHUB_OUTPUT; it appends single-line values as ${name}=${value}\n and multiline values with a generated EOF_${Date.now()}_${Math.random().toString(36).slice(2)} heredoc delimiter.publish command builder computes permitted --target choices from getConfiguration().targets after workspace resolution, retaining only known target implementations via getAllTargetNames() and mapping with BaseTarget.getId; if configuration cannot resolve during parse time, it falls back to all known target names rather than aborting parsing.publish commandβs target choices include configured target IDs plus SpecialTarget.All and SpecialTarget.None; default is SpecialTarget.All. Other documented options include --rev, --merge-target, --remote defaulting to 'origin', --no-merge, --keep-branch, --keep-downloads, --no-status-check, and --no-git-checks.publishMain() expands npm workspace targets through expandWorkspaceTargets(config.targets || []) before publishing, and keys publish state using getPublishStatePath(newVersion, getPublishStateGitHubConfig(publishStateGithubConfig), process.cwd(), getActiveWorkspace()), making state workspace-specific.getPublishStateGitHubConfig() permits CRAFT_PUBLISH_STATE_GITHUB_REPO only as a GitHub owner/repository pair matching /^(?<owner>[A-Za-z0-9_.-]+)\/(?<repo>[A-Za-z0-9_.-]+)$/; invalid values throw ConfigurationError('CRAFT_PUBLISH_STATE_GITHUB_REPO must be a GitHub owner/repository pair.'). This override is deliberately limited to publish-state identity because a controller checkout repository can differ from the workspace release GitHub configuration..craft-publish-${newVersion}.json exists in the project directory, Craft warns it will not read it for security because repository contents can be attacker-influenced through PRs, and directs workflows to $XDG_STATE_HOME/craft/.handleReleaseBranch() merge strategy decision: first attempt default Git merge strategy ort with --no-ff --no-edit; if that fails, abort and retry with -s resolve --no-ff --no-edit, chosen because it can handle criss-cross ambiguities differently and may succeed on files such as CHANGELOG.md. If both fail, it captures git.status().conflicted and git.diff(conflictedFiles), aborts, and throws MergeConflictError; a post-merge push failure instead throws PushError.captureException(mergeError) and reported with manual remediation steps, but do not fail an otherwise fully published release. MergeConflictError messaging states both ort and resolve failed and may list conflicted files/diff; PushError messaging states local merge succeeded but remote push failed, likely due to an expired token during publishes longer than 1 hour.publishMain() determines no-merge via argv.noMerge || getNoMergeConfig().noMerge; when config auto-detection enables it, --merge-target is warned as ignored, and the source is reported as either CLI option, auto-detection for a compiled GitHub Action with dist/ folder, or config.