preflight

star 57

Pre-merge readiness check for a PR or local branch. Gathers context, runs reviews and checks, reports a results table. Interactive by default — asks what to review and whether to fix. Supports flags: --fix, --local, --review X,Y, --skip-review X,Y, --ci, --help.

opendatahub-io By opendatahub-io schedule Updated 6/5/2026

name: preflight description: "Pre-merge readiness check for a PR or local branch. Gathers context, runs reviews and checks, reports a results table. Interactive by default — asks what to review and whether to fix. Supports flags: --fix, --local, --review X,Y, --skip-review X,Y, --ci, --help." argument-hint: "[PR] [--fix] [--local] [--review X,Y] [--skip-review X,Y] [--ci] [--help]" disable-model-invocation: true

Preflight

Pre-merge readiness check. Gather context, review code, run checks, report results. Interactive by default — asks the user before making decisions. Never skip a check silently.

Never push (unless --fix --ci — push after committing fixes). Never comment on the PR (unless --ci flag is passed).

CI sandbox constraints (when running in GitHub Actions):

  • No /tmp/ writes — the sandbox only allows file writes within the workspace directory. Use the Write tool to create files in the workspace root (e.g., preflight-comment.md).
  • No writes to .claude/ — this directory is treated as sensitive. Write temp files to the workspace root instead.

--help

If $ARGUMENTS is --help, print the following and stop:

/preflight [PR] [flags]

  PR number or URL      Check a specific PR (optional — auto-detects from branch)
                        If no PR exists, runs in local mode automatically.

Flags:
  --fix                 Fix failing checks after reporting
  --local               Ignore PR even if one exists, run everything locally
  --review X,Y          Run specific reviewers without asking
                        Options: coderabbit, claude, style, rbac, jira-eval
  --skip-review X,Y     Run all reviewers EXCEPT these (no interactive prompt)
  --ci                  Non-interactive CI mode: skip all prompts, post results
                        as a PR review when done
  --help                Show this help

Examples:
  /preflight                                  Check current branch (auto-detect PR)
  /preflight 1234                             Check PR #1234
  /preflight --fix                            Check and fix current branch
  /preflight --review coderabbit,style,rbac    Run specific reviewers
  /preflight --skip-review coderabbit         Run all reviewers except CodeRabbit
  /preflight 1234 --review claude --fix       Check PR, run Claude review, fix issues
  /preflight --review jira-eval,style         Run Jira eval and style reviewers
  /preflight --skip-review jira-eval          Run all reviewers except Jira eval

How it works:
  1. Gather    Detect PR, sync status, affected packages, Jira key
  2. Review    Fetch PR reviews or run local reviewers (interactive)
  3. Check     Run all checks, print results table (read-only)
  4. Fix       Optionally fix failing checks (--fix or interactive)

Flags

Parse these from $ARGUMENTS before processing:

  • --fix — after reporting, fix failing checks without asking
  • --local — ignore PR even if one exists, run everything locally
  • --review X,Y — run specific reviewers without asking (options: coderabbit, claude, style, rbac, jira-eval)
  • --skip-review X,Y — run all reviewers EXCEPT the listed ones, without asking. Mutually exclusive with --review.
  • --ci — non-interactive CI mode. Skips all interactive prompts (no AskUserQuestion). Posts the results as a PR review using the template in references/ci-comment-template.md.
  • --help — print usage and stop
  • No flags — interactive mode: ask the user what to do at decision points

Execution

First, call TaskCreate for each applicable task before running any commands:

  • Task 1: "Gather context" — PR metadata, sync status, changed files, Jira key
  • Task 2: "Run reviews" — fetch existing or run local reviewers
  • Task 3: "Run checks" — CI, lint, type-check, tests, PR body, Jira, coverage
  • Task 4: "Fix failing checks" — ONLY create this task if --fix was passed
  • Task 5: "Write results and post comment" — ONLY create this task if --ci was passed

Then work through each task in order. Mark each task in_progress when starting and completed when done. You are not done until TaskList shows all tasks completed.

Step 0: Prerequisites

Before doing anything, verify required tools are available:

which gh jq git 2>/dev/null
  • gh — required for PR checks, CI status, review threads
  • jq — required by all scripts
  • git — required for branch/diff operations

If any are missing, stop and tell the user what to install. These are non-negotiable — the skill can't function without them.

Optional tools (check but don't block):

  • coderabbit — needed only if user selects CodeRabbit review
  • npm / npx — needed only for local lint/type-check/test runs

Step 1: Gather context

Try to find a PR (unless --local):

  • If a number/URL was given, use it
  • Otherwise: gh pr list --head "$(git branch --show-current)" --state open --json number --jq '.[0].number'
  • If found, fetch metadata: gh pr view "$pr_number" --json title,headRefName,baseRefName,mergeable,mergeStateStatus,number,body,author,reviewDecision

Get repo info:

owner=$(gh repo view --json owner --jq '.owner.login')
repo=$(gh repo view --json name --jq '.name')

Check if local matches PR (important — determines whether CI results are trustworthy):

pr_sha=$(gh pr view "$pr_number" --json headRefOid --jq '.headRefOid')
local_sha=$(git rev-parse HEAD)
has_changes=$(git status --porcelain)

If pr_sha == local_sha AND no uncommitted changes: local is synced with PR. CI results from the PR apply to this code.

If not synced (different SHA, uncommitted changes, or unpushed commits): CI results don't apply — need to run checks locally.

Figure out base branch and affected packages:

base_branch="main"  # or from PR metadata
git diff --name-only origin/$base_branch | cut -d'/' -f1-2 | sort -u

Extract Jira key from PR title/body, branch name, or recent commits:

grep -oE '[A-Z][A-Z0-9]+-[0-9]+' <<< "$pr_title $pr_body" | head -1 || git branch --show-current | grep -oE '[A-Z][A-Z0-9]+-[0-9]+' | head -1

Print a context summary:

Preflight — PR #1234: feat: add new feature (synced ✅)

or

Preflight — local branch: fix/RHOAIENG-14618 (no PR)

Step 2: Review

If a PR exists and is synced, fetch existing reviews:

${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh "$owner" "$repo" "$pr_number"

Report what's there — CodeRabbit threads with severity, human threads, review decision.

Prior preflight threads

When the PR has prior preflight review threads, classify them to avoid re-posting dismissed suggestions on subsequent runs. Extract the PR author from the metadata gathered in Step 1 and run:

${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh "$owner" "$repo" "$pr_number" \
  | ${CLAUDE_SKILL_DIR}/scripts/classify-prior-threads.sh --pr-author "$pr_author"

For each prior preflight thread, read the finding, the current code, any replies, and the PR context (diff, Jira description, etc.) to determine whether the finding is still valid. A thread is no longer valid when:

  • The code was changed to address the finding
  • A reply explains why the finding does not apply
  • The finding is no longer relevant given the current state of the PR

If the thread is no longer valid and --ci is active, resolve it:

  1. Post a reply explaining why (e.g., "Resolved — addressed in <short SHA>.")

    gh api "repos/$owner/$repo/pulls/$pr_number/comments/$database_id/replies" \
      -f body="Resolved — addressed in \`$sha\`."
    
  2. Collapse the thread:

    gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' \
      -f id="$thread_id"
    

Without --ci, report which threads would be resolved but do not post comments or call the API.

If the thread is still valid, do not re-post it — the original comment is already visible on the PR. Count it as an active finding.

See references/reviews.md § Prior Preflight Threads for details.

If no PR exists, or PR exists but is not synced, or --local: no reviews have been done on this code yet. Ask the user what reviewer to run:

If --review flag was passed, use those reviewers directly. If --skip-review flag was passed, run all reviewers except the listed ones (no interactive prompt). Otherwise use AskUserQuestion with multiSelect: true so the user can pick any combination:

  • "CodeRabbit CLI" — run coderabbit review --agent (requires CLI installed)
  • "Claude review" — invoke /review built-in skill
  • "Style review" — invoke /style-review for code style and pattern checks
  • "RBAC review" — invoke /rbac-review for Kubernetes RBAC permission enforcement checks
  • "Jira Eval review" — invoke /jira-eval-review to evaluate code changes against Jira acceptance criteria (requires Jira MCP; reports ➖ if no Jira key found, MCP unavailable, or no acceptance criteria)
  • "Skip review" — no review

Run whichever the user picks. If a reviewer fails (e.g. CR CLI not installed or errors), report the failure clearly — don't silently fall back to something else.

Step 3: Check

This step is read-only. Do not fix, edit, or modify any files during checks. Just run the checks, record the results, and report them. All fixes happen in Step 4.

Read references/checks.md for the full list of checks and how to run each one in each context (PR synced, PR not synced, no PR).

Statuses:

  • ✅ passed · ❌ failed · ⚠️ warning · ⏭️ covered by CI (same commit) · ➖ not applicable

⏭️ means CI ran this on the exact same commit. If a check can't run (OOM, missing tool), that's ❌ or ⚠️ — never ⏭️. If a check doesn't apply (no PR body because no PR), use ➖.

Print the results using the format from references/ci-comment-template.md. This format is used for both terminal output and PR comments. End with a verdict: any ❌ → NOT READY, all ✅ with ⚠️ → READY WITH WARNINGS, all ✅ → READY.

If --ci was passed, post everything as a single PR review — inline comments on files + the full report as the review summary body. You MUST follow the format in references/ci-comment-template.md exactly. No standalone PR comments.

  • If --ci without --fix: post the review now and skip Step 4.
  • If --ci with --fix: do NOT post yet — wait until after Step 4 so the review reflects the post-fix state.
  • If no --ci: just print results to terminal, do not post a review.

Step 4: Fix

If --ci was passed without --fix, skip this step.

If --fix was passed, proceed directly.

If no --fix and no --ci flag, use AskUserQuestion:

  • "Fix failing checks"
  • "Done — just wanted the report"

If fixing:

  1. Rebase if conflicts found. Don't push.
  2. Review fixes — PR: invoke coderabbit-autofix (decline commit/push), then fix human threads. Local: fix issues from Step 2 review.
  3. CI/lint/test fixes — fix specific errors in files changed by this branch. Don't auto-format directories. Don't fix pre-existing issues.
  4. Cleanup/simplify on changed files, lint those files. Skip if nothing changed.
  5. Commit — one commit, descriptive message, Co-Authored-By + Signed-off-by.
  6. Push — only if --ci was also passed (--fix --ci). Push to the PR branch: git push. In interactive mode (no --ci), never push.
  7. Recalculate — re-run lint and type-check on changed files. Update the checks table with post-fix results. The review must reflect the current state, not the pre-fix state.

If --ci was passed, now post the PR review with the updated results (see template).

Install via CLI
npx skills add https://github.com/opendatahub-io/odh-dashboard --skill preflight
Repository Details
star Stars 57
call_split Forks 303
navigation Branch main
article Path SKILL.md
More from Creator
opendatahub-io
opendatahub-io Explore all skills →