buildkite-builder 1.1.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 024ee5aff1b1a819fe74946becf1e3b1941c9f6e8ea86ba822a2d1411209e098
4
- data.tar.gz: d9716d08bb4512fd0c9490ad26b1618a2b5e4f896693d5f5bca76024500fef70
3
+ metadata.gz: 9a3cd9ffee7742ded0fca17e0a11a214bd6383bd05c1c6a8101348d45b938bb1
4
+ data.tar.gz: f1b32964a3da0acdef53ba9febe034d1e77dc826ccb0b6722ffec1839f0f8126
5
5
  SHA512:
6
- metadata.gz: 3d8130054bd4276b9d1c4505798985b9032ca406c126de026fa36bbb0fa919541c4c7d4cdd4c510b52e6554febb66c2e8a8bcc8e63aa54061fb727e6cbe8b752
7
- data.tar.gz: 2492024dff09bfd31688c07ca712fed1b3191584f9b5917c4294775f687671decfcd3f0e0b20635bb3941c88b7097129e79700706a916b615ca11867e47a75e9
6
+ metadata.gz: d0ecf15f187b6644cf1e1af05c9bf425f17c8f7e2ecf4054b973e977a9feb202db8a63014286a9177b276687f935cf8e62ffc56ea7933503e0355fcc378db6fb
7
+ data.tar.gz: 71813fc583c20d14b99f487283f111ffc77bf9ad0f3adfbf97c87d17e13451eb4436f99a53d182952c5e37ee65c20376730d63cf1dec98ae777fbaf49bf8e3be
data/CHANGELOG.md CHANGED
@@ -0,0 +1,13 @@
1
+ ## 1.4.1
2
+ * Fix the Github API Builder to account for Buildkite having both `.git` and no file exention repository URIs (#33)
3
+
4
+ ## 1.4.0
5
+ * Fix the `files` command. You now pass in the manifest with the `--manifest` CLI argument.
6
+
7
+ ## 1.3.1
8
+ * Expose `data` from `StepContext` to `Step`
9
+
10
+ ## 1.3.0
11
+ * Add ability for step to store data in step context
12
+ * Move `upload` from `BuildKite::Builder::Commands::Run` to `BuildKite::Builder::Context`
13
+ * Add ability to set custom artifacts in context and uplaod before `pipeile upload`
data/README.md CHANGED
@@ -28,7 +28,7 @@ steps:
28
28
  - label: ":toolbox:"
29
29
  plugins:
30
30
  - docker#v3.7.0:
31
- image: gusto/buildkite-builder:1.1.0
31
+ image: gusto/buildkite-builder:1.2.0
32
32
  propagate-environment: true
33
33
  ```
34
34
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.4.1
@@ -14,7 +14,6 @@ module Buildkite
14
14
  autoload :Manifest, File.expand_path('builder/manifest', __dir__)
15
15
  autoload :Processors, File.expand_path('builder/processors', __dir__)
16
16
  autoload :Rainbow, File.expand_path('builder/rainbow', __dir__)
17
- autoload :Runner, File.expand_path('builder/runner', __dir__)
18
17
 
19
18
  BUILDKITE_DIRECTORY_NAME = Pathname.new('.buildkite').freeze
20
19
 
@@ -6,6 +6,18 @@ module Buildkite
6
6
  module Builder
7
7
  module Commands
8
8
  class Abstract
9
+ PIPELINES_DIRECTORY = 'pipelines'
10
+ POSSIBLE_PIPELINE_PATHS = [
11
+ File.join('.buildkite', Context::PIPELINE_DEFINITION_FILE),
12
+ File.join('buildkite', Context::PIPELINE_DEFINITION_FILE),
13
+ File.join(Context::PIPELINE_DEFINITION_FILE)
14
+ ].freeze
15
+ POSSIBLE_PIPELINES_PATHS = [
16
+ File.join('.buildkite', PIPELINES_DIRECTORY),
17
+ File.join('buildkite', PIPELINES_DIRECTORY),
18
+ File.join(PIPELINES_DIRECTORY)
19
+ ].freeze
20
+
9
21
  class << self
10
22
  attr_accessor :description
11
23
 
@@ -35,6 +47,8 @@ module Buildkite
35
47
  if options[:help]
36
48
  puts options[:help]
37
49
  return
50
+ elsif !pipeline_path
51
+ abort "Unable to find pipeline"
38
52
  end
39
53
 
40
54
  run
@@ -42,6 +56,10 @@ module Buildkite
42
56
 
43
57
  private
44
58
 
59
+ def pipeline_slug
60
+ ARGV.last || Buildkite.env&.pipeline_slug
61
+ end
62
+
45
63
  def command_name
46
64
  Commands::COMMANDS.key(self.class.name.split('::').last.to_sym)
47
65
  end
@@ -51,12 +69,39 @@ module Buildkite
51
69
  # Subclasses should override to parse options.
52
70
  end
53
71
 
54
- def available_pipelines
55
- @available_pipelines ||= pipelines_path.children.select(&:directory?).map { |dir| dir.basename.to_s }
72
+ def log
73
+ @log ||= begin
74
+ Logger.new($stdout).tap do |logger|
75
+ logger.formatter = proc do |_severity, _datetime, _progname, msg|
76
+ "#{msg}\n"
77
+ end
78
+ end
79
+ end
56
80
  end
57
81
 
58
- def pipelines_path
59
- Builder.root.join(Builder::BUILDKITE_DIRECTORY_NAME).join(Runner::PIPELINES_PATH)
82
+ def pipeline_path
83
+ @pipeline_path ||=
84
+ find_root_by_main_pipeline ||
85
+ find_root_by_multi_pipeline
86
+ end
87
+
88
+ def find_root_by_main_pipeline
89
+ POSSIBLE_PIPELINE_PATHS.map { |path| Builder.root.join(path) }.find(&:exist?)&.dirname
90
+ end
91
+
92
+ def find_root_by_multi_pipeline
93
+ pipelines_path = POSSIBLE_PIPELINES_PATHS.map { |path| Builder.root.join(path) }.find(&:directory?)
94
+
95
+ if pipelines_path
96
+ if pipeline_slug
97
+ path = pipelines_path.join(pipeline_slug)
98
+ path if path.directory?
99
+ elsif pipelines_path.children.one?
100
+ pipelines_path.children.first
101
+ else
102
+ raise 'Your project has multiple pipelines, please specify one.'
103
+ end
104
+ end
60
105
  end
61
106
  end
62
107
  end
@@ -9,14 +9,13 @@ module Buildkite
9
9
  self.description = 'Outputs files that match the specified manifest.'
10
10
 
11
11
  def run
12
- pipeline, manifest = ARGV.first.to_s.split('/')
13
- if !pipeline || !manifest
14
- raise 'You must specify a pipeline and a manifest (eg "mypipeline/mymanifest")'
15
- end
12
+ manifests = Loaders::Manifests.load(pipeline_path)
13
+ puts manifests[options[:manifest]].files.sort.join("\n")
14
+ end
16
15
 
17
- manifests = Loaders::Manifests.load(pipeline)
18
- manifests[manifest].files.each do |file|
19
- puts file
16
+ def parse_options(opts)
17
+ opts.on('--manifest MANIFEST', 'The manifest to use') do |manifest|
18
+ options[:manifest] = manifest
20
19
  end
21
20
  end
22
21
  end
@@ -9,21 +9,7 @@ module Buildkite
9
9
  self.description = 'Outputs the pipeline YAML.'
10
10
 
11
11
  def run
12
- pipeline = ARGV.last
13
-
14
- if !pipeline && !root_pipeline?
15
- if available_pipelines.one?
16
- pipeline = available_pipelines.first
17
- else
18
- raise 'You must specify a pipeline'
19
- end
20
- end
21
-
22
- puts Runner.new(pipeline: pipeline).run.to_yaml
23
- end
24
-
25
- def root_pipeline?
26
- pipelines_path.join(Context::PIPELINE_DEFINITION_FILE).exist?
12
+ puts Context.build(pipeline_path).pipeline.to_yaml
27
13
  end
28
14
  end
29
15
  end
@@ -5,21 +5,31 @@ module Buildkite
5
5
  module Commands
6
6
  class Run < Abstract
7
7
  private
8
+ include LoggingUtils
9
+ using Rainbow
8
10
 
9
11
  self.description = 'Builds and uploads the generated pipeline.'
10
12
 
11
13
  def run
14
+ relative_pipeline_path = pipeline_path.relative_path_from(Builder.root)
15
+
12
16
  # This entrypoint is for running on CI. It expects certain environment
13
- # variables to be set.
14
- options = {
15
- upload: true
16
- }
17
+ # variables to be set. It also uploads the pipeline to Buildkite.
18
+ log.info "#{'+++ ' if Buildkite.env}🧰 " + 'Buildkite Builder'.color(:springgreen) + " ─ #{relative_pipeline_path.to_s.yellow}"
19
+ Context.new(pipeline_path, logger: log).upload
20
+ end
17
21
 
18
- if available_pipelines.include?(Buildkite.env.pipeline_slug)
19
- options[:pipeline] = Buildkite.env.pipeline_slug
20
- end
22
+ private
21
23
 
22
- Builder::Runner.new(**options).run
24
+ def pipeline_path
25
+ pipeline_path_override || super
26
+ end
27
+
28
+ def pipeline_path_override
29
+ if ENV['BUILDKITE_BUILDER_PIPELINE_PATH']
30
+ path = Pathname.new(ENV['BUILDKITE_BUILDER_PIPELINE_PATH'])
31
+ path.absolute? ? path : Builder.root.join(path)
32
+ end
23
33
  end
24
34
  end
25
35
  end
@@ -1,13 +1,19 @@
1
+ require 'logger'
2
+ require 'tempfile'
3
+
1
4
  module Buildkite
2
5
  module Builder
3
6
  class Context
4
7
  include Definition::Helper
8
+ include LoggingUtils
9
+ using Rainbow
5
10
 
6
11
  PIPELINE_DEFINITION_FILE = Pathname.new('pipeline.rb').freeze
7
12
 
8
13
  attr_reader :logger
9
14
  attr_reader :root
10
15
  attr_reader :pipeline
16
+ attr_reader :artifacts
11
17
 
12
18
  def self.build(root, logger: nil)
13
19
  context = new(root, logger: logger)
@@ -18,22 +24,44 @@ module Buildkite
18
24
  def initialize(root, logger: nil)
19
25
  @root = root
20
26
  @logger = logger || Logger.new(File::NULL)
27
+ @artifacts = []
21
28
  end
22
29
 
23
30
  def build
24
- unless @pipeline
25
- @pipeline = Pipelines::Pipeline.new
26
-
27
- load_manifests
28
- load_templates
29
- load_processors
30
- load_pipeline
31
- run_processors
31
+ results = benchmark("\nDone (%s)".color(:springgreen)) do
32
+ unless @pipeline
33
+ @pipeline = Pipelines::Pipeline.new
34
+
35
+ load_manifests
36
+ load_templates
37
+ load_processors
38
+ load_pipeline
39
+ run_processors
40
+ end
32
41
  end
42
+ logger.info(results)
33
43
 
34
44
  @pipeline
35
45
  end
36
46
 
47
+ def upload
48
+ build unless @pipeline
49
+
50
+ logger.info '+++ :paperclip: Uploading artifacts'
51
+ upload_artifacts
52
+
53
+ # Upload the pipeline.
54
+ Tempfile.create(['pipeline', '.yml']) do |file|
55
+ file.sync = true
56
+ file.write(pipeline.to_yaml)
57
+
58
+ logger.info '+++ :paperclip: Uploading pipeline.yml as artifact'
59
+ Buildkite::Pipelines::Command.artifact!(:upload, file.path)
60
+ logger.info '+++ :pipeline: Uploading pipeline'
61
+ Buildkite::Pipelines::Command.pipeline!(:upload, file.path)
62
+ end
63
+ end
64
+
37
65
  private
38
66
 
39
67
  def load_manifests
@@ -58,6 +86,16 @@ module Buildkite
58
86
  end
59
87
  end
60
88
 
89
+ def upload_artifacts
90
+ return if artifacts.empty?
91
+
92
+ artifacts.each do |path|
93
+ if File.exist?(path)
94
+ Buildkite::Pipelines::Command.artifact!(:upload, path)
95
+ end
96
+ end
97
+ end
98
+
61
99
  def load_pipeline
62
100
  pipeline.instance_eval(&pipeline_definition)
63
101
  end
File without changes
@@ -11,7 +11,7 @@ module Buildkite
11
11
  ACCEPT_HEADER = 'application/vnd.github.v3+json'
12
12
  LINK_HEADER = 'link'
13
13
  NEXT_LINK_REGEX = /<(?<uri>.+)>; rel="next"/.freeze
14
- REPO_REGEX = /github\.com(?::|\/)(.*)\.git\z/.freeze
14
+ REPO_REGEX = /github\.com(?::|\/)(.*?)(?:\.git)?\z/.freeze
15
15
  PER_PAGE = 100
16
16
 
17
17
  def self.pull_request_files
@@ -5,10 +5,12 @@ module Buildkite
5
5
  class StepContext
6
6
  attr_reader :step
7
7
  attr_reader :args
8
+ attr_reader :data
8
9
 
9
10
  def initialize(step, **args)
10
11
  @step = step
11
12
  @args = args
13
+ @data = {}
12
14
  end
13
15
 
14
16
  def pipeline
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
4
+
3
5
  module Buildkite
4
6
  module Pipelines
5
7
  module Steps
6
8
  class Abstract
9
+ extend Forwardable
7
10
  include Attributes
8
11
 
12
+ def_delegator :@context, :data
13
+
9
14
  attr_reader :pipeline
10
15
  attr_reader :template
11
16
 
@@ -16,10 +21,10 @@ module Buildkite
16
21
  def initialize(pipeline, template = nil, **args, &block)
17
22
  @pipeline = pipeline
18
23
  @template = template
19
- context = StepContext.new(self, **args)
24
+ @context = StepContext.new(self, **args)
20
25
 
21
- instance_exec(context, &template) if template
22
- instance_exec(context, &block) if block_given?
26
+ instance_exec(@context, &template) if template
27
+ instance_exec(@context, &block) if block_given?
23
28
  end
24
29
  end
25
30
  end
File without changes
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildkite-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ngan Pham
8
8
  - Andrew Lee
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-02-16 00:00:00.000000000 Z
12
+ date: 2021-04-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sorted_set
@@ -135,6 +135,7 @@ files:
135
135
  - lib/buildkite/builder/commands/run.rb
136
136
  - lib/buildkite/builder/context.rb
137
137
  - lib/buildkite/builder/definition.rb
138
+ - lib/buildkite/builder/dsl/pipeline.rb
138
139
  - lib/buildkite/builder/file_resolver.rb
139
140
  - lib/buildkite/builder/github.rb
140
141
  - lib/buildkite/builder/loaders.rb
@@ -148,7 +149,6 @@ files:
148
149
  - lib/buildkite/builder/processors.rb
149
150
  - lib/buildkite/builder/processors/abstract.rb
150
151
  - lib/buildkite/builder/rainbow.rb
151
- - lib/buildkite/builder/runner.rb
152
152
  - lib/buildkite/env.rb
153
153
  - lib/buildkite/pipelines.rb
154
154
  - lib/buildkite/pipelines/api.rb
@@ -172,6 +172,7 @@ files:
172
172
  - lib/buildkite/pipelines/steps/abstract.rb
173
173
  - lib/buildkite/pipelines/steps/block.rb
174
174
  - lib/buildkite/pipelines/steps/command.rb
175
+ - lib/buildkite/pipelines/steps/group.rb
175
176
  - lib/buildkite/pipelines/steps/input.rb
176
177
  - lib/buildkite/pipelines/steps/skip.rb
177
178
  - lib/buildkite/pipelines/steps/trigger.rb
@@ -184,7 +185,7 @@ metadata:
184
185
  source_code_uri: https://github.com/Gusto/buildkite-builder
185
186
  changelog_uri: https://github.com/Gusto/buildkite-builder/blob/master/CHANGELOG.md
186
187
  bug_tracker_uri: https://github.com/Gusto/buildkite-builder/issues
187
- post_install_message:
188
+ post_install_message:
188
189
  rdoc_options: []
189
190
  require_paths:
190
191
  - lib
@@ -200,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
201
  version: '0'
201
202
  requirements: []
202
203
  rubygems_version: 3.2.2
203
- signing_key:
204
+ signing_key:
204
205
  specification_version: 4
205
206
  summary: A gem for programmatically creating Buildkite pipelines.
206
207
  test_files: []
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler'
4
- require 'pathname'
5
- require 'tempfile'
6
- require 'logger'
7
-
8
- module Buildkite
9
- module Builder
10
- class Runner
11
- include LoggingUtils
12
- using Rainbow
13
-
14
- PIPELINES_PATH = Pathname.new('pipelines').freeze
15
-
16
- attr_reader :options
17
-
18
- def initialize(**options)
19
- @options = options
20
- end
21
-
22
- def run
23
- log.info "#{'+++ ' if Buildkite.env}🧰 " + 'Buildkite Builder'.color(:springgreen) + " ─ #{@options[:pipeline].yellow}"
24
- context = Context.new(root, logger: log)
25
-
26
- results = benchmark("\nDone (%s)".color(:springgreen)) do
27
- context.build
28
- end
29
- log.info(results)
30
-
31
- if options[:upload]
32
- upload(context.pipeline)
33
- end
34
-
35
- # Always return the pipeline.
36
- context.pipeline
37
- end
38
-
39
- private
40
-
41
- def log
42
- @log ||= begin
43
- Logger.new($stdout).tap do |logger|
44
- logger.formatter = proc do |_severity, _datetime, _progname, msg|
45
- "#{msg}\n"
46
- end
47
- end
48
- end
49
- end
50
-
51
- def upload(pipeline)
52
- Tempfile.create(['pipeline', '.yml']) do |file|
53
- file.sync = true
54
- file.write(pipeline.to_yaml)
55
-
56
- log.info '+++ :paperclip: Uploading artifact'
57
- Buildkite::Pipelines::Command.artifact!(:upload, file.path)
58
- log.info '+++ :pipeline: Uploading pipeline'
59
- Buildkite::Pipelines::Command.pipeline!(:upload, file.path)
60
- end
61
- end
62
-
63
- def root
64
- @root ||= begin
65
- path = Builder.root.join(Builder::BUILDKITE_DIRECTORY_NAME)
66
- if options[:pipeline]
67
- pipeline_path = path.join(PIPELINES_PATH).join(options[:pipeline])
68
- if pipeline_path.directory?
69
- path = pipeline_path
70
- end
71
- end
72
- path
73
- end
74
- end
75
- end
76
- end
77
- end