diff options
-rw-r--r-- | doc/ci/yaml/README.md | 5 | ||||
-rw-r--r-- | lib/ci/gitlab_ci_yaml_processor.rb | 29 | ||||
-rw-r--r-- | spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 44 |
3 files changed, 62 insertions, 16 deletions
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index fc813694ff2..7c085bf77c9 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -393,7 +393,7 @@ There are a few rules that apply to the usage of refs policy: * `only` and `except` are inclusive. If both `only` and `except` are defined in a job specification, the ref is filtered by `only` and `except`. * `only` and `except` allow the use of regular expressions. -* `only` and `except` allow the use of special keywords: `branches`, `tags`, and `triggers`. +* `only` and `except` allow the use of special keywords: `branches`, `tags`, `triggers` and `schedules`. * `only` and `except` allow to specify a repository path to filter jobs for forks. @@ -411,7 +411,7 @@ job: ``` In this example, `job` will run only for refs that are tagged, or if a build is -explicitly requested via an API trigger. +explicitly requested via an API trigger or a Pipeline Schedule. ```yaml job: @@ -419,6 +419,7 @@ job: only: - tags - triggers + - schedules ``` The repository path can be used to have jobs executed only for the parent diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 22af2671b18..b941a54c85a 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -20,26 +20,26 @@ module Ci raise ValidationError, e.message end - def jobs_for_ref(ref, tag = false, trigger_request = nil) + def jobs_for_ref(ref, tag = false, trigger_request = nil, pipeline_schedule = nil) @jobs.select do |_, job| - process?(job[:only], job[:except], ref, tag, trigger_request) + process?(job[:only], job[:except], ref, tag, trigger_request, pipeline_schedule) end end - def jobs_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil) - jobs_for_ref(ref, tag, trigger_request).select do |_, job| + def jobs_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil, pipeline_schedule = nil) + jobs_for_ref(ref, tag, trigger_request, pipeline_schedule).select do |_, job| job[:stage] == stage end end - def builds_for_ref(ref, tag = false, trigger_request = nil) - jobs_for_ref(ref, tag, trigger_request).map do |name, _| + def builds_for_ref(ref, tag = false, trigger_request = nil, pipeline_schedule = nil) + jobs_for_ref(ref, tag, trigger_request, pipeline_schedule).map do |name, _| build_attributes(name) end end - def builds_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil) - jobs_for_stage_and_ref(stage, ref, tag, trigger_request).map do |name, _| + def builds_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil, pipeline_schedule = nil) + jobs_for_stage_and_ref(stage, ref, tag, trigger_request, pipeline_schedule).map do |name, _| build_attributes(name) end end @@ -193,30 +193,31 @@ module Ci end end - def process?(only_params, except_params, ref, tag, trigger_request) + def process?(only_params, except_params, ref, tag, trigger_request, pipeline_schedule) if only_params.present? - return false unless matching?(only_params, ref, tag, trigger_request) + return false unless matching?(only_params, ref, tag, trigger_request, pipeline_schedule) end if except_params.present? - return false if matching?(except_params, ref, tag, trigger_request) + return false if matching?(except_params, ref, tag, trigger_request, pipeline_schedule) end true end - def matching?(patterns, ref, tag, trigger_request) + def matching?(patterns, ref, tag, trigger_request, pipeline_schedule) patterns.any? do |pattern| - match_ref?(pattern, ref, tag, trigger_request) + match_ref?(pattern, ref, tag, trigger_request, pipeline_schedule) end end - def match_ref?(pattern, ref, tag, trigger_request) + def match_ref?(pattern, ref, tag, trigger_request, pipeline_schedule) pattern, path = pattern.split('@', 2) return false if path && path != self.path return true if tag && pattern == 'tags' return true if !tag && pattern == 'branches' return true if trigger_request.present? && pattern == 'triggers' + return true if pipeline_schedule.present? && pattern == 'schedules' if pattern.first == "/" && pattern.last == "/" Regexp.new(pattern[1...-1]) =~ ref diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 72b9cde10e7..83085f61b37 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -230,6 +230,17 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy", false, true).size).to eq(1) end + it "returns builds if only has a schedules keyword specified and a schedule is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, only: ["schedules"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy", false, false, true).size).to eq(1) + end + it "does not return builds if only has a triggers keyword specified and no trigger is provided" do config = YAML.dump({ before_script: ["pwd"], @@ -241,6 +252,17 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0) end + it "does not return builds if only has a schedules keyword specified and no schedule is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, only: ["schedules"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0) + end + it "returns builds if only has current repository path" do config = YAML.dump({ before_script: ["pwd"], @@ -386,6 +408,17 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy", false, true).size).to eq(0) end + it "does not return builds if except has a schedules keyword specified and a schedule is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, except: ["schedules"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy", false, false, true).size).to eq(0) + end + it "returns builds if except has a triggers keyword specified and no trigger is provided" do config = YAML.dump({ before_script: ["pwd"], @@ -397,6 +430,17 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1) end + it "returns builds if except has a schedules keyword specified and no schedule is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, except: ["schedules"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1) + end + it "does not return builds if except has current repository path" do config = YAML.dump({ before_script: ["pwd"], |