Skip to content

CI status check and auto-remediation after PR creation #108

@Trecek

Description

@Trecek

CI Status Check After PR Creation

Problem

When a pipeline opens a PR (via the open-pr skill or recipe step), the orchestrator immediately moves on without verifying that CI checks pass on the pushed branch. If CI fails, the PR sits broken with no automated remediation.

Desired Behavior

After a PR is created (or a branch is pushed), the orchestrator should be able to:

  1. Poll CI status for the branch/PR until checks complete (or timeout).
  2. Gate on success — proceed only when CI passes.
  3. Auto-remediate on failure — route to resolve-failures (or similar) with the CI failure context, then re-push and re-check.

Design Decisions

MCP tool vs. recipe step?

run_cmd-based recipe steps using gh CLI. No new MCP tool.

  • gh run list, gh run watch, and gh api already provide everything needed for status polling and log retrieval.
  • run_cmd supports custom timeouts (default 600s) and returns structured {success, exit_code, stdout, stderr} — perfect for recipe step routing.
  • The open-pr skill already uses gh CLI directly, so this is consistent with established patterns.
  • A dedicated MCP tool would add maintenance burden for a thin wrapper around gh.

Polling strategy

gh run watch --exit-status with a 2.5-minute (150s) timeout.

CI duration data from the last 20 runs:

Metric Duration
Average 1m 47s
Min 1m 27s
Max 2m 03s

Multiple polls are cheap — if the first check is too early, it just keeps polling. 150s gives reasonable headroom without over-waiting.

Failure context extraction

No orchestrator-level extraction. resolve-failures handles its own investigation.

The orchestrator just tells resolve-failures that CI failed on the branch. resolve-failures has full tool access as a headless session — it will naturally know to run gh run view --log-failed (or whatever it needs) to diagnose and fix. This follows orchestrator discipline (§3.3: "Route Failures, Do Not Investigate"). No new utility callable needed.

Scope

GitHub Actions only.

  • All CI is GitHub Actions. The gh CLI is already a dependency (used in open-pr).
  • Provider-agnostic abstractions would be premature with zero non-GitHub CI users.
  • The recipe step pattern makes it easy to swap gh commands for provider-specific ones later without touching the tool layer.

Recipe integration

Implementation recipe

New steps between open_pr_step and cleanup_success in the implementation recipe:

push → open_pr_step → ci_watch → cleanup_success → done
                         ↓ (on_failure)
                    resolve_ci → re_push → ci_watch (retry loop)
                         ↓ (on_exhausted)
                    cleanup_failure → escalate_stop
  • ci_watch: run_cmdgh run watch $(gh run list --branch {run_name} --limit 1 --json databaseId -q '.[0].databaseId') --exit-status, timeout 150s. skip_when_false: "inputs.open_pr". on_success: cleanup_success, on_failure: resolve_ci.
  • resolve_ci: run_skill/autoskillit:resolve-failures with message indicating CI failed on branch {run_name}. on_success: re_push, on_failure: cleanup_failure. retries: 2, on_exhausted: cleanup_failure.
  • re_push: push_to_remote — pushes the fix. on_success: ci_watch (loops back).

Three steps. No orchestrator-level log extraction. The skill does its own investigation.

PR merge pipeline (integration branch)

The same CI watch pattern applies after the create-review-pr skill creates the integration PR. Add equivalent steps to the pr-merge-pipeline recipe:

create_review_pr → ci_watch_integration → done
                        ↓ (on_failure)
                   resolve_ci → re_push → ci_watch_integration (retry loop)
                        ↓ (on_exhausted)
                   escalate_stop

The integration branch aggregates multiple PRs, so CI failures here may involve cross-PR interactions that didn't surface in individual PR checks. The same resolve-failures → re-push → re-watch loop handles this. The CI watch step should use the same gh run watch --exit-status pattern with the integration branch name.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions