ship-app
Skill17 starsChanged 32 days agoMITView on GitHub
Stage, commit, push, and open a PR for one app, gated on a passing validation, then watch CI to a terminal state. Use when the user says "ship it", "open a PR", "deploy <slug>", or after preview and review look good.
- Deletes or force-pushes
- Commits and pushes
In this repository9 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- releaseSkill
- build-appSkill
- migrate-appSkill
- onboardSkill
- preview-appSkill
- review-appSkill
- sql-reviewSkill
- validate-appSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Preflight 0: review gate (asks, never blocks): Run streamsnow review-gate classify <slug> --format json and gate on .apps[0].needs_review …
- Distinctive: line 29
Hard gate: run /validate-app. Any FAIL → stop.
- Very specific: line 66
When the watch sees MERGED or step 4 finds a squash-merged branch, follow after-merge.md: it asks once only when the user did not approve …
- Distinctive: line 87
Before closing, ask what went wrong or got re-done and which layer fell short (config, a skill, a check or the deploy path).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/ship-app
Repo overlay: if
.streamsnow/overlays/ship-app.mdexists in this repo, read it first — committed, repo-specific additions/overrides (_shared/overlays.md). Outside Claude Code, also read _shared/other-agents.md.
Take a built app from working tree to open PR, gated on validation, then watch CI. One app at a
time; deployment is CI-only on merge to main — never a local Snowflake deploy. Repo-level
changes (templates, governance, CI) do not belong in a /ship-app PR; commit those separately.
Steps
- Resolve the slug;
git status --short apps/<slug>must show changes to ship — zero changes ahead ofmain→ nothing to PR; stop and say so. - Preflight 0: review gate (asks, never blocks). Run
streamsnow review-gate classify <slug> --format jsonand gate on.apps[0].needs_review(verdictis only review depth). False (reviewed, trivial or skip marker) → proceed. True → offer review first (/review-app <slug> --auto) or ship as-is, always available (ships can be time-critical; /validate-app + CI are the real publish gates), noting "shipped unreviewed" in the PR body. SQL changed → recommend/sql-review <slug>before merge (never required). Never auto-run either. Save.apps[0].commits_since_review,reviewed_head_statusand the JSON fromstreamsnow review-loop open-findings apps/<slug>/.reviewnow (the step 7 rebase rewrites SHAs); after a review-first pass, re-run these saves. - Hard gate: run /validate-app. Any FAIL → stop; report and do not stage, commit, or push. /validate-app is the fix-it path — don't auto-fix here.
- Branch hygiene. On
main→git switch -c ship/<slug>-<desc>first. Never reuse a squash-merged branch: a three-way merge can silently revert your own deletions. Checkgh pr list --search "head:$(git branch --show-current) is:merged" --json number; non-empty = spent: start fresh offmain, re-apply (cherry-pick or copy, nevergit mergethe old branch), and after step 6 clean it up per After merge. A stop there never ends the ship. - Stage only the app:
git add apps/<slug>(plus the repo README only if its app-index row changed). Showgit diff --cached --stat; unstage anything else — don't widen scope to "fix one more thing". - Commit conventionally (
feat(<slug>): <summary>), the summary matching the diff — underclaim, never overclaim. Pre-commit hooks block → stop and surface the error; never--no-verify(the hooks run the same checks CI does). - Sync with
origin/mainbefore pushing per sync-with-main: rebase (never merge), thengit push --force-with-lease. A rebase conflict stops with manual instructions — don't guess a resolution. - Push (
git push -u origin HEADif the sync didn't already) — refuse to push tomain. - Open the PR (title/body: what changed, validation passed, then
Open critical: Nand the commits since review from step 2, per these rules). Print the number and URL. - Note the deploy path: merging to
maintriggers CI, which deploys — no local deploy step. - Watch to a terminal state in the background, reporting once on exit. PR checks:
gh pr checks <num> --watchandgh pr view <num> --json state,mergeStateStatus. A host that tracks PR checks and forbids polling CI (PR checks only): hand over that command and end at "PR open, checks pending". Merged: alwaysgh run watch <id> --exit-statusthe deploy run.
Reporting the outcome
- A check fails → name it; translate deploy failures via _shared/deploy-error-translator.md (failure signatures differ by runtime — see _shared/runtime-decision.md); stop.
- Green but unmerged → it's waiting on a teammate's approval (you can't approve your own PR) — say so plainly rather than looping on the checks. /ship-app never merges; it stops here.
- Merged → confirm, report the deploy run's outcome; green →
streamsnow app-url <slug>per click-through.md (the link and checklist), then After merge.
After merge
When the watch sees MERGED or step 4 finds a squash-merged branch, follow after-merge.md: it asks once only when the user did not approve the merge in this run.
Gotchas
- Squash-merged branch reuse is the highest-severity trap — it fails silently: CI passes, the deploy ships the wrong code. The step 4 check is non-negotiable.
- Commit message must match the diff. A claimed change with no matching hunk means a fix was lost (often in manual conflict resolution): re-read the diff and correct one or the other first.
- Most deploy-run failures resolve to one-time, admin-applied DDL emitted by
streamsnow deploy-setup --admin: surface the named fix; never run DDL from here. - Push rejected (stale
--force-with-lease) → re-fetch, rebase, push, never plain--force. PR opens "behind" →mainmoved; re-run the sync step and let checks re-run.
Done when
The PR is open, validated before staging, rebased on current origin/main, and checks reached a
terminal state, reported: a named failed check, "awaiting approval," or merged + the deploy result.
Polling PR checks not allowed: "PR open, checks pending". Merged: on main, spent branch removed.
System-evolution retro (always, even on a clean ship)
Before closing, ask what went wrong or got re-done and which layer fell short (config, a skill, a check or the deploy path). Fix that layer, not the instance: retro.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

