Skip to content
Development
Command

/deploy-pr

Ship a branch to its deploy target — detect or create PR, fix CI, review, merge. Returns structured result for callers.

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/deploy-pr

Context preview

What this command does when you run it.

Ship a branch to its deploy target — detect or create PR, fix CI, review, merge. Returns structured result for callers.

Command definition

deploy-pr.md
description: Ship a branch to its deploy target — detect or create PR, fix CI, review, merge. Returns structured result for callers.
argument-hint: "[source_branch | \"staging\" | \"milestone/{slug}\"] [--target TARGET] [--issue ISSUE_NUMBER] [--repo REPO] [--max-ci-iterations N] [--max-review-iterations N] [--dry-run]"
allowed-tools: Bash, Read, Grep, Glob, Skill

<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios --> <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->

/deploy-pr — PR Ship Orchestrator

> **Skill names**: `{FORGE_SKILL_PREFIX}` is `forgedock:` (plugin install) or empty (`install.sh`), resolved once per run by `commands/work-on.md` § Skill Name Resolution. If the skill is not found under either name, STOP and report "skill not found" — never run the phase inline.

**Input**: $ARGUMENTS

**NEVER use plan mode (EnterPlanMode)** — it breaks execution context. **NEVER use the Agent tool** — deploy-pr dispatches sub-skills via `Skill(...)` only. The Agent tool bypasses the allowed-tools constraint and produces opaque output that cannot be structured into the deploy result.

**Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`.

<!-- FORGE:SPEC_LOADED — deploy-pr.md loaded and active. Agent is bound by this spec. -->

---

What This Command Does

`/deploy-pr` is a **sub-skill** designed to be invoked by callers like `/autopilot` that need to ship a branch without consuming their own context window. It handles the full PR shipping lifecycle:

1. Detect or create the PR for the source→target pair 2. Run the CI gate — fix failures via `/fix-ci` (loop up to max iterations) 3. Run the review gate — via `/review-pr` (fix + re-review loop up to max iterations) 4. Merge the PR after both gates pass 5. Return a structured result to the caller

**Never force-merges.** If CI or review fail after maximum iterations, the command stops and reports the blocking state without merging.

---

Forbidden Tools Self-Check

**Before executing any phase**, verify you are NOT using any of these tools:

| Tool | Status | Reason | |------|--------|--------| | `Agent` | **FORBIDDEN** | Bypasses allowed-tools; produces opaque output that cannot feed the structured result | | `EnterPlanMode` | **FORBIDDEN** | Breaks execution context; phases must be executed, not planned |

---

Phase 0: Config Resolution & Argument Parsing

0A: Read forge.yaml

Resolve all config variables before any logic runs. This prevents unresolved `{PLACEHOLDER}` values in bash blocks — a known failure mode on deploy-info.md (issues #318, #1392).

CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"

GH_REPO=$(yq '.project.owner + "/" + .project.repo' "$CONFIG_FILE" 2>/dev/null)
GH_FLAG="-R $GH_REPO"
STAGING_BRANCH=$(yq '.branches.staging // "staging"' "$CONFIG_FILE" 2>/dev/null || echo "staging")
DEFAULT_BRANCH=$(yq '.branches.default // "main"' "$CONFIG_FILE" 2>/dev/null || echo "main")
REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE" 2>/dev/null || echo "$(git rev-parse --show-toplevel)")

0B: Parse Arguments

$ARGUMENTS format examples:
  staging
  milestone/my-feature
  feat/my-branch --target staging
  staging --issue 1234 --repo owner/repo --max-ci-iterations 2 --max-review-iterations 3
  staging --dry-run

Parse:

  • `SOURCE` — first positional arg, or `staging` if omitted
  • `--target TARGET` — explicit PR target override (skips routing table)
  • `--issue ISSUE_NUMBER` — parent issue to reference in PR body (optional)
  • `--repo REPO` — override GH_REPO (optional — forge.yaml takes precedence if absent)
  • `--max-ci-iterations N` — max CI fix attempts, default 3
  • `--max-review-iterations N` — max review + fix cycles, default 3
  • `--dry-run` — run all phases but do NOT merge; print what would happen
SOURCE="${1:-staging}"
TARGET=""          # resolved in Phase 1 if not passed via --target
ISSUE_NUMBER=""
MAX_CI_ITER=3
MAX_REVIEW_ITER=3
DRY_RUN=false

# Parse optional flags
shift 2>/dev/null || true
while [[ $# -gt 0 ]]; do
  case "${1}" in
    --target)      TARGET="${2}";           shift 2 ;;
    --issue)       ISSUE_NUMBER="${2}";     shift 2 ;;
    --repo)        GH_REPO="${2}"; GH_FLAG="-R $GH_REPO"; shift 2 ;;
    --max-ci-iterations)     MAX_CI_ITER="${2}";     shift 2 ;;
    --max-review-iterations) MAX_REVIEW_ITER="${2}"; shift 2 ;;
    --dry-run)     DRY_RUN=true;          shift ;;
    *) shift ;;
  esac
done

---

Phase 1: Branch Routing

Determine the PR target from the source branch. If `--target` was passed explicitly, skip the routing table and use it directly.

Routing Table

| Source Branch Pattern | Target | PR Title Prefix | |----------------------|--------|-----------------| | `staging` | `main` (DEFAULT_BRANCH) | `Deploy` | | `milestone/*` | `staging` (STAGING_BRANCH) | `Ship` | | Any other branch | `staging` (STAGING_BRANCH) | `Merge` |

if [ -n "$TARGET" ]; then
  # Explicit override
  PR_TARGET="$TARGET"
  case "$SOURCE" in
    staging)        TITLE_PREFIX="Deploy" ;;
    milestone/*)    TITLE_PREFIX="Ship" ;;
    *)              TITLE_PREFIX="Merge" ;;
  esac
else
  case "$SOURCE" in
    staging)
      PR_TARGET="$DEFAULT_BRANCH"
      TITLE_PREFIX="Deploy"
      ;;
    milestone/*)
      PR_TARGET="$STAGING_BRANCH"
      TITLE_PREFIX="Ship"
      ;;
    *)
      PR_TARGET="$STAGING_BRANCH"
      TITLE_PREFIX="Merge"
      ;;
  esac
fi

echo "Source: $SOURCE → Target: $PR_TARGET (prefix: $TITLE_PREFIX)"

**Routing guard — staging→main**: When `SOURCE=staging` and `PR_TARGET=main`, the review gate (Phase 4) MUST route to `Skill("{FORGE_SKILL_PREFIX}review-pr-staging", ...)` rather than the standard `review-pr`. This ensures the staging deploy review (comprehensive, multi-agent) runs instead of the single-PR review.

**Routing guard — milestone→staging**: When `SOURCE` matc

Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.