| name | ship |
| description | Ship the current changes end-to-end for songsue — branch off main, commit, push to origin (daydeda/songsue), open a PR, merge it into main, delete the branch (local + remote), tag the merge with a semver version + description, cut a GitHub release, and record the day's entry in updates/. Use when the user says "ship this", "commit + PR + merge", "open a PR and merge", or otherwise wants the full feature-branch → PR → merge → tag → release → cleanup flow in one go. For deploys that touch the DB schema or read a new column, run /safe-deploy first. |
Ship (songsue)
Takes working-tree changes from "done on main's worktree" to "merged into main,
tagged, and released" without ever pushing to main directly. The merge happens
through a PR — that is the only sanctioned path to main (see CLAUDE.md: never
push to main). Every ship ends with a new vX.Y.Z tag and a matching GitHub
release — this is not optional, it's the last two steps of the flow, same as the
changelog entry. All of this targets origin = daydeda/songsue — see the
remote warning below before pushing anything.
When to use
- The user asks to "ship", "commit and open a PR and merge", or lists the full
branch → PR → merge → delete-branch sequence.
- The change is already implemented and reviewed enough to land.
When NOT to use (or do something first)
- Schema / new-column changes: run /safe-deploy first — prod must be
migrated before code that reads a new column merges. This skill does not migrate.
- Unreviewed or risky diffs: run /recheck first.
- The user only wants a commit, or only a PR (no merge) — just do that step.
Preconditions (verify before branching)
- Build + lint pass. Run
npm run build and npm run lint. Pre-existing
warnings/errors in files you didn't touch are fine; do not let new ones land.
- Know what's staged.
git status --short — commit only the intended files.
- Confirm you're pushing to
origin, not upstream. This repo has two
remotes: origin = daydeda/songsue (this project, what every step below
must touch) and upstream = daydeda/smocamt-website (the separate
ActiveCAMT production repo this one was forked from — a different app, a
different deploy, not yours to push to). Run git remote -v if unsure. Every
push/gh pr create/gh pr merge/gh release create in this skill must
resolve to origin; never pass upstream or daydeda/smocamt-website to any
of them, and never push a branch/tag straight to upstream.
Steps
-
Branch off main. Pick a descriptive name: feat/..., fix/..., chore/....
git checkout -b feat/<short-description>
-
Stage + commit. Quote any path containing [ ] — this repo has routes like
src/app/api/events/[id]/register/route.ts, and zsh glob-expands the brackets
(no matches found) unless the path is single-quoted.
git add 'src/app/api/events/[id]/.../route.ts' 'src/app/...'
Commit with a clear subject + body, ending with the trailer:
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: <this session's claude.ai/code URL>
-
Push to origin (never upstream) and set upstream tracking:
git push -u origin feat/<short-description>
-
Open the PR against daydeda/songsue's main with gh. Pass --repo
explicitly — belt-and-suspenders against gh ever resolving to upstream
since this checkout has two remotes. End the body with:
🤖 Generated with [Claude Code](https://claude.com/claude-code)
gh pr create --repo daydeda/songsue --base main --head feat/<short-description> \
--title "<conventional commit title>" --body "<summary>"
-
Merge + delete the branch (deletes both remote and local, returns you to
main):
gh pr merge <PR#> --repo daydeda/songsue --merge --delete-branch
Use --merge (a real merge commit, matching this repo's history) unless the user
asks for --squash or --rebase.
-
Confirm clean state:
Notes
- If branch protection blocks
gh pr merge (required reviews/checks), stop and tell
the user — do not try to bypass it or push to main.
- If the merge is not a fast-forward and conflicts arise, stop and surface the
conflict rather than force-anything.
- This skill is git mechanics only. It does not deploy or migrate — Vercel
auto-deploys
daydeda/songsue's main on merge (see docs/songsue-deploy.md),
so make sure prod is already migrated (via /safe-deploy) for any schema-dependent
change before you run step 5 (the merge).
- Tagging (step 7) always happens after the merge (step 5) lands, never before —
the tag must point at a commit that's actually on
main.
origin vs upstream, one more time: this checkout tracks both
daydeda/songsue (origin, this skill's only target) and
daydeda/smocamt-website (upstream, the unrelated production ActiveCAMT repo).
If any command in this flow ever prompts to pick a repo, resolves ambiguously,
or you're about to type upstream anywhere in a push/PR/release command — stop
and re-check git remote -v before proceeding.