* feat: /gsd:ship command for PR creation from verified phase work (#829) New command that bridges local completion → merged PR, closing the plan → execute → verify → ship loop. Workflow (workflows/ship.md): 1. Preflight: verification passed, clean tree, correct branch, gh auth 2. Push branch to remote 3. Auto-generate rich PR body from planning artifacts: - Phase goal from ROADMAP.md - Changes from SUMMARY.md files - Requirements addressed (REQ-IDs) - Verification status - Key decisions 4. Create PR via gh CLI (supports --draft) 5. Optional code review request 6. Update STATE.md with shipping status Files: - commands/gsd/ship.md: New command entry point - get-shit-done/workflows/ship.md: Full workflow implementation - get-shit-done/workflows/help.md: Add ship to help output - docs/COMMANDS.md: Command reference - docs/FEATURES.md: Feature spec with REQ-SHIP-01 through 05 - docs/USER-GUIDE.md: Add to command table - CHANGELOG.md: Document new command Fixes #829 * fix(tests): update expected skill count from 39 to 40 for new ship command The Copilot install E2E tests hardcode the expected number of skill directories and manifest entries. Adding commands/gsd/ship.md increased the count from 39 to 40.
This commit is contained in:
@@ -12,6 +12,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
- Pre-wave dependency check in `execute-phase`: verifies key-links from prior wave artifacts before spawning next wave
|
||||
- Cross-Plan Data Contracts (Dimension 9) in plan-checker: detects incompatible transformations between plans sharing data pipelines
|
||||
- Export-level spot check in `verify-phase`: catches dead stores that exist in wired files but are never called
|
||||
- **`/gsd:ship` command** — Native PR creation workflow that bridges local completion → merged PR. Auto-generates rich PR body from planning artifacts (SUMMARY.md, VERIFICATION.md, REQUIREMENTS.md), pushes branch, creates PR via `gh`, optionally requests review, and updates STATE.md with shipping status (#829)
|
||||
|
||||
### Fixed
|
||||
- **Requirements `mark-complete` is now idempotent** — Re-marking already-completed requirements returns `already_complete` instead of `not_found` (#948)
|
||||
|
||||
23
commands/gsd/ship.md
Normal file
23
commands/gsd/ship.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: gsd:ship
|
||||
description: Create PR, run review, and prepare for merge after verification passes
|
||||
argument-hint: "[phase number or milestone, e.g., '4' or 'v1.0']"
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Bash
|
||||
- Grep
|
||||
- Glob
|
||||
- Write
|
||||
- AskUserQuestion
|
||||
---
|
||||
<objective>
|
||||
Bridge local completion → merged PR. After /gsd:verify-work passes, ship the work: push branch, create PR with auto-generated body, optionally trigger review, and track the merge.
|
||||
|
||||
Closes the plan → execute → verify → ship loop.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/ship.md
|
||||
</execution_context>
|
||||
|
||||
Execute the ship workflow from @~/.claude/get-shit-done/workflows/ship.md end-to-end.
|
||||
@@ -132,6 +132,32 @@ User acceptance testing with auto-diagnosis.
|
||||
|
||||
---
|
||||
|
||||
### `/gsd:ship`
|
||||
|
||||
Create PR from completed phase work with auto-generated body.
|
||||
|
||||
| Argument | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `N` | No | Phase number or milestone version (e.g., `4` or `v1.0`) |
|
||||
| `--draft` | No | Create as draft PR |
|
||||
|
||||
**Prerequisites:** Phase verified (`/gsd:verify-work` passed), `gh` CLI installed and authenticated
|
||||
**Produces:** GitHub PR with rich body from planning artifacts, STATE.md updated
|
||||
|
||||
```bash
|
||||
/gsd:ship 4 # Ship phase 4
|
||||
/gsd:ship 4 --draft # Ship as draft PR
|
||||
```
|
||||
|
||||
**PR body includes:**
|
||||
- Phase goal from ROADMAP.md
|
||||
- Changes summary from SUMMARY.md files
|
||||
- Requirements addressed (REQ-IDs)
|
||||
- Verification status
|
||||
- Key decisions
|
||||
|
||||
---
|
||||
|
||||
### `/gsd:ui-review`
|
||||
|
||||
Retroactive 6-pillar visual audit of implemented frontend.
|
||||
|
||||
@@ -261,6 +261,25 @@
|
||||
|
||||
---
|
||||
|
||||
### 6.5. Ship
|
||||
|
||||
**Command:** `/gsd:ship [N] [--draft]`
|
||||
|
||||
**Purpose:** Bridge local completion → merged PR. After verification passes, push branch, create PR with auto-generated body from planning artifacts, optionally trigger review, and track in STATE.md.
|
||||
|
||||
**Requirements:**
|
||||
- REQ-SHIP-01: System MUST verify phase has passed verification before shipping
|
||||
- REQ-SHIP-02: System MUST push branch and create PR via `gh` CLI
|
||||
- REQ-SHIP-03: System MUST auto-generate PR body from SUMMARY.md, VERIFICATION.md, and REQUIREMENTS.md
|
||||
- REQ-SHIP-04: System MUST update STATE.md with shipping status and PR number
|
||||
- REQ-SHIP-05: System MUST support `--draft` flag for draft PRs
|
||||
|
||||
**Prerequisites:** Phase verified, `gh` CLI installed and authenticated, work on feature branch
|
||||
|
||||
**Produces:** GitHub PR with rich body, STATE.md updated
|
||||
|
||||
---
|
||||
|
||||
### 7. UI Review
|
||||
|
||||
**Command:** `/gsd:ui-review [N]`
|
||||
|
||||
@@ -284,6 +284,7 @@ Controlled by `workflow.ui_safety_gate` config toggle.
|
||||
| `/gsd:plan-phase [N]` | Research + plan + verify | Before executing a phase |
|
||||
| `/gsd:execute-phase <N>` | Execute all plans in parallel waves | After planning is complete |
|
||||
| `/gsd:verify-work [N]` | Manual UAT with auto-diagnosis | After execution completes |
|
||||
| `/gsd:ship [N]` | Create PR from verified work | After verification passes |
|
||||
| `/gsd:ui-review [N]` | Retroactive 6-pillar visual audit | After execution or verify-work (frontend projects) |
|
||||
| `/gsd:audit-milestone` | Verify milestone met its definition of done | Before completing milestone |
|
||||
| `/gsd:complete-milestone` | Archive milestone, tag release | All phases verified |
|
||||
|
||||
@@ -308,6 +308,20 @@ Validate built features through conversational UAT.
|
||||
|
||||
Usage: `/gsd:verify-work 3`
|
||||
|
||||
### Ship Work
|
||||
|
||||
**`/gsd:ship [phase]`**
|
||||
Create a PR from completed phase work with an auto-generated body.
|
||||
|
||||
- Pushes branch to remote
|
||||
- Creates PR with summary from SUMMARY.md, VERIFICATION.md, REQUIREMENTS.md
|
||||
- Optionally requests code review
|
||||
- Updates STATE.md with shipping status
|
||||
|
||||
Prerequisites: Phase verified, `gh` CLI installed and authenticated.
|
||||
|
||||
Usage: `/gsd:ship 4` or `/gsd:ship 4 --draft`
|
||||
|
||||
### Milestone Auditing
|
||||
|
||||
**`/gsd:audit-milestone [version]`**
|
||||
|
||||
228
get-shit-done/workflows/ship.md
Normal file
228
get-shit-done/workflows/ship.md
Normal file
@@ -0,0 +1,228 @@
|
||||
<purpose>
|
||||
Create a pull request from completed phase/milestone work, generate a rich PR body from planning artifacts, optionally run code review, and prepare for merge. Closes the plan → execute → verify → ship loop.
|
||||
</purpose>
|
||||
|
||||
<required_reading>
|
||||
Read all files referenced by the invoking prompt's execution_context before starting.
|
||||
</required_reading>
|
||||
|
||||
<process>
|
||||
|
||||
<step name="initialize">
|
||||
Parse arguments and load project state:
|
||||
|
||||
```bash
|
||||
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init phase-op "${PHASE_ARG}")
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
```
|
||||
|
||||
Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`.
|
||||
|
||||
Also load config for branching strategy:
|
||||
```bash
|
||||
CONFIG=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state load)
|
||||
```
|
||||
|
||||
Extract: `branching_strategy`, `branch_name`.
|
||||
</step>
|
||||
|
||||
<step name="preflight_checks">
|
||||
Verify the work is ready to ship:
|
||||
|
||||
1. **Verification passed?**
|
||||
```bash
|
||||
VERIFICATION=$(cat ${PHASE_DIR}/*-VERIFICATION.md 2>/dev/null)
|
||||
```
|
||||
Check for `status: passed` or `status: human_needed` (with human approval).
|
||||
If no VERIFICATION.md or status is `gaps_found`: warn and ask user to confirm.
|
||||
|
||||
2. **Clean working tree?**
|
||||
```bash
|
||||
git status --short
|
||||
```
|
||||
If uncommitted changes exist: ask user to commit or stash first.
|
||||
|
||||
3. **On correct branch?**
|
||||
```bash
|
||||
CURRENT_BRANCH=$(git branch --show-current)
|
||||
```
|
||||
If on `main`/`master`: warn — should be on a feature branch.
|
||||
If branching_strategy is `none`: offer to create a branch now.
|
||||
|
||||
4. **Remote configured?**
|
||||
```bash
|
||||
git remote -v | head -2
|
||||
```
|
||||
Detect `origin` remote. If no remote: error — can't create PR.
|
||||
|
||||
5. **`gh` CLI available?**
|
||||
```bash
|
||||
which gh && gh auth status 2>&1
|
||||
```
|
||||
If `gh` not found or not authenticated: provide setup instructions and exit.
|
||||
</step>
|
||||
|
||||
<step name="push_branch">
|
||||
Push the current branch to remote:
|
||||
|
||||
```bash
|
||||
git push origin ${CURRENT_BRANCH} 2>&1
|
||||
```
|
||||
|
||||
If push fails (e.g., no upstream): set upstream:
|
||||
```bash
|
||||
git push --set-upstream origin ${CURRENT_BRANCH} 2>&1
|
||||
```
|
||||
|
||||
Report: "Pushed `{branch}` to origin ({commit_count} commits ahead of main)"
|
||||
</step>
|
||||
|
||||
<step name="generate_pr_body">
|
||||
Auto-generate a rich PR body from planning artifacts:
|
||||
|
||||
**1. Title:**
|
||||
```
|
||||
Phase {phase_number}: {phase_name}
|
||||
```
|
||||
Or for milestone: `Milestone {version}: {name}`
|
||||
|
||||
**2. Summary section:**
|
||||
Read ROADMAP.md for phase goal. Read VERIFICATION.md for verification status.
|
||||
|
||||
```markdown
|
||||
## Summary
|
||||
|
||||
**Phase {N}: {Name}**
|
||||
**Goal:** {goal from ROADMAP.md}
|
||||
**Status:** Verified ✓
|
||||
|
||||
{One paragraph synthesized from SUMMARY.md files — what was built}
|
||||
```
|
||||
|
||||
**3. Changes section:**
|
||||
For each SUMMARY.md in the phase directory:
|
||||
```markdown
|
||||
## Changes
|
||||
|
||||
### Plan {plan_id}: {plan_name}
|
||||
{one_liner from SUMMARY.md frontmatter}
|
||||
|
||||
**Key files:**
|
||||
{key-files.created and key-files.modified from SUMMARY.md frontmatter}
|
||||
```
|
||||
|
||||
**4. Requirements section:**
|
||||
```markdown
|
||||
## Requirements Addressed
|
||||
|
||||
{REQ-IDs from plan frontmatter, linked to REQUIREMENTS.md descriptions}
|
||||
```
|
||||
|
||||
**5. Testing section:**
|
||||
```markdown
|
||||
## Verification
|
||||
|
||||
- [x] Automated verification: {pass/fail from VERIFICATION.md}
|
||||
- {human verification items from VERIFICATION.md, if any}
|
||||
```
|
||||
|
||||
**6. Decisions section:**
|
||||
```markdown
|
||||
## Key Decisions
|
||||
|
||||
{Decisions from STATE.md accumulated context relevant to this phase}
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="create_pr">
|
||||
Create the PR using the generated body:
|
||||
|
||||
```bash
|
||||
gh pr create \
|
||||
--title "Phase ${PHASE_NUMBER}: ${PHASE_NAME}" \
|
||||
--body "${PR_BODY}" \
|
||||
--base main
|
||||
```
|
||||
|
||||
If `--draft` flag was passed: add `--draft`.
|
||||
|
||||
Report: "PR #{number} created: {url}"
|
||||
</step>
|
||||
|
||||
<step name="optional_review">
|
||||
Ask if user wants to trigger a code review:
|
||||
|
||||
```
|
||||
AskUserQuestion:
|
||||
question: "PR created. Run a code review before merge?"
|
||||
options:
|
||||
- label: "Skip review"
|
||||
description: "PR is ready — merge when CI passes"
|
||||
- label: "Self-review"
|
||||
description: "I'll review the diff in the PR myself"
|
||||
- label: "Request review"
|
||||
description: "Request review from a teammate"
|
||||
```
|
||||
|
||||
**If "Request review":**
|
||||
```bash
|
||||
gh pr edit ${PR_NUMBER} --add-reviewer "${REVIEWER}"
|
||||
```
|
||||
|
||||
**If "Self-review":**
|
||||
Report the PR URL and suggest: "Review the diff at {url}/files"
|
||||
</step>
|
||||
|
||||
<step name="track_shipping">
|
||||
Update STATE.md to reflect the shipping action:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state update "Last Activity" "$(date +%Y-%m-%d)"
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state update "Status" "Phase ${PHASE_NUMBER} shipped — PR #${PR_NUMBER}"
|
||||
```
|
||||
|
||||
If `commit_docs` is true:
|
||||
```bash
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(${padded_phase}): ship phase ${PHASE_NUMBER} — PR #${PR_NUMBER}" --files .planning/STATE.md
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="report">
|
||||
```
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
## ✓ Phase {X}: {Name} — Shipped
|
||||
|
||||
PR: #{number} ({url})
|
||||
Branch: {branch} → main
|
||||
Commits: {count}
|
||||
Verification: ✓ Passed
|
||||
Requirements: {N} REQ-IDs addressed
|
||||
|
||||
Next steps:
|
||||
- Review/approve PR
|
||||
- Merge when CI passes
|
||||
- /gsd:complete-milestone (if last phase in milestone)
|
||||
- /gsd:progress (to see what's next)
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
```
|
||||
</step>
|
||||
|
||||
</process>
|
||||
|
||||
<offer_next>
|
||||
After shipping:
|
||||
|
||||
- /gsd:complete-milestone — if all phases in milestone are done
|
||||
- /gsd:progress — see overall project state
|
||||
- /gsd:execute-phase {next} — continue to next phase
|
||||
</offer_next>
|
||||
|
||||
<success_criteria>
|
||||
- [ ] Preflight checks passed (verification, clean tree, branch, remote, gh)
|
||||
- [ ] Branch pushed to remote
|
||||
- [ ] PR created with rich auto-generated body
|
||||
- [ ] STATE.md updated with shipping status
|
||||
- [ ] User knows PR number and next steps
|
||||
</success_criteria>
|
||||
Reference in New Issue
Block a user