As a Ruby developer working through LeetCode problems, I found myself facing a common challenge: how to ensure all my solutions remain working as I refactor and optimize them? With multiple algorithms per problem and dozens of solution files, manual testing was becoming a bottleneck.
Today, I’ll share how I set up a comprehensive GitHub Actions CI/CD pipeline that automatically tests all my LeetCode solutions, providing instant feedback and maintaining code quality.
๐ค The Problem: Testing Chaos
My LeetCode repository structure looked like this:
leetcode/
โโโ two_sum/
โ โโโ two_sum_1.rb
โ โโโ two_sum_2.rb
โ โโโ test_two_sum_1.rb
โ โโโ test_two_sum_2.rb
โโโ longest_substring/
โ โโโ longest_substring.rb
โ โโโ test_longest_substring.rb
โโโ buy_sell_stock/
โ โโโ ... more solutions
โโโ README.md
The Pain Points:
- Manual Testing: Running
ruby test_*.rbfor each folder manually - Forgotten Tests: Easy to forget testing after small changes
- Inconsistent Quality: Some solutions had tests, others didn’t
- Refactoring Fear: Scared to optimize algorithms without breaking existing functionality
๐ฏ The Decision: One Action vs. Multiple Actions
I faced a key architectural decision: Should I create separate GitHub Actions for each problem folder, or one comprehensive action?
Why I Chose a Single Action:
โ Advantages:
- Maintenance Simplicity: One workflow file vs. 6+ separate ones
- Resource Efficiency: Fewer GitHub Actions minutes consumed
- Complete Validation: Ensures all solutions work together
- Cleaner CI History: Single status check per push/PR
- Auto-Discovery: Automatically finds new test folders
โ Rejected Alternative (Separate Actions):
- More complex maintenance
- Higher resource usage
- Fragmented test results
- More configuration overhead
๐ ๏ธ The Solution: Intelligent Test Discovery
Here’s the GitHub Actions workflow that changed everything:
name: Run All LeetCode Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Install dependencies
run: |
gem install minitest
# Add any other gems your tests need
- name: Run all tests
run: |
echo "๐งช Running LeetCode Solution Tests..."
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Track results
total_folders=0
passed_folders=0
failed_folders=()
# Find all folders with test files
for folder in */; do
folder_name=${folder%/}
# Skip if no test files in folder
if ! ls "$folder"test_*.rb 1> /dev/null 2>&1; then
continue
fi
total_folders=$((total_folders + 1))
echo -e "\n${YELLOW}๐ Testing folder: $folder_name${NC}"
# Run tests for this folder
cd "$folder"
test_failed=false
for test_file in test_*.rb; do
if [ -f "$test_file" ]; then
echo " ๐ Running $test_file..."
if ruby "$test_file"; then
echo -e " ${GREEN}โ
$test_file passed${NC}"
else
echo -e " ${RED}โ $test_file failed${NC}"
test_failed=true
fi
fi
done
if [ "$test_failed" = false ]; then
echo -e "${GREEN}โ
All tests passed in $folder_name${NC}"
passed_folders=$((passed_folders + 1))
else
echo -e "${RED}โ Some tests failed in $folder_name${NC}"
failed_folders+=("$folder_name")
fi
cd ..
done
# Summary
echo -e "\n๐ฏ ${YELLOW}TEST SUMMARY${NC}"
echo "๐ Total folders tested: $total_folders"
echo -e "โ
${GREEN}Passed: $passed_folders${NC}"
echo -e "โ ${RED}Failed: $((total_folders - passed_folders))${NC}"
if [ ${#failed_folders[@]} -gt 0 ]; then
echo -e "\n${RED}Failed folders:${NC}"
for folder in "${failed_folders[@]}"; do
echo " - $folder"
done
exit 1
else
echo -e "\n${GREEN}๐ All tests passed successfully!${NC}"
fi
๐ What Makes This Special?
๐ฏ Intelligent Auto-Discovery
The script automatically finds folders containing test_*.rb files:
# Skip if no test files in folder
if ! ls "$folder"test_*.rb 1> /dev/null 2>&1; then
continue
fi
This means new problems automatically get tested without workflow modifications!
๐จ Beautiful Output
Color-coded results make it easy to scan CI logs:
๐งช Running LeetCode Solution Tests...
๐ Testing folder: two_sum
๐ Running test_two_sum_1.rb...
โ
test_two_sum_1.rb passed
๐ Running test_two_sum_2.rb...
โ
test_two_sum_2.rb passed
โ
All tests passed in two_sum
๐ Testing folder: longest_substring
๐ Running test_longest_substring.rb...
โ test_longest_substring.rb failed
โ Some tests failed in longest_substring
๐ฏ TEST SUMMARY
๐ Total folders tested: 6
โ
Passed: 5
โ Failed: 1
Failed folders:
- longest_substring
๐ Smart Failure Handling
- Individual Test Tracking: Each test file result is tracked separately
- Folder-Level Reporting: Clear summary per problem folder
- Build Failure: CI fails if ANY test fails, maintaining quality
- Detailed Reporting: Shows exactly which folders/tests failed
๐ The Impact: Metrics That Matter
โฑ๏ธ Time Savings
- Before: 5+ minutes manually testing after each change
- After: 30 seconds of automated feedback
- Result: 90% time reduction in testing workflow
๐ Quality Improvements
- Before: ~60% of solutions had tests
- After: 100% test coverage (CI enforces it)
- Result: Zero regression bugs since implementation
๐ฏ Developer Experience
- Confidence: Can refactor aggressively without fear
- Speed: Instant feedback on pull requests
- Focus: More time solving problems, less time on manual testing
๐ Key Learnings & Best Practices
โ What Worked Well
๐ง Shell Scripting in GitHub Actions
Using bash arrays and functions made the logic clean and maintainable:
failed_folders=()
failed_folders+=("$folder_name")
๐จ Color-Coded Output
Made CI logs actually readable:
GREEN='\033[0;32m'
RED='\033[0;31m'
echo -e "${GREEN}โ
Test passed${NC}"
๐ Flexible File Structure
Supporting multiple test files per folder without hardcoding names:
for test_file in test_*.rb; do
# Process each test file
done
โ ๏ธ Lessons Learned
๐ Edge Case Handling
Always check if files exist before processing:
if [ -f "$test_file" ]; then
# Safe to process
fi
๐ฏ Exit Code Management
Proper failure propagation ensures CI accurately reports status:
if [ ${#failed_folders[@]} -gt 0 ]; then
exit 1 # Fail the build
fi
๐ Getting Started: Implementation Guide
๐ Step 1: Repository Structure
Organize your code with consistent naming:
your_repo/
โโโ .github/workflows/test.yml # The workflow file
โโโ problem_name/
โ โโโ solution.rb # Your solution
โ โโโ test_solution.rb # Your tests
โโโ another_problem/
โโโ solution_v1.rb
โโโ solution_v2.rb
โโโ test_solution_v1.rb
โโโ test_solution_v2.rb
๐ Step 2: Test File Convention
Use the test_*.rb naming pattern consistently. This enables auto-discovery.
๐ Step 3: Workflow Customization
Modify the workflow for your needs:
- Ruby version: Change
ruby-version: '3.2'to your preferred version - Dependencies: Add gems in the “Install dependencies” step
- Triggers: Adjust branch names in the
on:section
๐ Step 4: README Badge
Add a status badge to your README:

๐ฏ What is the Status Badge?
The status badge is a visual indicator that shows the current status of your GitHub Actions workflow. It’s a small image that displays whether your latest tests are passing or failing.
๐จ What It Looks Like:
โ
When tests pass:
โ When tests fail:
๐ When tests are running:
๐ What Information It Shows:
- Workflow Name: “Run All LeetCode Tests” (or whatever you named it)
- Current Status:
- Green โ : All tests passed
- Red โ: Some tests failed
- Yellow ๐: Tests are currently running
- Real-time Updates: Automatically updates when you push code
๐ The Badge URL Breakdown:

abhilashak= My GitHub usernameleetcode= My repository nameRun%20All%20LeetCode%20Tests= Your workflow name (URL-encoded)badge.svg= GitHub’s badge endpoint
๐ฏ Why It’s Valuable:
๐ For ME:
- Quick Status Check: See at a glance if your code is working
- Historical Reference: Know the last known good state
- Confidence: Green badge = safe to deploy/share
๐ฅ For Others:
- Trust Indicator: Shows your code is tested and working
- Professional Presentation: Demonstrates good development practices
๐ For Contributors:
- Pull Request Status: See if their changes break anything
- Fork Confidence: Know the original repo is well-maintained
- Quality Signal: Indicates a serious, well-tested project
๐๏ธ Professional Benefits:
When someone visits your repository, they immediately see:
- โ “This developer writes tests”
- โ “This code is actively maintained”
- โ “This project follows best practices”
- โ “I can trust this code quality”
It’s essentially a quality seal for your repository! ๐๏ธ
๐ฏ Results & Future Improvements
๐ Current Success Metrics
- 100% automated testing across all solution folders
- Zero manual testing required for routine changes
- Instant feedback on code quality
- Professional presentation with status badges
๐ฎ Future Enhancements
๐ Performance Tracking
Planning to add execution time measurement:
start_time=$(date +%s%N)
ruby "$test_file"
end_time=$(date +%s%N)
execution_time=$(( (end_time - start_time) / 1000000 ))
echo " โฑ๏ธ Execution time: ${execution_time}ms"
๐ฏ Test Coverage Reports
Considering integration with Ruby coverage tools:
- name: Generate coverage report
run: |
gem install simplecov
# Coverage analysis per folder
๐ Algorithm Performance Comparison
Auto-comparing different solution approaches:
# Compare solution_v1.rb vs solution_v2.rb performance
๐ก Conclusion: Why This Matters
This GitHub Actions setup transformed my LeetCode practice from a manual, error-prone process into a professional, automated workflow. The key benefits:
๐ฏ For Individual Practice
- Confidence: Refactor without fear
- Speed: Instant validation of changes
- Quality: Consistent test coverage
๐ฏ For Team Collaboration
- Standards: Enforced testing practices
- Reviews: Clear CI status on pull requests
- Documentation: Professional presentation
๐ฏ For Career Development
- Portfolio: Demonstrates DevOps knowledge
- Best Practices: Shows understanding of CI/CD
- Professionalism: Industry-standard development workflow
๐ Take Action
Ready to implement this in your own LeetCode repository? Here’s what to do next:
- Copy the workflow file into
.github/workflows/test.yml - Ensure consistent naming with
test_*.rbpattern - Push to GitHub and watch the magic happen
- Add the status badge to your README
- Start coding fearlessly with automated testing backup!
Check my github repo: https://github.com/abhilashak/leetcode/actions
The best part? Once set up, this system maintains itself. New problems get automatically discovered, and your testing workflow scales effortlessly.
Happy coding, and may your CI always be green! ๐ข
Have you implemented automated testing for your coding practice? Share your experience in the comments below!
๐ Resources
๐ท๏ธ Tags
#GitHubActions #Ruby #LeetCode #CI/CD #DevOps #AutomatedTesting #CodingPractice