rails_pulse 0.4.0.pre.2 → 0.4.0.pre.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -171
- data/README.md +2 -0
- data/app/controllers/rails_pulse/application_controller.rb +60 -1
- data/app/controllers/rails_pulse/deployments_controller.rb +1 -4
- data/app/helpers/rails_pulse/breadcrumbs_helper.rb +6 -3
- data/app/models/rails_pulse/deployment.rb +6 -0
- data/app/services/rails_pulse/exception_capture_service.rb +2 -0
- data/app/services/rails_pulse/route_controller_action_backfiller.rb +0 -4
- data/app/views/rails_pulse/shared/schema_outdated.html.erb +96 -0
- data/exe/rails_pulse_server +9 -0
- data/lib/generators/rails_pulse/install_generator.rb +2 -0
- data/lib/generators/rails_pulse/templates/rails_pulse.rb +22 -1
- data/lib/generators/rails_pulse/upgrade_generator.rb +56 -5
- data/lib/rails_pulse/configuration.rb +21 -0
- data/lib/rails_pulse/engine.rb +5 -2
- data/lib/rails_pulse/installers/config_updater.rb +17 -0
- data/lib/rails_pulse/job_run_collector.rb +1 -1
- data/lib/rails_pulse/middleware/asset_server.rb +5 -4
- data/lib/rails_pulse/schema_check.rb +136 -0
- data/lib/rails_pulse/standalone.rb +50 -0
- data/lib/rails_pulse/tasks/status_reporter.rb +217 -0
- data/lib/rails_pulse/tracker.rb +1 -0
- data/lib/rails_pulse/version.rb +1 -1
- data/lib/rails_pulse.rb +2 -0
- data/lib/rails_pulse_server.ru +37 -4
- data/lib/tasks/rails_pulse.rake +48 -2
- data/lib/tasks/rails_pulse_tasks.rake +5 -0
- metadata +7 -3
data/lib/rails_pulse/version.rb
CHANGED
data/lib/rails_pulse.rb
CHANGED
data/lib/rails_pulse_server.ru
CHANGED
|
@@ -19,14 +19,19 @@ else
|
|
|
19
19
|
MESSAGE
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# Root-relative links and standalone authentication — see lib/rails_pulse/standalone.rb.
|
|
23
|
+
RailsPulse.standalone!
|
|
24
|
+
|
|
22
25
|
# Disable output buffering so logs appear immediately
|
|
23
26
|
$stdout.sync = true
|
|
24
27
|
$stderr.sync = true
|
|
25
28
|
|
|
26
29
|
# Build the Rack app with session support
|
|
27
30
|
require "rack/session/cookie"
|
|
31
|
+
require "rack/static"
|
|
28
32
|
require "securerandom"
|
|
29
33
|
require_relative "rails_pulse/rack_compat"
|
|
34
|
+
require_relative "rails_pulse/middleware/asset_server"
|
|
30
35
|
|
|
31
36
|
# Simple Rack app that just serves the dashboard
|
|
32
37
|
class DashboardApp
|
|
@@ -57,10 +62,38 @@ class DashboardApp
|
|
|
57
62
|
end
|
|
58
63
|
end
|
|
59
64
|
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
# Dashboard assets. RouteHelper#asset_path emits one of two URL shapes: the
|
|
66
|
+
# gem-served fallback (/rails-pulse-assets/<version>/...) or, once
|
|
67
|
+
# assets:precompile has run, the digested copies it installs under the host's
|
|
68
|
+
# public/assets. In the main app those are served by AssetServer (inserted
|
|
69
|
+
# into the host middleware stack by the engine) and by ActionDispatch::Static
|
|
70
|
+
# or the CDN. This process calls the engine directly and has neither, so both
|
|
71
|
+
# are served here; without them every dashboard page renders unstyled.
|
|
72
|
+
use RailsPulse::Middleware::AssetServer,
|
|
73
|
+
RailsPulse::Engine.root.join("public").to_s,
|
|
74
|
+
urls: [ "/rails-pulse-assets" ],
|
|
75
|
+
headers: RailsPulse::Engine.asset_headers
|
|
76
|
+
|
|
77
|
+
use Rack::Static,
|
|
78
|
+
urls: [ "/assets" ],
|
|
79
|
+
root: Rails.public_path.to_s,
|
|
80
|
+
header_rules: [ [ :all, RailsPulse::Engine.asset_headers ] ]
|
|
81
|
+
|
|
82
|
+
# Add session middleware for the dashboard. The cookie is signed with
|
|
83
|
+
# SECRET_KEY_BASE when set, otherwise with the host app's own secret_key_base
|
|
84
|
+
# (config/environment.rb is already loaded above) — hosts on encrypted
|
|
85
|
+
# credentials have no SECRET_KEY_BASE environment variable.
|
|
86
|
+
secret_key = ENV["SECRET_KEY_BASE"].to_s
|
|
87
|
+
if secret_key.empty?
|
|
88
|
+
secret_key = begin
|
|
89
|
+
Rails.application.secret_key_base.to_s
|
|
90
|
+
rescue StandardError
|
|
91
|
+
""
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
if secret_key.empty?
|
|
95
|
+
raise "SECRET_KEY_BASE environment variable must be set for standalone dashboard " \
|
|
96
|
+
"(no Rails secret_key_base was available to fall back to)"
|
|
64
97
|
end
|
|
65
98
|
|
|
66
99
|
# `secure` keeps the session cookie off plain HTTP in production. Set
|
data/lib/tasks/rails_pulse.rake
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "stringio"
|
|
2
|
+
|
|
1
3
|
namespace :db do
|
|
2
4
|
namespace :schema do
|
|
3
5
|
desc "Load Rails Pulse schema (for separate database setup only)"
|
|
@@ -36,13 +38,25 @@ end
|
|
|
36
38
|
# for test runs, not just for development/production db:prepare.
|
|
37
39
|
# The task may be namespaced as "app:db:schema:load_rails_pulse" in engine context
|
|
38
40
|
# vs "db:schema:load_rails_pulse" in a host app — try both.
|
|
41
|
+
#
|
|
42
|
+
# This fires on every single `rails test` process (once per appraisal/test_matrix
|
|
43
|
+
# combination, again for the migration regression process), and after the first
|
|
44
|
+
# run it only ever reports "tables already exist" — so its output is muted here.
|
|
45
|
+
# The task itself stays fully verbose when invoked directly (installs, upgrades,
|
|
46
|
+
# and test/lib/tasks/rails_pulse_test.rb assert on that direct-invocation output).
|
|
39
47
|
Rake::Task["db:test:prepare"].enhance do
|
|
40
48
|
if separate_database_setup?
|
|
41
49
|
task_name = %w[db:schema:load_rails_pulse app:db:schema:load_rails_pulse]
|
|
42
50
|
.find { |name| Rake::Task.task_defined?(name) }
|
|
43
51
|
if task_name
|
|
44
52
|
Rake::Task[task_name].reenable
|
|
45
|
-
|
|
53
|
+
original_stdout = $stdout
|
|
54
|
+
$stdout = StringIO.new
|
|
55
|
+
begin
|
|
56
|
+
Rake::Task[task_name].invoke
|
|
57
|
+
ensure
|
|
58
|
+
$stdout = original_stdout
|
|
59
|
+
end
|
|
46
60
|
end
|
|
47
61
|
end
|
|
48
62
|
end if Rake::Task.task_defined?("db:test:prepare")
|
|
@@ -151,9 +165,41 @@ namespace :rails_pulse do
|
|
|
151
165
|
revision = args[:revision]
|
|
152
166
|
abort "ERROR: revision is required. Usage: rake rails_pulse:record_deployment[abc1234]" if revision.blank?
|
|
153
167
|
|
|
154
|
-
|
|
168
|
+
attributes = { revision: revision, started_at: Time.current }
|
|
169
|
+
metadata = deployment_metadata_from_env
|
|
170
|
+
attributes[:metadata] = metadata if metadata
|
|
171
|
+
|
|
172
|
+
deployment = RailsPulse::Deployment.create!(attributes)
|
|
155
173
|
puts "[RailsPulse] Deployment recorded: #{deployment.revision} at #{deployment.started_at}"
|
|
156
174
|
rescue ActiveRecord::RecordInvalid => e
|
|
157
175
|
abort "ERROR: #{e.message}"
|
|
158
176
|
end
|
|
177
|
+
|
|
178
|
+
desc "Mark the latest deployment for a revision as finished. Usage: rake rails_pulse:finish_deployment[revision]"
|
|
179
|
+
task :finish_deployment, [ :revision ] => :environment do |_t, args|
|
|
180
|
+
revision = args[:revision]
|
|
181
|
+
abort "ERROR: revision is required. Usage: rake rails_pulse:finish_deployment[abc1234]" if revision.blank?
|
|
182
|
+
|
|
183
|
+
deployment = RailsPulse::Deployment.latest_for_revision(revision)
|
|
184
|
+
abort "ERROR: no deployment recorded for revision #{revision}" unless deployment
|
|
185
|
+
|
|
186
|
+
deployment.update!(finished_at: Time.current)
|
|
187
|
+
puts "[RailsPulse] Deployment finished: #{deployment.revision} at #{deployment.finished_at} (#{deployment.duration.round}s)"
|
|
188
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
189
|
+
abort "ERROR: #{e.message}"
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Optional metadata for rails_pulse:record_deployment, as a JSON object:
|
|
194
|
+
# RAILS_PULSE_DEPLOYMENT_METADATA='{"environment":"production"}'
|
|
195
|
+
# Rake splits task arguments on commas, so JSON cannot be passed positionally.
|
|
196
|
+
def deployment_metadata_from_env
|
|
197
|
+
raw = ENV["RAILS_PULSE_DEPLOYMENT_METADATA"]
|
|
198
|
+
return nil if raw.blank?
|
|
199
|
+
|
|
200
|
+
parsed = JSON.parse(raw)
|
|
201
|
+
abort "ERROR: RAILS_PULSE_DEPLOYMENT_METADATA must be a JSON object" unless parsed.is_a?(Hash)
|
|
202
|
+
parsed.to_json
|
|
203
|
+
rescue JSON::ParserError => e
|
|
204
|
+
abort "ERROR: RAILS_PULSE_DEPLOYMENT_METADATA is not valid JSON: #{e.message}"
|
|
159
205
|
end
|
|
@@ -23,6 +23,11 @@ namespace :rails_pulse do
|
|
|
23
23
|
RailsPulse::Stats::CleanupStatsReporter.report
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
desc "Reports schema, migration, route backfill and initializer state for this install; exits 1 when something needs action."
|
|
27
|
+
task status: :environment do
|
|
28
|
+
exit 1 unless RailsPulse::Tasks::StatusReporter.report
|
|
29
|
+
end
|
|
30
|
+
|
|
26
31
|
desc "Migrate existing routes: backfill controller actions, normalize paths, consolidate multi-verb routes."
|
|
27
32
|
task migrate_routes: :environment do
|
|
28
33
|
ca_results = RailsPulse::RouteControllerActionBackfiller.call
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_pulse
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.0.pre.
|
|
4
|
+
version: 0.4.0.pre.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Harvey
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -451,6 +451,7 @@ files:
|
|
|
451
451
|
- app/views/rails_pulse/routes/index.html.erb
|
|
452
452
|
- app/views/rails_pulse/routes/show.html.erb
|
|
453
453
|
- app/views/rails_pulse/shared/_deployment_markers_toggle.html.erb
|
|
454
|
+
- app/views/rails_pulse/shared/schema_outdated.html.erb
|
|
454
455
|
- app/views/rails_pulse/skeletons/_chart.html.erb
|
|
455
456
|
- app/views/rails_pulse/skeletons/_metric_card.html.erb
|
|
456
457
|
- app/views/rails_pulse/skeletons/_panel.html.erb
|
|
@@ -501,11 +502,14 @@ files:
|
|
|
501
502
|
- lib/rails_pulse/paginator.rb
|
|
502
503
|
- lib/rails_pulse/rack_compat.rb
|
|
503
504
|
- lib/rails_pulse/route_indexes.rb
|
|
505
|
+
- lib/rails_pulse/schema_check.rb
|
|
506
|
+
- lib/rails_pulse/standalone.rb
|
|
504
507
|
- lib/rails_pulse/statistics.rb
|
|
505
508
|
- lib/rails_pulse/stats/cleanup_stats_reporter.rb
|
|
506
509
|
- lib/rails_pulse/subscribers/exception_subscriber.rb
|
|
507
510
|
- lib/rails_pulse/subscribers/operation_subscriber.rb
|
|
508
511
|
- lib/rails_pulse/tasks/cleanup_task_runner.rb
|
|
512
|
+
- lib/rails_pulse/tasks/status_reporter.rb
|
|
509
513
|
- lib/rails_pulse/tracker.rb
|
|
510
514
|
- lib/rails_pulse/version.rb
|
|
511
515
|
- lib/rails_pulse_server.ru
|
|
@@ -543,7 +547,7 @@ metadata:
|
|
|
543
547
|
bug_tracker_uri: https://github.com/railspulse/rails_pulse/issues
|
|
544
548
|
rubygems_mfa_required: 'true'
|
|
545
549
|
post_install_message: |
|
|
546
|
-
Rails Pulse 0.4.0.pre.
|
|
550
|
+
Rails Pulse 0.4.0.pre.4 installed.
|
|
547
551
|
|
|
548
552
|
UPGRADING from any 0.3.x? This release changes route identity and DROPS
|
|
549
553
|
rails_pulse_routes.method. Back up your database first, then run:
|