gitlab-exporter 17.0.0 → 17.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cc0cadf1891c19066f388f384d51f47b9c489e8e0ee7c162565228fb661bada
4
- data.tar.gz: 7ae7c0ac398b1832c58c2348297139fd88e3ff02e447669043990312160ed0a8
3
+ metadata.gz: 0f38401d83375e243787b0f692035d11cc9cc9e5a3bde34ca9d468261be12a41
4
+ data.tar.gz: 4f8f1dbed6854da6003209745214b6687f405145b79c5dc2a0ee06d0bbedec4f
5
5
  SHA512:
6
- metadata.gz: 7a358dbc90fe7bed11fc33a179fe2eb726e0d218925a56e7f076cc4c51d14272de4adca57cd5ae084e0a57d51feed0cf331b2dbf3ae67a5c0a2a972c4dba1863
7
- data.tar.gz: c937591c8d81ad5296955bd5a55f92bcdd6f2ecb0f1fe7cdd36e9f429e88f5bbf2da8bce8375e8897fec29eda18ea0dd60fcd1bbfc5070c49e9b886a0faf3037
6
+ metadata.gz: 7c88e061a15dcc9f640c29a910de6d81eedb345c113bce789b08a44a252ddc708bdb082e5aa7ee881eb383dcf51c72d34fd7ec8c00353fe210e0b97915e05ab4
7
+ data.tar.gz: 9a26c277997d178c65607aadbba2b82b931bc1375a1f732c35665639cfb1a404869409272f85b640df8a5f101cf25eddee985c1f20dbb8d75f6904aaffd1e7c6
data/.gitlab-ci.yml CHANGED
@@ -32,7 +32,7 @@ default:
32
32
  # to avoid https://github.com/rubygems/rubygems/issues/5380 use an
33
33
  # older Bundler version.
34
34
  case ${RUBY_VERSION} in
35
- "3.0"|"3.1")
35
+ "3.1")
36
36
  export BUNDLER_VERSION="2.4.20"
37
37
  ;;
38
38
  esac
@@ -53,7 +53,7 @@ rspec:
53
53
  before_script: *before_scripts
54
54
  parallel:
55
55
  matrix:
56
- - RUBY_VERSION: ["3.0", "3.1", "3.2", "3.3", "3.4"]
56
+ - RUBY_VERSION: ["3.1", "3.2", "3.3", "3.4", "4.0"]
57
57
 
58
58
  rspec_integration:
59
59
  script:
@@ -88,7 +88,7 @@ rspec_integration:
88
88
  REDIS_SENTINEL_PASSWORD: "my-sentinel-password"
89
89
  parallel:
90
90
  matrix:
91
- - RUBY_VERSION: ["3.0", "3.1", "3.2", "3.3", "3.4"]
91
+ - RUBY_VERSION: ["3.1", "3.2", "3.3", "3.4", "4.0"]
92
92
 
93
93
  rubocop:
94
94
  script:
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 3.0
4
+ TargetRubyVersion: 3.1
5
5
  DisplayCopNames: true
6
6
 
7
7
  # Just use double quotes please
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.7
1
+ 3.1.7
data/AGENTS.md ADDED
@@ -0,0 +1,75 @@
1
+ # gitlab-exporter — AI agent guidelines
2
+
3
+ gitlab-exporter is a Prometheus web exporter (a Ruby gem) that collects GitLab
4
+ production metrics via custom probes and exposes them over HTTP for a Prometheus
5
+ scraper. See `README.md` for the probe catalog.
6
+
7
+ ## Project layout
8
+
9
+ - `lib/gitlab_exporter/` — probes and the exporter runtime
10
+ - `lib/gitlab_exporter/version.rb` — the gem version; bumping this on `master`
11
+ triggers a release (see below)
12
+ - `bin/gitlab-exporter` — executable entry point
13
+ - `spec/` — RSpec tests (`-t integration` marks integration specs that need Redis/PG)
14
+
15
+ ## Development commands
16
+
17
+ ```sh
18
+ bundle install
19
+ bundle exec rspec spec # unit tests
20
+ bundle exec rspec spec -t integration # integration tests (needs Redis/Postgres)
21
+ bundle exec rubocop # lint
22
+ ```
23
+
24
+ ## Commit messages
25
+
26
+ Follow the [GitLab commit message guidelines](https://docs.gitlab.com/development/contributing/merge_request_workflow/#commit-messages-guidelines).
27
+
28
+ - Subject: imperative mood, capitalized, no trailing period, ≤ 72 chars
29
+ ("Add Zoekt probe", not "Added Zoekt probe").
30
+ - Body: explain *why*, wrap at 72 chars. Reference issues/MRs with full URLs,
31
+ not short references (`#123`).
32
+
33
+ ## Changelog trailer (required for user-facing changes)
34
+
35
+ Releases are cut by the `gem-release` CI component, which builds the release
36
+ notes from GitLab's changelog generator. That generator **only includes commits
37
+ that carry a `Changelog:` git trailer** — commits without one are dropped, which
38
+ is why a release can end up saying "No changes." and produce an empty changelog
39
+ in downstream projects (e.g. omnibus-gitlab's Renovate MRs).
40
+
41
+ Add the trailer as a **separate block at the end of the commit message**,
42
+ preceded by a blank line (the blank line is required for git to parse it as a
43
+ trailer; without it the changelog generator silently drops the commit):
44
+
45
+ ```
46
+ Changelog: <type>
47
+ ```
48
+
49
+ Valid types: `added`, `fixed`, `changed`, `deprecated`, `removed`, `security`,
50
+ `performance`, `other`.
51
+
52
+ **Include a trailer for:** new or changed probes/metrics, behavior changes,
53
+ bug fixes, dependency bumps that affect users, security fixes.
54
+
55
+ **Skip the trailer for:** test-only changes, documentation-only changes, CI/
56
+ tooling-only changes, and pure internal refactors with no user-visible effect.
57
+
58
+ Example:
59
+
60
+ ```
61
+ Add remote mirror staleness metric
62
+
63
+ Exposes project_remote_mirror_last_successful_update_time_seconds so
64
+ operators can alert on mirrors that have stopped syncing.
65
+
66
+ Changelog: added
67
+ ```
68
+
69
+ ## Releasing
70
+
71
+ A release happens when `lib/gitlab_exporter/version.rb` changes on `master`.
72
+ The CI pipeline then generates the changelog from the `Changelog:` trailers
73
+ since the previous tag, creates the GitLab Release, and publishes the gem to
74
+ RubyGems. Keeping trailers accurate on every merged commit is what makes those
75
+ release notes meaningful.
data/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ @AGENTS.md
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-exporter (17.0.0)
5
- base64 (= 0.2.0)
4
+ gitlab-exporter (17.0.2)
5
+ base64 (= 0.3.0)
6
6
  connection_pool (= 2.5.5)
7
7
  deep_merge (~> 1.2.2)
8
8
  faraday (= 2.14.3)
@@ -17,7 +17,7 @@ GEM
17
17
  remote: https://rubygems.org/
18
18
  specs:
19
19
  ast (2.4.3)
20
- base64 (0.2.0)
20
+ base64 (0.3.0)
21
21
  connection_pool (2.5.5)
22
22
  deep_merge (1.2.2)
23
23
  diff-lcs (1.5.0)
@@ -57,11 +57,11 @@ GEM
57
57
  diff-lcs (>= 1.2.0, < 2.0)
58
58
  rspec-support (~> 3.12.0)
59
59
  rspec-support (3.12.0)
60
- rubocop (1.84.2)
60
+ rubocop (1.89.0)
61
61
  json (~> 2.3)
62
62
  language_server-protocol (~> 3.17.0.2)
63
63
  lint_roller (~> 1.1.0)
64
- parallel (~> 1.10)
64
+ parallel (>= 1.10)
65
65
  parser (>= 3.3.0.2)
66
66
  rainbow (>= 2.2.2, < 4.0)
67
67
  regexp_parser (>= 2.9.3, < 3.0)
@@ -78,7 +78,7 @@ GEM
78
78
  redis (>= 4.5.0, < 5)
79
79
  unicode-display_width (3.1.4)
80
80
  unicode-emoji (~> 4.0, >= 4.0.4)
81
- unicode-emoji (4.0.4)
81
+ unicode-emoji (4.2.0)
82
82
  webrick (1.9.1)
83
83
 
84
84
  PLATFORMS
@@ -91,4 +91,4 @@ DEPENDENCIES
91
91
  rubocop (~> 1.0)
92
92
 
93
93
  BUNDLED WITH
94
- 2.7.1
94
+ 4.0.10
data/README.md CHANGED
@@ -23,9 +23,10 @@ metrics.
23
23
  `gitlab_pg_sequences_min_value`, `gitlab_pg_sequences_max_value`, `gitlab_pg_sequences_current_value`
24
24
  * [Row count queries](lib/gitlab_exporter/database/row_count.rb) --
25
25
  `gitlab_database_rows`
26
- * [CI builds](lib/gitlab_exporter/database/ci_builds.rb) --
26
+ * [CI builds](lib/gitlab_exporter/database/ci_builds.rb) (**deprecated**) --
27
27
  `ci_pending_builds`, `ci_created_builds`, `ci_stale_builds`,
28
- `ci_running_builds`
28
+ `ci_running_builds`, `ci_unarchived_traces`
29
+ (see [Deprecated: CI builds metrics](#deprecated-ci-builds-metrics))
29
30
  * [Bloat](lib/gitlab_exporter/database/bloat.rb) --
30
31
  `gitlab_database_bloat_$type_$key` with type `btree` (index bloat) or `table`
31
32
  (table bloat) and keys `bloat_ratio bloat_size extra_size real_size` (see below)
@@ -133,6 +134,57 @@ Also see the [original documentation](https://github.com/ioguix/pgsql-bloat-esti
133
134
  Note that all metrics returned are estimates without an upper bound for
134
135
  the error.
135
136
 
137
+ ### Deprecated: CI builds metrics
138
+
139
+ The [CI builds probe](lib/gitlab_exporter/database/ci_builds.rb) is deprecated and
140
+ will be removed in a future major version. It collects its metrics by querying
141
+ `p_ci_builds` directly, which puts avoidable load on tables that job scheduling
142
+ already loads heavily, and it has had almost no maintenance since 2021. GitLab
143
+ Rails and GitLab Runner instrument most of the same information by counting
144
+ events as they happen; GitLab.com stopped using this probe for CI state years
145
+ ago.
146
+
147
+ The probe prints a deprecation notice on every run, and each of its metrics
148
+ carries `(deprecated, ...)` in its `# HELP` line, so the warning reaches
149
+ Prometheus and Grafana and not only the exporter's log.
150
+
151
+ Replacements, where one exists:
152
+
153
+ | Deprecated metric | Replacement |
154
+ | --- | --- |
155
+ | `ci_pending_builds` | `gitlab_ci_current_queue_size` (Rails, gauge, by `runner_type`) |
156
+ | `ci_running_builds` | `gitlab_runner_jobs` (Runner, gauge, by `runner`, `state`, `stage`) |
157
+ | `ci_created_builds` | None. A `created` build is not queued yet, so nothing counts it. |
158
+ | `ci_stale_builds` | None. The nearest signal is `gitlab_ci_queue_operations_total{operation="build_status_stale"}` (Rails, counter), which counts stale rows met while queueing rather than how many are stale now. |
159
+ | `ci_unarchived_traces` | None. |
160
+
161
+ The replacements are not a like-for-like relabel: the Rails queue metrics are
162
+ keyed by `runner_type` and the Runner metrics by runner, so neither carries the
163
+ `namespace` label this probe reports. Queue health is better served by the Rails
164
+ metrics that have no exporter equivalent at all -- `job_queue_duration_seconds`
165
+ (how long jobs wait), `job_register_attempts_total` and
166
+ `job_register_attempts_failed_total`, and `gitlab_ci_queue_operations_total`.
167
+ Those four are always instrumented.
168
+
169
+ **`gitlab_ci_current_queue_size`, and every other `gitlab_ci_queue_*` metric, is
170
+ behind the `gitlab_ci_builds_queuing_metrics` ops feature flag, which is disabled
171
+ by default.** Enable it before pointing a dashboard at them, or the replacement
172
+ panels stay empty:
173
+
174
+ ```ruby
175
+ Feature.enable(:gitlab_ci_builds_queuing_metrics)
176
+ ```
177
+
178
+ Metric definitions live in
179
+ [`lib/gitlab/ci/queue/metrics.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/queue/metrics.rb)
180
+ (Rails) and
181
+ [`commands/builds_helper.go`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/main/commands/builds_helper.go)
182
+ (Runner). See
183
+ [GitLab Prometheus metrics](https://docs.gitlab.com/administration/monitoring/prometheus/gitlab_metrics/)
184
+ for enabling the Rails exporter, and
185
+ [Monitoring runners](https://docs.gitlab.com/runner/monitoring/) for the
186
+ Runner's.
187
+
136
188
  ## Contributing
137
189
 
138
190
  gitlab-exporter is an open source project and we are very happy to accept community contributions. Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details.
@@ -20,12 +20,12 @@ Gem::Specification.new do |s|
20
20
  s.homepage = "https://gitlab.com/gitlab-org/ruby/gems/gitlab-exporter"
21
21
  s.license = "MIT"
22
22
 
23
- s.required_ruby_version = Gem::Requirement.new(">= 3.0")
23
+ s.required_ruby_version = Gem::Requirement.new(">= 3.1")
24
24
 
25
25
  # base64 is required by sidekiq but not declared by it, and is no longer a
26
26
  # default gem as of Ruby 3.4. It used to be pulled in transitively via
27
27
  # sinatra -> rack-protection; declare it directly now that those are gone.
28
- s.add_runtime_dependency "base64", "0.2.0"
28
+ s.add_runtime_dependency "base64", "0.3.0"
29
29
  s.add_runtime_dependency "connection_pool", "2.5.5"
30
30
  s.add_runtime_dependency "deep_merge", "~> 1.2.2"
31
31
  s.add_runtime_dependency "faraday", "2.14.3"
@@ -294,12 +294,53 @@ module GitLab
294
294
 
295
295
  # The prober which is called when gathering metrics
296
296
  class CiBuildsProber
297
+ # The stdout notice in #probe_db reaches whoever reads the exporter's log,
298
+ # which is not who reads the metrics. HELP is the one channel that travels
299
+ # with the sample to the scraper, so the deprecation rides there too: it
300
+ # survives into Prometheus and shows up in Grafana's metric browser.
301
+ DEPRECATED = "(deprecated, to be removed in a future major version)".freeze
302
+ REPLACEMENT = "See the CI builds entry in README.md for replacements.".freeze
303
+
304
+ PrometheusMetrics.describe(
305
+ "ci_created_builds",
306
+ "#{DEPRECATED} Number of CI builds in the created state, by namespace. #{REPLACEMENT}",
307
+ "gauge"
308
+ )
309
+
310
+ PrometheusMetrics.describe(
311
+ "ci_pending_builds",
312
+ "#{DEPRECATED} Number of CI builds in the pending state, by namespace. #{REPLACEMENT}",
313
+ "gauge"
314
+ )
315
+
316
+ PrometheusMetrics.describe(
317
+ "ci_stale_builds",
318
+ "#{DEPRECATED} Number of running CI builds not updated for over an hour. #{REPLACEMENT}",
319
+ "gauge"
320
+ )
321
+
322
+ PrometheusMetrics.describe(
323
+ "ci_running_builds",
324
+ "#{DEPRECATED} Number of running CI builds, by runner and namespace. #{REPLACEMENT}",
325
+ "gauge"
326
+ )
327
+
328
+ PrometheusMetrics.describe(
329
+ "ci_unarchived_traces",
330
+ "#{DEPRECATED} Number of finished CI builds whose trace is not archived. #{REPLACEMENT}",
331
+ "gauge"
332
+ )
333
+
297
334
  def initialize(metrics: PrometheusMetrics.new, **opts)
298
335
  @metrics = metrics
299
336
  @collector = CiBuildsCollector.new(**opts)
300
337
  end
301
338
 
302
339
  def probe_db
340
+ puts "[DEPRECATED] probe_db and CiBuildsProber are now considered obsolete"\
341
+ " and will be removed in a future major version,"\
342
+ " please use the CI/CD queuing metrics emitted by GitLab Rails instead"
343
+
303
344
  @results = @collector.run
304
345
 
305
346
  ci_builds_metrics(@results[:created_builds], "ci_created_builds") if @results[:created_builds]
@@ -35,8 +35,6 @@ module GitLab
35
35
 
36
36
  result.each do |table_name, tuple_stats|
37
37
  tuple_stats.each do |column_name, value|
38
- next if value.is_a?(Numeric)
39
-
40
38
  @metrics.add("gitlab_database_stat_table_#{column_name}",
41
39
  value.to_f,
42
40
  table_name: table_name)
@@ -1,5 +1,5 @@
1
1
  module GitLab
2
2
  module Exporter
3
- VERSION = "17.0.0".freeze
3
+ VERSION = "17.0.2".freeze
4
4
  end
5
5
  end
@@ -361,3 +361,55 @@ describe GitLab::Exporter::Database do
361
361
  end
362
362
  end
363
363
  end
364
+
365
+ # Asserting on the notice keeps a later refactor of #probe_db from dropping it
366
+ # silently, which would leave operators unwarned before the probe goes (issue #119).
367
+ describe GitLab::Exporter::Database::CiBuildsProber do
368
+ let(:prober) do
369
+ described_class.new(connection_string: "host=localhost",
370
+ metrics: GitLab::Exporter::PrometheusMetrics.new(include_timestamp: false))
371
+ end
372
+
373
+ let(:metric_names) do
374
+ %w[ci_created_builds ci_pending_builds ci_stale_builds ci_running_builds ci_unarchived_traces]
375
+ end
376
+
377
+ it "warns that the probe is deprecated and names the replacement" do
378
+ allow_any_instance_of(GitLab::Exporter::Database::CiBuildsCollector).to receive(:run)
379
+ .and_return(pending_builds: [], stale_builds: 0, per_runner: [], unarchived_traces: 0)
380
+
381
+ expect { prober.probe_db }.to output(/\[DEPRECATED\].*CiBuildsProber.*GitLab Rails/m).to_stdout
382
+ end
383
+
384
+ # The stdout notice never reaches the scraper. HELP does, so every metric the
385
+ # probe can emit has to carry the deprecation, not just the ones with a
386
+ # replacement.
387
+ it "describes every metric it can emit as deprecated" do
388
+ metric_names.each do |name|
389
+ expect(GitLab::Exporter::PrometheusMetrics.description(name))
390
+ .to start_with("(deprecated"), "#{name} is emitted without a deprecated HELP line"
391
+ expect(GitLab::Exporter::PrometheusMetrics.metric_type(name)).to eq("gauge")
392
+ end
393
+ end
394
+
395
+ it "renders the deprecation into the scrape output" do
396
+ allow_any_instance_of(GitLab::Exporter::Database::CiBuildsCollector).to receive(:run)
397
+ .and_return(pending_builds: [{ namespace: "1", shared_runners: "yes", value: 12 }],
398
+ stale_builds: 3, per_runner: [], unarchived_traces: 0)
399
+
400
+ output = StringIO.new
401
+ capture_stdout do prober.probe_db.write_to(output) end
402
+
403
+ expect(output.string).to include("# HELP ci_pending_builds (deprecated")
404
+ expect(output.string).to include("# TYPE ci_pending_builds gauge")
405
+ expect(output.string).to include(%(ci_pending_builds{namespace="1",shared_runners="yes"} 12.0))
406
+ end
407
+
408
+ def capture_stdout
409
+ original = $stdout
410
+ $stdout = StringIO.new
411
+ yield
412
+ ensure
413
+ $stdout = original
414
+ end
415
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+ require "gitlab_exporter/database/tuple_stats"
3
+
4
+ describe GitLab::Exporter::Database::TuplesProber do
5
+ let(:opts) { { connection_string: "" } }
6
+ let(:metrics) { double("PrometheusMetrics", add: nil) }
7
+ let(:collector) { double("TupleStatsCollector", run: data) }
8
+
9
+ before do
10
+ allow(GitLab::Exporter::Database::TupleStatsCollector).to receive(:new).and_return(collector)
11
+ end
12
+
13
+ describe "#probe_db" do
14
+ subject { described_class.new(metrics: metrics, **opts).probe_db }
15
+
16
+ context "when the connection casts columns to native Integer (PG::BasicTypeMapForResults)" do
17
+ let(:data) { { "projects" => { "seq_tup_read" => 42, "n_dead_tup" => 0 } } }
18
+
19
+ it "still records a metric for every column" do
20
+ expect(metrics).to receive(:add)
21
+ .with("gitlab_database_stat_table_seq_tup_read", 42.0, table_name: "projects")
22
+ expect(metrics).to receive(:add)
23
+ .with("gitlab_database_stat_table_n_dead_tup", 0.0, table_name: "projects")
24
+
25
+ subject
26
+ end
27
+ end
28
+
29
+ context "when the connection returns unmapped string values" do
30
+ let(:data) { { "projects" => { "seq_tup_read" => "42" } } }
31
+
32
+ it "records a metric" do
33
+ expect(metrics).to receive(:add)
34
+ .with("gitlab_database_stat_table_seq_tup_read", 42.0, table_name: "projects")
35
+
36
+ subject
37
+ end
38
+ end
39
+ end
40
+ end
@@ -29,15 +29,29 @@ describe GitLab::Exporter::PrometheusMetrics do
29
29
 
30
30
  allow(Time).to receive(:now).and_return(time)
31
31
 
32
- described_class.describe("mymetric", "description")
33
- described_class.describe("missingmetric", "otherdescription")
34
- subject.add("mymetric", 1.3, mylabel: "x", myotherlabel: "y")
35
-
36
- expect(subject.to_s).to eq(<<~METRICS)
32
+ # Descriptions are class-level state, and probes register theirs when their
33
+ # file loads, which happens once. Describing on a subclass keeps this example
34
+ # out of the shared registry: clearing it here would drop those registrations
35
+ # for every later example, and nothing can put them back.
36
+ metrics_class = Class.new(described_class)
37
+ metrics = metrics_class.new
38
+
39
+ metrics_class.describe("mymetric", "description")
40
+ metrics_class.describe("missingmetric", "otherdescription")
41
+ metrics.add("mymetric", 1.3, mylabel: "x", myotherlabel: "y")
42
+
43
+ expect(metrics.to_s).to eq(<<~METRICS)
37
44
  # HELP mymetric description
38
45
  mymetric{mylabel="x",myotherlabel="y"} 1.3 #{(time.to_f * 1000).to_i}
39
46
  METRICS
47
+ end
48
+
49
+ it "clears descriptions" do
50
+ metrics_class = Class.new(described_class)
51
+ metrics_class.describe("mymetric", "description", "gauge")
40
52
 
41
- described_class.clear_descriptions
53
+ expect { metrics_class.clear_descriptions }
54
+ .to change { metrics_class.description("mymetric") }.from("description").to(nil)
55
+ expect(metrics_class.metric_type("mymetric")).to be_nil
42
56
  end
43
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 17.0.0
4
+ version: 17.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Carranza
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.0
19
+ version: 0.3.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.0
26
+ version: 0.3.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: connection_pool
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -191,6 +191,8 @@ files:
191
191
  - ".rubocop.yml"
192
192
  - ".rubocop_todo.yml"
193
193
  - ".ruby-version"
194
+ - AGENTS.md
195
+ - CLAUDE.md
194
196
  - CONTRIBUTING.md
195
197
  - Gemfile
196
198
  - Gemfile.lock
@@ -230,6 +232,7 @@ files:
230
232
  - spec/database/ci_builds_spec.rb
231
233
  - spec/database/pg_sequences_spec.rb
232
234
  - spec/database/row_count_spec.rb
235
+ - spec/database/tuple_stats_spec.rb
233
236
  - spec/database/zoekt_spec.rb
234
237
  - spec/elasticsearch_spec.rb
235
238
  - spec/fixtures/config.yml
@@ -256,7 +259,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
259
  requirements:
257
260
  - - ">="
258
261
  - !ruby/object:Gem::Version
259
- version: '3.0'
262
+ version: '3.1'
260
263
  required_rubygems_version: !ruby/object:Gem::Requirement
261
264
  requirements:
262
265
  - - ">="
@@ -273,6 +276,7 @@ test_files:
273
276
  - spec/database/ci_builds_spec.rb
274
277
  - spec/database/pg_sequences_spec.rb
275
278
  - spec/database/row_count_spec.rb
279
+ - spec/database/tuple_stats_spec.rb
276
280
  - spec/database/zoekt_spec.rb
277
281
  - spec/elasticsearch_spec.rb
278
282
  - spec/fixtures/config.yml