Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b7d8de5
Add RuboCop rake task as the default task
eclectic-coding May 18, 2026
3a31681
Add rspec-rails to Gemfile for test environment
eclectic-coding May 18, 2026
66290bf
Add RSpec rake task and make default run rubocop then spec
eclectic-coding May 18, 2026
91e2763
Require pagy and solid_queue in engine for proper constant loading
eclectic-coding May 18, 2026
731c254
Migrate from Pagy::Backend/Frontend to Pagy::Method for v43 API
eclectic-coding May 18, 2026
4c1d5ef
Update controllers to use pagy(:offset, ...) syntax for v43
eclectic-coding May 18, 2026
3352e8b
Replace pagy_nav helper with pagy v43 instance method series_nav
eclectic-coding May 18, 2026
a7568b3
Ignore test SQLite database and dummy app runtime directories
eclectic-coding May 18, 2026
d6eeed1
Add RSpec test environment with dummy Rails app and dashboard spec
eclectic-coding May 18, 2026
53c3242
Add test job to CI workflow running rspec
eclectic-coding May 18, 2026
c445bbb
Add simplecov gem for code coverage reporting
eclectic-coding May 18, 2026
d62c8fe
Configure SimpleCov with rails profile and controller/helper/view groups
eclectic-coding May 18, 2026
7ff3052
Ignore SimpleCov coverage output directory
eclectic-coding May 18, 2026
8ed2e69
Add CHANGELOG following Keep a Changelog format and wire gemspec URI
eclectic-coding May 18, 2026
0564d8b
Set minimum Ruby version to 3.3 in gemspec
eclectic-coding May 18, 2026
8985c56
Add aarch64-linux platform to lockfile for CI matrix compatibility
eclectic-coding May 18, 2026
9973352
Add Ruby version matrix (3.3, 3.4, 4.0) to CI test job
eclectic-coding May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
lint:
runs-on: ubuntu-latest
env:
RUBY_VERSION: 4.0.4
RUBY_VERSION: "4.0"
RUBOCOP_CACHE_ROOT: tmp/rubocop
steps:
- name: Checkout code
Expand All @@ -34,3 +34,23 @@ jobs:
- name: Lint code for consistent style
run: bin/rubocop -f github

test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [ "3.3", "3.4", "4.0" ]
env:
RAILS_ENV: test
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Ruby ${{ matrix.ruby }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- name: Run tests
run: bundle exec rspec
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
/log/*.log
/pkg/
/tmp/
/spec/dummy/db/*.sqlite3
/spec/dummy/log/
/spec/dummy/tmp/
/coverage/
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--require spec_helper
--color
--format documentation
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- RSpec test environment with dummy Rails app for request specs
- SimpleCov code coverage reporting with Rails profile and grouped output
- RuboCop and RSpec rake tasks; `bundle exec rake` runs the full suite
- CI test job running `bundle exec rspec`

## [0.1.0] - 2026-05-18

### Added

- Rails engine scaffold with isolated namespace `SolidQueueDashboard`
- Configurable authentication hook (`SolidQueueDashboard.authenticate`)
- Dashboard page with stat cards for ready, scheduled, running, blocked, failed jobs, queues, and processes
- Queues page with pause/resume actions and latency display
- Jobs page with status filter tabs (ready, scheduled, running, blocked, failed) and per-queue filtering
- Failed jobs page with per-job retry and discard, and bulk discard-all
- Pagination via pagy (v43+)
- Minimal CSS with stat cards, tables, badges, and buttons — no external CSS framework required
- Runtime dependencies: `rails >= 8.1.3`, `solid_queue >= 1.0`, `pagy >= 9.0`
- CI workflow with lint (RuboCop) and test (RSpec) jobs

[Unreleased]: https://github.com/eclectic-coding/solid_queue_dashboard/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/eclectic-coding/solid_queue_dashboard/releases/tag/v0.1.0
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ gem "sqlite3"
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
gem "rubocop-rails-omakase", require: false

# Start debugger with binding.b [https://github.com/ruby/debug]
# gem "debug", ">= 1.0.0"
gem "rspec-rails"
gem "simplecov", require: false
43 changes: 43 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ GEM
connection_pool (3.0.2)
crass (1.0.6)
date (3.5.1)
diff-lcs (1.6.2)
docile (1.4.1)
drb (2.2.3)
erb (6.0.4)
erubi (1.13.1)
Expand Down Expand Up @@ -137,6 +139,8 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nokogiri (1.19.3-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.19.3-x86_64-linux-gnu)
Expand Down Expand Up @@ -207,6 +211,23 @@ GEM
regexp_parser (2.12.0)
reline (0.6.3)
io-console (~> 0.5)
rspec-core (3.13.6)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.8)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.4)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
rspec-core (>= 3.13.0, < 5.0.0)
rspec-expectations (>= 3.13.0, < 5.0.0)
rspec-mocks (>= 3.13.0, < 5.0.0)
rspec-support (>= 3.13.0, < 5.0.0)
rspec-support (3.13.7)
rubocop (1.86.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
Expand Down Expand Up @@ -237,13 +258,20 @@ GEM
rubocop-rails (>= 2.30)
ruby-progressbar (1.13.0)
securerandom (0.4.1)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.2)
simplecov_json_formatter (0.1.4)
solid_queue (1.4.0)
activejob (>= 7.1)
activerecord (>= 7.1)
concurrent-ruby (>= 1.3.1)
fugit (~> 1.11)
railties (>= 7.1)
thor (>= 1.3.1)
sqlite3 (2.9.4-aarch64-linux-gnu)
sqlite3 (2.9.4-arm64-darwin)
sqlite3 (2.9.4-x86_64-linux-gnu)
stringio (3.2.0)
Expand All @@ -265,12 +293,15 @@ GEM
zeitwerk (2.7.5)

PLATFORMS
aarch64-linux
arm64-darwin
x86_64-linux

DEPENDENCIES
puma
rspec-rails
rubocop-rails-omakase
simplecov
solid_queue_dashboard!
sqlite3

Expand All @@ -295,6 +326,8 @@ CHECKSUMS
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
Expand All @@ -318,6 +351,7 @@ CHECKSUMS
net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736
nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1
nokogiri (1.19.3-aarch64-linux-gnu) sha256=46b89e5d7b9e844c2ee360794240c6ea2a4e6fa0c5892a4ed487db621224b639
nokogiri (1.19.3-arm64-darwin) sha256=71b9bd424b1b7abc18b05052a1a3cfd3627abdca62be280854cc411791357e42
nokogiri (1.19.3-x86_64-linux-gnu) sha256=2f5078620fe12e83669b5b17311b32532a8153d02eee7ad06948b926d6080976
pagy (43.5.4) sha256=2bdf3fa6b1e0cac5bbafe5d077fb24eb971f72f3194f8c6863a0f3867261ce59
Expand All @@ -343,15 +377,24 @@ CHECKSUMS
rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
rspec-rails (8.0.4) sha256=06235692fc0892683d3d34977e081db867434b3a24ae0dd0c6f3516bad4e22df
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
rubocop (1.86.1) sha256=44415f3f01d01a21e01132248d2fd0867572475b566ca188a0a42133a08d4531
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
rubocop-rails (2.35.0) sha256=a5d9f0f6c6d9b73d9ddd181c4c0b6d2e00dd17107480828d31c7b369ebfcd49c
rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
solid_queue (1.4.0) sha256=e6a18d196f0b27cb6e3c77c5b31258b05fb634f8ed64fb1866ed164047216c2a
solid_queue_dashboard (0.1.0)
sqlite3 (2.9.4-aarch64-linux-gnu) sha256=ecabed721e6eaad54601d2685f09029d90025efc8d931040dc89cb3f8a2080ec
sqlite3 (2.9.4-arm64-darwin) sha256=1d5aad413a815d236e96d43f05a1acc600b6cd086800770342a3f9c2877499ff
sqlite3 (2.9.4-x86_64-linux-gnu) sha256=537a3eda71b1df1336d0055cbebe55a7317c34870c192c7b6b9d8d0be6871847
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
Expand Down
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
require "bundler/setup"

require "bundler/gem_tasks"
require "rubocop/rake_task"
require "rspec/core/rake_task"

RuboCop::RakeTask.new
RSpec::Core::RakeTask.new(:spec)

task default: [ :rubocop, :spec ]
15 changes: 8 additions & 7 deletions app/assets/stylesheets/solid_queue_dashboard/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,16 @@ tbody tr:hover { background: var(--bg); }
white-space: nowrap;
}

/* Pagination (pagy) */
.pagy-nav {
/* Pagination (pagy v43 series-nav) */
nav.pagy {
display: flex;
justify-content: center;
gap: 0.25rem;
padding: 1rem;
list-style: none;
}

.pagy-nav a,
.pagy-nav span {
nav.pagy a {
display: inline-flex;
align-items: center;
justify-content: center;
Expand All @@ -288,6 +288,7 @@ tbody tr:hover { background: var(--bg); }
background: var(--surface);
}

.pagy-nav a:hover { background: var(--bg); }
.pagy-nav span.current { background: var(--primary); color: #fff; border-color: var(--primary); }
.pagy-nav span.gap, .pagy-nav span.disabled { color: var(--muted); }
nav.pagy a:hover:not([aria-disabled="true"]) { background: var(--bg); }
nav.pagy a[aria-current="page"] { background: var(--primary); color: #fff; border-color: var(--primary); }
nav.pagy a[role="separator"],
nav.pagy a[aria-disabled="true"] { color: var(--muted); cursor: default; }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module SolidQueueDashboard
class ApplicationController < ActionController::Base
include Pagy::Backend
include Pagy::Method

before_action :authenticate!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module SolidQueueDashboard
class FailedJobsController < ApplicationController
def index
scope = SolidQueue::FailedExecution.includes(:job).order(created_at: :desc)
@pagy, @failed_jobs = pagy(scope, limit: 50)
@pagy, @failed_jobs = pagy(:offset, scope, limit: 50)
end

def retry
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/solid_queue_dashboard/jobs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def index
scope = scope.where(jobs: { queue_name: @queue }) if @queue.present?
scope = scope.order(created_at: :desc)

@pagy, @jobs = pagy(scope, limit: 50)
@pagy, @jobs = pagy(:offset, scope, limit: 50)
end
end
end
2 changes: 1 addition & 1 deletion app/controllers/solid_queue_dashboard/queues_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module SolidQueueDashboard
class QueuesController < ApplicationController
def index
all_queues = SolidQueue::Queue.all.sort_by(&:name)
@pagy, @queues = pagy_array(all_queues, limit: 50)
@pagy, @queues = pagy(:offset, all_queues, limit: 50)
end

def pause
Expand Down
1 change: 0 additions & 1 deletion app/helpers/solid_queue_dashboard/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module SolidQueueDashboard
module ApplicationHelper
include Pagy::Frontend
end
end
2 changes: 1 addition & 1 deletion app/views/solid_queue_dashboard/failed_jobs/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@
<% end %>
</tbody>
</table>
<%= pagy_nav(@pagy) if @pagy.pages > 1 %>
<%= raw @pagy.series_nav if @pagy.pages > 1 %>
<% end %>
</div>
2 changes: 1 addition & 1 deletion app/views/solid_queue_dashboard/jobs/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<% end %>
</tbody>
</table>
<%= pagy_nav(@pagy) if @pagy.pages > 1 %>
<%= raw @pagy.series_nav if @pagy.pages > 1 %>
<% end %>
</div>

Expand Down
2 changes: 1 addition & 1 deletion app/views/solid_queue_dashboard/queues/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
<% end %>
</tbody>
</table>
<%= pagy_nav(@pagy) if @pagy.pages > 1 %>
<%= raw @pagy.series_nav if @pagy.pages > 1 %>
<% end %>
</div>
4 changes: 4 additions & 0 deletions lib/solid_queue_dashboard/engine.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
require "pagy"
require "pagy/toolbox/paginators/method"
require "solid_queue"

module SolidQueueDashboard
class Engine < ::Rails::Engine
isolate_namespace SolidQueueDashboard
Expand Down
4 changes: 3 additions & 1 deletion solid_queue_dashboard.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ Gem::Specification.new do |spec|

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
spec.metadata["changelog_uri"] = "https://github.com/eclectic-coding/solid_queue_dashboard/blob/main/CHANGELOG.md"

spec.files = Dir.chdir(File.expand_path(__dir__)) do
Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
end

spec.required_ruby_version = ">= 3.3"

spec.add_dependency "rails", ">= 8.1.3"
spec.add_dependency "solid_queue", ">= 1.0"
spec.add_dependency "pagy", ">= 9.0"
Expand Down
14 changes: 14 additions & 0 deletions spec/dummy/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require_relative "boot"

require "rails/all"

Bundler.require(*Rails.groups)

module Dummy
class Application < Rails::Application
config.root = File.expand_path("..", __dir__)
config.load_defaults 8.1
config.eager_load = false
config.active_support.deprecation = :stderr
end
end
3 changes: 3 additions & 0 deletions spec/dummy/config/boot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__)

require "bundler/setup"
8 changes: 8 additions & 0 deletions spec/dummy/config/database.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
default: &default
adapter: sqlite3
pool: 5
timeout: 5000

test:
<<: *default
database: <%= File.expand_path("../db/test.sqlite3", __dir__) %>
5 changes: 5 additions & 0 deletions spec/dummy/config/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ENV["RAILS_ENV"] ||= "test"

require_relative "application"

Rails.application.initialize!
3 changes: 3 additions & 0 deletions spec/dummy/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rails.application.routes.draw do
mount SolidQueueDashboard::Engine, at: "/jobs"
end
Loading