rspec-openapi 0.27.0 → 0.29.0
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/README.md +37 -1
- data/lib/rspec/openapi/extractors/shared_extractor.rb +5 -7
- data/lib/rspec/openapi/record_builder.rb +1 -0
- data/lib/rspec/openapi/result_recorder.rb +36 -24
- data/lib/rspec/openapi/schema_builder.rb +32 -28
- data/lib/rspec/openapi/schema_file.rb +20 -13
- data/lib/rspec/openapi/version.rb +1 -1
- data/rspec-openapi.gemspec +3 -3
- metadata +3 -25
- data/.github/dependabot.yml +0 -8
- data/.github/release.yaml +0 -24
- data/.github/workflows/codeql-analysis.yml +0 -39
- data/.github/workflows/create_release.yml +0 -95
- data/.github/workflows/publish.yml +0 -46
- data/.github/workflows/rubocop.yml +0 -35
- data/.github/workflows/test.yml +0 -50
- data/.github/workflows/validate-openapi.yml +0 -21
- data/.gitignore +0 -18
- data/.rspec +0 -4
- data/.rubocop.yml +0 -29
- data/.rubocop_todo.yml +0 -52
- data/.simplecov_spawn.rb +0 -16
- data/CHANGELOG.md +0 -290
- data/Gemfile +0 -38
- data/Rakefile +0 -10
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/redocly.yaml +0 -31
- data/scripts/rspec +0 -11
- data/scripts/rspec_with_simplecov +0 -48
- data/test.png +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97857dc0658df5323bf3997e3acc31cf8f8b2f713a2d2ec6e3fdb0be7661aaf5
|
|
4
|
+
data.tar.gz: 9ecdb6c88c4c58042f805d899cda3d50fe2b670286de4d7f64b3799fd1ee5d48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 14577c70d8caca9754f4893be1720ed67dbb4762f1479a4454e188cc954ba8e9651f887cc0c69a95c91c1c98f994739bf12667f7470a491b60f9f2ce21ac81fc
|
|
7
|
+
data.tar.gz: feb18e9c32bed1f101dca61683e30975857257999fac322ff9ed51519a7ac13d583ad1cf68b3f20c56782919c9bb2d6d83d94396204c3287c468c692b1b121e1
|
data/README.md
CHANGED
|
@@ -116,6 +116,10 @@ RSpec::OpenAPI.path = 'doc/schema.yaml'
|
|
|
116
116
|
# Change the output type to JSON
|
|
117
117
|
RSpec::OpenAPI.path = 'doc/schema.json'
|
|
118
118
|
|
|
119
|
+
# Or emit the same schema in multiple formats from a single run by passing an array.
|
|
120
|
+
# The output format of each file is still chosen by its extension (`.json` -> JSON, otherwise YAML).
|
|
121
|
+
RSpec::OpenAPI.path = ['doc/openapi.yaml', 'doc/openapi.json']
|
|
122
|
+
|
|
119
123
|
# Or generate multiple partial schema files, given an RSpec example
|
|
120
124
|
RSpec::OpenAPI.path = -> (example) {
|
|
121
125
|
case example.file_path
|
|
@@ -125,6 +129,12 @@ RSpec::OpenAPI.path = -> (example) {
|
|
|
125
129
|
end
|
|
126
130
|
}
|
|
127
131
|
|
|
132
|
+
# The two can be combined: a proc may also return an array to fan a partial schema out to multiple formats.
|
|
133
|
+
RSpec::OpenAPI.path = -> (example) {
|
|
134
|
+
base = example.file_path.match?(%r[spec/requests/api/v2/]) ? 'doc/openapi/v2' : 'doc/openapi'
|
|
135
|
+
["#{base}.yaml", "#{base}.json"]
|
|
136
|
+
}
|
|
137
|
+
|
|
128
138
|
# Change the default title of the generated schema
|
|
129
139
|
RSpec::OpenAPI.title = 'OpenAPI Documentation'
|
|
130
140
|
|
|
@@ -190,10 +200,16 @@ RSpec::OpenAPI.description_builder = -> (example) { example.description }
|
|
|
190
200
|
|
|
191
201
|
# Generate a custom summary, given an RSpec example
|
|
192
202
|
# This example uses the summary from the example_group.
|
|
203
|
+
# NOTE: a fixed `dig` only reaches one specific depth. `summary` declared on an
|
|
204
|
+
# ancestor group is already inherited automatically (see "Inheritance of
|
|
205
|
+
# `openapi:` metadata"), so a builder is only needed for fully custom logic.
|
|
193
206
|
RSpec::OpenAPI.summary_builder = ->(example) { example.metadata.dig(:example_group, :openapi, :summary) }
|
|
194
207
|
|
|
195
208
|
# Generate a custom tags, given an RSpec example
|
|
196
|
-
# This example uses the tags from the parent_example_group
|
|
209
|
+
# This example uses the tags from the parent_example_group.
|
|
210
|
+
# NOTE: `dig(:example_group, :parent_example_group, ...)` only matches tags
|
|
211
|
+
# declared exactly two levels up; it won't find tags on deeper ancestors. Rely
|
|
212
|
+
# on the built-in inheritance unless you need custom resolution.
|
|
197
213
|
RSpec::OpenAPI.tags_builder = -> (example) { example.metadata.dig(:example_group, :parent_example_group, :openapi, :tags) }
|
|
198
214
|
|
|
199
215
|
# Configure custom format for specific properties
|
|
@@ -369,6 +385,26 @@ end
|
|
|
369
385
|
|
|
370
386
|
**NOTE**: `description` key will override also the one provided by `RSpec::OpenAPI.description_builder` method.
|
|
371
387
|
|
|
388
|
+
### Inheritance of `openapi:` metadata
|
|
389
|
+
|
|
390
|
+
`openapi:` metadata is inherited from the surrounding `describe`/`context` groups down to each
|
|
391
|
+
example, at any nesting depth. Inner levels override outer ones key by key, so a nested group only
|
|
392
|
+
needs to declare the keys it wants to change:
|
|
393
|
+
|
|
394
|
+
```rb
|
|
395
|
+
describe 'GET /tables', openapi: { summary: 'Get a list of tables', tags: %w[Table] } do
|
|
396
|
+
context 'with pagination', openapi: { example_mode: :multiple } do
|
|
397
|
+
# This example inherits summary: 'Get a list of tables' and tags: ['Table']
|
|
398
|
+
# from the outer describe, and adds example_mode: :multiple.
|
|
399
|
+
it { get '/tables', params: { page: 1 } }
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
The merge happens at the top level of the `openapi:` hash. Scalar keys (`summary`, `operation_id`,
|
|
405
|
+
…) follow last-wins, and a nested level that re-declares a structured key (`tags`, `security`,
|
|
406
|
+
`enum`, …) replaces the inherited value for that key rather than deep-merging it.
|
|
407
|
+
|
|
372
408
|
### Enum Support
|
|
373
409
|
|
|
374
410
|
You can specify enum values for string properties that should have a fixed set of allowed values. Since enums cannot be
|
|
@@ -86,14 +86,12 @@ class SharedExtractor
|
|
|
86
86
|
|
|
87
87
|
def self.collect_openapi_metadata(metadata)
|
|
88
88
|
[].tap do |result|
|
|
89
|
-
|
|
89
|
+
result.unshift(metadata[:openapi]) if metadata[:openapi]
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
current = current[:parent_example_group]
|
|
91
|
+
group = metadata.fetch(:example_group) { metadata[:parent_example_group] }
|
|
92
|
+
while group
|
|
93
|
+
result.unshift(group[:openapi]) if group[:openapi]
|
|
94
|
+
group = group[:parent_example_group]
|
|
97
95
|
end
|
|
98
96
|
end
|
|
99
97
|
end
|
|
@@ -7,31 +7,16 @@ class RSpec::OpenAPI::ResultRecorder
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def record_results!
|
|
10
|
-
@path_records.each do |
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
puts "WARNING: Unable to load #{config_file}: #{e}"
|
|
17
|
-
end
|
|
10
|
+
@path_records.each do |paths, records|
|
|
11
|
+
# A single record set may target multiple output files (e.g. both YAML and
|
|
12
|
+
# JSON). The first path is the canonical source we read/merge into; the rest
|
|
13
|
+
# mirror the same built spec, each formatted by its own extension.
|
|
14
|
+
primary, *mirrors = Array(paths)
|
|
15
|
+
next if primary.nil?
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
schema[:info].merge!(RSpec::OpenAPI.info)
|
|
23
|
-
RSpec::OpenAPI::SchemaMerger.merge!(spec, schema)
|
|
24
|
-
new_from_zero = {}
|
|
25
|
-
records.each do |record|
|
|
26
|
-
record_schema = RSpec::OpenAPI::SchemaBuilder.build(record)
|
|
27
|
-
RSpec::OpenAPI::SchemaMerger.merge!(spec, record_schema)
|
|
28
|
-
RSpec::OpenAPI::SchemaMerger.merge!(new_from_zero, record_schema)
|
|
29
|
-
rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
|
|
30
|
-
@error_records[e] = record # Avoid failing the build
|
|
31
|
-
end
|
|
32
|
-
cleanup_schema!(new_from_zero, spec)
|
|
33
|
-
execute_post_process_hook(path, records, spec)
|
|
34
|
-
end
|
|
17
|
+
load_path_config(primary)
|
|
18
|
+
built_spec = build_spec(primary, records)
|
|
19
|
+
mirrors.each { |mirror_path| RSpec::OpenAPI::SchemaFile.new(mirror_path).write(built_spec) }
|
|
35
20
|
end
|
|
36
21
|
end
|
|
37
22
|
|
|
@@ -49,6 +34,33 @@ class RSpec::OpenAPI::ResultRecorder
|
|
|
49
34
|
|
|
50
35
|
private
|
|
51
36
|
|
|
37
|
+
# Look for a path-specific config file and run it.
|
|
38
|
+
def load_path_config(path)
|
|
39
|
+
config_file = File.join(File.dirname(path), RSpec::OpenAPI.config_filename)
|
|
40
|
+
require config_file if File.exist?(config_file)
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
puts "WARNING: Unable to load #{config_file}: #{e}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def build_spec(primary, records)
|
|
46
|
+
title = records.first.title
|
|
47
|
+
RSpec::OpenAPI::SchemaFile.new(primary).edit do |spec|
|
|
48
|
+
schema = RSpec::OpenAPI::DefaultSchema.build(title)
|
|
49
|
+
schema[:info].merge!(RSpec::OpenAPI.info)
|
|
50
|
+
RSpec::OpenAPI::SchemaMerger.merge!(spec, schema)
|
|
51
|
+
new_from_zero = {}
|
|
52
|
+
records.each do |record|
|
|
53
|
+
record_schema = RSpec::OpenAPI::SchemaBuilder.build(record)
|
|
54
|
+
RSpec::OpenAPI::SchemaMerger.merge!(spec, record_schema)
|
|
55
|
+
RSpec::OpenAPI::SchemaMerger.merge!(new_from_zero, record_schema)
|
|
56
|
+
rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
|
|
57
|
+
@error_records[e] = record # Avoid failing the build
|
|
58
|
+
end
|
|
59
|
+
cleanup_schema!(new_from_zero, spec)
|
|
60
|
+
execute_post_process_hook(primary, records, spec)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
52
64
|
def execute_post_process_hook(path, records, spec)
|
|
53
65
|
RSpec::OpenAPI.post_process_hook.call(path, records, spec) if RSpec::OpenAPI.post_process_hook.is_a?(Proc)
|
|
54
66
|
end
|
|
@@ -327,16 +327,30 @@ class << RSpec::OpenAPI::SchemaBuilder
|
|
|
327
327
|
|
|
328
328
|
def build_merged_schema_from_variations(variations)
|
|
329
329
|
return {} if variations.empty?
|
|
330
|
-
return variations.first if variations.size == 1
|
|
331
330
|
|
|
332
|
-
|
|
333
|
-
|
|
331
|
+
# Drop empty `{}` schemas (e.g. items of an empty array) — they carry no
|
|
332
|
+
# type info and would otherwise spuriously mark every property of their
|
|
333
|
+
# populated siblings as nullable via the missing-key nullable rule.
|
|
334
|
+
non_empty = variations.reject(&:empty?)
|
|
335
|
+
return {} if non_empty.empty?
|
|
336
|
+
return non_empty.first if non_empty.size == 1
|
|
334
337
|
|
|
335
|
-
{
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
338
|
+
types = non_empty.map { |v| v[:type] }.compact.uniq
|
|
339
|
+
return one_of_schema(non_empty) if types.size > 1
|
|
340
|
+
|
|
341
|
+
case types.first
|
|
342
|
+
when 'object'
|
|
343
|
+
{
|
|
344
|
+
type: 'object',
|
|
345
|
+
properties: merge_property_variations(non_empty, allow_recursive_merge: true),
|
|
346
|
+
required: non_empty.map { |v| v[:required] || [] }.reduce(:&) || [],
|
|
347
|
+
}
|
|
348
|
+
when 'array'
|
|
349
|
+
items_variations = non_empty.map { |v| v[:items] }.compact
|
|
350
|
+
{ type: 'array', items: build_merged_schema_from_variations(items_variations) }
|
|
351
|
+
else
|
|
352
|
+
non_empty.first
|
|
353
|
+
end
|
|
340
354
|
end
|
|
341
355
|
|
|
342
356
|
# Merge the per-key property schemas of multiple object variations.
|
|
@@ -377,10 +391,8 @@ class << RSpec::OpenAPI::SchemaBuilder
|
|
|
377
391
|
merged =
|
|
378
392
|
if prop_variations.size == 1
|
|
379
393
|
prop_variations.first.dup
|
|
380
|
-
elsif allow_recursive_merge
|
|
381
|
-
merge_multi_recursive(prop_variations)
|
|
382
394
|
else
|
|
383
|
-
|
|
395
|
+
merge_multi(prop_variations)
|
|
384
396
|
end
|
|
385
397
|
|
|
386
398
|
return merged unless merged.is_a?(Hash)
|
|
@@ -397,13 +409,16 @@ class << RSpec::OpenAPI::SchemaBuilder
|
|
|
397
409
|
merged
|
|
398
410
|
end
|
|
399
411
|
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return
|
|
412
|
+
# Combine multiple variations of the same property: flatten existing oneOf
|
|
413
|
+
# entries, recurse into objects and arrays, and combine divergent types into
|
|
414
|
+
# oneOf. Scalar variations of a single type collapse to the first schema.
|
|
415
|
+
def merge_multi(prop_variations)
|
|
416
|
+
return { oneOf: flatten_one_of(prop_variations) } if prop_variations.any? { |p| p.key?(:oneOf) }
|
|
405
417
|
|
|
406
|
-
|
|
418
|
+
prop_types = prop_variations.map { |p| p[:type] }.compact.uniq
|
|
419
|
+
return one_of_schema(prop_variations) if prop_types.size > 1
|
|
420
|
+
|
|
421
|
+
case prop_types.first
|
|
407
422
|
when 'array'
|
|
408
423
|
items_variations = prop_variations.map { |p| p[:items] }.compact
|
|
409
424
|
{ type: 'array', items: build_merged_schema_from_variations(items_variations) }
|
|
@@ -414,17 +429,6 @@ class << RSpec::OpenAPI::SchemaBuilder
|
|
|
414
429
|
end
|
|
415
430
|
end
|
|
416
431
|
|
|
417
|
-
# Recursive-merge mode (used inside build_merged_schema_from_variations):
|
|
418
|
-
# additionally flattens existing oneOf entries and recurses into objects.
|
|
419
|
-
def merge_multi_recursive(prop_variations)
|
|
420
|
-
return { oneOf: flatten_one_of(prop_variations) } if prop_variations.any? { |p| p.key?(:oneOf) }
|
|
421
|
-
|
|
422
|
-
prop_types = prop_variations.map { |p| p[:type] }.compact.uniq
|
|
423
|
-
return one_of_schema(prop_variations) if prop_types.size > 1
|
|
424
|
-
|
|
425
|
-
prop_types.first == 'object' ? build_merged_schema_from_variations(prop_variations) : prop_variations.first.dup
|
|
426
|
-
end
|
|
427
|
-
|
|
428
432
|
def flatten_one_of(prop_variations)
|
|
429
433
|
prop_variations.each_with_object([]) do |prop, options|
|
|
430
434
|
clean = without_nullable(prop)
|
|
@@ -14,11 +14,30 @@ class RSpec::OpenAPI::SchemaFile
|
|
|
14
14
|
@path = path
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Reads the existing spec, lets the block mutate it, writes the result back
|
|
18
|
+
# and returns the (symbolized) spec so it can be mirrored to other files.
|
|
19
|
+
# @return [Hash]
|
|
17
20
|
def edit(&block)
|
|
18
21
|
spec = read
|
|
19
22
|
block.call(spec)
|
|
23
|
+
spec
|
|
20
24
|
ensure
|
|
21
|
-
write(
|
|
25
|
+
write(spec)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Writes an already-built spec to this file, choosing the format from the
|
|
29
|
+
# file extension.
|
|
30
|
+
# @param [Hash] spec
|
|
31
|
+
def write(spec)
|
|
32
|
+
stringified = RSpec::OpenAPI::KeyTransformer.stringify(spec)
|
|
33
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
|
34
|
+
output =
|
|
35
|
+
if json?
|
|
36
|
+
JSON.pretty_generate(stringified)
|
|
37
|
+
else
|
|
38
|
+
prepend_comment(YAML.dump(stringified))
|
|
39
|
+
end
|
|
40
|
+
File.write(@path, output)
|
|
22
41
|
end
|
|
23
42
|
|
|
24
43
|
private
|
|
@@ -33,18 +52,6 @@ class RSpec::OpenAPI::SchemaFile
|
|
|
33
52
|
RSpec::OpenAPI::KeyTransformer.symbolize(content)
|
|
34
53
|
end
|
|
35
54
|
|
|
36
|
-
# @param [Hash] spec
|
|
37
|
-
def write(spec)
|
|
38
|
-
FileUtils.mkdir_p(File.dirname(@path))
|
|
39
|
-
output =
|
|
40
|
-
if json?
|
|
41
|
-
JSON.pretty_generate(spec)
|
|
42
|
-
else
|
|
43
|
-
prepend_comment(YAML.dump(spec))
|
|
44
|
-
end
|
|
45
|
-
File.write(@path, output)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
55
|
def prepend_comment(content)
|
|
49
56
|
return content if RSpec::OpenAPI.comment.nil?
|
|
50
57
|
|
data/rspec-openapi.gemspec
CHANGED
|
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
|
-
`git ls-files -z`.split("\x0").
|
|
25
|
+
`git ls-files -z`.split("\x0").select do |f|
|
|
26
|
+
f.start_with?('lib/') || ['LICENSE.txt', 'README.md', 'rspec-openapi.gemspec'].include?(f)
|
|
27
|
+
end
|
|
26
28
|
end
|
|
27
|
-
spec.bindir = 'exe'
|
|
28
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ['lib']
|
|
30
30
|
|
|
31
31
|
spec.add_dependency 'actionpack', '>= 5.2.0'
|
metadata
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rspec-openapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.29.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Takashi Kokubun
|
|
8
8
|
- TATSUNO Yasuhiro
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
@@ -60,26 +60,8 @@ executables: []
|
|
|
60
60
|
extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
|
62
62
|
files:
|
|
63
|
-
- ".github/dependabot.yml"
|
|
64
|
-
- ".github/release.yaml"
|
|
65
|
-
- ".github/workflows/codeql-analysis.yml"
|
|
66
|
-
- ".github/workflows/create_release.yml"
|
|
67
|
-
- ".github/workflows/publish.yml"
|
|
68
|
-
- ".github/workflows/rubocop.yml"
|
|
69
|
-
- ".github/workflows/test.yml"
|
|
70
|
-
- ".github/workflows/validate-openapi.yml"
|
|
71
|
-
- ".gitignore"
|
|
72
|
-
- ".rspec"
|
|
73
|
-
- ".rubocop.yml"
|
|
74
|
-
- ".rubocop_todo.yml"
|
|
75
|
-
- ".simplecov_spawn.rb"
|
|
76
|
-
- CHANGELOG.md
|
|
77
|
-
- Gemfile
|
|
78
63
|
- LICENSE.txt
|
|
79
64
|
- README.md
|
|
80
|
-
- Rakefile
|
|
81
|
-
- bin/console
|
|
82
|
-
- bin/setup
|
|
83
65
|
- lib/rspec/openapi.rb
|
|
84
66
|
- lib/rspec/openapi/components_updater.rb
|
|
85
67
|
- lib/rspec/openapi/default_schema.rb
|
|
@@ -104,18 +86,14 @@ files:
|
|
|
104
86
|
- lib/rspec/openapi/schema_sorter.rb
|
|
105
87
|
- lib/rspec/openapi/shared_hooks.rb
|
|
106
88
|
- lib/rspec/openapi/version.rb
|
|
107
|
-
- redocly.yaml
|
|
108
89
|
- rspec-openapi.gemspec
|
|
109
|
-
- scripts/rspec
|
|
110
|
-
- scripts/rspec_with_simplecov
|
|
111
|
-
- test.png
|
|
112
90
|
homepage: https://github.com/exoego/rspec-openapi
|
|
113
91
|
licenses:
|
|
114
92
|
- MIT
|
|
115
93
|
metadata:
|
|
116
94
|
homepage_uri: https://github.com/exoego/rspec-openapi
|
|
117
95
|
source_code_uri: https://github.com/exoego/rspec-openapi
|
|
118
|
-
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.
|
|
96
|
+
changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.29.0
|
|
119
97
|
rubygems_mfa_required: 'true'
|
|
120
98
|
rdoc_options: []
|
|
121
99
|
require_paths:
|
data/.github/dependabot.yml
DELETED
data/.github/release.yaml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
changelog:
|
|
2
|
-
exclude:
|
|
3
|
-
labels:
|
|
4
|
-
- ignore-for-release
|
|
5
|
-
authors:
|
|
6
|
-
- octocat
|
|
7
|
-
categories:
|
|
8
|
-
- title: 🛠 Breaking Changes
|
|
9
|
-
labels:
|
|
10
|
-
- semver-major
|
|
11
|
-
- breaking-change
|
|
12
|
-
- title: 🎉 Exciting New Features
|
|
13
|
-
labels:
|
|
14
|
-
- semver-minor
|
|
15
|
-
- enhancement
|
|
16
|
-
- title: 🐞 Bugfixes
|
|
17
|
-
labels:
|
|
18
|
-
- bug
|
|
19
|
-
- title: 📄 Documentation
|
|
20
|
-
labels:
|
|
21
|
-
- documentation
|
|
22
|
-
- title: 📦 Other Changes
|
|
23
|
-
labels:
|
|
24
|
-
- "*"
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
name: "CodeQL"
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ "master" ]
|
|
6
|
-
pull_request:
|
|
7
|
-
# The branches below must be a subset of the branches above
|
|
8
|
-
branches: [ "master" ]
|
|
9
|
-
schedule:
|
|
10
|
-
- cron: '20 22 * * 2'
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
analyze:
|
|
14
|
-
name: Analyze
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
permissions:
|
|
17
|
-
actions: read
|
|
18
|
-
contents: read
|
|
19
|
-
security-events: write
|
|
20
|
-
|
|
21
|
-
strategy:
|
|
22
|
-
fail-fast: false
|
|
23
|
-
matrix:
|
|
24
|
-
language: [ 'ruby' ]
|
|
25
|
-
|
|
26
|
-
steps:
|
|
27
|
-
- name: Checkout repository
|
|
28
|
-
uses: actions/checkout@v6
|
|
29
|
-
|
|
30
|
-
- name: Initialize CodeQL
|
|
31
|
-
uses: github/codeql-action/init@v4
|
|
32
|
-
with:
|
|
33
|
-
languages: ${{ matrix.language }}
|
|
34
|
-
|
|
35
|
-
- name: Autobuild
|
|
36
|
-
uses: github/codeql-action/autobuild@v4
|
|
37
|
-
|
|
38
|
-
- name: Perform CodeQL Analysis
|
|
39
|
-
uses: github/codeql-action/analyze@v4
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
name: prepare release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
version:
|
|
7
|
-
description: 'Version to release (e.g. 0.27.1 or 0.28.0)'
|
|
8
|
-
required: true
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
push:
|
|
12
|
-
name: Prepare release PR
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v6
|
|
17
|
-
with:
|
|
18
|
-
fetch-depth: 0
|
|
19
|
-
token: ${{ secrets.PREPARE_RELEASE_PAT }}
|
|
20
|
-
|
|
21
|
-
- name: Bump version.rb
|
|
22
|
-
run: |
|
|
23
|
-
set -euo pipefail
|
|
24
|
-
version="${{ github.event.inputs.version }}"
|
|
25
|
-
version="${version#v}"
|
|
26
|
-
|
|
27
|
-
echo "VERSION_NO_V=$version" >> "$GITHUB_ENV"
|
|
28
|
-
echo "VERSION_TAG=v$version" >> "$GITHUB_ENV"
|
|
29
|
-
|
|
30
|
-
current_version=$(ruby -e "require_relative './lib/rspec/openapi/version'; puts RSpec::OpenAPI::VERSION")
|
|
31
|
-
VERSION_NO_V="$version" CURRENT_VERSION="$current_version" ruby - <<'RUBY'
|
|
32
|
-
version = ENV.fetch('VERSION_NO_V')
|
|
33
|
-
unless version.match?(/\A\d+(?:\.\d+)*\z/)
|
|
34
|
-
warn "Invalid version format: #{version}"
|
|
35
|
-
exit 1
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
require 'rubygems'
|
|
39
|
-
new_version = Gem::Version.new(version)
|
|
40
|
-
current_version = Gem::Version.new(ENV.fetch('CURRENT_VERSION'))
|
|
41
|
-
if new_version <= current_version
|
|
42
|
-
warn "Given version (#{new_version}) must be newer than current version (#{current_version})"
|
|
43
|
-
exit 1
|
|
44
|
-
end
|
|
45
|
-
RUBY
|
|
46
|
-
ruby -pi -e "sub(/VERSION = .*/, \"VERSION = '$version'\")" lib/rspec/openapi/version.rb
|
|
47
|
-
|
|
48
|
-
VERSION_NO_V="$version" ruby - <<'RUBY'
|
|
49
|
-
version = ENV.fetch('VERSION_NO_V')
|
|
50
|
-
segments = version.split('.').map(&:to_i)
|
|
51
|
-
unless segments.size >= 3
|
|
52
|
-
warn "Version must have at least major.minor.patch: #{version}"
|
|
53
|
-
exit 1
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
major, minor, patch = segments
|
|
57
|
-
patch_bump = [major, minor, patch + 1].join('.')
|
|
58
|
-
minor_bump = [major, minor + 1, 0].join('.')
|
|
59
|
-
example = "Version to release (e.g. #{patch_bump} or #{minor_bump})"
|
|
60
|
-
|
|
61
|
-
path = ".github/workflows/create_release.yml"
|
|
62
|
-
content = File.read(path)
|
|
63
|
-
content.sub!(/description:\s*'Version to release \(e\.g\. [^']+\)'/,
|
|
64
|
-
"description: '#{example}'")
|
|
65
|
-
File.write(path, content)
|
|
66
|
-
RUBY
|
|
67
|
-
git status --short
|
|
68
|
-
|
|
69
|
-
- name: Commit version bump
|
|
70
|
-
run: |
|
|
71
|
-
set -euo pipefail
|
|
72
|
-
version="$VERSION_NO_V"
|
|
73
|
-
|
|
74
|
-
release_branch="release/v${version}"
|
|
75
|
-
echo "RELEASE_BRANCH=${release_branch}" >> "$GITHUB_ENV"
|
|
76
|
-
|
|
77
|
-
git config user.name "github-actions[bot]"
|
|
78
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
79
|
-
git commit -am "Bump version to ${version}"
|
|
80
|
-
git push origin "HEAD:${release_branch}"
|
|
81
|
-
|
|
82
|
-
- name: Open release PR
|
|
83
|
-
uses: peter-evans/create-pull-request@v8
|
|
84
|
-
with:
|
|
85
|
-
token: ${{ secrets.PREPARE_RELEASE_PAT }}
|
|
86
|
-
add-paths: |
|
|
87
|
-
lib/rspec/openapi/version.rb
|
|
88
|
-
.github/workflows/create_release.yml
|
|
89
|
-
branch: ${{ env.RELEASE_BRANCH }}
|
|
90
|
-
title: Release v${{ env.VERSION_NO_V }}
|
|
91
|
-
commit-message: Bump version to ${{ env.VERSION_NO_V }}
|
|
92
|
-
body: |
|
|
93
|
-
Automated release PR created by workflow_dispatch.
|
|
94
|
-
- Version: v${{ env.VERSION_NO_V }}
|
|
95
|
-
- Triggered by: ${{ github.actor }}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
name: Publish to RubyGems
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
name: Publish gem and GitHub release
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
|
-
permissions:
|
|
14
|
-
id-token: write # for RubyGems trusted publishing
|
|
15
|
-
contents: write # to create GitHub release
|
|
16
|
-
|
|
17
|
-
steps:
|
|
18
|
-
- uses: actions/checkout@v6
|
|
19
|
-
with:
|
|
20
|
-
fetch-depth: 0
|
|
21
|
-
|
|
22
|
-
- name: Set up Ruby
|
|
23
|
-
uses: ruby/setup-ruby@v1
|
|
24
|
-
with:
|
|
25
|
-
bundler-cache: true
|
|
26
|
-
ruby-version: '4.0'
|
|
27
|
-
|
|
28
|
-
- name: Verify tag matches version.rb
|
|
29
|
-
run: |
|
|
30
|
-
set -euo pipefail
|
|
31
|
-
tag="${GITHUB_REF_NAME}"
|
|
32
|
-
version="${tag#v}"
|
|
33
|
-
file_version=$(ruby -e "require_relative './lib/rspec/openapi/version'; puts RSpec::OpenAPI::VERSION")
|
|
34
|
-
if [ "$version" != "$file_version" ]; then
|
|
35
|
-
echo "Tag version ($version) does not match lib/rspec/openapi/version.rb ($file_version)" >&2
|
|
36
|
-
exit 1
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
- uses: rubygems/release-gem@v1
|
|
40
|
-
|
|
41
|
-
- name: Create GitHub release
|
|
42
|
-
uses: softprops/action-gh-release@v3
|
|
43
|
-
with:
|
|
44
|
-
tag_name: ${{ github.ref_name }}
|
|
45
|
-
name: ${{ github.ref_name }}
|
|
46
|
-
generate_release_notes: true
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
name: "Rubocop"
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ "master" ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ "master" ]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
rubocop:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
strategy:
|
|
13
|
-
fail-fast: false
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout repository
|
|
17
|
-
uses: actions/checkout@v6
|
|
18
|
-
|
|
19
|
-
- name: Set up Ruby
|
|
20
|
-
uses: ruby/setup-ruby@v1
|
|
21
|
-
with:
|
|
22
|
-
ruby-version: '4.0'
|
|
23
|
-
bundler-cache: true
|
|
24
|
-
|
|
25
|
-
- name: Rubocop run
|
|
26
|
-
run: |
|
|
27
|
-
bash -c "
|
|
28
|
-
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
|
29
|
-
[[ $? -ne 2 ]]
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
- name: Upload Sarif output
|
|
33
|
-
uses: github/codeql-action/upload-sarif@v4
|
|
34
|
-
with:
|
|
35
|
-
sarif_file: rubocop.sarif
|