buildkite-builder 1.1.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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