name: ship-it description: Run the quality gate (lint, type-check, tests), resolve issues, commit, push, open a PR to main, then monitor the deploy workflow after merge and resolve any deploy failures. Use when user says "ship it", "commit and deploy", "push and deploy", or "land this".
Ship It: Quality Gate, Commit, Push & Monitor Deploy
Run the steps in order. Do not skip steps. Surface git and CI errors to the user instead of forcing past them.
Prerequisites
ghCLI authenticated. Check withgh auth statusat the very start (see Step 1).gitconfigured with push access to the remote- Workspace dependencies installed (
uv sync --all-packages --locked), which provides thepoeandprekdev tools - Working directory is inside the repository
Step 0: Match User's Energy
Reply with "LFG 🚀 I'll ship it" to acknowledge the user's intent.
Step 1: Confirm Branch and GitHub Auth
Capture the current branch into a variable so later commands are copy-pasteable, and confirm gh is authenticated before doing anything that depends on it.
branch=$(git branch --show-current)
echo "On branch: $branch"
gh auth status || echo "gh NOT authenticated, deploy monitoring will be skipped"
- Never commit on
main. If$branchismain, stop and ask the user for a feature branch name first. - If
ghis not authenticated, you can still run checks, commit, push, and open a PR through the web link, but you will not be able to monitor the deploy run from here. Tell the user this up front.
Step 2: Run the Quality Gate
Stage everything first, then run the full quality gate. uv run poe check runs
the static checks (ruff lint, ruff format, ty type check, migration SQL lint)
followed by the test suites and the verification import smoke test. It is the
same command CI runs, so passing here means CI should pass too.
cd <workspace>
git add -A
uv run poe check
Stage files first (
git add -A). The static checks runprek run --all-files, which only inspects git-tracked files, so newly-created files (new migrations, modules, tests) are silently skipped unless staged.
Handling Failures
Many static hooks auto-fix in place (ruff lint --fix, ruff format, trailing
whitespace, end-of-file). If uv run poe check fails:
- Read the failure output and fix the cause (lint, types, a failing test,
malformed YAML/JSON, large file, merge-conflict markers). Never silence a
failure with
# noqaortype: ignore. - If hooks auto-fixed files,
git add -Aagain. - Re-run
uv run poe checkuntil it passes cleanly.
Do NOT proceed to commit until uv run poe check passes. No exceptions.
Step 3: Stage and Commit
Stage everything (ship it means ship all changes, never cherry-pick), review, then commit.
git add -A
git diff --cached --stat
Use the user's commit message if given; otherwise write a conventional-commit message (feat:, fix:, refactor:, docs:, style:, test:, chore:). Include the repo's trailer unless the user opts out. Ask the user if the intent is ambiguous.
git commit -m "<type>: <concise description>" \
-m "Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
Step 4: Push and Open a PR
git push -u origin "$branch"
If the push is rejected (remote has commits you don't): do NOT auto-rebase or force-push. Try only a safe fast-forward, and if that fails, stop and surface the situation to the user:
git pull --ff-only || {
echo "Remote and local have diverged. Stopping."
git status -sb
git log --oneline --left-right --graph "@{u}"...HEAD
}
Rebasing rewrites history and can introduce conflicts that need human judgment, so let the user decide how to reconcile before pushing again.
If the branch is not main, open a PR to main:
gh pr create --fill --base main --head "$branch"
Then watch the PR's own checks (CI, terraform-ci, dependency-review). These run on the pull_request event but do NOT deploy:
gh pr checks "$branch" --watch --fail-fast
Merging is a separate, explicit decision. Deploy only happens after the PR merges to main, and branch protection may require a human review, so do not assume you can merge. If the user wants to merge and it is allowed:
gh pr merge "$branch" --squash --auto --delete-branch
Note: The deploy.yml deploy jobs are gated to github.ref == 'refs/heads/main' && github.event_name != 'pull_request'. A feature-branch push or PR runs CI only; the real Terraform apply and deploy happen on the push to main that the merge creates. If gh is not authenticated here, stop after opening the PR and tell the user deployment will run after merge.
Step 5: Monitor the Deploy Workflow
Only do this once the PR has merged to main. Select the deploy run precisely by branch, event, and the merge commit SHA so you do not accidentally watch the PR's CI-only run or another branch's run.
git fetch origin main
merge_sha=$(git rev-parse origin/main)
# Give Actions a moment to register the push, then find the run for this commit
sleep 5
run_id=$(gh run list --workflow=deploy.yml --branch main --event push \
--commit "$merge_sha" --limit 1 --json databaseId --jq '.[0].databaseId')
Watch it with the built-in command instead of a hand-rolled poll loop. --exit-status returns non-zero on failure (handy for chaining), --compact keeps output small:
gh run watch "$run_id" --compact --exit-status
If the workflow succeeds: report success and the deploy URL (gh run view "$run_id" --json url --jq .url). Done!
Step 6: Diagnose Deploy Failures
If gh run watch exits non-zero, pull just the failed logs:
gh run view "$run_id" --log-failed
For anything beyond an obvious lint/test slip (Terraform state locks, Azure auth/RBAC, container or migration job failures), hand off to the dedicated debug-deploy skill instead of duplicating that guidance here.
Fix and Re-deploy
After fixing on the feature branch: re-run the quality gate (Step 2), commit, push, and once merged to main, monitor again (Step 5).
If no code changes are needed (e.g., a transient state lock that debug-deploy cleared):
gh run rerun "$run_id"
gh run watch "$run_id" --compact --exit-status
Step 7: Verify Production
After a successful deploy:
curl -s https://<api-url>/health
curl -s https://<api-url>/ready
Full Ship-It Flow Summary
## Ship It: <branch-name>
1. **Branch + Auth**: on feature branch `<branch>`; gh authenticated (or noted)
2. **Quality Gate**: `uv run poe check` passed (static checks + tests across api, shared, verification-functions)
3. **Commit**: `<commit-hash>` `<commit-message>`
4. **Push + PR**: pushed `<branch>`; PR opened to `main`; PR checks passing
5. **Deploy (after merge)**: Run #<id> succeeded / failed (see step 6) / pending merge
6. **Deploy fix (if needed)**: `<failure>` → fixed → re-deployed
7. **Production**: /health healthy | /ready ready
Retry Policy
- Quality gate auto-fixes: re-run
uv run poe checkup to 3 times - Deploy failures: attempt fix + re-deploy up to 2 times
- Git push rejected or rebase conflict: do not force past it, surface to the user
- If still failing: stop and report with full error context