mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-09 12:46:07 +10:00
Merge branch 'feature-ci-only-except-trigger' into 'master'
CI: Add 'triggers' keyword to 'only' and 'except' lists to allow control over when triggers cause builds to run Currently, the `only` and `except` keywords in `.gitlab-ci.yml` only accept ref names or the special `branches` and `tags` keywords. However, these are primarily useful when controlling how repository activity affects the creation of builds. In my case, instead of building on every commit, I'd like to use the following logic: - If the repository is tagged, do a build. - Any other normal commits should not cause a build. - If a build is triggered via the API, always create one for the specified ref. From what I can tell, this isn't possible via the existing YAML syntax. In this MR, I introduce a new keyword `triggers` that goes along with `branches` and `tags`. I can implement the logic above using the following job configuration: ```yaml only: - tags - triggers ``` I updated the tests and documentation to reflect this and everything seems to pass. See merge request !3230
This commit is contained in:
@@ -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|
|
||||
|
||||
+12
-1
@@ -331,7 +331,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.
|
||||
|
||||
@@ -348,6 +348,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:
|
||||
|
||||
|
||||
@@ -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,29 +266,30 @@ 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
|
||||
|
||||
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'
|
||||
return true if !tag && pattern == 'branches'
|
||||
return true if trigger_request.present? && pattern == 'triggers'
|
||||
|
||||
if pattern.first == "/" && pattern.last == "/"
|
||||
Regexp.new(pattern[1...-1]) =~ ref
|
||||
|
||||
@@ -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"],
|
||||
|
||||
Reference in New Issue
Block a user