From a8f1c5ed03dff11a59a87a25ba2bde837963bb00 Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 09:27:33 -0400 Subject: add 'triggers' keyword to gitlab-ci.yml 'only' and 'except' fields to allow control over whether triggers will cause jobs to run --- app/services/ci/create_builds_service.rb | 2 +- lib/ci/gitlab_ci_yaml_processor.rb | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index 002f7ba1278..2cd51a7610f 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -1,7 +1,7 @@ module Ci class CreateBuildsService def execute(commit, stage, ref, tag, user, trigger_request, status) - builds_attrs = commit.config_processor.builds_for_stage_and_ref(stage, ref, tag) + builds_attrs = commit.config_processor.builds_for_stage_and_ref(stage, ref, tag, trigger_request) # check when to create next build builds_attrs = builds_attrs.select do |build_attrs| diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index c89e1b51019..bc6fea9a286 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -26,8 +26,8 @@ module Ci validate! end - def builds_for_stage_and_ref(stage, ref, tag = false) - builds.select{|build| build[:stage] == stage && process?(build[:only], build[:except], ref, tag)} + def builds_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil) + builds.select{|build| build[:stage] == stage && process?(build[:only], build[:except], ref, tag, trigger_request)} end def builds @@ -266,21 +266,21 @@ module Ci value.in?([true, false]) end - def process?(only_params, except_params, ref, tag) + def process?(only_params, except_params, ref, tag, trigger_request) if only_params.present? - return false unless matching?(only_params, ref, tag) + return false unless matching?(only_params, ref, tag, trigger_request) end if except_params.present? - return false if matching?(except_params, ref, tag) + return false if matching?(except_params, ref, tag, trigger_request) end true end - def matching?(patterns, ref, tag) + def matching?(patterns, ref, tag, trigger_request) patterns.any? do |pattern| - match_ref?(pattern, ref, tag) + match_ref?(pattern, ref, tag, trigger_request) end end @@ -289,6 +289,7 @@ module Ci return false if path && path != self.path return true if tag && pattern == 'tags' return true if !tag && pattern == 'branches' + return true if trigger_request != nil && pattern == 'triggers' if pattern.first == "/" && pattern.last == "/" Regexp.new(pattern[1...-1]) =~ ref -- cgit v1.2.1 From 6c1badbd108a12d1217596a3319f9bd3ca7319b8 Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 09:35:38 -0400 Subject: add tests for only/except 'triggers' keyword --- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index fab6412d29f..b79b8147ce0 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -97,6 +97,28 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(0) end + it "returns builds if only has a triggers keyword specified and a trigger is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, only: ["triggers"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy", 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"], + rspec: { script: "rspec", type: type, only: ["triggers"] } + }) + + 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"], @@ -203,6 +225,28 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "deploy").size).to eq(1) end + it "does not return builds if except has a triggers keyword specified and a trigger is provided" do + config = YAML.dump({ + before_script: ["pwd"], + rspec: { script: "rspec", type: type, except: ["triggers"] } + }) + + config_processor = GitlabCiYamlProcessor.new(config, path) + + expect(config_processor.builds_for_stage_and_ref(type, "deploy", 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"], + rspec: { script: "rspec", type: type, except: ["triggers"] } + }) + + 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"], -- cgit v1.2.1 From b6ede127294fd0df63facb9a65791c018067db9f Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 09:46:09 -0400 Subject: add some documentation for `triggers` keyword [ci skip] --- doc/ci/yaml/README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 5158e3c387c..510fab7340a 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -286,7 +286,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` and `tags`. +* `only` and `except` allow the use of special keywords: `branches`, `tags`, and `triggers`. * `only` and `except` allow to specify a repository path to filter jobs for forks. @@ -303,6 +303,17 @@ job: - branches ``` +In this example, `job` will run only for refs that are tagged, or if a build is explicitly requested +via an API trigger. + +```yaml +job: + # use special keywords + only: + - tags + - triggers +``` + The repository path can be used to have jobs executed only for the parent repository and not forks: -- cgit v1.2.1 From c57c9c41e02907959a5dd78f2896734f0034aafc Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 09:47:47 -0400 Subject: fix rubocop violation --- lib/ci/gitlab_ci_yaml_processor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index bc6fea9a286..610c56ddd92 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -289,7 +289,7 @@ module Ci return false if path && path != self.path return true if tag && pattern == 'tags' return true if !tag && pattern == 'branches' - return true if trigger_request != nil && pattern == 'triggers' + return true if !trigger_request.nil? && pattern == 'triggers' if pattern.first == "/" && pattern.last == "/" Regexp.new(pattern[1...-1]) =~ ref -- cgit v1.2.1 From 588002d8c70da8b4c52e409c62a95a63e24b391b Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 11:03:00 -0400 Subject: fixed missing argument in list --- lib/ci/gitlab_ci_yaml_processor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 610c56ddd92..abab91ddf53 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -284,7 +284,7 @@ module Ci end end - def match_ref?(pattern, ref, tag) + def match_ref?(pattern, ref, tag, trigger_request) pattern, path = pattern.split('@', 2) return false if path && path != self.path return true if tag && pattern == 'tags' -- cgit v1.2.1 From 5adaabdd30388993ce547a782146d166d30cfc9b Mon Sep 17 00:00:00 2001 From: Jason Roehm Date: Tue, 15 Mar 2016 21:28:06 -0400 Subject: make conditional a bit clearer --- lib/ci/gitlab_ci_yaml_processor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index abab91ddf53..2228425076b 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -289,7 +289,7 @@ module Ci return false if path && path != self.path return true if tag && pattern == 'tags' return true if !tag && pattern == 'branches' - return true if !trigger_request.nil? && pattern == 'triggers' + return true if trigger_request.present? && pattern == 'triggers' if pattern.first == "/" && pattern.last == "/" Regexp.new(pattern[1...-1]) =~ ref -- cgit v1.2.1