buildkite-builder 3.8.3 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -30
- data/VERSION +1 -1
- data/lib/buildkite/builder/extension_manager.rb +5 -1
- data/lib/buildkite/builder/extensions/plugins.rb +36 -0
- data/lib/buildkite/builder/extensions/steps.rb +44 -29
- data/lib/buildkite/builder/extensions.rb +1 -1
- data/lib/buildkite/builder/pipeline.rb +1 -3
- data/lib/buildkite/builder/plugin.rb +7 -7
- data/lib/buildkite/builder/plugin_manager.rb +6 -13
- data/lib/buildkite/builder/step_collection.rb +5 -13
- data/lib/buildkite/builder.rb +0 -2
- data/lib/buildkite/pipelines/helpers/plugins.rb +1 -6
- data/lib/buildkite/pipelines/steps/abstract.rb +4 -8
- data/lib/buildkite/pipelines/steps/group.rb +37 -0
- data/lib/buildkite/pipelines/steps.rb +1 -0
- metadata +5 -7
- data/lib/buildkite/builder/extensions/sub_pipelines.rb +0 -107
- data/lib/buildkite/builder/group.rb +0 -44
- data/lib/buildkite/builder/pipeline_collection.rb +0 -40
- data/lib/buildkite/builder/plugin_collection.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d9385a6b39f83697f501167fac9988d2e0b351a3e1b877b24e6c93670959d27
|
4
|
+
data.tar.gz: d5fe308edf2e426eb4c7be9bf9bf5996056533eb70724e18d438109732101492
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c406b7822bd571773bc3e2f29bf71b1067cacf1cf434b92457c8936a64757efdc48c8f8a63f9f56fc7885d5505d2505bd6f9ac8c9447f1f90d992b263508b3cb
|
7
|
+
data.tar.gz: ddfc34afe276f2716b86d5db4fe07a6854ef0135dd93f8e4b0bd8d5fb14aa07ffcd8c892661823bad17b90e6bcea3b977a7d5ca46694429250e7c9f818ea9baa
|
data/README.md
CHANGED
@@ -135,36 +135,6 @@ Buildkite::Builder.pipeline do
|
|
135
135
|
end
|
136
136
|
```
|
137
137
|
|
138
|
-
### Subpipeline
|
139
|
-
|
140
|
-
While triggering another pipeline, you can predefine subpipeline's steps using `pipeline(NAME_OF_SUBPIPELINE)` in the main pipeline's `pipeline.rb` file and share with main pipeline's plugins and templates definition.
|
141
|
-
|
142
|
-
`.buildkite/pipelines/pipeline-triggerer/pipeline.rb`
|
143
|
-
|
144
|
-
```ruby
|
145
|
-
Buildkite::Builder.pipeline do
|
146
|
-
pipeline('rspec-pipeline') do
|
147
|
-
command do
|
148
|
-
label "Run RSpec in separate pipeline"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
```
|
153
|
-
|
154
|
-
Inside your Buildkite pipeline setup, you can do the following:
|
155
|
-
|
156
|
-
In `https://buildkite.com/your-org/rspec-pipeline/steps`
|
157
|
-
|
158
|
-
```yaml
|
159
|
-
steps:
|
160
|
-
- label: ":pipeline:"
|
161
|
-
commands:
|
162
|
-
- buildkite-agent artifact download $BKB_SUBPIPELINE_FILE . --build $BUILDKITE_TRIGGERED_FROM_BUILD_ID
|
163
|
-
- buildkite-agent pipeline upload $BKB_SUBPIPELINE_FILE
|
164
|
-
```
|
165
|
-
|
166
|
-
This will upload the pregenerated `pipeline.yml` to `rspec-pipeline`.
|
167
|
-
|
168
138
|
## Development
|
169
139
|
|
170
140
|
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.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
@@ -8,7 +8,7 @@ module Buildkite
|
|
8
8
|
@context = context
|
9
9
|
@extensions = {}
|
10
10
|
|
11
|
-
|
11
|
+
Loaders::Extensions.load(@context.root)
|
12
12
|
end
|
13
13
|
|
14
14
|
def use(extension, native: false, **args, &block)
|
@@ -34,6 +34,10 @@ module Buildkite
|
|
34
34
|
@extensions.fetch(klass)
|
35
35
|
end
|
36
36
|
|
37
|
+
def all
|
38
|
+
@extensions.keys
|
39
|
+
end
|
40
|
+
|
37
41
|
private
|
38
42
|
|
39
43
|
def log
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Buildkite
|
2
|
+
module Builder
|
3
|
+
module Extensions
|
4
|
+
class Plugins < Extension
|
5
|
+
attr_reader :manager
|
6
|
+
|
7
|
+
dsl do
|
8
|
+
def plugin(name, uri, default_attributes = {})
|
9
|
+
context.extensions.find(Buildkite::Builder::Extensions::Plugins).manager.add(name, uri, default_attributes)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def prepare
|
14
|
+
@manager = PluginManager.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def build
|
18
|
+
context.data.steps.each(:command) do |step|
|
19
|
+
next unless step.has?(:plugins)
|
20
|
+
|
21
|
+
step.get(:plugins).map! do |plugin|
|
22
|
+
resource, attributes = extract_resource_and_attributes(plugin)
|
23
|
+
resource.is_a?(Symbol) ? manager.build(resource, attributes) : plugin
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def extract_resource_and_attributes(plugin)
|
31
|
+
[plugin.keys.first, plugin.values.first]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -2,61 +2,76 @@ module Buildkite
|
|
2
2
|
module Builder
|
3
3
|
module Extensions
|
4
4
|
class Steps < Extension
|
5
|
+
attr_reader :templates
|
6
|
+
|
5
7
|
def prepare
|
6
|
-
|
7
|
-
|
8
|
-
PluginManager.new
|
9
|
-
)
|
8
|
+
@templates = TemplateManager.new(context.root)
|
9
|
+
context.data.steps = StepCollection.new
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
raise "Group does not allow nested in another Group" if context.is_a?(Group)
|
12
|
+
def build_step(step_class, template_name, **args, &block)
|
13
|
+
template = @templates.find(template_name)
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
15
|
+
step_class.new(**args).tap do |step|
|
16
|
+
step.process(template) if template
|
17
|
+
step.process(block) if block_given?
|
20
18
|
|
21
|
-
|
19
|
+
if @current_group
|
20
|
+
@current_group.steps.push(step)
|
21
|
+
else
|
22
|
+
context.data.steps.push(step)
|
23
|
+
end
|
22
24
|
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_group(group, &block)
|
28
|
+
raise "Group cannot be nested" if @current_group
|
23
29
|
|
24
|
-
|
25
|
-
|
30
|
+
@current_group = group
|
31
|
+
|
32
|
+
group.process(block)
|
33
|
+
context.data.steps.push(group).last
|
34
|
+
ensure
|
35
|
+
@current_group = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
dsl do
|
39
|
+
def group(&block)
|
40
|
+
context.extensions.find(Steps).with_group(Pipelines::Steps::Group.new(context), &block)
|
26
41
|
end
|
27
42
|
|
28
43
|
def block(template = nil, **args, &block)
|
29
|
-
context.
|
44
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Block, template, **args, &block)
|
30
45
|
end
|
31
46
|
|
32
47
|
def command(template = nil, **args, &block)
|
33
|
-
context.
|
48
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Command, template, **args, &block)
|
34
49
|
end
|
35
50
|
|
36
51
|
def input(template = nil, **args, &block)
|
37
|
-
context.
|
52
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Input, template, **args, &block)
|
38
53
|
end
|
39
54
|
|
40
55
|
def trigger(template = nil, **args, &block)
|
41
|
-
context.
|
56
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Trigger, template, **args, &block)
|
42
57
|
end
|
43
58
|
|
44
59
|
def skip(template = nil, **args, &block)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
60
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Skip, template, **args, &block).tap do |step|
|
61
|
+
# A skip step has a nil/noop command.
|
62
|
+
step.command(nil)
|
63
|
+
# Always set the skip attribute if it's in a falsey state.
|
64
|
+
step.skip(true) if !step.get(:skip) || step.skip.empty?
|
65
|
+
end
|
51
66
|
end
|
52
67
|
|
53
68
|
def wait(attributes = {}, &block)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
69
|
+
context.extensions.find(Steps).build_step(Pipelines::Steps::Wait, nil, &block).tap do |step|
|
70
|
+
step.wait(nil)
|
71
|
+
attributes.each do |key, value|
|
72
|
+
step.set(key, value)
|
73
|
+
end
|
58
74
|
end
|
59
|
-
step
|
60
75
|
end
|
61
76
|
end
|
62
77
|
end
|
@@ -6,8 +6,8 @@ module Buildkite
|
|
6
6
|
autoload :Env, File.expand_path('extensions/env', __dir__)
|
7
7
|
autoload :Lib, File.expand_path('extensions/lib', __dir__)
|
8
8
|
autoload :Notify, File.expand_path('extensions/notify', __dir__)
|
9
|
-
autoload :SubPipelines, File.expand_path('extensions/sub_pipelines', __dir__)
|
10
9
|
autoload :Steps, File.expand_path('extensions/steps', __dir__)
|
10
|
+
autoload :Plugins, File.expand_path('extensions/plugins', __dir__)
|
11
11
|
autoload :Use, File.expand_path('extensions/use', __dir__)
|
12
12
|
end
|
13
13
|
end
|
@@ -19,7 +19,6 @@ module Buildkite
|
|
19
19
|
attr_reader :logger,
|
20
20
|
:root,
|
21
21
|
:artifacts,
|
22
|
-
:plugins,
|
23
22
|
:dsl,
|
24
23
|
:data,
|
25
24
|
:extensions
|
@@ -28,7 +27,6 @@ module Buildkite
|
|
28
27
|
@root = root
|
29
28
|
@logger = logger || Logger.new(File::NULL)
|
30
29
|
@artifacts = []
|
31
|
-
@plugins = {}
|
32
30
|
@dsl = Dsl.new(self)
|
33
31
|
@extensions = ExtensionManager.new(self)
|
34
32
|
@data = Data.new
|
@@ -38,7 +36,7 @@ module Buildkite
|
|
38
36
|
use(Extensions::Env)
|
39
37
|
use(Extensions::Notify)
|
40
38
|
use(Extensions::Steps)
|
41
|
-
use(Extensions::
|
39
|
+
use(Extensions::Plugins)
|
42
40
|
end
|
43
41
|
|
44
42
|
def upload
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module Buildkite
|
4
4
|
module Builder
|
5
5
|
class Plugin
|
6
|
-
attr_reader
|
6
|
+
attr_reader \
|
7
|
+
:uri,
|
8
|
+
:source,
|
9
|
+
:version,
|
10
|
+
:default_attributes
|
7
11
|
|
8
|
-
def initialize(uri,
|
12
|
+
def initialize(uri, default_attributes = {})
|
9
13
|
@uri = uri
|
10
14
|
@source, @version = uri.split('#')
|
11
|
-
@
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_h
|
15
|
-
Buildkite::Pipelines::Helpers.sanitize(uri => (attributes&.empty? ? nil : attributes))
|
15
|
+
@default_attributes = default_attributes
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -7,23 +7,16 @@ module Buildkite
|
|
7
7
|
|
8
8
|
def add(name, uri, default_attributes = {})
|
9
9
|
name = name.to_s
|
10
|
+
raise(ArgumentError, "Plugin already defined: #{name}") if @plugins.key?(name)
|
10
11
|
|
11
|
-
|
12
|
-
raise ArgumentError, "Plugin already defined: #{name}"
|
13
|
-
end
|
14
|
-
|
15
|
-
@plugins[name] = {
|
16
|
-
uri: uri,
|
17
|
-
default_attributes: default_attributes
|
18
|
-
}
|
12
|
+
@plugins[name] = Plugin.new(uri, default_attributes)
|
19
13
|
end
|
20
14
|
|
21
|
-
def
|
22
|
-
@plugins[name]
|
23
|
-
|
15
|
+
def build(name, attributes = {})
|
16
|
+
plugin = @plugins[name.to_s]
|
17
|
+
raise(ArgumentError, "Plugin is not registered: #{resource}") unless plugin
|
24
18
|
|
25
|
-
|
26
|
-
# No-op
|
19
|
+
{ plugin.uri => plugin.default_attributes.merge(attributes) }
|
27
20
|
end
|
28
21
|
end
|
29
22
|
end
|
@@ -1,13 +1,9 @@
|
|
1
1
|
module Buildkite
|
2
2
|
module Builder
|
3
3
|
class StepCollection
|
4
|
-
attr_reader :templates
|
5
|
-
attr_reader :plugins
|
6
4
|
attr_reader :steps
|
7
5
|
|
8
|
-
def initialize
|
9
|
-
@templates = templates
|
10
|
-
@plugins = plugins
|
6
|
+
def initialize
|
11
7
|
@steps = []
|
12
8
|
end
|
13
9
|
|
@@ -15,12 +11,12 @@ module Buildkite
|
|
15
11
|
types = types.flatten
|
16
12
|
|
17
13
|
@steps.each do |step|
|
18
|
-
if
|
19
|
-
|
20
|
-
elsif step.is_a?(Group)
|
21
|
-
step.data.steps.each(*types) do |step|
|
14
|
+
if step.class.to_sym == :group
|
15
|
+
step.steps.each(*types) do |step|
|
22
16
|
yield step
|
23
17
|
end
|
18
|
+
elsif types.include?(step.class.to_sym)
|
19
|
+
yield step
|
24
20
|
elsif types.empty?
|
25
21
|
yield step
|
26
22
|
end
|
@@ -35,10 +31,6 @@ module Buildkite
|
|
35
31
|
find(key) || raise(ArgumentError, "Can't find step with key: #{key}")
|
36
32
|
end
|
37
33
|
|
38
|
-
def add(step_class, template = nil, **args, &block)
|
39
|
-
@steps.push(step_class.new(self, template, **args, &block)).last
|
40
|
-
end
|
41
|
-
|
42
34
|
def push(step)
|
43
35
|
@steps.push(step)
|
44
36
|
end
|
data/lib/buildkite/builder.rb
CHANGED
@@ -5,7 +5,6 @@ require 'pathname'
|
|
5
5
|
module Buildkite
|
6
6
|
module Builder
|
7
7
|
autoload :Commands, File.expand_path('builder/commands', __dir__)
|
8
|
-
autoload :Group, File.expand_path('builder/group', __dir__)
|
9
8
|
autoload :Pipeline, File.expand_path('builder/pipeline', __dir__)
|
10
9
|
autoload :Definition, File.expand_path('builder/definition', __dir__)
|
11
10
|
autoload :Data, File.expand_path('builder/data', __dir__)
|
@@ -18,7 +17,6 @@ module Buildkite
|
|
18
17
|
autoload :Processors, File.expand_path('builder/processors', __dir__)
|
19
18
|
autoload :Rainbow, File.expand_path('builder/rainbow', __dir__)
|
20
19
|
autoload :Plugin, File.expand_path('builder/plugin', __dir__)
|
21
|
-
autoload :PluginCollection, File.expand_path('builder/plugin_collection', __dir__)
|
22
20
|
autoload :StepCollection, File.expand_path('builder/step_collection', __dir__)
|
23
21
|
autoload :PipelineCollection, File.expand_path('builder/pipeline_collection', __dir__)
|
24
22
|
autoload :TemplateManager, File.expand_path('builder/template_manager', __dir__)
|
@@ -5,12 +5,7 @@ module Buildkite
|
|
5
5
|
module Helpers
|
6
6
|
module Plugins
|
7
7
|
def plugin(name_or_source, plugin_attributes = {})
|
8
|
-
|
9
|
-
attributes['plugins'].add(name_or_source, plugin_attributes)
|
10
|
-
end
|
11
|
-
|
12
|
-
def plugins
|
13
|
-
attributes['plugins']
|
8
|
+
append(:plugins, { name_or_source => plugin_attributes })
|
14
9
|
end
|
15
10
|
end
|
16
11
|
end
|
@@ -11,20 +11,16 @@ module Buildkite
|
|
11
11
|
|
12
12
|
def_delegator :@context, :data
|
13
13
|
|
14
|
-
attr_reader :template
|
15
|
-
attr_reader :step_collection
|
16
|
-
|
17
14
|
def self.to_sym
|
18
15
|
name.split('::').last.downcase.to_sym
|
19
16
|
end
|
20
17
|
|
21
|
-
def initialize(
|
22
|
-
@step_collection = step_collection
|
23
|
-
@template = step_collection.templates.find(template_name)
|
18
|
+
def initialize(**args)
|
24
19
|
@context = StepContext.new(self, **args)
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
instance_exec(@context, &block)
|
22
|
+
def process(block)
|
23
|
+
instance_exec(@context, &block)
|
28
24
|
end
|
29
25
|
end
|
30
26
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Buildkite
|
4
|
+
module Pipelines
|
5
|
+
module Steps
|
6
|
+
class Group < Abstract
|
7
|
+
attribute :depends_on, append: true
|
8
|
+
attribute :key
|
9
|
+
attribute :label
|
10
|
+
|
11
|
+
attr_reader :steps
|
12
|
+
|
13
|
+
def initialize(pipeline, **args)
|
14
|
+
@pipeline = pipeline
|
15
|
+
@context = StepContext.new(self, **args)
|
16
|
+
@steps = Buildkite::Builder::StepCollection.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(method_name, ...)
|
20
|
+
if @pipeline.dsl.respond_to?(method_name)
|
21
|
+
@pipeline.dsl.public_send(method_name, ...)
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to_missing?(...)
|
28
|
+
@pipeline.dsl.respond_to?(...) || super
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
super.merge(group: nil, steps: steps.to_definition)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -6,6 +6,7 @@ module Buildkite
|
|
6
6
|
autoload :Abstract, File.expand_path('steps/abstract', __dir__)
|
7
7
|
autoload :Block, File.expand_path('steps/block', __dir__)
|
8
8
|
autoload :Command, File.expand_path('steps/command', __dir__)
|
9
|
+
autoload :Group, File.expand_path('steps/group', __dir__)
|
9
10
|
autoload :Input, File.expand_path('steps/input', __dir__)
|
10
11
|
autoload :Skip, File.expand_path('steps/skip', __dir__)
|
11
12
|
autoload :Trigger, File.expand_path('steps/trigger', __dir__)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: buildkite-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ngan Pham
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-12-
|
12
|
+
date: 2022-12-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rainbow
|
@@ -113,19 +113,16 @@ files:
|
|
113
113
|
- lib/buildkite/builder/extensions/env.rb
|
114
114
|
- lib/buildkite/builder/extensions/lib.rb
|
115
115
|
- lib/buildkite/builder/extensions/notify.rb
|
116
|
+
- lib/buildkite/builder/extensions/plugins.rb
|
116
117
|
- lib/buildkite/builder/extensions/steps.rb
|
117
|
-
- lib/buildkite/builder/extensions/sub_pipelines.rb
|
118
118
|
- lib/buildkite/builder/extensions/use.rb
|
119
|
-
- lib/buildkite/builder/group.rb
|
120
119
|
- lib/buildkite/builder/loaders.rb
|
121
120
|
- lib/buildkite/builder/loaders/abstract.rb
|
122
121
|
- lib/buildkite/builder/loaders/extensions.rb
|
123
122
|
- lib/buildkite/builder/loaders/templates.rb
|
124
123
|
- lib/buildkite/builder/logging_utils.rb
|
125
124
|
- lib/buildkite/builder/pipeline.rb
|
126
|
-
- lib/buildkite/builder/pipeline_collection.rb
|
127
125
|
- lib/buildkite/builder/plugin.rb
|
128
|
-
- lib/buildkite/builder/plugin_collection.rb
|
129
126
|
- lib/buildkite/builder/plugin_manager.rb
|
130
127
|
- lib/buildkite/builder/rainbow.rb
|
131
128
|
- lib/buildkite/builder/step_collection.rb
|
@@ -150,6 +147,7 @@ files:
|
|
150
147
|
- lib/buildkite/pipelines/steps/abstract.rb
|
151
148
|
- lib/buildkite/pipelines/steps/block.rb
|
152
149
|
- lib/buildkite/pipelines/steps/command.rb
|
150
|
+
- lib/buildkite/pipelines/steps/group.rb
|
153
151
|
- lib/buildkite/pipelines/steps/input.rb
|
154
152
|
- lib/buildkite/pipelines/steps/skip.rb
|
155
153
|
- lib/buildkite/pipelines/steps/trigger.rb
|
@@ -177,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
175
|
- !ruby/object:Gem::Version
|
178
176
|
version: '0'
|
179
177
|
requirements: []
|
180
|
-
rubygems_version: 3.3.
|
178
|
+
rubygems_version: 3.3.26
|
181
179
|
signing_key:
|
182
180
|
specification_version: 4
|
183
181
|
summary: A gem for programmatically creating Buildkite pipelines.
|
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
|
3
|
-
module Buildkite
|
4
|
-
module Builder
|
5
|
-
module Extensions
|
6
|
-
class SubPipelines < Extension
|
7
|
-
class Pipeline
|
8
|
-
include Buildkite::Pipelines::Attributes
|
9
|
-
|
10
|
-
attr_reader :data, :name, :dsl
|
11
|
-
|
12
|
-
# These attributes are for triggered step
|
13
|
-
attribute :label
|
14
|
-
attribute :key
|
15
|
-
attribute :skip
|
16
|
-
attribute :if, as: :condition
|
17
|
-
attribute :depends_on, append: true
|
18
|
-
attribute :allow_dependency_failure
|
19
|
-
attribute :branches
|
20
|
-
attribute :async
|
21
|
-
attribute :build
|
22
|
-
|
23
|
-
def self.to_sym
|
24
|
-
name.split('::').last.downcase.to_sym
|
25
|
-
end
|
26
|
-
|
27
|
-
def initialize(name, context, &block)
|
28
|
-
@context = context
|
29
|
-
@name = name
|
30
|
-
@data = Data.new
|
31
|
-
@data.steps = StepCollection.new(
|
32
|
-
context.data.steps.templates,
|
33
|
-
context.data.steps.plugins
|
34
|
-
)
|
35
|
-
@data.notify = []
|
36
|
-
@data.env = {}
|
37
|
-
|
38
|
-
# Use `clone` to copy over dsl's extended extensions
|
39
|
-
@dsl = context.dsl.clone
|
40
|
-
# Override dsl context to current pipeline
|
41
|
-
@dsl.instance_variable_set(:@context, self)
|
42
|
-
|
43
|
-
instance_eval(&block) if block_given?
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_h
|
48
|
-
# Merge envs from main pipeline, since ruby does not have `reverse_merge` and
|
49
|
-
# `data` does not allow keys override, we have to reset the data hash per key.
|
50
|
-
@context.data.env.merge(data.env).each do |key, value|
|
51
|
-
data.env[key] = value
|
52
|
-
end
|
53
|
-
data.to_definition
|
54
|
-
end
|
55
|
-
|
56
|
-
def method_missing(method_name, *args, **kwargs, &_block)
|
57
|
-
@dsl.public_send(method_name, *args, **kwargs, &_block)
|
58
|
-
end
|
59
|
-
|
60
|
-
def pipeline_yml
|
61
|
-
@pipeline_yml ||= "tmp/buildkite-builder/#{SecureRandom.urlsafe_base64}.yml"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def prepare
|
66
|
-
context.data.pipelines = PipelineCollection.new(context.artifacts)
|
67
|
-
end
|
68
|
-
|
69
|
-
dsl do
|
70
|
-
def pipeline(name, &block)
|
71
|
-
raise "Subpipeline must have a name" if name.empty?
|
72
|
-
raise "Subpipeline does not allow nested in another Subpipeline" if context.is_a?(Buildkite::Builder::Extensions::SubPipelines::Pipeline)
|
73
|
-
|
74
|
-
sub_pipeline = Buildkite::Builder::Extensions::SubPipelines::Pipeline.new(name, context, &block)
|
75
|
-
context.data.pipelines.add(sub_pipeline)
|
76
|
-
|
77
|
-
trigger_step = context.data.steps.add(Pipelines::Steps::Trigger)
|
78
|
-
trigger_step.trigger(name)
|
79
|
-
|
80
|
-
build_options = {
|
81
|
-
message: '${BUILDKITE_MESSAGE}',
|
82
|
-
commit: '${BUILDKITE_COMMIT}',
|
83
|
-
branch: '${BUILDKITE_BRANCH}',
|
84
|
-
env: {
|
85
|
-
BUILDKITE_PULL_REQUEST: '${BUILDKITE_PULL_REQUEST}',
|
86
|
-
BUILDKITE_PULL_REQUEST_BASE_BRANCH: '${BUILDKITE_PULL_REQUEST_BASE_BRANCH}',
|
87
|
-
BUILDKITE_PULL_REQUEST_REPO: '${BUILDKITE_PULL_REQUEST_REPO}',
|
88
|
-
BKB_SUBPIPELINE_FILE: sub_pipeline.pipeline_yml
|
89
|
-
}
|
90
|
-
}
|
91
|
-
build_options.merge!(sub_pipeline.build) if sub_pipeline.build
|
92
|
-
|
93
|
-
trigger_step.build(build_options)
|
94
|
-
trigger_step.key(sub_pipeline.key || "subpipeline_#{name}_#{context.data.pipelines.count}")
|
95
|
-
trigger_step.label(sub_pipeline.label || name.capitalize)
|
96
|
-
trigger_step.async(sub_pipeline.async || false)
|
97
|
-
trigger_step.branches(sub_pipeline.branches) if sub_pipeline.branches
|
98
|
-
trigger_step.condition(sub_pipeline.condition) if sub_pipeline.condition
|
99
|
-
trigger_step.depends_on(*sub_pipeline.get('depends_on')) if sub_pipeline.get('depends_on')
|
100
|
-
trigger_step.allow_dependency_failure(sub_pipeline.allow_dependency_failure || false)
|
101
|
-
trigger_step.skip(sub_pipeline.skip || false)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Buildkite
|
2
|
-
module Builder
|
3
|
-
class Group
|
4
|
-
include Buildkite::Pipelines::Attributes
|
5
|
-
|
6
|
-
attr_reader :label
|
7
|
-
attr_reader :data
|
8
|
-
|
9
|
-
attribute :depends_on, append: true
|
10
|
-
attribute :key
|
11
|
-
|
12
|
-
def self.to_sym
|
13
|
-
name.split('::').last.downcase.to_sym
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(label, context, &block)
|
17
|
-
@label = label
|
18
|
-
@data = Data.new
|
19
|
-
@data.steps = StepCollection.new(
|
20
|
-
context.data.steps.templates,
|
21
|
-
context.data.steps.plugins
|
22
|
-
)
|
23
|
-
@data.notify = []
|
24
|
-
|
25
|
-
# Use `clone` to copy over dsl's extended extensions
|
26
|
-
@dsl = context.dsl.clone
|
27
|
-
# Override dsl context to current group
|
28
|
-
@dsl.instance_variable_set(:@context, self)
|
29
|
-
|
30
|
-
instance_eval(&block) if block_given?
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_h
|
35
|
-
attributes = super
|
36
|
-
{ group: label }.merge(attributes).merge(data.to_definition)
|
37
|
-
end
|
38
|
-
|
39
|
-
def method_missing(method_name, *args, **kwargs, &_block)
|
40
|
-
@dsl.public_send(method_name, *args, **kwargs, &_block)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require "forwardable"
|
2
|
-
|
3
|
-
module Buildkite
|
4
|
-
module Builder
|
5
|
-
class PipelineCollection
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
attr_reader :pipelines
|
9
|
-
|
10
|
-
def_delegator :@pipelines, :count
|
11
|
-
def_delegator :@pipelines, :each
|
12
|
-
|
13
|
-
def initialize(artifacts)
|
14
|
-
@artifacts = artifacts
|
15
|
-
@pipelines = []
|
16
|
-
end
|
17
|
-
|
18
|
-
def add(pipeline)
|
19
|
-
unless pipeline.is_a?(Buildkite::Builder::Extensions::SubPipelines::Pipeline)
|
20
|
-
raise "`#{pipeline}` must be a Buildkite::Builder::Extensions::SubPipelines::Pipeline"
|
21
|
-
end
|
22
|
-
|
23
|
-
pipelines << pipeline
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_definition
|
27
|
-
# Instead of generates pipeline.yml, subpipelines save generated file to artifacts
|
28
|
-
pipelines.each do |pipeline|
|
29
|
-
file = Pathname.new(pipeline.pipeline_yml)
|
30
|
-
file.dirname.mkpath
|
31
|
-
file.write(YAML.dump(Pipelines::Helpers.sanitize(pipeline.to_h)))
|
32
|
-
|
33
|
-
@artifacts << file
|
34
|
-
end
|
35
|
-
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Buildkite
|
2
|
-
module Builder
|
3
|
-
class PluginCollection
|
4
|
-
attr_reader :plugin_manager
|
5
|
-
|
6
|
-
def initialize(plugin_manager)
|
7
|
-
@plugin_manager = plugin_manager
|
8
|
-
@collection = []
|
9
|
-
end
|
10
|
-
|
11
|
-
def add(resource, attributes = {})
|
12
|
-
plugin =
|
13
|
-
case resource
|
14
|
-
when Symbol
|
15
|
-
registered_plugin = plugin_manager.fetch(resource.to_s)
|
16
|
-
|
17
|
-
raise ArgumentError, "Plugin `#{resource}` does not exist" unless registered_plugin
|
18
|
-
|
19
|
-
Plugin.new(registered_plugin[:uri], registered_plugin[:default_attributes].merge(attributes))
|
20
|
-
when String
|
21
|
-
Plugin.new(resource, attributes)
|
22
|
-
when Plugin
|
23
|
-
resource
|
24
|
-
else
|
25
|
-
raise ArgumentError, "Unknown plugin `#{resource.inspect}`"
|
26
|
-
end
|
27
|
-
|
28
|
-
@collection.push(plugin).last
|
29
|
-
end
|
30
|
-
|
31
|
-
def find(source)
|
32
|
-
source_string =
|
33
|
-
case source
|
34
|
-
when String then source
|
35
|
-
when Plugin then source.source
|
36
|
-
else raise ArgumentError, "Unknown source #{source.inspect}"
|
37
|
-
end
|
38
|
-
|
39
|
-
@collection.select do |plugin|
|
40
|
-
plugin.source == source_string
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def to_definition
|
45
|
-
@collection.map(&:to_h)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|