rspec-pipeline 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +81 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/rspec/pipeline/context.rb +24 -0
- data/lib/rspec/pipeline/fixture_loader.rb +80 -0
- data/lib/rspec/pipeline/helper/type.rb +2 -0
- data/lib/rspec/pipeline/helper.rb +62 -0
- data/lib/rspec/pipeline/matcher/run_after.rb +16 -0
- data/lib/rspec/pipeline/matcher/run_always.rb +11 -0
- data/lib/rspec/pipeline/matcher/run_on_failure.rb +11 -0
- data/lib/rspec/pipeline/matcher/run_on_success.rb +11 -0
- data/lib/rspec/pipeline/matcher/run_on_success_or_failure.rb +11 -0
- data/lib/rspec/pipeline/matcher/run_when.rb +11 -0
- data/lib/rspec/pipeline/matcher.rb +8 -0
- data/lib/rspec/pipeline/pipeline_loader.rb +88 -0
- data/lib/rspec/pipeline/template_loader.rb +70 -0
- data/lib/rspec/pipeline/version.rb +7 -0
- data/lib/rspec/pipeline.rb +26 -0
- data/lib/rspec-pipeline.rb +8 -0
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f14148b4cb5d701e8e2807e9022233f137b98d215f4f4653a0c4c1f4dc79b2fb
|
4
|
+
data.tar.gz: 7eb882d5a10c2b37f7385cde684ace19dcf2d43adca80cdca001601592fa3ee7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3bae63d085cdb5324eb9f98e1b8f172f76f75acfd859aff88e54b88798f0a529f13fa3a8c03f88fad62a396a66f43428efed5b0ed0b24eb0bb1560d8889ac9d
|
7
|
+
data.tar.gz: 82a39c6fb1001234c702da8ae800e91e3fb18d3e9218b24d9e30ae63313d87452fa57fc2167418aed08dffbdd884d8a3db313ea4dedb5d219042d5913a2fff52
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## [0.1.0] - 2021-10-18
|
4
|
+
|
5
|
+
- Initial release
|
6
|
+
- Verify stage and job dependecy
|
7
|
+
- Verify when something is limited to run from a specific branch
|
8
|
+
- Verify when a step is limited to run when a previous step failed or got succeeded
|
9
|
+
|
10
|
+
## [0.2.0] - 2021-10-30
|
11
|
+
- Evaluate and render local templates
|
12
|
+
- Validate template parameters
|
13
|
+
|
14
|
+
## [0.3.0] - 2120-10-31
|
15
|
+
|
16
|
+
- Evaluate and render remote templates by fetching remote repositories using git
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Thiago Marinho
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# RSpec tests for your pipelines
|
2
|
+
|
3
|
+
Create tests for your pipelines to validate dependencies between blocks and other characteristics.
|
4
|
+
|
5
|
+
> Only Azure YAML Pipelines are supported at the moment.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'rspec-pipeline'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```shell
|
18
|
+
$ bundle install
|
19
|
+
```
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
```shell
|
24
|
+
$ gem install rspec-pipeline
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Add this at the beginning of your spec_helper.rb:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'rspec-pipeline'
|
33
|
+
```
|
34
|
+
|
35
|
+
When writing your test you can use the keywords `pipeline`, `stage`, `job` and `step` as example groups, and the example's `subject` will be the corresponding item, filtered by its description. For example:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
pipeline 'pipeline.yml' do
|
39
|
+
stage 'DeployToDev' do
|
40
|
+
it { is_expected.to run_after('Build') }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
The test will pass if your pipeline is defined like this:
|
46
|
+
|
47
|
+
```yaml
|
48
|
+
stages:
|
49
|
+
- stage: Build
|
50
|
+
jobs:
|
51
|
+
- job: Build
|
52
|
+
steps:
|
53
|
+
- bash: echo "Build"
|
54
|
+
|
55
|
+
- stage: DeployToDev
|
56
|
+
dependsOn: Build
|
57
|
+
jobs:
|
58
|
+
- job: B1
|
59
|
+
steps:
|
60
|
+
- bash: echo "Deploy to Dev"
|
61
|
+
```
|
62
|
+
|
63
|
+
Please go to the `examples` folder to see a few more use cases.
|
64
|
+
|
65
|
+
### About remote templates
|
66
|
+
|
67
|
+
Note that if you try to use a template from a remote git repository you need to have clone permission and your git credentials configured if it is a private repository.
|
68
|
+
|
69
|
+
## Development
|
70
|
+
|
71
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
72
|
+
|
73
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/thiagomarinho/rspec-pipeline.
|
78
|
+
|
79
|
+
## License
|
80
|
+
|
81
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'rspec-pipeline'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_context 'pipeline context', type: :pipeline do
|
4
|
+
let!(:pipeline_name) { self.class.top_level_description }
|
5
|
+
end
|
6
|
+
|
7
|
+
shared_context 'stage context', type: :stage do
|
8
|
+
subject { stage(RSpec.current_example.metadata[:example_group][:description]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_context 'job context', type: :job do
|
12
|
+
subject do
|
13
|
+
job(RSpec.current_example.metadata[:example_group][:parent_example_group][:description],
|
14
|
+
RSpec.current_example.metadata[:example_group][:description])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
shared_context 'step context', type: :step do
|
19
|
+
subject do
|
20
|
+
step(RSpec.current_example.metadata[:example_group][:parent_example_group][:parent_example_group][:description],
|
21
|
+
RSpec.current_example.metadata[:example_group][:parent_example_group][:description],
|
22
|
+
RSpec.current_example.metadata[:example_group][:description])
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module RSpec::Pipeline # rubocop:disable Style/ClassAndModuleChildren
|
6
|
+
# This class configures and loads fixtures. It this moment, the only fixtures we have are repositories usually
|
7
|
+
# utilized for remote templates.
|
8
|
+
class FixtureLoader
|
9
|
+
def self.load(verbose: true)
|
10
|
+
['spec', File.join('spec', 'fixtures')].each { |dir| safe_mkdir(dir, verbose: verbose) }
|
11
|
+
|
12
|
+
RSpec.configuration.fixtures_repos.each do |repo_definition|
|
13
|
+
if repo_definition[:path]
|
14
|
+
safe_cp_r(repo_definition[:path], File.join('spec', 'fixtures', repo_definition[:name]), verbose: verbose)
|
15
|
+
elsif repo_definition[:repo]
|
16
|
+
safe_git_clone(repo_definition, verbose: verbose)
|
17
|
+
else
|
18
|
+
warn "!! invalid fixture repository definition: #{repo_definition}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.safe_mkdir(dir, verbose: true)
|
24
|
+
if File.exist? dir
|
25
|
+
warn "!! #{dir} already exists and is not a directory" unless File.directory? dir
|
26
|
+
else
|
27
|
+
begin
|
28
|
+
FileUtils.mkdir dir
|
29
|
+
rescue Errno::EEXIST => e
|
30
|
+
raise e unless File.directory? dir
|
31
|
+
end
|
32
|
+
|
33
|
+
puts " + #{dir}/" if verbose
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.safe_cp_r(src, dest, verbose: true) # rubocop:disable Metrics/MethodLength
|
38
|
+
if File.exist? dest
|
39
|
+
warn "!! #{dest} already exists and is not a directory" unless File.directory? dest
|
40
|
+
elsif !File.exist? src
|
41
|
+
warn "!! #{src} not found"
|
42
|
+
else
|
43
|
+
begin
|
44
|
+
FileUtils.cp_r src, dest
|
45
|
+
rescue Errno::EEXIST => e
|
46
|
+
raise e unless File.directory? dest
|
47
|
+
end
|
48
|
+
|
49
|
+
puts " + #{dest}/" if verbose
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.safe_git_clone(repo_definition, verbose: true) # rubocop:disable Metrics/MethodLength
|
54
|
+
dest = File.join('spec', 'fixtures', repo_definition[:name])
|
55
|
+
|
56
|
+
if File.exist? dest
|
57
|
+
if File.directory? dest
|
58
|
+
if File.exist? "#{dest}/.git"
|
59
|
+
git_pull_and_checkout(repo_definition, dest)
|
60
|
+
else
|
61
|
+
warn "!! #{dest} already exists and is not a git repo"
|
62
|
+
end
|
63
|
+
else
|
64
|
+
warn "!! #{dest} already exists and is not a directory"
|
65
|
+
end
|
66
|
+
else
|
67
|
+
`git clone #{repo_definition[:repo]} #{dest}`
|
68
|
+
|
69
|
+
puts " + #{dest}/" if verbose
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.git_pull_and_checkout(repo_definition, dest)
|
74
|
+
`git -C #{dest} pull`
|
75
|
+
|
76
|
+
ref_to_checkout = (repo_definition[:ref] || 'main')
|
77
|
+
`git -C #{dest} checkout #{ref_to_checkout}`
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'pipeline_loader'
|
4
|
+
require_relative 'template_loader'
|
5
|
+
|
6
|
+
def pipeline
|
7
|
+
pipeline = RSpec::Pipeline::PipelineLoader.new(pipeline_name)
|
8
|
+
|
9
|
+
pipeline.load
|
10
|
+
end
|
11
|
+
|
12
|
+
def stage(name)
|
13
|
+
stage = pipeline['stages'].find { |item| item['stage'] == name }
|
14
|
+
|
15
|
+
raise "Stage not found: #{name}" if stage.nil?
|
16
|
+
|
17
|
+
stage['blockType'] = 'Stage'
|
18
|
+
stage['blockName'] = stage['stage']
|
19
|
+
|
20
|
+
stage
|
21
|
+
end
|
22
|
+
|
23
|
+
def job(stage_name, name)
|
24
|
+
job = stage(stage_name)['jobs'].find { |item| item['job'] == name }
|
25
|
+
|
26
|
+
raise "Job not found: #{name}" if job.nil?
|
27
|
+
|
28
|
+
job['blockType'] = 'Job'
|
29
|
+
job['blockName'] = job['job']
|
30
|
+
|
31
|
+
job
|
32
|
+
end
|
33
|
+
|
34
|
+
def step(stage_name, job_name, name)
|
35
|
+
job_to_search = job(stage_name, job_name)
|
36
|
+
raise "Job #{job_name} doesn't have steps" unless job_to_search['steps']
|
37
|
+
|
38
|
+
step = job_to_search['steps'].find { |item| item['name'] == name }
|
39
|
+
raise "Step not found: #{name} (available: #{job_to_search['steps'].map { |item| item['name'] }})" if step.nil?
|
40
|
+
|
41
|
+
step['blockType'] = 'Step'
|
42
|
+
step['blockName'] = step['name']
|
43
|
+
|
44
|
+
step
|
45
|
+
end
|
46
|
+
|
47
|
+
# events
|
48
|
+
def push_to_branch(name)
|
49
|
+
{
|
50
|
+
'type' => :push,
|
51
|
+
'branch' => name,
|
52
|
+
'condition' => "eq(variables['build.sourceBranch'], 'refs/heads/#{name}'"
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def push_to_master
|
57
|
+
push_to_branch 'master'
|
58
|
+
end
|
59
|
+
|
60
|
+
def pull_request
|
61
|
+
# TODO
|
62
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec::Matchers.define :run_after do |thing|
|
4
|
+
match do |actual|
|
5
|
+
if actual['dependsOn'].is_a?(Array)
|
6
|
+
actual['dependsOn'].include?(thing)
|
7
|
+
else
|
8
|
+
actual['dependsOn'] == thing
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
failure_message do |_event|
|
13
|
+
"#{actual['blockType']} \"#{actual['blockName']}\" was expected to depend on #{actual['blockType']} \"#{thing}\"" \
|
14
|
+
"but depends on \"#{actual['dependsOn']}\" instead."
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec::Matchers.define :run_on_success do
|
4
|
+
match do |actual|
|
5
|
+
!actual['condition'] || actual['condition'].include?('succeeded()')
|
6
|
+
end
|
7
|
+
|
8
|
+
failure_message do |_event|
|
9
|
+
"Expected condition to include succeeded() but the actual value is #{actual['condition']} instead"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/pipeline/matcher/run_when'
|
4
|
+
require 'rspec/pipeline/matcher/run_on_success'
|
5
|
+
require 'rspec/pipeline/matcher/run_on_failure'
|
6
|
+
require 'rspec/pipeline/matcher/run_on_success_or_failure'
|
7
|
+
require 'rspec/pipeline/matcher/run_always'
|
8
|
+
require 'rspec/pipeline/matcher/run_after'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module RSpec::Pipeline # rubocop:disable Style/ClassAndModuleChildren
|
6
|
+
# This class loads the pipeline from a YAML file, also calling required methods to
|
7
|
+
# evaluate templates.
|
8
|
+
class PipelineLoader
|
9
|
+
def initialize(pipeline_name)
|
10
|
+
@pipeline_name = pipeline_name
|
11
|
+
@template_loader = TemplateLoader.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def load
|
15
|
+
pipeline = YAML.load_file(@pipeline_name)
|
16
|
+
|
17
|
+
pipeline['stages'] = evaluate_stages(pipeline)
|
18
|
+
|
19
|
+
pipeline['stages'].each do |stage|
|
20
|
+
stage['jobs'] = evaluate_jobs(stage, pipeline)
|
21
|
+
|
22
|
+
stage['jobs'].each do |job|
|
23
|
+
job['steps'] = evaluate_steps(job, stage, pipeline)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
pipeline
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def evaluate_stages(pipeline)
|
33
|
+
templated_items = pipeline['stages'].map do |item|
|
34
|
+
if item['template']
|
35
|
+
load_template(item, 'stages', [pipeline])
|
36
|
+
else
|
37
|
+
item
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
templated_items.flatten.compact
|
42
|
+
end
|
43
|
+
|
44
|
+
def evaluate_jobs(stage, pipeline)
|
45
|
+
templated_items = stage['jobs'].map do |item|
|
46
|
+
if item['template']
|
47
|
+
load_template(item, 'jobs', [stage, pipeline])
|
48
|
+
else
|
49
|
+
item
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
templated_items.flatten.compact
|
54
|
+
end
|
55
|
+
|
56
|
+
def evaluate_steps(job, stage, pipeline)
|
57
|
+
templated_steps = job['steps'].map do |step|
|
58
|
+
if step['template']
|
59
|
+
load_template(step, 'steps', [job, stage, pipeline])
|
60
|
+
else
|
61
|
+
step
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
templated_steps.flatten.compact
|
66
|
+
end
|
67
|
+
|
68
|
+
def load_template(template, type, context)
|
69
|
+
template_name, template_repo = parse_template_metadata(template, context)
|
70
|
+
|
71
|
+
@template_loader.load(type, template_name, template_repo, template['parameters'])
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_template_metadata(template, context)
|
75
|
+
if template['template'].include? '@'
|
76
|
+
template['template'].split '@'
|
77
|
+
else
|
78
|
+
item_with_metadata = context.detect { |item| item['_meta'] && item['_meta']['repo'] }
|
79
|
+
|
80
|
+
if item_with_metadata
|
81
|
+
[template['template'], item_with_metadata['_meta']['repo']]
|
82
|
+
else
|
83
|
+
[template['template'], '.']
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# TODO: handle parameter default values
|
6
|
+
# TODO: validate parameters
|
7
|
+
# - throw SyntaxError: parameter used but not defined
|
8
|
+
module RSpec::Pipeline # rubocop:disable Style/ClassAndModuleChildren
|
9
|
+
# This class loads and validates templates from YAML files.
|
10
|
+
class TemplateLoader
|
11
|
+
def initialize
|
12
|
+
@repo_stack = ['.']
|
13
|
+
end
|
14
|
+
|
15
|
+
def load(type, template, repo, parameters) # rubocop:disable Metrics/MethodLength
|
16
|
+
template_content = load_template_file(repo, template)
|
17
|
+
|
18
|
+
parameters&.each do |key, value|
|
19
|
+
template_content = template_content.gsub("${{ parameters.#{key} }}", value)
|
20
|
+
end
|
21
|
+
|
22
|
+
yaml_template = YAML.safe_load(template_content)
|
23
|
+
|
24
|
+
validate_parameters_not_found(parameters, yaml_template)
|
25
|
+
validate_required_parameters_not_defined(parameters, yaml_template)
|
26
|
+
|
27
|
+
yaml_template[type]&.map do |item|
|
28
|
+
item['_meta'] = {
|
29
|
+
'repo' => repo
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
yaml_template[type]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_template_file(repo, template)
|
39
|
+
template_file = if repo == '.'
|
40
|
+
template
|
41
|
+
else
|
42
|
+
"spec/fixtures/#{repo}/#{template}"
|
43
|
+
end
|
44
|
+
|
45
|
+
raise "Expected to have a template file called #{template_file}" unless File.exist? template_file
|
46
|
+
|
47
|
+
File.read template_file
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_parameters_not_found(parameters, yaml_template)
|
51
|
+
parameters_not_found = (parameters || {}).keys -
|
52
|
+
(yaml_template['parameters'] || []).map { |parameter| parameter['name'] }
|
53
|
+
|
54
|
+
unless parameters_not_found.empty? # rubocop:disable Style/GuardClause
|
55
|
+
raise 'These parameters have been defined when you called the template but ' \
|
56
|
+
"they are not in the template: #{parameters_not_found.join(', ')}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_required_parameters_not_defined(parameters, yaml_template)
|
61
|
+
required_parameters_not_defined = (yaml_template['parameters'] || []).map { |parameter| parameter['name'] } -
|
62
|
+
(parameters || {}).keys
|
63
|
+
|
64
|
+
unless required_parameters_not_defined.empty? # rubocop:disable Style/GuardClause
|
65
|
+
raise "These parameters doesn't have default values but are not being defined when you called the " \
|
66
|
+
"template: #{required_parameters_not_defined.join(', ')}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'pipeline/version'
|
4
|
+
|
5
|
+
module RSpec::Pipeline # rubocop:disable Style/ClassAndModuleChildren
|
6
|
+
class Error < StandardError; end
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.alias_example_group_to :pipeline, detailed: true, type: :pipeline, include_shared: true
|
11
|
+
config.alias_example_group_to :stage, detailed: true, type: :stage, include_shared: true
|
12
|
+
config.alias_example_group_to :job, detailed: true, type: :job, include_shared: true
|
13
|
+
config.alias_example_group_to :step, detailed: true, type: :step, include_shared: true
|
14
|
+
|
15
|
+
config.expect_with :rspec do |c|
|
16
|
+
c.syntax = :expect
|
17
|
+
end
|
18
|
+
|
19
|
+
config.add_setting :setup_fixtures, default: true
|
20
|
+
config.add_setting :fixtures_repos, default: []
|
21
|
+
|
22
|
+
config.before(:all) do
|
23
|
+
RSpec::Pipeline::FixtureLoader.load if RSpec.configuration.setup_fixtures? &&
|
24
|
+
RSpec.configuration.fixtures_repos.any?
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thiago Marinho
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -30,7 +30,28 @@ email:
|
|
30
30
|
executables: []
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
|
-
files:
|
33
|
+
files:
|
34
|
+
- CHANGELOG.md
|
35
|
+
- LICENSE.txt
|
36
|
+
- README.md
|
37
|
+
- bin/console
|
38
|
+
- bin/setup
|
39
|
+
- lib/rspec-pipeline.rb
|
40
|
+
- lib/rspec/pipeline.rb
|
41
|
+
- lib/rspec/pipeline/context.rb
|
42
|
+
- lib/rspec/pipeline/fixture_loader.rb
|
43
|
+
- lib/rspec/pipeline/helper.rb
|
44
|
+
- lib/rspec/pipeline/helper/type.rb
|
45
|
+
- lib/rspec/pipeline/matcher.rb
|
46
|
+
- lib/rspec/pipeline/matcher/run_after.rb
|
47
|
+
- lib/rspec/pipeline/matcher/run_always.rb
|
48
|
+
- lib/rspec/pipeline/matcher/run_on_failure.rb
|
49
|
+
- lib/rspec/pipeline/matcher/run_on_success.rb
|
50
|
+
- lib/rspec/pipeline/matcher/run_on_success_or_failure.rb
|
51
|
+
- lib/rspec/pipeline/matcher/run_when.rb
|
52
|
+
- lib/rspec/pipeline/pipeline_loader.rb
|
53
|
+
- lib/rspec/pipeline/template_loader.rb
|
54
|
+
- lib/rspec/pipeline/version.rb
|
34
55
|
homepage: https://github.com/thiagomarinho/rspec-pipeline
|
35
56
|
licenses:
|
36
57
|
- MIT
|