CLAUDE CODE MARKETPLACES
Skillslifinance/contractspost-pr-for-review

post-pr-for-review

Post a `lifinance/contracts` pull request to `#dev-sc-review` and enable auto-merge (squash). Top-level message plus a thread reply tagging `@smartcontract_core`. Use when the user says "post PR for review", "send for review", "share for review", "post to dev-sc-review", or supplies a `lifinance/contracts` PR URL with review intent. Requires the Slack MCP server.

npx skills add https://github.com/lifinance/contracts --skill post-pr-for-review
SKILL.md

Post PR for Review (Smart Contracts)

Posts a lifinance/contracts pull request to #dev-sc-review and (optionally) enables auto-merge. This is the smart-contract variant of post-pr-for-review and lives in the contracts repo. Other repos (backend, frontend, tooling) have their own routing skills — do not extend this one to handle them; surface the mismatch and stop.

Inputs

PR URL (optional). If omitted, resolve from the current branch via:

gh pr view --json url,title,body,number,headRefName,isDraft

If no PR exists, ask for the URL.

Scope guard

This skill posts to #dev-sc-review only. If the PR's owner/repo is not lifinance/contracts, stop and tell the user which skill or channel to use instead. Do not guess a backend / frontend channel.

Channel and tag

ChannelChannel IDGroup tag
#dev-sc-reviewC088UJWC8PR<!subteam^S096X6MCB0C> (renders @smartcontract_core)

@smartcontract_core MUST be sent as <!subteam^S096X6MCB0C> — plain @… does not notify (verified 2026-05-13).

Post format

Top-level message (no prefix, no decorative emoji — channel is high-signal / low-noise):

<PR_URL> << <PR_TITLE>

Thread reply (sent immediately after the top-level):

<!subteam^S096X6MCB0C> please review 🙏

Workflow

1. Resolve PR

Parse owner/repo/pull/N from URL or gh pr view. Extract title, url, number, isDraft. Confirm owner/repo == lifinance/contracts; otherwise hit the scope guard above.

2. Pre-flight

Two blocking checks plus one workflow branch:

  • Unresolved review threads (blocking) — REST lacks isResolved; use GraphQL:

    gh api graphql -f query='
      query($owner:String!,$repo:String!,$num:Int!){
        repository(owner:$owner,name:$repo){
          pullRequest(number:$num){
            reviewThreads(first:100){
              nodes{ isResolved isOutdated
                comments(first:1){ nodes{ author{login} body url path } } } } } } }' \
      -f owner=lifinance -f repo=contracts -F num=<N> \
      --jq '.data.repository.pullRequest.reviewThreads.nodes
            | map(select(.isResolved == false and .isOutdated == false))'
    

    Group by author; CodeRabbit is coderabbitai / coderabbitai[bot].

  • Failing CI (blocking, gh pr checks <N>): block on FAILURE / CANCELLED / TIMED_OUT / ACTION_REQUIRED. Ignore any check whose name ends in (pull_request_review) — those are review-gated workflows that haven't fired yet; posting is what triggers them, so blocking would be circular. Match on the suffix only — version-control, audit-verification, and some protect-* checks appear in both push and (pull_request_review) forms; only the latter is exempt. Surface unfamiliar checks; don't silently widen the allowlist.

  • Draft status (workflow branch) — if drafted, offer gh pr ready <N>; confirm first.

3. Gate on pre-flight

  • Unresolved threads OR failing CI → don't post. Summarize and stop:

    Not posting to #dev-sc-review yet — please resolve these first:
    
    Unresolved review threads (N): • <author> (X): <url>, <url>…
    Failing CI: • <name>: <conclusion> — <details_url>
    
    Re-run after fixing.
    

    This skill does NOT auto-fix.

  • CI in progress, nothing failing → tell user, default to waiting.

  • Draft + clean → offer gh pr ready <N>; confirm first.

  • Clean + ready → step 4.

4. Confirm

Skip confirmation if the invoking message includes explicit intent ("post for review", "ship it", "send it", "post to dev-sc-review", "move to ready and push"). Re-asking is friction the user has cleared.

Otherwise show the planned top-level + thread reply text and wait for go.

Step 3's pre-flight is the real safety net; step 4 is content-check only.

5. Auto-merge

First, fetch merge state — --auto consumes immediately on a fully-approved + green PR, which would merge the PR before step 6 posts to Slack (leaving the team a "please review" message for an already-merged PR):

state=$(gh pr view <N> --repo lifinance/contracts \
  --json mergeStateStatus --jq '.mergeStateStatus')

if [ "$state" = "CLEAN" ]; then
  # PR would merge instantly under --auto. Skip and ask the user:
  # "PR is already mergeable; not enabling auto-merge so reviewers can still see it. Merge now instead?"
else
  gh pr merge <N> --repo lifinance/contracts --auto --squash
fi

Squash is LI.FI's default for lifinance/contracts.

Silently log + continue on:

  • Already enabled → no-op.
  • "Auto-merge is not enabled for this repository" → skip with a one-line note.
  • Any other gh error → surface verbatim, ask.

Opt-out: invoking message contains "without auto-merge" / "no auto-merge" / "manual merge" → skip.

6. Resolve channel + post

Channel ID: primary is C088UJWC8PR. Use slack_search_channels as a safety net to confirm the exact-name non-archived match if needed.

Top-level: slack_send_message with text = "<url> << <title>". Capture ts.

Thread reply: slack_send_message with thread_ts = <ts>, text = "<!subteam^S096X6MCB0C> please review 🙏".

7. Report

Posted to #dev-sc-review ✓ — auto-merge (squash) enabled

Failure modes

  • MCP not connected → ask user to connect Slack MCP. Do NOT fall back to webhooks (wrong identity).
  • Channel not found → surface search results; may have been renamed.
  • gh missing / unauthenticated → ask for URL, skip pre-flight, warn.
  • GraphQL fails → fall back to gh pr view --json reviewDecision,comments with a warning that resolution state is unknown.

Variations

  • "also @ <person>" → append @<person> after the group tag in the thread reply.
  • "add context: <msg>" → append as a second thread reply, never the top-level.
  • "quiet ping" → drop the 🙏; thread reply becomes <!subteam^S096X6MCB0C> please review. Keep the subteam syntax — plain @smartcontract_core does not notify.
  • "without auto-merge" → skip step 5.
  • Explicit channel override → use that channel; keep the post shape unless overridden too.

Why this design

Slack MCP posts as the human user, preserving thread-reply notifications and attribution — right etiquette for review channels. Webhook posting (used by audit-request-slack-relay) is intentionally NOT used here (wrong identity). No secrets stored; each teammate authenticates the MCP themselves.

The skill is intentionally scoped to lifinance/contracts#dev-sc-review only. A multi-repo dispatcher (SC + backend + others) lives outside the contracts repo; mixing routing logic into this file invites the wrong-channel posts the routing rule was meant to prevent.

Installs0
GitHub Stars204
LanguageSolidity
AddedMay 25, 2026
View on GitHub