Ship It
Automate the full PR lifecycle: commit changes, create a PR, wait for CI/CD, and squash merge into main.
Workflow
Follow each step sequentially. Stop and report to the user if any step fails.
Step 1: Pre-flight Checks
Run these checks before anything else. If any fail, stop and tell the user why.
- Branch check: Run
git branch --show-current. If in detached HEAD state, stop — tell the user to check out a named branch. - Remote check: Run
git remote -v. If no remote is configured, stop — tell the user to add a remote. - GitHub CLI check: Run
gh auth status. If not authenticated, stop — tell the user to rungh auth login.
Save the current branch name for later use.
Step 2: Handle Uncommitted Changes
- Run
git status --porcelainto check for uncommitted changes (staged, unstaged, and untracked). - If the working tree is clean (no output) and not on
main, skip to Step 3. If the working tree is clean and onmain, stop — there is nothing to ship. - If there are changes, display the list of changed files and ask the user:
- A) Include all changes — stage everything shown
- B) Select individual files — present a numbered list and let the user pick which files to include (e.g., "1, 3, 5")
- C) Cancel — abort the entire workflow
- Stage the selected files using
git add <file1> <file2> ...with explicit file paths. Never usegit add -Aorgit add .. - Run
git diff --cached --statandgit diff --cachedto understand the changes. - If on
main, create a feature branch before committing (see Step 2b below). - Generate a clear, descriptive commit message based on the diff.
- Create the commit.
Step 2b: Create Feature Branch (if on main)
This step is called from Step 2.6 when the current branch is main. The branch must be created before the commit so that local main stays clean and avoids divergence after the PR is squash-merged.
- Generate a descriptive branch name from the staged changes (e.g.,
feat/add-user-validation,fix/null-pointer-in-parser). Use kebab-case with a conventional prefix (feat/,fix/,chore/,refactor/, etc.). - Run
git checkout -b <branch-name>to create and switch to the new branch. Staged changes carry over to the new branch. - Save this branch name for cleanup in Step 6.
- Return to Step 2.7 to commit on the new branch.
Step 3: Push and Create PR
- Run
git push -u origin HEADto push the branch to the remote. - Check if a PR already exists:
gh pr view --json number,url 2>/dev/null.- If a PR exists, display its URL and skip to Step 4.
- If no PR exists:
- Review the commits with
git log main..HEAD --oneline. - Generate a concise PR title (under 70 characters) and a body summarizing the changes.
- Create the PR:
gh pr create --base main --title "<title>" --body "<body>".
- Review the commits with
- Display the PR URL to the user.
Step 4: Poll CI/CD Checks
- Wait 10 seconds before the first check to give CI time to start.
- Run
gh pr checksto get check status. - Parse the results:
- All checks pass → proceed to Step 5.
- Any check fails → stop and report the failure to the user. Include the check name, status, and link. Do not proceed.
- Checks still pending → wait 30 seconds, then poll again.
- No checks configured (empty output) → ask the user whether to proceed with merge anyway or stop.
- If checks are still pending after 15 minutes of polling, stop and tell the user. Provide the PR URL so they can monitor manually.
Step 5: Squash Merge
- Run
gh pr merge --squash --delete-branchto squash merge and delete the remote branch. - If the merge fails (merge conflicts, branch protection rules, etc.), report the specific error to the user and stop.
Step 6: Clean Up
- Run
git checkout main. - Run
git pull origin mainto get the merged changes. - Delete the local feature branch:
git branch -d <branch-name>(using the branch name saved in Step 1). - Report success with a summary:
- PR URL
- Merge status
- Branches cleaned up
Edge Cases
- On main with changes: Create a feature branch automatically (Step 2b) before committing, so local
mainstays clean. - On main with no changes: Stop — nothing to ship.
- Detached HEAD: Stop immediately with a message to check out a named branch.
- PR already exists: Use the existing PR. Skip PR creation, proceed to CI polling.
- No CI checks configured: Ask the user whether to merge without checks.
- CI timeout (15 min): Report PR URL for manual monitoring. Do not merge.
- Merge conflicts: Report the error. Do not attempt to resolve automatically.
- Branch protection rules block merge: Report the specific error from
gh. - User cancels during file selection: Abort the entire workflow gracefully.