One-way, on-demand tool to publish a staging ticket to production (for sharing on social without exposing staging)
Background
All ticket tracking happens on staging (staging.musehub.ai) — that's deliberate, per the standing "staging first" workflow. But gabriel shares tickets on social media as part of developing in public, and doesn't want to send people to staging infrastructure (it's not meant for public traffic, and pointing external visitors at it blurs the "this is our test environment" line).
Decision
Rejected a full bidirectional staging↔production issue sync: given the phantom-success write bug and issue-numbering collision found in this same session (staging's own issue-numbering already has fragility — see #182/#183/#184), layering an always-on two-way mirror on top of that is asking for silent divergence. Instead: a one-way, on-demand "publish" action. When gabriel wants to share a specific ticket, a script copies that ticket's current content to the production repo as a new issue — no ongoing sync obligation, no attempt to keep numbers aligned between environments.
Scope
scripts/dev/publish-issue.sh <staging-issue-number>— fetches the issue (title, body, labels) from staging viamuse hub issue read, creates an equivalent issue on the production repo viamuse hub issue create --hub https://musehub.ai, and prints the production URL.- Idempotency: running it twice for the same staging issue should not silently create two production copies — either detect an existing mirror (e.g. via a marker in the body, like a trailing
_Mirrored from staging#<n>._line) and update it in place, or refuse with a clear message pointing at the existing production issue. - Explicitly not in scope: comments, assignees (staging-only handles like
aaronrenemay not exist or mean the same thing on production), state transitions, or any kind of two-way sync. This is a one-shot content copy for public sharing, not a tracker mirror. - Should strip anything staging-specific from the body before publishing (staging URLs, references to internal-only tickets that don't exist on production) — at minimum, flag/warn if the source body contains a
staging.musehub.aiURL so gabriel can review before it goes public.
Suggested TDD approach
- Write tests first against a fake/mocked
muse hubCLI (or against a local hub instance) covering: fresh publish creates exactly one production issue with matching title/body/labels; re-running against the same staging issue updates the existing mirror rather than duplicating it; a body containing astaging.musehub.ailink triggers a warning. - Implement the script to pass.
- Manually verify against a real low-stakes staging ticket before using it on anything sensitive.
Mirrored from staging#186.