Dashboard › craft › Distillation
bb7367b3-d989-418a-8d12-cae23aff65a5["lore_tm_v1_1P55O6KsojOpTGPVktllrwYoRdHS_LjlC7QZjZj74dE","lore_tm_v1_l6N0pIbkKAfXPS5Zxvcjq3ueldrA2FqRuZOg4tm8Rkg","lore_tm_v1_ykiNkJOt7nw_no6vYG9C_dvFkz-UtlncwA3toEhOQ6c","lore_tm_v1_1ojBn2PdhaK322X4R7gxqYdvSO-SQaGinE8F9ALLoAc","lore_tm_v1_EsYntswaWATWlRvbvRyLyi3p1j6bsP1QPWRdjP6QpAc"]
Date: Aug 26, 2026
src/__tests__/action.test.ts defines an action-step test harness that loads action.yml with js-yaml, runs named steps through bash -e -c, and creates temporary fake craft/git binaries recording calls in CRAFT_CALLS and GIT_CALLS; afterEach recursively removes all craft-action-test-* temporary directories.src/__tests__/action.test.ts tests that option-looking workspace name --config-from=untrusted is passed inline rather than interpreted as a separate Craft option: Craft Prepare and Read Craft Targets must exit 0, with exact calls prepare --workspace=--config-from=untrusted and targets --workspace=--config-from=untrusted.src/__tests__/action.test.ts tests validation ordering: Validate workspace is the first action step; workspace cli\u202enext is rejected with exit status 1 before any Git or Craft side effect, leaving both recorded-call files empty.ci-ready label after checking CI; if ci-ready was already present, waiting-for-ci removes it first so a fresh labeled event fires..github/workflows/publish.yml publish job is gated exclusively on an open issue receiving the ci-ready label, while retaining accepted and ci-ready labels and lacking ci-pending/ci-failed; it intentionally does not trigger directly on accepted to avoid racing the waiting-for-ci workflow. Publish timeout is 90 minutes.CRAFT_WORKSPACE: ${{ fromJSON(steps.inputs.outputs.result).workspace || '' }}.src/utils/publishState.ts moves Craft publish-resume state from repository-local .craft-publish-<version>.json to $XDG_STATE_HOME/craft/, with fallback $HOME/.local/state/craft/; rationale: a committed repository file or earlier CI step could pre-populate completed targets and cause craft publish to silently skip targets.getCraftStateDir() in src/utils/publishState.ts returns join(process.env.XDG_STATE_HOME, 'craft') when XDG_STATE_HOME is nonempty; otherwise join(homedir(), '.local', 'state', 'craft').getPublishStateFilename(version, githubConfig, cwd = process.cwd(), workspace?) in src/utils/publishState.ts sanitizes owner/repo/version by lowercasing and replacing non-[a-z0-9._-] runs with _; GitHub-configured filenames are publish-state-<owner>-<repo>-<sha1(cwd)[:12]>-<workspace-prefix><version>.json, while non-GitHub/offline filenames are publish-state-<sha256(cwd)[:16]>-<workspace-prefix><version>.json.Buffer.from(workspace).toString('base64url'), producing workspace-<base64url>- before the version; this prevents same-repository/same-version independent release units from sharing completed-target state.getPublishStatePath(version, githubConfig, cwd = process.cwd(), workspace?) returns join(getCraftStateDir(), getPublishStateFilename(version, githubConfig, cwd, workspace)).sha1sum | cut -c1-12, base64url-encodes CRAFT_PUBLISH_WORKSPACE via base64 -w 0 | tr '+/' '-_' | tr -d '=', and writes state under an external XDG-state location so repository contents cannot pre-populate it.src/index.ts resolves the active workspace before yargs command parsing/builders by calling setActiveWorkspace(extractWorkspaceSelection(argv)); rationale: builders read config-derived target choices before middleware, so selection must come from raw --workspace or CRAFT_WORKSPACE according to extractWorkspaceSelection precedence.src/index.ts exposes a workspace CLI option described as selecting a named workspace/release unit from configuration, required when config defines "workspaces", with CRAFT_WORKSPACE as its environment-variable counterpart.