feat: add 'roborev ci review' command and 'init gh-action' workflow generator#312
feat: add 'roborev ci review' command and 'init gh-action' workflow generator#312wesm merged 22 commits intoroborev-dev:mainfrom
Conversation
roborev: Combined Review (
|
roborev: Combined Review (
|
roborev: Combined Review (
|
|
I haven't had a chance to look at this closely yet but this should try to advantage of the existing CI configuration work in https://www.roborev.io/integrations/github/ Personally I wouldn't use this (instead preferring the CI poller that runs in this repository — this runs on a machine in my tailnet):
I can see why this would be convenient for some people though! |
Add new subcommand 'roborev init gh-action' that generates a GitHub Actions workflow file for running roborev CI reviews on pull requests. - Create internal/ghaction package with WorkflowConfig struct and YAML template - Add ghActionCmd() in cmd/roborev/ghaction.go with flag parsing and config inference - Wire subcommand into initCmd() in main.go - Support agent/model/review-types/reasoning/secret-name/output/force flags - Infer defaults from existing .roborev.toml and global config - Map agents to their expected environment variables (ANTHROPIC_API_KEY, etc.) - Include roborev install, agent install, and review steps in generated workflow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 16 tests covering: - Default configuration values - Workflow generation for all agent types (codex, claude-code, gemini, copilot) - Agent-to-environment-variable mapping (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) - Agent CLI install command generation - Model flag inclusion/exclusion - Pinned vs latest roborev version - Multiple review types (comma-joined) - File write behavior (create, no-force conflict, force overwrite) - Empty config defaults to sensible values Fix template to pre-join review types as string instead of using template function on slice. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 11 tests covering the full CLI flow: - Default flag values produce valid workflow with codex agent - Custom agent, model, reasoning, secret-name, review-types flags - Pinned roborev version - Config inference from .roborev.toml (agent, CI review types) - CLI flags override repo config values - Force overwrite behavior (error without --force, success with --force) - Error when run outside a git repository Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ain hardening - Add allowlist validation for agent, reasoning, review types to prevent shell injection in generated workflow scripts - Add regex validation for secret names, versions, and model strings - Fix generated workflow to use correct CLI flags: positional SHA instead of non-existent --commit, separate --type per review type instead of comma-separated, --local flag for daemonless CI execution - Replace non-existent 'list --format json' with 'list --json' and remove broken 'comment --pr' interface in post-results step - Fix gemini and droid agent installers to use correct packages instead of incorrectly installing claude-code CLI - Pin actions/checkout to SHA (de0fac2e..., v6.0.2) matching repo ci.yml - Add sha256sum checksum verification for roborev binary download - Add set -euo pipefail to shell scripts for strict error handling - Update all unit tests (22) and CLI integration tests (11) for new behavior - Add injection rejection tests validating all config field sanitization Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
I checked out the branch and I'm working on this a bit |
- Fix gemini package from @anthropic-ai/gemini-cli to @google/gemini-cli (typosquat risk — wrong npm scope) - Fix copilot install from deprecated gh-copilot extension to standalone @github/copilot npm package - Make @latest explicit on all npm agent installs for visibility - Install roborev to $HOME/.local/bin instead of /usr/local/bin (self-hosted runners may lack write permission) - Add $HOME/.local/bin to $GITHUB_PATH for PATH availability - Replace sha256sum --ignore-missing (can pass vacuously) with explicit grep for archive name then sha256sum --check - Add version pinning TODO comment to agent install step - Add tests for install path, checksum logic, package name cross-referencing, and version pinning comment - Use slices.Contains per modernize lint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new `roborev ci review` command that runs the full review_type x agent matrix in parallel without a daemon or database, synthesizes results, and optionally posts a PR comment. New internal/review/ package extracts formatting and synthesis logic into reusable, daemon-free functions: parallel batch execution (RunBatch), comment formatting (FormatSynthesized, FormatRaw, FormatAllFailed), and synthesis orchestration. Rework the GitHub Actions workflow template to call `roborev ci review` instead of per-commit `roborev review --local` loops. WorkflowConfig now takes Agents []string for multi-agent support; review types, reasoning, and severity are configured in .roborev.toml [ci] and resolved at runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 8 local formatting functions and the severityAbove map in ci_poller.go with calls to the exported review.* equivalents. Add toReviewResults/toReviewResult adapter functions to convert storage.BatchReviewResult to review.ReviewResult. Replace the local quotaErrorPrefix constant in worker.go with review.QuotaErrorPrefix. Update all test files to use the review package's exported API. Net deletion: ~200 lines of duplicated code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…puts - Use explicit path "$HOME/.local/bin/roborev" for version check since GITHUB_PATH additions only take effect in subsequent steps - Use grep -F for fixed-string matching in checksum verification to avoid regex interpretation of dots in archive filenames - Validate resolved agents and reviewTypes are non-empty before running batch, returning a clear error for comma-only flag values - Add TestToReviewResults to cover the storage-to-review adapter layer - Add tests for empty flag validation and explicit install path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lot GITHUB_TOKEN - Extract ValidateReviewTypes into internal/config to deduplicate validation logic across ci_poller, server, and the new ci review command - Log config load errors in `roborev ci review` instead of silently discarding them (warnings, not hard failures) - Skip GITHUB_TOKEN from ghaction envEntries since the template already provides it via the hardcoded GH_TOKEN line, removing the misleading "add repository secret GITHUB_TOKEN" instruction for copilot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gitRef - Synthesize returns ErrAllFailed when all review jobs fail (not quota), so ci review exits non-zero and CI workflows correctly show failure - Invalid --reasoning and --min-severity flags now return errors instead of silently falling back to defaults (config-file values remain permissive) - Pass GitRef to synthesis agent instead of empty string - Use distinct header "Review Passed" vs "Review Complete" in formatSingleResult based on whether findings exist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1f81299 to
5b08592
Compare
roborev: Combined Review (
|
Registers a capturingAgent mock that records the gitRef argument passed to Review, then verifies Synthesize forwards SynthesizeOpts.GitRef to the synthesis agent call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
splitTrimmedGhAction was byte-for-byte identical to splitTrimmed in ci.go. Remove the duplicate and call the existing function directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
detectGitRef and detectPRNumber each independently read and unmarshalled GITHUB_EVENT_PATH. Extract shared ghPREvent struct and readPREvent helper to eliminate the duplication. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace four local 60000 constants across three files with a single review.MaxCommentLen. Alias the review import in ci_poller.go to avoid shadowing by local variables named review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ReviewTypeDefault/Security/Design to config and ResultDone/ResultFailed to review. Replace string literals in production code; test literals left as-is for independent verification. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add git.ShortSHA that returns the first 7 characters of a SHA hash, matching git's default abbreviation length. Delete the duplicate shortSHA in main.go (7-char) and review.ShortSHA (8-char). Replace all inline [:7] and [:8] SHA truncation across 15 files with the canonical function. Update test expectations from 8 to 7 chars. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ci review previously used a flat agent list, ignoring per-workflow config like security_agent or review_agent_thorough. The CI poller used config.ResolveAgentForWorkflow for workflow- and level-aware resolution, producing different behavior for the same config. Add GlobalConfig to BatchConfig so runSingle resolves agents and models through the same config.ResolveAgentForWorkflow and ResolveModelForWorkflow paths the poller uses. When GlobalConfig is nil (e.g. non-CI callers), behavior is unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make mockAgent.WithModel record the model and include it in Review output so tests can observe it. Add TestRunBatch_WorkflowModelResolution that configures a security-specific model override and verifies it reaches the agent while the default review type gets no model. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
Guard against silent empty-string returns from missing map keys by checking ok before content assertions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
"Thanks for the review. Assessed all five findings: Finding 1 (.npmrc injection) — Not applicable. This commit doesn't touch .npmrc handling. The Finding 2 (Credential cross-exposure) — Not applicable. This commit adds GlobalConfig passthrough Finding 3 (Unpinned agent installs) — Not applicable. This commit doesn't modify agent Finding 4 (releases/latest redirect) — Not applicable. Same as above — no changes to the Finding 5 (Global CI reasoning fallback ignored) — Not valid. The global CIConfig struct Summary: 0 of 5 findings are valid for this commit. No changes needed." |
Move flag validation (review types, reasoning, min severity) and git ref resolution before the git.GetRepoRoot call in runCIReview. This ensures users get specific validation errors even when not inside a git repository, fixing test failures in sandboxed environments (nix) where the working directory is not a git repo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
TestSynthesize_MultipleResults_FallsBackToRaw relied on "nonexistent-synthesis-agent" being truly unavailable to trigger the raw fallback path. In CI (no real agents installed), GetAvailable falls back to any registered mock agent from other tests in the same package, causing synthesis to succeed instead of failing. Fix by registering an explicit failing-synth agent that always errors, making the test self-contained regardless of global agent registry state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
|
"Finding 1 (High): Unpinned agent installs — Pre-existing, not introduced by this PR. Already has a Finding 2: ROBOREV_VERSION from "latest" — Same as above. Pre-existing, not touched by this diff. Finding 3: Unbounded CI batch fan-out — Theoretical. The agent list comes from user-controlled Finding 4: Global [ci].reasoning fallback ignored — Not valid. Already investigated and confirmed: Finding 5: Repo-level synthesis agent fallback ignored — Not valid. Already investigated and Finding 6: init gh-action --agent doesn't pass --agent to ci review — Let me check this one. ⏺ Searched for 3 patterns, read 2 files (ctrl+o to expand) ⏺ Finding 6 is observing that init gh-action --agent codex,gemini installs those agents in the So this finding is partially valid: if you do init gh-action --agent codex,gemini, the workflow Summary: 0 of 6 findings are introduced by this PR's diff. Findings 4 and 5 are factually wrong |
|
thank you! I haven't tested out the gh action end to end but if you run into any issues just open an issue or a PR to fix! |
|
Awesome! Thank you @wesm - testing as we speak! |
Summary
roborev init gh-action— generates a GitHub Actions workflow file for running roborev reviews on pull requests, with multi-agent support, version pinning, and supply-chain hardening (SHA-pinned actions, checksum verification)roborev ci review— daemon-free CLI command that runs batch reviews, synthesizes results, and optionally posts PR comments directly from CIinternal/reviewpackage for batch execution, synthesis, and comment formatting, shared by both the daemon CI poller and the new CLI commandinternal/ghactionpackage for workflow generation with input validation, agent-aware env/secret wiring, and injection protectionci reviewand CI poller behavior: workflow-aware agent/model resolution, shared constants, shared comment formattingKey design decisions
ci reviewruns without a daemon — it invokes agents directly so the workflow doesn't need to manage daemon lifecycleci reviewuses the sameconfig.ResolveAgentForWorkflow/ResolveModelForWorkflowpaths as the CI poller, so per-workflow config likesecurity_agentworks consistently in both modesci reviewexits non-zero when all review jobs fail (quota-skipped batches exit 0)--reasoning,--min-severity, and--review-typesflags return errors instead of silently falling back to defaultsGH_TOKENline in the workflow template, not a separate secret entryci revieware logged as warnings, not hard failures — the command works with zero configgit.ShortSHA) across all files, matching git's defaultCleanup included in this branch
splitTrimmed(ghaction.go had a copy)GITHUB_EVENT_PATHparsing into sharedghPREventstructreview.MaxCommentLenconstant (was duplicated as local60000in 4 places)config.ReviewTypeDefault/Security/Designandreview.ResultDone/ResultFailedconstants, replace string literals in production codegit.ShortSHA(delete 2 duplicate implementations, replace ~30 inline[:7]/[:8]slices)Files
cmd/roborev/ci.go,cmd/roborev/ghaction.go,cmd/roborev/main.gointernal/review/batch.go,internal/review/result.go,internal/review/synthesis.go,internal/review/synthesize.gointernal/ghaction/ghaction.gointernal/config/config.go(ReviewType*),internal/review/result.go(ResultDone/Failed,MaxCommentLen)internal/git/git.go(ShortSHA)internal/daemon/ci_poller.go,internal/daemon/server.go,internal/daemon/hooks.gocmd/roborev/fix.go,compact.go,refine.go,tui.go,tui_handlers.go,internal/prompt/prompt.go,internal/agent/test_agent.goTest plan
go test ./...passes (unit tests for all new and modified packages)go vet ./...cleango build ./...cleanTestRunBatch_WorkflowAwareResolution)TestRunBatch_WorkflowModelResolution)roborev init gh-actiongenerates valid workflow YAMLroborev ci review --ref HEAD~1..HEADruns a review without daemon🤖 Generated with Claude Code