Dashboard › craft › Distillation
ad73b9ff-b9c4-4cfa-82e9-c6c983784190["lore_tm_v1_QnAp-scqmGZTmyDDj-GNA0NiIoH2VuPWXSZOOtvBBHs","lore_tm_v1_EQTzr5jm5OuQXlU9c0uI09hQjM_Tui7Llcyh9fK7hjE"]
Date: Sep 8, 2026
6dae341 (feat: propagate release workspaces) and matching src/commands/publish.ts:180, src/commands/publish.ts:191, and src/commands/__tests__/publish.test.ts:208; earlier matching revisions were 48620564f86d8724982cddb6506c040235fe8954 (publish.test.ts:209) and d48b90604ba5e86b80211effc4d91b5384492dc1 (publish.test.ts:209).workflow_dispatch must always be allowed for manual recovery..github/workflows/ci-poller.yml retains job gating vars.CI_POLLER_HAS_PENDING == 'true' || github.event_name == 'workflow_dispatch', concurrency group ci-status-poller, and cancel-in-progress: false; it now checks out the publish controller with actions/checkout@v7 at .__publish__.ci-poller.yml replaces permissive shell sed title parsing and global body SHA substitution with node .__publish__/src/publish/resolve-ci-poller-input.js, passing PUBLISH_ISSUE_BODY_FILE, PUBLISH_TITLE, and, for revision updates, PUBLISH_REVISION; canonical parsed output provides .repo, .version, .revision, and .issueBody.ci-poller.yml serializes each issue body into a mktemp file using printf '%s' "$issue" | jq -jr '.body'; parse failures warn Could not parse canonical publish input for issue #${number}, skipping., delete the temporary file, and skip that issue.ci-poller.yml regenerates only the canonical issue body revision through resolve-ci-poller-input.js, writes .issueBody to a second temporary file, calls gh issue edit ... --body-file, and cleans up both temporary files; this replaces the previous updated_body="${body//${issue_sha}/${sha}}" global replacement.ci-poller.yml continues to poll only open issues carrying both ci-pending and accepted, up to 200; cross-repository GitHub APIs use a release-bot token through gh_api_release(), which captures stderr/stdout and returns nonzero on API failure including 404s..github/workflows/cocoapods-keepalive.yml changes its workflow display name from quoted "CocoaPods Token Keep-Alive" to unquoted CocoaPods Token Keep-Alive; it still runs daily at midnight UTC (0 0 * * *) and via workflow_dispatch, on macos-15 in production, installing CocoaPods, printing pod --version, and executing pod trunk me > /dev/null 2>&1..github/workflows/publish.yml adds Resolve CI-approved release revision (id: release-revision) after Parse and set inputs, invoking node .__publish__/src/publish/resolve-release-revision.js with PUBLISH_ARGS and PUBLISH_ISSUE_BODY; Inform start now requires both steps.inputs.outcome == 'success' and steps.release-revision.outcome == 'success'.publish.yml removes the Set target repo checkout branch allowlist that previously selected merge-target branches for sentry-migr8/tmp-merge-target, sentry-javascript/{v10,v9,v8,v7,master}, sentry-python/alpha, and sentry-wizard/1.x; target-repository checkout now uses ref: ${{ steps.release-revision.outputs.revision }} instead of steps.target-repo-branch.outputs.target_repo_branch || ''.publish.yml adds Resolve publish location (id: location), running node .__publish__/src/publish/discover-location.js with PUBLISH_ARGS and PUBLISH_REPOSITORY_DIRECTORY: __repo__; subsequent steps use steps.location.outputs.result.path and optional .workspace.publish.yml Set targets now has id: craft-state, sets CRAFT_PUBLISH_PATH from resolved location and CRAFT_PUBLISH_WORKSPACE from its optional workspace, and writes state_file=<path> to $GITHUB_OUTPUT.publish.yml hardens safe Craft state-file generation: computes container_cwd with realpath -m "/github/workspace/__repo__/$CRAFT_PUBLISH_PATH" and exits with ::error::Publish path must remain inside the target checkout. unless it is /github/workspace/__repo__ or a descendant; it hashes that canonical container path via sha1sum | cut -c1-12.publish.yml mirrors Craftβs state filename encoding: sanitizes owner/repository/version; uses version-${base64url(version)} when sanitization changes the version; prepends workspace-${base64url(workspace)}- when workspace is nonempty; and writes .craft-state/craft/publish-state-${owner_sanitised}-${repo_sanitised}-${cwd_hash}-${workspace_prefix}${version_component}.json.publish.yml invokes Craft from __repo__/${{ fromJSON(steps.location.outputs.result).path }} and runs craft publish <version> --rev ${{ steps.release-revision.outputs.revision }}; it supplies CRAFT_WORKSPACE and CRAFT_PUBLISH_STATE_GITHUB_REPO: getsentry/${{ fromJSON(steps.inputs.outputs.result).repo }} so state remains tied to issue checkout identity rather than an optional workspace GitHub release-repository override.publish.yml now passes CRAFT_STATE_FILE_PATH: ${{ steps.craft-state.outputs.state_file }} to node .__publish__/src/publish/update-issue.js, enabling completed target state synchronization before removing the label.README.md adds a ## Publish Issue Format section linking to docs/publish-issue-format.md as the stable title/body contract accepted for release workflow publish requests.package.json changes test from vitest run to yarn check:generated && vitest run, adds generate and check:generated scripts using scripts/generate-publish-issue-title-parser.js, and adds exact dev dependency peggy: "5.1.0".yarn.lock adds Peggy parser-generation dependency chain: peggy@5.1.0, @peggyjs/from-mem@3.1.3, commander@^14.0.3 resolved to 14.0.3, semver@7.7.4, and source-map-generator@2.0.6.