Dashboard › craft › Distillation
30629412-23f0-4bee-8ee4-1b98471d6e02["lore_tm_v1_ceHrEhsbtN6J5oPHWS2pYQngCvmknYzKRy-JzEZs794","lore_tm_v1_y6UhOyJD5ITajUYzc4M6RTMa7vzP1S6xiqlyU-5ZC7M","lore_tm_v1_cInw-k_RJ0YWI6Jsfk7lZKtvCQXjF_W6zp6QJETvWxA","lore_tm_v1_8YsIi6H0j1S74sFj5AhIA-2L7qj5yvv5Z58PvnlCmWk"]
Date: Sep 3, 2026
ci-ready after checking CI..github/workflows/publish.yml is a Publish workflow triggered by issues labeled events. It uses concurrency group ${{ github.event.issue.title }} with cancel-in-progress: false, and permissions contents: read, issues: write, packages: write..github/workflows/publish.yml waiting-for-ci job runs on accepted labeling of an open issue whose title starts publish: . It runs in production; acquires an app token through actions/create-github-app-token@v3 using SENTRY_INTERNAL_APP_ID and SENTRY_INTERNAL_APP_PRIVATE_KEY..github/workflows/publish.yml Mark ci-pending step resets an accepted issue by removing ci-failed and ci-ready, then adding ci-pending via gh issue edit. Removing ci-ready is required so the poller’s subsequent --add-label ci-ready generates a fresh labeled event after retrying a publish failure..github/workflows/publish.yml comments “Retrying — CI was previously failed. Checking CI status now.” if the triggering issue had ci-failed; otherwise it comments “Approved. Checking CI status on the release branch. Publishing will start automatically when CI passes.”.github/workflows/publish.yml enables the cron CI poller best-effort by obtaining a dedicated CI_POLLER_APP_CLIENT_ID/CI_POLLER_APP_PRIVATE_KEY token, because sentry-internal-app lacks actions_variables:write, then setting repository variable CI_POLLER_HAS_PENDING to true. It immediately triggers ci-poller.yml with gh workflow run; an app token is required because GITHUB_TOKEN-originated workflow_dispatch events are suppressed..github/workflows/publish.yml publish job runs only for open issues on a ci-ready label event where labels include accepted and ci-ready, and exclude ci-pending and ci-failed; it has timeout-minutes: 90. This prevents racing the waiting-for-ci job and prevents publishing without CI verification during auto-approval races..github/workflows/publish.yml publish job checks out its own workflow repository to .__publish__, uses actions/setup-node@v6 with Node 24 and Yarn cache keyed by .__publish__/yarn.lock, runs yarn install --cwd ".__publish__", then executes src/publish/inputs.js and src/publish/resolve-release-revision.js..github/workflows/publish.yml checks out the target repository as getsentry/${{ fromJSON(steps.inputs.outputs.result).repo }} into __repo__, at ${{ steps.release-revision.outputs.revision }}, using a SENTRY_RELEASE_BOT_CLIENT_ID/SENTRY_RELEASE_BOT_PRIVATE_KEY app token with owner: getsentry and fetch-depth: 0..github/workflows/publish.yml resolves workspace names by running getsentry/craft:latest workspace list against __repo__ when __repo__/.craft.yml exists, then passes JSON via CRAFT_WORKSPACE_NAMES to src/publish/resolve-location.js..github/workflows/publish.yml Set targets creates a Craft publish-state JSON payload marking requested CRAFT_PUBLISH_TARGETS_JSON targets as already published. It writes the file under $GITHUB_WORKSPACE/.craft-state/craft/, outside __repo__/, to prevent repository contents from pre-populating state; this relies on getsentry/craft#797, released in Craft 2.26.0..github/workflows/publish.yml state-file naming hashes the canonical container cwd using sha1sum | cut -c1-12; it validates CRAFT_PUBLISH_PATH remains inside /github/workspace/__repo__. The filename is publish-state-${owner_sanitised}-${repo_sanitised}-${cwd_hash}-${workspace_prefix}${version_sanitised}.json, where a nonempty workspace uses URL-safe base64 without = as workspace-${workspace_encoded}-..github/workflows/publish.yml publishes with docker://getsentry/craft:latest, executing craft publish <version> --rev <CI-approved revision> from __repo__/<resolved path>. It pins XDG_STATE_HOME to /github/workspace/.craft-state, sets CRAFT_PUBLISH_STATE_GITHUB_REPO to the issue checkout repository rather than a workspace’s optional release-repository override, and configures CRAFT_MERGE_TARGET, CRAFT_LOG_LEVEL defaulting to Info, CRAFT_DRY_RUN, and CRAFT_WORKSPACE..github/workflows/publish.yml deliberately uses separate credentials for GHCR and cross-repository GitHub API operations: secrets.GITHUB_TOKEN as DOCKER_GHCR_IO_PASSWORD with username x-access-token, and the Release Bot app token as GITHUB_API_TOKEN/GITHUB_TOKEN. The workflow also references publishing credentials for Cloudflare, CocoaPods, GCS, crates.io, Docker, Hex, Twine, npm, RubyGems, AWS, NuGet, PowerShell, GPG, OSSRH, pub.dev, and Vercel; secret values were provided in workflow configuration and are not recorded..github/workflows/publish.yml on cancellation or failure runs src/publish/update-issue.js with CRAFT_STATE_FILE_PATH; it posts cancellation/failure results through src/publish/post-result.js, and on success posts success through the same script, which closes the issue./home/byk/Code/getsentry/publish-workspace-acceptance contains 15 top-level entries: .eslintrc.js, .git, .github/, .gitignore, AGENTS.md, auto-approve-repos.txt, docs/, LICENSE, node_modules/, package.json, README.md, scripts/, src/, vitest.config.js, and yarn.lock./home/byk/Code/getsentry/craft-workspace-action-propagation, src/commands/workspace_cmds/list.ts implements workspace list, described as “List defined release workspaces as a JSON array,” by printing formatJson(getWorkspaceNames()). Its tests verify exact configured workspace names ['cli', 'mcp.v2'] and an empty array when no workspaces are configured./home/byk/Code/getsentry/craft-workspace-action-propagation, src/commands/workspace.ts defines command workspace <command> with description “Manage release workspaces”; workspace-related behavior also appears in src/commands/targets.ts and src/commands/publish.ts, including workspace target expansion and workspace-resolved publish target choices./home/byk/Code/getsentry/craft-workspace-action-propagation/src/index.ts imports Sentry instrumentation (./instrument) first, before other code, and wraps main with withTracing(main, { name: 'craft.cli', op: 'cli' }).src/index.ts calls sanitizeDynamicLinkerEnv() before other CLI processing to prevent LD_PRELOAD, DYLD_*, and related dynamic-linker environment variables from leaking into subprocesses; it then calls warnIfCraftEnvFileExists().src/index.ts defines global boolean flags no-input (default isCI; suppresses prompts) and dry-run (default process.env.DRY_RUN; no file writes, commits, pushes, or API mutations). fixGlobalBooleanFlags() injects '1' after standalone flags so env-variable false-like strings and --flag=no behavior can coexist.src/index.ts resolves the active workspace before yargs parsing via setActiveWorkspace(extractWorkspaceSelection(argv)). Decision rationale: yargs command builders run before middleware, and publish builders read configuration to derive --target choices; resolving workspace in middleware would be too late and could fail validation for workspace configs. extractWorkspaceSelection(argv) is the single source of truth for --workspace/CRAFT_WORKSPACE precedence.src/index.ts configures yargs with boolean-negation: false, .env('CRAFT'), commands prepare, publish, targets, config, artifacts, changelog, and workspace, .strictCommands(), and setGlobals middleware. Its global workspace option is a string described as selecting a named release-unit workspace, required when configuration defines workspaces, with environment variable CRAFT_WORKSPACE.