pgbus 0.2.2 → 0.2.3
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/Rakefile +88 -25
- data/app/controllers/pgbus/application_controller.rb +2 -2
- data/app/views/layouts/pgbus/application.html.erb +24 -25
- data/app/views/pgbus/dashboard/_processes_table.html.erb +1 -1
- data/app/views/pgbus/dashboard/_queues_table.html.erb +1 -1
- data/app/views/pgbus/dashboard/_recent_failures.html.erb +1 -1
- data/app/views/pgbus/dashboard/_stats_cards.html.erb +1 -1
- data/app/views/pgbus/dead_letter/_messages_table.html.erb +1 -1
- data/app/views/pgbus/jobs/_enqueued_table.html.erb +1 -1
- data/app/views/pgbus/jobs/_failed_table.html.erb +1 -1
- data/app/views/pgbus/processes/_processes_table.html.erb +1 -1
- data/app/views/pgbus/queues/_queues_list.html.erb +1 -1
- data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +1 -1
- data/config/routes.rb +1 -1
- data/lib/pgbus/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85f2e8748cf70bb74cb736b23e3e0288be5ca0b946b0eb80c08e1d28650e98c0
|
|
4
|
+
data.tar.gz: d1fd675bb9d9a5beb4607f8e0da684c606d096a835948abf60034bd601cdd7f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 99b168d4276ef5149effdbf7d18955c542b9f8507a67d022381a61c7c36cacdf58ab414e166e528495e244313ef12d10e054119361bbf77ca2e6cc260f6d1982
|
|
7
|
+
data.tar.gz: 606324c33ddd072b24135c91314258fc2c162e54b6610ec813457cae2b4df3ba5c0391fc5dbd8a1ff6e13f14032968320b41b9a1d9450d0b5fbe2d66686f2c9e
|
data/Rakefile
CHANGED
|
@@ -50,15 +50,24 @@ task :build do
|
|
|
50
50
|
sh("rm -rf /tmp/gem-verify #{gem_file}")
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
desc "Release a new version (rake release[1.2.3] or rake release[pre])"
|
|
54
|
-
task :release, [
|
|
53
|
+
desc "Release a new version (rake release[1.2.3] or rake release[pre] or rake release[1.2.3,force])"
|
|
54
|
+
task :release, %i[version force] do |_t, args|
|
|
55
55
|
require_relative "lib/pgbus/version"
|
|
56
56
|
|
|
57
|
+
def info(msg) = puts "\e[34m→\e[0m #{msg}"
|
|
58
|
+
def success(msg) = puts "\e[32m✓\e[0m #{msg}"
|
|
59
|
+
def skip(msg) = puts "\e[33m⊘\e[0m #{msg} \e[33m(skipped)\e[0m"
|
|
60
|
+
def warn(msg) = puts "\e[33m⚠\e[0m #{msg}"
|
|
61
|
+
def error(msg) = puts "\e[31m✗\e[0m #{msg}"
|
|
62
|
+
def header(msg) = puts "\n\e[1;36m#{msg}\e[0m\n#{"─" * msg.length}"
|
|
63
|
+
|
|
57
64
|
new_version = args[:version]
|
|
58
|
-
abort "
|
|
65
|
+
abort "\e[31mUsage: rake release[X.Y.Z] or rake release[X.Y.Z,force]\e[0m" unless new_version
|
|
66
|
+
|
|
67
|
+
force = args[:force]&.to_s&.downcase == "force"
|
|
59
68
|
|
|
60
69
|
dirty = `git status --porcelain`.strip
|
|
61
|
-
abort "
|
|
70
|
+
abort "\e[31mAborting: working directory is not clean.\e[0m\n#{dirty}" unless dirty.empty?
|
|
62
71
|
|
|
63
72
|
current = Pgbus::VERSION
|
|
64
73
|
prerelease = new_version.match?(/alpha|beta|rc|pre/) || new_version == "pre"
|
|
@@ -69,43 +78,97 @@ task :release, [:version] do |_t, args|
|
|
|
69
78
|
end
|
|
70
79
|
|
|
71
80
|
tag = "v#{new_version}"
|
|
81
|
+
version_file = "lib/pgbus/version.rb"
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
title = "Release #{tag}"
|
|
84
|
+
title += " (force)" if force
|
|
85
|
+
header title
|
|
86
|
+
info "Current version: #{current}"
|
|
87
|
+
info "New version: #{new_version}"
|
|
88
|
+
info "Pre-release: #{prerelease}"
|
|
89
|
+
|
|
90
|
+
# Step 0: Force cleanup — delete existing release and tag
|
|
91
|
+
if force
|
|
92
|
+
header "Force cleanup"
|
|
93
|
+
if system("gh release view #{tag} >/dev/null 2>&1")
|
|
94
|
+
sh("gh release delete #{tag} --yes --cleanup-tag")
|
|
95
|
+
success "Deleted release and remote tag #{tag}"
|
|
96
|
+
else
|
|
97
|
+
skip "No release #{tag} to delete"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if system("git rev-parse #{tag} >/dev/null 2>&1")
|
|
101
|
+
sh("git tag -d #{tag}")
|
|
102
|
+
success "Deleted local tag #{tag}"
|
|
103
|
+
else
|
|
104
|
+
skip "No local tag #{tag} to delete"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
78
107
|
|
|
79
|
-
# Update version file
|
|
80
|
-
|
|
81
|
-
if new_version
|
|
108
|
+
# Step 1: Update version file
|
|
109
|
+
header "Version"
|
|
110
|
+
if new_version == current
|
|
111
|
+
skip "Version already #{new_version}"
|
|
112
|
+
else
|
|
82
113
|
content = File.read(version_file)
|
|
83
114
|
content.sub!(/VERSION = ".*"/, "VERSION = \"#{new_version}\"")
|
|
84
115
|
File.write(version_file, content)
|
|
85
|
-
|
|
116
|
+
success "Updated #{version_file}"
|
|
86
117
|
end
|
|
87
118
|
|
|
88
|
-
# Verify gem builds cleanly
|
|
119
|
+
# Step 2: Verify gem builds cleanly
|
|
120
|
+
header "Build verification"
|
|
89
121
|
sh("gem build pgbus.gemspec --strict")
|
|
90
122
|
sh("rm -f pgbus-*.gem")
|
|
123
|
+
success "Gem builds cleanly"
|
|
91
124
|
|
|
92
|
-
#
|
|
93
|
-
|
|
125
|
+
# Step 3: Commit version bump
|
|
126
|
+
header "Git commit"
|
|
127
|
+
version_changed = !`git diff #{version_file}`.strip.empty? || !`git diff --cached #{version_file}`.strip.empty?
|
|
128
|
+
if version_changed
|
|
94
129
|
sh("git add #{version_file}")
|
|
95
130
|
sh("git commit -m 'chore: bump version to #{new_version}'")
|
|
131
|
+
success "Committed version bump"
|
|
132
|
+
else
|
|
133
|
+
skip "No version change to commit"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Step 4: Push to origin
|
|
137
|
+
header "Git push"
|
|
138
|
+
local_sha = `git rev-parse HEAD`.strip
|
|
139
|
+
remote_sha = `git rev-parse origin/main 2>/dev/null`.strip
|
|
140
|
+
if local_sha == remote_sha
|
|
141
|
+
skip "origin/main already at #{local_sha[0..6]}"
|
|
142
|
+
else
|
|
143
|
+
sh("git push origin main")
|
|
144
|
+
success "Pushed to origin/main"
|
|
96
145
|
end
|
|
97
|
-
sh("git push origin main")
|
|
98
146
|
|
|
99
|
-
|
|
100
|
-
|
|
147
|
+
# Step 5: Create release
|
|
148
|
+
header "Release"
|
|
149
|
+
tag_exists = system("git rev-parse #{tag} >/dev/null 2>&1")
|
|
150
|
+
release_exists = system("gh release view #{tag} >/dev/null 2>&1")
|
|
151
|
+
|
|
152
|
+
if release_exists
|
|
153
|
+
skip "Release #{tag} already exists (use force to re-create)"
|
|
154
|
+
elsif tag_exists
|
|
155
|
+
info "Tag #{tag} exists, creating release from it"
|
|
156
|
+
pre_flag = prerelease ? "--prerelease" : ""
|
|
157
|
+
sh("gh release create #{tag} --generate-notes #{pre_flag}".strip)
|
|
158
|
+
success "Release #{tag} created from existing tag"
|
|
159
|
+
else
|
|
160
|
+
pre_flag = prerelease ? "--prerelease" : ""
|
|
161
|
+
sh("gh release create #{tag} --generate-notes --target main #{pre_flag}".strip)
|
|
162
|
+
success "Release #{tag} created"
|
|
163
|
+
end
|
|
101
164
|
|
|
102
165
|
puts ""
|
|
103
|
-
|
|
104
|
-
puts "
|
|
105
|
-
puts "
|
|
106
|
-
puts "
|
|
107
|
-
puts "
|
|
108
|
-
puts "
|
|
166
|
+
success "\e[1mRelease #{tag} complete!\e[0m CI will handle the rest:"
|
|
167
|
+
puts " • Run tests"
|
|
168
|
+
puts " • Build + verify gem"
|
|
169
|
+
puts " • Sign with Sigstore"
|
|
170
|
+
puts " • Publish to RubyGems"
|
|
171
|
+
puts " • Upload assets to the release"
|
|
109
172
|
end
|
|
110
173
|
|
|
111
174
|
task default: %i[spec rubocop]
|
|
@@ -51,6 +51,7 @@ module Pgbus
|
|
|
51
51
|
@available_locales ||= Dir[Pgbus::Engine.root.join("config", "locales", "*.yml")]
|
|
52
52
|
.map { |f| File.basename(f, ".yml").to_sym }
|
|
53
53
|
end
|
|
54
|
+
helper_method :available_locales
|
|
54
55
|
|
|
55
56
|
def data_source
|
|
56
57
|
@data_source ||= Pgbus.configuration.web_data_source || Web::DataSource.new
|
|
@@ -67,9 +68,8 @@ module Pgbus
|
|
|
67
68
|
def insights_minutes
|
|
68
69
|
config = Pgbus.configuration
|
|
69
70
|
default = config.insights_default_minutes.to_i
|
|
70
|
-
max = config.stats_retention.to_i / 60
|
|
71
71
|
value = (params[:minutes] || default).to_i
|
|
72
|
-
value.clamp(1, [
|
|
72
|
+
value.clamp(1, [default, 43_200].max)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def turbo_frame_request?
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title><%= t("pgbus.layout.title") %></title>
|
|
7
|
+
<style>
|
|
8
|
+
/* Prevent white flash during navigation in dark mode.
|
|
9
|
+
Applied before Tailwind CDN loads so the background is correct immediately. */
|
|
10
|
+
html.dark { background-color: #030712; } /* gray-950 */
|
|
11
|
+
html.dark body { background-color: #030712; }
|
|
12
|
+
</style>
|
|
7
13
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
14
|
<script>
|
|
9
15
|
tailwind.config = { darkMode: 'class' };
|
|
@@ -17,24 +23,17 @@
|
|
|
17
23
|
var isDark = document.documentElement.classList.toggle('dark');
|
|
18
24
|
localStorage.setItem('pgbus-dark', isDark);
|
|
19
25
|
}
|
|
20
|
-
//
|
|
26
|
+
// Close locale dropdown when clicking outside
|
|
21
27
|
document.addEventListener('click', function(e) {
|
|
22
|
-
var
|
|
23
|
-
var menu =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
if (menu) { menu.classList.toggle('hidden'); e.stopPropagation(); }
|
|
29
|
-
});
|
|
30
|
-
document.addEventListener('click', function() {
|
|
31
|
-
document.querySelectorAll('[data-dropdown-target="menu"]').forEach(function(m) {
|
|
32
|
-
m.classList.add('hidden');
|
|
33
|
-
});
|
|
28
|
+
var switcher = document.getElementById('pgbus-locale-switcher');
|
|
29
|
+
var menu = document.getElementById('pgbus-locale-menu');
|
|
30
|
+
if (menu && switcher && !switcher.contains(e.target)) {
|
|
31
|
+
menu.classList.add('hidden');
|
|
32
|
+
}
|
|
34
33
|
});
|
|
35
34
|
</script>
|
|
36
35
|
<script type="module">
|
|
37
|
-
import * as Turbo from "https://
|
|
36
|
+
import * as Turbo from "https://esm.sh/@hotwired/turbo@8";
|
|
38
37
|
|
|
39
38
|
<% if Pgbus.configuration.web_live_updates %>
|
|
40
39
|
const interval = <%= Pgbus.configuration.web_refresh_interval %>;
|
|
@@ -43,7 +42,10 @@
|
|
|
43
42
|
function refreshFrames() {
|
|
44
43
|
if (document.hidden) return;
|
|
45
44
|
document.querySelectorAll("turbo-frame[data-auto-refresh]")
|
|
46
|
-
.forEach(frame =>
|
|
45
|
+
.forEach(frame => {
|
|
46
|
+
if (!frame.src && frame.dataset.src) frame.src = frame.dataset.src;
|
|
47
|
+
if (frame.src) frame.reload();
|
|
48
|
+
});
|
|
47
49
|
}
|
|
48
50
|
function start() { timer = setInterval(refreshFrames, interval); }
|
|
49
51
|
function stop() { clearInterval(timer); }
|
|
@@ -81,19 +83,16 @@
|
|
|
81
83
|
|
|
82
84
|
<div class="flex items-center space-x-2">
|
|
83
85
|
<!-- Locale switcher -->
|
|
84
|
-
<div class="relative"
|
|
85
|
-
<button type="button"
|
|
86
|
+
<div class="relative" id="pgbus-locale-switcher">
|
|
87
|
+
<button type="button" onclick="document.getElementById('pgbus-locale-menu').classList.toggle('hidden')" class="rounded-md px-2 py-1 text-sm text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500">
|
|
86
88
|
<%= pgbus_locale_flag(I18n.locale) %> <%= I18n.locale.to_s.upcase %>
|
|
87
89
|
</button>
|
|
88
|
-
<div
|
|
90
|
+
<div id="pgbus-locale-menu" class="hidden absolute right-0 z-50 mt-1 w-44 origin-top-right rounded-md bg-white dark:bg-gray-800 shadow-lg ring-1 ring-black/5 dark:ring-white/10">
|
|
89
91
|
<div class="py-1" role="menu">
|
|
90
|
-
<%
|
|
91
|
-
<%=
|
|
92
|
-
<%=
|
|
93
|
-
|
|
94
|
-
<%= pgbus_locale_flag(loc) %> <%= pgbus_locale_name(loc) %>
|
|
95
|
-
</button>
|
|
96
|
-
<% end %>
|
|
92
|
+
<% available_locales.sort.each do |loc| %>
|
|
93
|
+
<a href="<%= pgbus.set_locale_path(locale: loc) %>" role="menuitem" class="block px-3 py-1 text-sm no-underline <%= loc == I18n.locale ? 'bg-indigo-50 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300 font-medium' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700' %>">
|
|
94
|
+
<%= pgbus_locale_flag(loc) %> <%= pgbus_locale_name(loc) %>
|
|
95
|
+
</a>
|
|
97
96
|
<% end %>
|
|
98
97
|
</div>
|
|
99
98
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="dashboard-processes" data-auto-refresh src="<%= pgbus.root_path(frame: 'processes') %>">
|
|
1
|
+
<turbo-frame id="dashboard-processes" data-auto-refresh data-src="<%= pgbus.root_path(frame: 'processes') %>">
|
|
2
2
|
<div>
|
|
3
3
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-3"><%= t("pgbus.dashboard.processes_table.title") %></h2>
|
|
4
4
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="dashboard-queues" data-auto-refresh src="<%= pgbus.root_path(frame: 'queues') %>">
|
|
1
|
+
<turbo-frame id="dashboard-queues" data-auto-refresh data-src="<%= pgbus.root_path(frame: 'queues') %>">
|
|
2
2
|
<div class="mb-8">
|
|
3
3
|
<div class="flex items-center justify-between mb-3">
|
|
4
4
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white"><%= t("pgbus.dashboard.queues_table.title") %></h2>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="dashboard-failures" data-auto-refresh src="<%= pgbus.root_path(frame: 'failures') %>">
|
|
1
|
+
<turbo-frame id="dashboard-failures" data-auto-refresh data-src="<%= pgbus.root_path(frame: 'failures') %>">
|
|
2
2
|
<div>
|
|
3
3
|
<div class="flex items-center justify-between mb-3">
|
|
4
4
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white"><%= t("pgbus.dashboard.recent_failures.title") %></h2>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="dashboard-stats" data-auto-refresh src="<%= pgbus.root_path(frame: 'stats') %>">
|
|
1
|
+
<turbo-frame id="dashboard-stats" data-auto-refresh data-src="<%= pgbus.root_path(frame: 'stats') %>">
|
|
2
2
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-6 mb-8">
|
|
3
3
|
<div class="rounded-lg bg-white dark:bg-gray-800 p-5 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
4
4
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400"><%= t("pgbus.dashboard.stats_cards.queues") %></p>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="dlq-messages" data-auto-refresh src="<%= pgbus.dead_letter_index_path(frame: 'list') %>">
|
|
1
|
+
<turbo-frame id="dlq-messages" data-auto-refresh data-src="<%= pgbus.dead_letter_index_path(frame: 'list') %>">
|
|
2
2
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
3
3
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
4
4
|
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="jobs-enqueued" data-auto-refresh src="<%= pgbus.jobs_path(request.query_parameters.merge(frame: 'enqueued')) %>">
|
|
1
|
+
<turbo-frame id="jobs-enqueued" data-auto-refresh data-src="<%= pgbus.jobs_path(request.query_parameters.merge(frame: 'enqueued')) %>">
|
|
2
2
|
<div>
|
|
3
3
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-3"><%= t("pgbus.jobs.enqueued_table.title") %></h2>
|
|
4
4
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="jobs-failed" data-auto-refresh src="<%= pgbus.jobs_path(frame: 'failed') %>">
|
|
1
|
+
<turbo-frame id="jobs-failed" data-auto-refresh data-src="<%= pgbus.jobs_path(frame: 'failed') %>">
|
|
2
2
|
<div class="mb-8">
|
|
3
3
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-3"><%= t("pgbus.jobs.failed_table.title") %></h2>
|
|
4
4
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="processes-list" data-auto-refresh src="<%= pgbus.processes_path(frame: 'list') %>">
|
|
1
|
+
<turbo-frame id="processes-list" data-auto-refresh data-src="<%= pgbus.processes_path(frame: 'list') %>">
|
|
2
2
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
3
3
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
4
4
|
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="queues-list" data-auto-refresh src="<%= pgbus.queues_path(frame: 'list') %>">
|
|
1
|
+
<turbo-frame id="queues-list" data-auto-refresh data-src="<%= pgbus.queues_path(frame: 'list') %>">
|
|
2
2
|
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
3
3
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
4
4
|
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<turbo-frame id="recurring-tasks" data-auto-refresh src="<%= pgbus.recurring_tasks_path(frame: 'recurring_tasks') %>">
|
|
1
|
+
<turbo-frame id="recurring-tasks" data-auto-refresh data-src="<%= pgbus.recurring_tasks_path(frame: 'recurring_tasks') %>">
|
|
2
2
|
<div class="rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700">
|
|
3
3
|
<% if @recurring_tasks.empty? %>
|
|
4
4
|
<div class="p-8 text-center text-gray-500">
|
data/config/routes.rb
CHANGED
|
@@ -52,7 +52,7 @@ Pgbus::Engine.routes.draw do
|
|
|
52
52
|
resources :locks, only: [:index]
|
|
53
53
|
resource :insights, only: [:show], controller: "insights"
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
get :set_locale, to: "locale#update"
|
|
56
56
|
|
|
57
57
|
namespace :api do
|
|
58
58
|
get :stats, to: "stats#show"
|
data/lib/pgbus/version.rb
CHANGED