Dashboard › craft › Distillation
24d5c106-5595-4afb-bfc8-590a2648e21d["lore_tm_v1_f42eknkbb6Ogn7jPOwnl4fO0kr6bP_rD9qn0jOyxJO4"]
Date: Aug 25, 2026
--workspace selector, never separately.npm, gcs, registry) may already have succeeded. Recovery sequence is: 1. verify completed targets via npm registry, GCS bucket, and release-registry repo; 2. update the publish issue body to check off completed targets; 3. re-add the accepted label to re-trigger publishing, which skips checked targets. Docker Hub 400 Bad Request during blob upload is a known transient infrastructure flake and retry resolves it.action.yml:241 constructs titles as publish: ${GITHUB_REPOSITORY}${SUBDIRECTORY}@${RESOLVED_VERSION}; existing-issue lookup matches only that title via gh issue list --json title | jq select(.title==$t) | first, without workspace/product ID. Current one-.craft.yml-per-product distinct-subdirectory convention avoids collisions, but a single-file multi-product workspaces: model could cause two root-level products at the same version to edit the wrong issue and merge/overwrite the ### Targets checklist into a mixed publish..opencode/plans/workspaces-redesign-design.md: add a workspace input to action.yml; thread it to craft prepare/craft targets; scope craft targets to the selected workspace; and key issue title, targets, and state by workspace. Proposed formats were publish: <repo> [<workspace>] @<version> or <repo>#<workspace>@<version>; the chosen title is publish: <repo> [<workspace>] @<version>, omitting the workspace segment when none is selected.getsentry/publish CI-gating state machine: accepted is added first; waiting-for-ci then adds ci-pending; the poller swaps it to ci-ready when CI passes; ci-failed is added on failure and removes accepted. Publish fires only on a fresh ci-ready label event, not on accepted. On retry, waiting-for-ci removes both ci-failed and stale ci-ready, adds ci-pending, comments, and triggers the poller. Concurrency is keyed by github.event.issue.title.ci-pending.yml; waiting-for-ci in publish.yml adds ci-pending only after accepted; poller swaps it to ci-ready; publish requires accepted && !ci-pending and cannot fire from the initial accepted event alone.publish: getsentry/relay/py@0.9.26 cannot use naive sed 's/^publish: \(.*\)@.*/\1/p', which yields invalid GitHub repo getsentry/relay/py and causes 404s. Required parser is sed -n 's|^publish: \([^/]*/[^/@]*\).*@.*|\1|p', extracting only owner/repo; applies to ci-poller.yml, auto-approve.yml, and craft-action.yml request-publish workflows.action.yml input ci_ready: 'true' causes craft prepare to create the publish issue with ci-pending atomically through gh issue create --label; signal-ready/action.yml is a composite action that sends repository_dispatch event type ci-ready with {repo, version, sha} to the publish repo after target CI passes. ci-ready.yml finds the exact publish: {repo}@{version} title, verifies ci-pending, and swaps labels. Sender requires publish-repo write access via a sentry-release-bot app token, not GITHUB_TOKEN.ci-poller.yml uses self-dispatch rather than relying only on GitHub Actions */5 cron, which can drift to 30–40 minutes under load. While pending issues remain it invokes gh workflow run itself, capped at 60 attempts (~30 minutes); concurrency group ci-status-poller has cancel-in-progress: false, yielding roughly 30–60 seconds between checks. It starts from waiting-for-ci upon accepted; cron is a fallback and skips when CI_POLLER_HAS_PENDING == 'false'. Self-dispatch must require successful steps.token and steps.remaining outcomes to avoid dispatching with an empty token.