Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Nov 11, 2025

Problem

Debugging CI failures currently requires:

  1. Waiting for CI to complete
  2. Manually identifying which jobs failed
  3. Figuring out which local commands replicate those jobs
  4. Running entire test suites when only a few specs failed

This is slow and inefficient.

Solution

Adds two powerful scripts that automate CI failure reproduction:

1. bin/ci-rerun-failures

Automatically detects and re-runs only failed CI jobs:

# Run failed jobs from current commit
bin/ci-rerun-failures

# Search recent commits for failures
bin/ci-rerun-failures --previous

# Run failures from specific PR
bin/ci-rerun-failures 1964

Features:

  • ✨ Fetches actual CI failures from GitHub using gh CLI
  • 🎯 Runs only what failed (no wasted time on passing tests)
  • ⏳ Waits for in-progress CI or searches previous commits
  • 📋 Shows exactly what will run before executing
  • 🚀 Maps CI job names to local rake commands automatically

2. bin/ci-run-failed-specs

Runs only specific failing RSpec examples:

# Copy failure output from CI, then:
pbpaste | bin/ci-run-failed-specs

# Or pass spec paths directly:
bin/ci-run-failed-specs './spec/system/integration_spec.rb[1:1:1:1]'

Features:

  • 🎯 Runs only failing examples (not entire test suite)
  • 📋 Parses RSpec output to extract spec paths
  • 🔄 Deduplicates specs
  • 📁 Auto-detects spec/dummy directory when needed

Benefits

  • Faster iteration: Run exactly what failed, skip what passed
  • No more guessing: Scripts map CI jobs to local commands
  • No waiting: Replicate failures immediately without CI feedback loop
  • Surgical precision: Run individual failing specs, not entire suites

Documentation

Added comprehensive usage guide to CLAUDE.md with examples.


🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com


This change is Reviewable

Summary by CodeRabbit

  • Documentation

    • Added comprehensive guides for replicating CI failures locally, including configuration switching workflows and troubleshooting guidance.
    • Documented local system test setup and SSL-related considerations.
  • Chores

    • Added developer scripts for re-running failed CI jobs, switching between configurations, and executing specific test examples locally.

Adds two powerful scripts to replicate CI failures locally:

1. bin/ci-rerun-failures:
   - Fetches actual CI failures from GitHub using gh CLI
   - Runs only failed jobs locally (no wasted time on passing tests)
   - Waits for in-progress CI or searches previous commits
   - Maps CI job names to local rake commands automatically
   - Supports --previous flag and specific PR numbers

2. bin/ci-run-failed-specs:
   - Runs only specific failing RSpec examples
   - Parses RSpec output from CI to extract spec paths
   - Auto-detects spec/dummy directory when needed
   - Deduplicates spec paths
   - Accepts input from clipboard, arguments, or files

These tools eliminate the wait-for-CI-feedback loop by running exactly
what failed, exactly how CI runs it.

Documentation added to CLAUDE.md with usage examples.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Warning

Rate limit exceeded

@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c8b62e3 and 25f5be6.

📒 Files selected for processing (4)
  • CLAUDE.md (1 hunks)
  • bin/ci-rerun-failures (1 hunks)
  • bin/ci-run-failed-specs (1 hunks)
  • bin/ci-switch-config (1 hunks)

Walkthrough

This PR adds development tools and documentation for replicating and debugging CI failures locally. It introduces three new Bash scripts for managing CI configurations, re-running failed CI jobs, and executing failed RSpec tests. Documentation guides developers through common CI debugging workflows and system testing issues.

Changes

Cohort / File(s) Summary
CI Debugging Scripts
bin/ci-rerun-failures, bin/ci-run-failed-specs, bin/ci-switch-config
New executable Bash scripts that detect and re-run failed GitHub Actions CI jobs, execute specific failed RSpec specs locally, and switch between minimum/latest CI runtime configurations with version manager support (mise/asdf). Includes version detection, colorized output, and interactive prompts.
Development Documentation
CLAUDE.md, SWITCHING_CI_CONFIGS.md, spec/dummy/TESTING_LOCALLY.md
New and updated documentation files explaining how to replicate CI failures locally, switch between CI configurations (Latest vs. Minimum with specific Ruby/Node versions), troubleshoot common pitfalls, and handle SSL-related system test failures under Ruby 3.4.3.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • bin/ci-rerun-failures: GitHub API integration via gh/jq, PR detection logic, CI job status polling, and command mapping require careful validation
  • bin/ci-switch-config: Version manager detection, .tool-versions file generation, and git restore workflows need attention for edge cases
  • bin/ci-run-failed-specs: Spec path extraction regex and working directory logic (root vs. spec/dummy) should be verified
  • All scripts: Shell error handling, user prompts, and dependency checks throughout
  • Documentation: Accuracy of commands, configuration details, and troubleshooting steps

Suggested reviewers

  • Judahmeek
  • AbanoubGhadban

Poem

🐰 Scripts now hop through CI logs with glee,
Switching configs fast, from max to min we see,
Failed specs and jobs no longer hide,
Local debugging made easier, tested far and wide!
Documentation guides the way so clear,
CI failures replicated here, no need to fear! 🚀

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding CI debugging tools for local failure reproduction, which directly aligns with the core additions of bin/ci-rerun-failures and bin/ci-run-failed-specs scripts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Adds additional CI debugging tools:

1. bin/ci-switch-config:
   - Switch between latest (Ruby 3.4, Node 22, Shakapacker 9.3.0, React 19)
     and minimum (Ruby 3.2, Node 20, Shakapacker 8.2.0, React 18) configs
   - Check current configuration status
   - Helps debug failures specific to minimum dependency versions

2. SWITCHING_CI_CONFIGS.md:
   - Complete guide to using ci-switch-config
   - Troubleshooting common issues
   - Understanding CI configuration matrix

3. spec/dummy/TESTING_LOCALLY.md:
   - Local testing tips and workflows
   - Known issues (e.g., Ruby 3.4.3 + OpenSSL 3.6 SSL errors)
   - When to rely on CI as source of truth

Updated CLAUDE.md to reference these new resources.
@claude
Copy link

claude bot commented Nov 11, 2025

Pull Request Review: CI Debugging Tools

I've reviewed this PR and overall it's an excellent addition that will significantly improve the developer experience. The tools are well-designed, thoroughly documented, and follow good bash scripting practices.

✅ Strengths

Code Quality

  • Excellent bash practices: Proper use of set -euo pipefail, quoting variables, and error handling
  • Well-structured: Clear separation of concerns with functions
  • Good UX: Colorful output, progress indicators, and confirmation prompts
  • Comprehensive help: Each script has clear --help documentation

Documentation

  • Outstanding documentation: SWITCHING_CI_CONFIGS.md and TESTING_LOCALLY.md are thorough
  • Clear examples: Multiple usage examples for different scenarios
  • Troubleshooting guide: Covers common issues developers will encounter

Functionality

  • Smart CI integration: Uses gh CLI to fetch actual CI failures from GitHub
  • Deduplication: Properly handles duplicate commands and specs
  • Interactive features: Polling for in-progress CI, confirmation prompts
  • Version manager support: Works with both mise and asdf

🔍 Potential Issues & Suggestions

1. Security: Command Injection Risk (Medium Priority)

Location: bin/ci-rerun-failures:242, bin/ci-run-failed-specs:148

Both scripts use eval with user-controlled input. While relatively controlled, eval can be risky.

Recommendation: Consider safer alternatives like direct command execution for rspec specs.

2. Portability: macOS-specific Command (Low Priority)

Multiple examples use pbpaste which only exists on macOS. Linux users would need xclip or xsel.

Recommendation: Add a note about cross-platform alternatives.

3. Error Handling: Missing Dependency Checks (Low Priority)

Scripts depend on external tools (gh, jq, yarn, bundle) but don't verify they're installed upfront.

4. Feature Gap: No Dry-Run Mode

Consider adding --dry-run support, especially for ci-switch-config.

🧪 Test Coverage

Recommendation: Add shellcheck linting to CI workflow.

🎯 Overall Assessment

Verdict: ✅ Approve with minor suggestions

This is a high-quality PR that:

  • ✅ Solves a real pain point for developers
  • ✅ Follows repository conventions
  • ✅ Includes comprehensive documentation
  • ✅ Uses best practices for bash scripting

The issues identified are mostly minor and don't block merging.

Recommendation

Merge after considering:

  1. (Optional) Replace eval with safer alternatives
  2. (Optional) Add dependency checks
  3. (Optional) Add shellcheck to CI

🙏 Great Work!

This tooling will significantly speed up the development workflow. The level of documentation and attention to user experience is exemplary.

Reviewed by: Claude Code
Review date: 2025-11-11

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
bin/ci-run-failed-specs (1)

125-148: Consider using array for command arguments instead of string concatenation.

The current approach builds a command string with single-quoted arguments and uses eval, which could fail if spec paths contain single quotes (though rare in practice). A more robust approach uses Bash arrays:

-# Build rspec command
-RSPEC_CMD="bundle exec rspec"
-for spec in "${UNIQUE_SPECS[@]}"; do
-  RSPEC_CMD="$RSPEC_CMD '$spec'"
-done
+# Build rspec command as array
+RSPEC_CMD=("bundle" "exec" "rspec")
+for spec in "${UNIQUE_SPECS[@]}"; do
+  RSPEC_CMD+=("$spec")
+done

-echo -e "${BLUE}Command:${NC} cd $WORKING_DIR && $RSPEC_CMD"
+echo -e "${BLUE}Command:${NC} cd $WORKING_DIR && bundle exec rspec ${UNIQUE_SPECS[*]}"
 echo ""

 # Confirm (read from /dev/tty to handle piped input)
 if [ -t 0 ]; then
   read -p "Run these specs now? [Y/n] " -n 1 -r
 else
   read -p "Run these specs now? [Y/n] " -n 1 -r < /dev/tty
 fi
 echo
 if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ ! -z $REPLY ]]; then
   echo "Cancelled."
   exit 0
 fi

 # Run the specs
 cd "$WORKING_DIR"
-eval "$RSPEC_CMD"
+"${RSPEC_CMD[@]}"
 RESULT=$?

This avoids eval and handles special characters in paths more safely.

bin/ci-rerun-failures (1)

188-190: Consider using a cleaner approach for checking empty arrays.

The set +u / set -u workaround is functional but can be replaced with a more idiomatic approach:

-# Check if any commands were found (handle empty array with set -u)
-set +u
-NUM_COMMANDS=${#COMMANDS_TO_RUN[@]}
-set -u
+# Check if any commands were found
+NUM_COMMANDS="${#COMMANDS_TO_RUN[@]:-0}"

Or alternatively, check directly in the conditional:

-# Check if any commands were found (handle empty array with set -u)
-set +u
-NUM_COMMANDS=${#COMMANDS_TO_RUN[@]}
-set -u
-
-if [ "$NUM_COMMANDS" -eq 0 ]; then
+if [ "${#COMMANDS_TO_RUN[@]:-0}" -eq 0 ]; then

Both approaches handle empty arrays gracefully without toggling shell options.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d2710a and c8b62e3.

📒 Files selected for processing (6)
  • CLAUDE.md (1 hunks)
  • SWITCHING_CI_CONFIGS.md (1 hunks)
  • bin/ci-rerun-failures (1 hunks)
  • bin/ci-run-failed-specs (1 hunks)
  • bin/ci-switch-config (1 hunks)
  • spec/dummy/TESTING_LOCALLY.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.

Applied to files:

  • spec/dummy/TESTING_LOCALLY.md
📚 Learning: 2024-06-27T05:22:46.156Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1622
File: spec/dummy/spec/rake/assets_precompile_rake_spec.rb:12-12
Timestamp: 2024-06-27T05:22:46.156Z
Learning: When stubbing environment variables in RSpec tests, use `before` and `after` hooks to ensure that the original values are restored after the tests, preventing any side effects on other tests. Example provided by justin808:
```ruby
describe "My test" do
  before do
    original_value = ENV["VARIABLE_NAME"]
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_return("stubbed_value")
  end

  after do
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_call_original
    ENV["VARIABLE_NAME"] = original_value
  end

  it "tests something" do
    # Your test code here
  end
end
```
This practice ensures test isolation and reliability.

Applied to files:

  • spec/dummy/TESTING_LOCALLY.md
🪛 LanguageTool
SWITCHING_CI_CONFIGS.md

[grammar] ~246-~246: There seems to be a noun/verb agreement error. Did you mean “installs” or “installed”?
Context: ...m ruby asdf reshim nodejs ``` ### Yarn install fails If you get package resolution er...

(SINGULAR_NOUN_VERB_AGREEMENT)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: rspec-package-tests (3.2, minimum)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20, minimum)
  • GitHub Check: build
  • GitHub Check: markdown-link-check
  • GitHub Check: claude-review
🔇 Additional comments (5)
spec/dummy/TESTING_LOCALLY.md (1)

1-73: Excellent documentation for local testing guidance.

This documentation provides clear, actionable guidance for developers encountering environment-specific SSL issues. The structure is logical, moving from problem identification to workarounds and solutions. The recommendation to use CI as the source of truth for system tests is pragmatic.

SWITCHING_CI_CONFIGS.md (1)

1-299: Comprehensive guide for switching CI configurations.

This documentation provides excellent coverage of the CI configuration switching workflow, including prerequisites, detailed steps, troubleshooting, and integration with other tools. The examples are clear and the troubleshooting section addresses common issues developers might encounter.

bin/ci-rerun-failures (1)

1-269: Well-structured CI failure reproduction script.

This script provides excellent automation for reproducing CI failures locally. The logic for detecting failures, mapping to local commands, and executing them is sound. The user experience is thoughtful with confirmations, progress indicators, and helpful tips.

bin/ci-switch-config (1)

37-285: Well-designed configuration switching implementation.

The script provides a robust mechanism for switching between CI configurations. The version manager detection, dependency management, and user guidance are all well-implemented. The functions are clearly separated and the overall flow is logical.

CLAUDE.md (1)

51-117: Excellent integration of CI debugging tools into the development guide.

The new section provides clear, actionable documentation for the CI debugging workflow. The structure progresses logically from configuration switching to failure detection to targeted test execution. The feature lists with emojis make it easy to scan capabilities, and the cross-references guide users to more detailed documentation.

Changes set -e to set -euo pipefail for more robust error handling:
- -u: Treat unset variables as errors
- -o pipefail: Fail if any command in a pipeline fails

Updates variable handling to avoid -u failures:
- Initialize SHAKAPACKER_GEM, SHAKAPACKER_NPM, REACT_ROOT, REACT_DUMMY
  with empty strings before conditional assignment
- Add || echo "" to grep/sed commands to prevent pipeline failures
- Use ${VAR:-default} syntax for safe variable expansion
- Explicitly name REPLY variable in read commands

This matches the error handling strictness of other scripts in the PR
(bin/ci-rerun-failures, bin/ci-run-failed-specs).
@claude
Copy link

claude bot commented Nov 11, 2025

Code Review: CI Debugging Tools

I've reviewed this PR and it's an excellent addition to the developer tooling! The scripts are well-designed and will significantly improve the CI debugging workflow. Here's my detailed feedback:


Strengths

1. Excellent Code Quality

  • Clean bash scripting: Proper use of set -euo pipefail for error handling
  • Good error messages: Clear, colored output with helpful context
  • User-friendly: Interactive prompts with sensible defaults
  • Well-documented: Comprehensive help text in each script

2. Smart Design Decisions

  • Deduplication: Both ci-rerun-failures and ci-run-failed-specs deduplicate inputs
  • Confirmation prompts: Prevents accidental execution
  • Flexible input methods: Scripts accept arguments, stdin, or piped input
  • Progress feedback: Clear indication of what's running and results

3. Great Documentation

  • CLAUDE.md integration is perfect for AI assistants
  • SWITCHING_CI_CONFIGS.md is thorough and practical
  • TESTING_LOCALLY.md addresses known issues proactively

🔍 Potential Issues & Suggestions

Security Concerns

1. Command Injection Risk (bin/ci-rerun-failures:242)

if eval "$cmd"; then

Issue: Using eval with commands constructed from a hash map. While currently safe (hardcoded commands), this could become a security risk if the JOB_MAP is ever made configurable or loaded from external sources.

Recommendation: Consider using functions or case statements instead of eval:

case "$cmd" in
  "lint-js-and-ruby")
    bundle exec rubocop && yarn run eslint && yarn start format.listDifferent
    ;;
  # ... other cases
esac

2. Command Injection Risk (bin/ci-run-failed-specs:148)

eval "$RSPEC_CMD"

Issue: User-provided spec paths are directly interpolated into the command. Malicious input like './spec/foo.rb; rm -rf /' could be dangerous.

Recommendation: Pass specs as array arguments instead:

cd "$WORKING_DIR"
bundle exec rspec "${UNIQUE_SPECS[@]}"

Bug: Array Access Without Bounds Check (bin/ci-run-failed-specs:118)

if [[ "${UNIQUE_SPECS[0]}" == *"spec/system"* ]] || [[ "${UNIQUE_SPECS[0]}" == *"spec/helpers"* ]]; then

Issue: Accessing array index without checking if array is non-empty first (despite check at line 97, defensive coding suggests rechecking).

Recommendation: Add bounds check for safety.

Reliability Issues

3. Hardcoded Ruby Command (bin/ci-switch-config:134)

ruby script/convert

Issue: Executes ruby before version manager has been reloaded. Might use wrong Ruby version.

Recommendation: Document that current Ruby must be compatible with script/convert.

4. Git Restore Error Handling (bin/ci-switch-config:214)

git restore Gemfile.development_dependencies package.json spec/dummy/package.json packages/react-on-rails-pro/package.json 2>/dev/null || true

Issue: Silently fails if files don't exist or aren't tracked. User won't know if restoration failed.

Recommendation: Check exit status and warn user if restoration fails.

Usability Improvements

5. Missing jq Dependency Check

All three scripts use jq but don't check if it's installed.

Recommendation: Add early check with helpful installation instructions.

6. Missing gh Dependency Check

bin/ci-rerun-failures assumes gh is installed and authenticated.

Recommendation: Add helpful error message if gh not found.


🎯 Performance Considerations

Good

  • ✅ Polling interval (30s) is reasonable for CI waiting
  • ✅ Scripts exit early when possible
  • ✅ Deduplication prevents redundant work

Minor Optimization

  • The --previous flag loops through commits one-by-one. For repos with many commits, this could be slow. Consider fetching all check runs at once with pagination.

📝 Documentation Quality

Excellent

  • ✅ Clear usage examples in help text
  • ✅ Related tools cross-referenced
  • ✅ Known issues documented proactively
  • ✅ CLAUDE.md integration helps AI assistants

Suggestions

  1. Add a troubleshooting section to CLAUDE.md for common script failures
  2. Consider adding a --dry-run flag to show what would run without executing

🧪 Test Coverage

Missing: No automated tests for these bash scripts.

Recommendation: Consider adding:

  • Basic smoke tests using bats-core or similar
  • CI job that validates scripts can parse sample data
  • Error case testing (missing dependencies, malformed input)

🔐 Security Assessment

Overall: Low risk for current use case (developer tooling), but be aware:

  • ⚠️ eval usage could be dangerous if scripts evolve
  • ⚠️ User input directly in commands needs validation
  • ✅ No secrets or credentials exposed
  • ✅ Scripts run with user's permissions (appropriate for dev tools)

📊 Overall Assessment

Quality Score: 8.5/10

This is high-quality developer tooling that will genuinely improve productivity. The code is clean, well-structured, and thoughtfully designed. The security issues I've identified are low-risk in the current context but worth addressing before these patterns are copied elsewhere.

Recommendations for Merge

Before merging (high priority):

  1. Fix the command injection vulnerabilities by avoiding eval with user input
  2. Add dependency checks for jq and gh
  3. Fix array bounds check bug

Nice to have (can be follow-up PRs):

  • Add --dry-run flag
  • Replace eval with safer alternatives
  • Add basic automated tests
  • Improve git restore error handling

🎉 Conclusion

Excellent work! This PR adds genuinely useful tools that follow bash best practices. The code is clean, the UX is thoughtful, and the documentation is outstanding.

The security issues are low-risk for developer tooling but should be addressed to prevent these patterns from spreading. Once those fixes are in, this will be a valuable addition to the project.

Special kudos for:

  • The comprehensive CLAUDE.md integration
  • Interactive UX with confirmation prompts
  • Clear, colored output that's easy to read
  • Cross-referencing between related tools

1. Security: Remove eval from bin/ci-run-failed-specs
   - Use bash array instead of string for RSPEC_CMD
   - Execute command directly with "${RSPEC_CMD[@]}" (safer)
   - Eliminates command injection risk from spec paths

2. Security: Document safe eval usage in bin/ci-rerun-failures
   - Add comment explaining eval is safe (commands from predefined JOB_MAP)
   - Fix REPLY variable to use explicit naming

3. Error handling: Add dependency checks
   - bin/ci-rerun-failures: Check for gh and jq
   - bin/ci-run-failed-specs: Check for bundle
   - Provide clear error messages with install instructions

4. Portability: Document cross-platform clipboard alternatives
   - Add Linux alternatives (xclip, wl-clipboard) in CLAUDE.md
   - Maintain pbpaste as primary example for macOS

5. Consistency: Fix REPLY variable handling
   - Explicitly name REPLY in all read commands
   - Use ${REPLY} with quotes for -u compatibility

All scripts now have consistent error handling, better security,
and clearer documentation for cross-platform usage.
@justin808 justin808 merged commit 28405e3 into master Nov 11, 2025
27 checks passed
@justin808 justin808 deleted the justin808/add-ci-debugging-tools branch November 11, 2025 03:23
@claude
Copy link

claude bot commented Nov 11, 2025

Code Review: PR #1973 - CI Debugging Tools

Overview

Excellent addition! These tools address a real pain point in the development workflow by eliminating the wait-for-CI feedback loop. The implementation is well-thought-out and provides significant value.


✅ Strengths

1. Code Quality

  • Excellent error handling: Proper use of set -euo pipefail throughout
  • Safe command execution: ci-run-failed-specs uses array-based command building instead of eval, which is more secure
  • Dependency checking: Both scripts validate required tools (gh, jq, bundle) upfront
  • User-friendly: Color-coded output, clear help messages, confirmation prompts

2. Security Considerations

  • Justified eval usage: In ci-rerun-failures:260, the comment explains why eval is safe (commands come from predefined JOB_MAP, not user input) ✅
  • Input sanitization: Spec paths are extracted via regex, not arbitrary code execution
  • Smart stdin handling: ci-run-failed-specs:154-158 properly handles both piped and interactive input by reading from /dev/tty

3. Robustness

  • Empty array handling: Lines 203-206 in ci-rerun-failures properly handle empty arrays with set -u
  • Status checking: Waits for in-progress CI jobs with polling
  • Fallback behavior: Suggests manual commands when no mappings found
  • Deduplication: Both scripts deduplicate their inputs

4. Documentation

  • Comprehensive: SWITCHING_CI_CONFIGS.md (299 lines) covers all scenarios
  • Clear examples: Multiple usage patterns demonstrated
  • Troubleshooting: Known issues documented with workarounds
  • Integration: Well-integrated into CLAUDE.md

🔍 Minor Observations

1. Bash Array Handling (ci-rerun-failures)

Line 233: The quote placement is slightly inconsistent

read -p "Run these tests now? [Y/n] " -n 1 -r REPLY

vs line 156:

read -p "Run these specs now? [Y/n] " -n 1 -r REPLY

Both work fine, just noting the REPLY variable is set differently. Not a bug, just a style observation.

2. Job Mapping Maintenance

Lines 183-189: The JOB_MAP is hardcoded. Consider if this should be:

  • Documented in CONTRIBUTING.md so contributors know to update it when CI job names change
  • Or potentially extracted to a config file

This isn't urgent since CI job names rarely change, but worth considering for long-term maintenance.

3. Error Message Clarity (ci-run-failed-specs)

Lines 133-138: The automatic working directory detection is clever, but if it guesses wrong, the error might be confusing. Consider adding a flag like --dir to manually override.

Current behavior is fine for 99% of cases though.


🎯 Performance & Efficiency

Efficient:

  • Fetches only needed data from GitHub API
  • Deduplicates commands before running
  • Polls with reasonable 30s intervals
  • No unnecessary file operations

🧪 Test Coverage

Observation: No automated tests for these scripts. This is acceptable for developer tooling, but consider:

  • Adding shellcheck to CI for these scripts
  • Testing with different edge cases manually

For bash scripts like these, manual testing is often sufficient, but shellcheck would catch potential issues.


📚 Documentation Quality

Excellent documentation:

  • ✅ Clear usage examples in all help messages
  • ✅ Step-by-step workflows in markdown docs
  • ✅ Troubleshooting sections
  • ✅ Integration with existing tools explained
  • ✅ Known issues documented (Ruby 3.4.3 + OpenSSL 3.6)

🔒 Security Assessment

Overall: SECURE

  1. eval usage (ci-rerun-failures:260): Justified and documented
  2. Input parsing: Uses regex extraction, not arbitrary execution
  3. No credential exposure: Relies on existing gh authentication
  4. Shell injection: Not vulnerable - commands from predefined map or parsed safely

💡 Suggestions for Future Enhancements

These are NOT blockers, just ideas for future iterations:

  1. Cache CI status: Could cache recent PR checks to avoid repeated API calls
  2. Parallel execution: Run multiple failing jobs in parallel (with user consent)
  3. Time estimates: Show approximate duration for each test suite
  4. Notification: Desktop notification when tests complete
  5. History tracking: Keep log of what was run and when

🎓 Adherence to Project Standards

Follows CLAUDE.md requirements:

  • Scripts are executable
  • Use bash shebang
  • Color-coded output
  • Error handling with set -euo pipefail
  • Help messages provided
  • Documentation updated

No formatting issues (these are bash scripts, so RuboCop/ESLint don't apply)

Git hooks: Scripts properly check for dependencies


📊 Summary

Aspect Rating Notes
Code Quality ⭐⭐⭐⭐⭐ Clean, well-structured bash
Security ⭐⭐⭐⭐⭐ Proper input handling
Documentation ⭐⭐⭐⭐⭐ Comprehensive and clear
User Experience ⭐⭐⭐⭐⭐ Intuitive with helpful prompts
Error Handling ⭐⭐⭐⭐⭐ Robust with fallbacks
Maintainability ⭐⭐⭐⭐☆ Could benefit from JOB_MAP docs

✅ Recommendation

APPROVE - This is production-ready code that provides significant value to the development workflow. The minor observations above are suggestions for future improvements, not blockers.

Key Wins:

  1. Eliminates CI wait times for debugging
  2. Surgical test execution saves time
  3. Excellent error handling and UX
  4. Comprehensive documentation
  5. Secure implementation

Next Steps:

  • Consider adding shellcheck to CI for bash scripts
  • Document JOB_MAP maintenance in CONTRIBUTING.md
  • Monitor usage and gather feedback for future enhancements

Great work! 🚀


Review conducted following CLAUDE.md guidelines with focus on code quality, security, performance, and best practices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants