gitlab-labkit 5.3.0 → 5.3.1

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +136 -0
  3. data/gitlab-labkit.gemspec +1 -0
  4. metadata +16 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e333c26dffb8c22bb8a131e820b01920887c2792dcffcee8f4ee012663b70831
4
- data.tar.gz: 1cd8ac6e3b87b8bf1e214234e0d44dfc2b593798554fb1a1206d6e94cc8a2863
3
+ metadata.gz: aed1a8c61c569399190d8729a7121c1f45a5d4cd9d95f0f94cb83712f369d4c5
4
+ data.tar.gz: 7c20c5fe22b0012fd0149d238b525254d18a97da8df75e2bdf7c83da5f25796f
5
5
  SHA512:
6
- metadata.gz: 4f602e792b4e8573f1ce8e29a9654221f274a3789e262af412f3b52a937970f5605748bbf9f4580698f6457436c561c905c7e1021e964f545bc511508892f8bc
7
- data.tar.gz: b131bf8715cecbd30484b89299607b9781e6cda5c690da7dc24f851b1558fdd5eb78a417cbd9baaaf2d93393d3694de8c98aa180b0103e27f5e61d598aa110a8
6
+ metadata.gz: 33023dcf68427b86e1c63440e7edc0795a1cd612dea306e025170ad3a070cd394622e69d2b9f8b44dcae63674a3f70bf4715b5e2c0e1dd19cb5fdc884a0c7137
7
+ data.tar.gz: dd800774b482b0b51c79640d1b97080ce5688fb30e2c06b6b0542606a1e7b08ec719a17c4b0111cc39f697c9582bc4abe790a8f94f94942cdfd5d0e630dc410c
data/AGENTS.md ADDED
@@ -0,0 +1,136 @@
1
+ # AGENTS.md
2
+
3
+ Instructions for AI agents and automated tooling working in this repository.
4
+
5
+ ## Project context
6
+
7
+ LabKit-Ruby (`gitlab-labkit` on RubyGems) is GitLab's Ruby SDK for cross-project infrastructure concerns: request context and correlation, structured logging, tracing, metrics, SLIs, and rate limiting.
8
+ It is consumed by GitLab Rails and other Ruby services, so every public API is a compatibility commitment.
9
+
10
+ It is one of several LabKit SDKs.
11
+ The others are Go ([labkit](https://gitlab.com/gitlab-org/labkit)), Rust ([labkit-rs](https://gitlab.com/gitlab-org/rust/labkit-rs)), and Python ([labkit-python](https://gitlab.com/gitlab-org/labkit-python)).
12
+ Behaviour that services observe, and anything written to a shared store, must be the same in every SDK.
13
+ The contract lives in [labkit-spec](https://gitlab.com/gitlab-org/quality/tooling/labkit-spec), and its conformance harness is the judge.
14
+
15
+ ### Layout
16
+
17
+ One gem, one `Labkit` namespace, one directory per capability under `lib/labkit/`.
18
+ `lib/gitlab-labkit.rb` autoloads each capability unless the table says otherwise, so requiring the gem stays cheap and callers load only what they touch.
19
+
20
+ | Module | Directory | Notes |
21
+ | --- | --- | --- |
22
+ | `Labkit::Context`, `Labkit::Correlation` | `lib/labkit/context.rb`, `lib/labkit/correlation/` | Request context for logs and propagation |
23
+ | `Labkit::Logging` | `lib/labkit/logging/` | Log sanitisation and JSON formatting |
24
+ | `Labkit::Tracing` | `lib/labkit/tracing/` | OpenTelemetry and legacy OpenTracing |
25
+ | `Labkit::Metrics` | `lib/labkit/metrics/` | Prometheus client wrappers |
26
+ | `Labkit::ApplicationSli`, `Labkit::UserExperienceSli` | `lib/labkit/application_sli/`, `lib/labkit/user_experience_sli/` | Apdex and error-rate SLIs |
27
+ | `Labkit::RateLimit` | `lib/labkit/rate_limit/` | Rules-based, Redis-backed rate limiting, see below |
28
+ | `Labkit::Middleware` | `lib/labkit/middleware/` | Rack and Sidekiq middleware for context, tracing, and SLIs |
29
+ | `Labkit::JsonSchema` | `lib/labkit/json_schema/` | `RefResolver` for remote `$ref` in JSON schemas. Not autoloaded; required by `UserExperienceSli` |
30
+ | `Labkit::FIPS` | `lib/labkit/fips.rb` | FIPS mode detection and OpenSSL digest substitution |
31
+ | `Labkit::System` | `lib/labkit/system.rb` | Monotonic clock helper used by metrics, tracing, and logging |
32
+ | `Labkit::Redis` | `lib/labkit/redis/` | Redis helpers shared by capabilities |
33
+ | `Labkit::Fields` | `lib/labkit/fields.rb` | Generated by labkit-spec CI from `schema/fields.yaml`. Change the field there, not here |
34
+ | `Labkit::RSpec` | `lib/labkit/rspec/` | Matchers for consumers' test suites. Not autoloaded; `require "labkit/rspec/matchers"` |
35
+
36
+ `lib/labkit/*_publisher.rb` hook Excon, HTTPClient, and Net::HTTP to publish outbound request notifications.
37
+
38
+ Modules with their own README (`lib/labkit/<module>/README.md`) document their public API there.
39
+ Update that README in the same MR as a behaviour change.
40
+
41
+ ## Commands
42
+
43
+ ```shell
44
+ bundle install
45
+ bundle exec rake verify # rspec + rubocop, what CI runs
46
+ bundle exec rake fix # rubocop autocorrect
47
+ bundle exec rspec spec/labkit/<module> # one module's specs
48
+ bundle exec rake console # IRB with the gem loaded
49
+ ```
50
+
51
+ Specs that need Redis use the instance at `LABKIT_TEST_REDIS_URL`, default `redis://localhost:6390/0`.
52
+ If nothing answers there and `LABKIT_TEST_REDIS_URL` is unset, the suite starts one with `docker compose up -d redis` and stops it at exit.
53
+ A Redis already listening on that URL is used as is and left running.
54
+ Autostart is off when `LABKIT_TEST_REDIS_URL` is set, even to the default value, when `CI` is set, or when `LABKIT_TEST_REDIS_NO_AUTOSTART=1` is set.
55
+ In those cases, start Redis yourself.
56
+
57
+ Style is `gitlab-styles` via RuboCop with `NewCops: enable`.
58
+ Do not edit `.rubocop_todo.yml` to silence a new offence; fix the code.
59
+ Tool versions come from `.tool-versions` through mise.
60
+
61
+ ## CI
62
+
63
+ - `rspec` runs the suite with a Redis service.
64
+ - `ruby-versions` and `legacy-ruby-versions` repeat it on Ruby 3.4 and 3.3. The versions are set in `.gitlab-ci.yml`, not read from the gemspec.
65
+ - `conformance-spec` triggers a downstream pipeline in labkit-spec that checks out this MR's commit and runs the conformance harness against it.
66
+ It runs when `lib/`, the gemspec, the Gemfile, or `.gitlab-ci.yml` change, and a red downstream run blocks the merge.
67
+ Renovate's bot user cannot start pipelines in labkit-spec, so on its MRs the job has `allow_failure: true` and a human rerun is the gate.
68
+ - Danger runs the shared `gitlab-dangerfiles` checks except changelog and commit message, which semantic-release owns.
69
+
70
+ ## Commits, MRs, and releases
71
+
72
+ Conventional Commits: `feat`, `fix`, `perf`, `revert`, `docs`, `refactor`, `test`, `chore`, `ci`, `style`.
73
+ Scope is the module, for example `fix(rate_limit): ...`.
74
+
75
+ Releases are cut from `master` and the `N-N-stable` branches by semantic-release with the `conventionalcommits` preset, so the commit type decides the version bump.
76
+
77
+ | Type | Release |
78
+ | --- | --- |
79
+ | `feat!`, or any type with a `BREAKING CHANGE:` footer | major |
80
+ | `feat` | minor |
81
+ | `fix`, `perf`, `revert` | patch |
82
+ | `docs`, `refactor`, `test`, `chore`, `ci`, `style` | none |
83
+
84
+ There is no hand-edited changelog.
85
+
86
+ Public APIs stay backward compatible.
87
+ Add keyword arguments with defaults; do not add required parameters or rename public methods.
88
+ Keep an MR to one concern, and separate mechanical changes such as renames from behavioural ones.
89
+
90
+ ## Rate limiting
91
+
92
+ `Labkit::RateLimit` is documented in `lib/labkit/rate_limit/README.md`.
93
+ It is the one capability that shares state across SDKs: services in any language enforce the same limits against the same Redis.
94
+ That makes the Redis key shape and the Lua scripts as much a contract as the HTTP headers, so changes here follow stricter rules than the rest of the gem.
95
+
96
+ ### Where each SDK keeps it
97
+
98
+ | SDK | Repository | Module | Tests | Status |
99
+ | --- | --- | --- | --- | --- |
100
+ | Ruby (this repository) | gitlab-org/ruby/gems/labkit-ruby | `lib/labkit/rate_limit/` | `spec/labkit/rate_limit/` | released |
101
+ | Go | gitlab-org/labkit | `v2/ratelimit/` | `v2/ratelimit/*_test.go`, run with `go -C v2 test ./ratelimit/...` | released |
102
+ | Rust | gitlab-org/rust/labkit-rs | in progress | | not released, skip |
103
+ | Python | gitlab-org/labkit-python | in progress | | not released, skip |
104
+ | Spec | gitlab-org/quality/tooling/labkit-spec | `conformance/README.md` ("v1 decisions"), `conformance/ratelimit_scenarios/*.json`, `conformance/aspect_ratelimit.go` | `conformance/` | judge |
105
+
106
+ ### The three layers
107
+
108
+ Every SDK must agree on three layers.
109
+ This section defines the layers; the current values (key grammar, header names, counting rules, metric names, log fields) live in labkit-spec, in the "v1 decisions" list in `conformance/README.md` and the scenarios under `conformance/ratelimit_scenarios/`.
110
+ If this file and labkit-spec disagree, labkit-spec wins.
111
+
112
+ 1. **Storage contract.**
113
+ Anything written to or read from Redis: key shape and prefix, how values are encoded, TTL rules, and the Lua scripts.
114
+ Two SDKs sharing one Redis with different storage rules keep two counters for one limit.
115
+ Never change this layer in one SDK.
116
+ It changes in labkit-spec first, then every SDK follows.
117
+ 2. **Observable contract.**
118
+ Anything a caller or an operator can see: response status and headers, the counting rule that decides a block, log line messages and field sets, metric families and labels.
119
+ Also changes in labkit-spec first.
120
+ 3. **Behaviour within the contract.**
121
+ Input validation and edge cases the contract already implies, where one SDK does something the contract does not allow.
122
+ These may be fixed SDK by SDK, and every SDK should end up the same.
123
+
124
+ A change that mixes layers is governed by the strictest one: storage, then observable, then behaviour.
125
+ When a change does not fit one layer clearly, say so in the MR instead of picking one.
126
+
127
+ ### Rules for rate-limit changes
128
+
129
+ - A change to layer 1 or 2 opens a labkit-spec MR first and waits for it to merge.
130
+ - A change to layer 3 should be checked against the Go SDK.
131
+ If Go has the same gap, say so in the MR so it can be ported.
132
+ - When a review finds a divergence between SDKs, a conformance scenario in labkit-spec must follow in the same week, so the harness sees the gap next time.
133
+ The author of the MR where the divergence was found owns this.
134
+ Mention the sync agent on the review thread to have it draft the scenario MR; if it cannot, open a labkit-spec issue and link it from the thread.
135
+ - Never edit Lua scripts, key construction, header names, metric names, or log field names to fix a Ruby-only bug.
136
+ If a fix seems to need that, it is a contract change.
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_runtime_dependency "pg_query", ">= 6.1.0", "< 7.0"
37
37
  spec.add_runtime_dependency "prometheus-client-mmap", ">= 1.2", "< 2.0"
38
38
  spec.add_runtime_dependency "redis", "> 3.0.0", "< 6.0.0"
39
+ spec.add_runtime_dependency "thrift", "< 0.25" # Pinned for jaeger-client 1.1.0 compatibility; thrift 0.25 requires transports to implement message_boundaries?
39
40
 
40
41
  # Please maintain alphabetical order for dev dependencies
41
42
  spec.add_development_dependency "excon", "~> 0.78.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-labkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.0
4
+ version: 5.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Newdigate
@@ -277,6 +277,20 @@ dependencies:
277
277
  - - "<"
278
278
  - !ruby/object:Gem::Version
279
279
  version: 6.0.0
280
+ - !ruby/object:Gem::Dependency
281
+ name: thrift
282
+ requirement: !ruby/object:Gem::Requirement
283
+ requirements:
284
+ - - "<"
285
+ - !ruby/object:Gem::Version
286
+ version: '0.25'
287
+ type: :runtime
288
+ prerelease: false
289
+ version_requirements: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - "<"
292
+ - !ruby/object:Gem::Version
293
+ version: '0.25'
280
294
  - !ruby/object:Gem::Dependency
281
295
  name: excon
282
296
  requirement: !ruby/object:Gem::Requirement
@@ -568,6 +582,7 @@ files:
568
582
  - ".rufo"
569
583
  - ".tool-versions"
570
584
  - ".yamllint.yaml"
585
+ - AGENTS.md
571
586
  - CODEOWNERS
572
587
  - CONTRIBUTING.md
573
588
  - Dangerfile