SuperAPI AI Directory

gh-pr

General & other

View repository

Updated 10-15 16:46

About this skill

GH PR

Overview

Create or update GitHub Pull Requests with the gh CLI using a detailed body template and strict same-branch rules.

Decision rules (must follow)

  1. Do not create or switch branches. Always use the current branch as the PR head.
  2. Check local working tree state before push/PR operations.
    • git status --porcelain
    • If output is non-empty (tracked or untracked changes), pause and ask the user what to do.
    • Present 3 options: continue as-is, abort, or manual cleanup then rerun.
    • Do not run git stash, git commit, or git clean automatically unless explicitly requested.
  3. Check for an existing PR for the current head branch.
    • gh pr list --head <head> --state all --json number,state,mergedAt,updatedAt,url,title,mergeCommit
  4. If no PR exists → create a new PR.
  5. If any PR exists and is NOT merged (mergedAt is null) → push only and finish (do not create a new PR).
    • This applies to OPEN or CLOSED (unmerged) PRs.
    • Only update title/body/labels if the user explicitly requests changes.
  6. If all PRs for the head are merged → check for post-merge commits (see below).
  7. If multiple PRs exist for the head → use the most recently updated PR for reporting, but the create vs push decision is based on mergedAt.

Post-merge commit check (critical)

When all PRs for the head branch are merged, you must check whether there are new commits after the merge:

  1. Get the merge commit SHA of the most recent merged PR.
  2. Count commits after the merge: git rev-list --count <merge_commit>..HEAD
  3. Decision:
    • If new commits exist → create a new PR (these changes are not in the base branch)
    • If no new commits → report "No changes since last merge" and finish (do not create an empty PR)

Why this matters

  • Scenario A: PR merged → user makes local changes → pushes → changes are NOT in the merged PR
    • Without this check, the changes would be lost or require manual intervention
  • Scenario B: PR merged → user says "create PR" without new changes → would create empty/duplicate PR
    • This check prevents unnecessary PR creation

PR title rules (must follow)

  1. Format: <type>(<scope>): <subject> — Conform to the Conventional Commits format.
  2. type: feat / fix / docs / chore / refactor / test / ci / perf either.
  3. scope: Optional. Briefly indicate the scope of impact of the change (e.g., gui, core, pty)。
  4. subject: Within 70 characters. Write in the imperative mood (e.g., "add …" / "fix …"). Do not capitalize the first letter, and do not end with a period.
  5. If the branch name has a prefix (feat/, fix/ , etc.),match it with the title's type。

PR body rules (must follow)

Section classification

Section Required Notes
Summary YES 1-3 bullet points. Include both "what" and "why"
Changes YES List the changes by file/module
Testing YES Specifically describe the commands executed or the manual test procedure
Closing Issues YES Closes #N or None only. gwt-spec issues may appear in Closing Issues for release PRs
Related Issues / Links YES Specify the Issue number, SPEC, or "None" for reference
Checklist YES Check all items and mark them as checked/N-A
Context Conditional Required when 3 or more files are changed, or when there is a non-obvious reason for the change
Risk / Impact Conditional Required when there are breaking changes, performance impacts, or rollback procedures
Screenshots Conditional Required only when there are UI changes
Deployment Optional Describe only when there is a deployment procedure
Notes Optional Describe only when there are notes for reviewers

Validation (agent must check before creating PR)

  1. In the Required section, TODO If any remain, do not create the PR.
  2. If a Conditional section does not apply, delete the section itself (do not leave empty TODOs).
  3. Each bullet in the Summary should be completed in one sentence . Vague expressions ("some changes", "various fixes") are prohibited.
  4. Changes は Include the changed file or module name Make it a specific description.
  5. Testing は Write reproducible steps (vague descriptions like "tested" are prohibited).
  6. Closing Issues は Closes #123 or None Only allow. bare #123 is prohibited.
  7. gwt-spec issues may appear in Closing Issues for release PRs when they should auto-close on release. develop PR で Related Issues / Links gwt-spec placed only in will also be promoted by the release tooling to the Closing Issues of the release PR. For a regular Issue, if placed only in Related Issues / Links , it is treated as reference-only.
  8. Add a reason comment to unchecked items in the Checklist (e.g., - [ ] Docs updated — N/A: no user-facing change)。
  9. Related Issues は #123 Describe in the format or URL. If not applicable, explicitly state "None".

Issue/PR Comment Formatting (must follow)

  • Final comment text must not contain escaped newline literals such as \n.
  • Use real line breaks in comment bodies. Do not rely on escaped sequences for formatting.
  • Before posting, verify the final body does not accidentally include escaped control sequences (\n, \t).
  • If a raw escape sequence must be shown for explanation, include it only inside a fenced code block and clarify it is intentional.

Issue Progress Comment Template (required for issue-based work)

When work is tracked in GitHub Issues, progress updates must use this template:

Progress
- ...

Done
- ...

Next
- ...
  • Post updates at least when starting work, after meaningful progress, and when blocked/unblocked.
  • In Next, explicitly state blockers or the immediate next action.

Workflow (recommended)

  1. Confirm repo + branches

    • Repo root: git rev-parse --show-toplevel
    • Current branch (head): git rev-parse --abbrev-ref HEAD
    • Base branch defaults to develop unless user specifies.
  2. Check local working tree state (preflight)

    • Run git status --porcelain.
    • If empty, continue.
    • If non-empty, show detected files and ask the user to choose:
      • Continue as-is
      • Abort
      • Manual cleanup first (git commit / git stash / git clean) and rerun
    • Proceed only when the user explicitly chooses continue.
  3. Fetch latest remote state

    • git fetch origin to ensure accurate comparison
  4. Check existing PR for head branch

    • Use decision rules above to pick action.
    • Treat mergedAt as the source of truth for "merged".
  5. If all PRs are merged, perform post-merge commit check

    • Get merge commit: gh pr list --head <head> --state merged --json mergeCommit -q '.[0].mergeCommit.oid'
    • Count new commits: git rev-list --count <merge_commit>..HEAD
    • If 0 → finish with message "No new changes since merge"
    • If >0 → proceed to create new PR
  6. Ensure the head branch is pushed

    • If no upstream: git push -u origin <head>
    • Otherwise: git push
  7. Collect PR inputs (for new PR or explicit update)

    • Title, Summary, Context, Changes, Testing, Closing Issues, Risk/Impact, Deployment, Screenshots, Related Links, Notes
    • Optional: labels, reviewers, assignees, draft
  8. Build PR body from template

  • Read the template from the gh-pr skill path (not the current project path):
    • GH_PR_SKILL_DIR="${GH_PR_SKILL_DIR:-$HOME/.codex/skills/gh-pr}"
    • PR_BODY_TEMPLATE="${GH_PR_SKILL_DIR}/references/pr-body-template.md"
  • Read ${PR_BODY_TEMPLATE} and fill all required placeholders.
  • If a Conditional section does not apply, delete the entire section.
  • In the template, <!-- GUIDE: ... --> delete comments from the final output.
  • If a TODO remains in a Required section, do not create the PR and ask the user for the missing information.
  • Closing Issues は Closes #N か None Only allow. gwt-specs that you want to auto-close in the release PR should be listed in Closing Issues. gwt-specs in the Related Issues of a develop PR are promoted by the release tooling to Closing Issues.
  1. Create or update the PR

    • Create: gh pr create -B <base> -H <head> --title "<title>" --body-file <file>
    • Update (only if user asked): gh pr edit <number> --title "<title>" --body-file <file>
  2. Return PR URL

  • gh pr view <number> --json url -q .url
  1. Post-PR CI/merge check (automatic).
  • After PR creation or push, load github/skills/gh-fix-ci/SKILL.md and follow its workflow to inspect CI status, merge state, and review feedback.
  • If all CI checks are still pending, poll (30s interval) until complete.
  • If conflicts, review issues, or CI failures are detected, proceed with the gh-fix-ci workflow to diagnose and fix.

Command snippets (bash)

head=$(git rev-parse --abbrev-ref HEAD)
base=develop
GH_PR_SKILL_DIR="${GH_PR_SKILL_DIR:-$HOME/.codex/skills/gh-pr}"
PR_BODY_TEMPLATE="${GH_PR_SKILL_DIR}/references/pr-body-template.md"

if [ ! -f "$PR_BODY_TEMPLATE" ]; then
  echo "PR template not found: $PR_BODY_TEMPLATE" >&2
  exit 1
fi

# Preflight: local working tree state
status_lines=$(git status --porcelain)
if [ -n "$status_lines" ] && [ "${ALLOW_DIRTY_WORKTREE:-0}" != "1" ]; then
  echo "Detected local uncommitted/untracked changes:" >&2
  echo "$status_lines" >&2
  echo "Choose one before continuing: continue as-is, abort, or manual cleanup then rerun." >&2
  echo "Set ALLOW_DIRTY_WORKTREE=1 only after explicit user confirmation to continue." >&2
  exit 1
fi

# Fetch latest remote state
git fetch origin

# Check existing PRs for the head branch
pr_json=$(gh pr list --head "$head" --state all --json number,state,mergedAt,mergeCommit)
pr_count=$(echo "$pr_json" | jq 'length')
unmerged_count=$(echo "$pr_json" | jq 'map(select(.mergedAt == null)) | length')

if [ "$pr_count" -eq 0 ]; then
  action=create
elif [ "$unmerged_count" -gt 0 ]; then
  action=push_only
else
  # All PRs are merged - check for post-merge commits
  merge_commit=$(echo "$pr_json" | jq -r 'sort_by(.mergedAt) | last | .mergeCommit.oid')

  if [ -n "$merge_commit" ] && [ "$merge_commit" != "null" ]; then
    new_commits=$(git rev-list --count "$merge_commit"..HEAD 2>/dev/null || echo "0")

    if [ "$new_commits" -gt 0 ]; then
      echo "Found $new_commits commit(s) after merge - creating new PR"
      action=create
    else
      echo "No new commits since merge - nothing to do"
      action=none
    fi
  else
    # Fallback: check against base branch
    new_commits=$(git rev-list --count "origin/$base"..HEAD 2>/dev/null || echo "0")

    if [ "$new_commits" -gt 0 ]; then
      action=create
    else
      action=none
    fi
  fi
fi

# Execute action
case "$action" in
  create)
    cp "$PR_BODY_TEMPLATE" /tmp/pr-body.md

    git push -u origin "$head"
    gh pr create -B "$base" -H "$head" --title "..." --body-file /tmp/pr-body.md
    ;;
  push_only)
    echo "Existing unmerged PR found - pushing changes only"
    git push
    gh pr list --head "$head" --state open --json url -q '.[0].url'
    ;;
  none)
    echo "No action needed - no new changes since last merge"
    ;;
esac

References

  • ${GH_PR_SKILL_DIR}/references/pr-body-template.md: PR body template