buildkite-builder 2.3.0 → 3.0.0

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: 2c6eaf580c5dea018a834cf11f76e5d1d1aa13792fda9b9d513993e53f56f0a7
4
- data.tar.gz: 5958862296476f8421ccb62fb0f23e7fef86302fdf354b00c8db9885f71691f0
3
+ metadata.gz: b19e2a9c84be58408585027ddc221dd1b8d6b5f9303085f874a97b460eaf4b7f
4
+ data.tar.gz: 939afa112be8163360618af03a4d21241b3cdceebef90fee3501052d1258e2cc
5
5
  SHA512:
6
- metadata.gz: 42719a13b6515e91edd391ea18e3f3e18b8db49ec4e4b36d81d0388a701a7567c63992b72860c20f1041b378c6b7a5475c2f5c33a2e454886c3f8a8a678d0b75
7
- data.tar.gz: f19d241a0507f434f778560bb4bf5b10dacbe1f8e743718257ac235b433cffd69f472b4d8eb30f9b3ceb28401cb241bda022743a29ffa8f72449964b3a091fa2
6
+ metadata.gz: 54cb436ddc5a4d68da270ae84e62af8902d15388d2d44edaf6f9cc0473bec0f7744286a8e8d9ed1ed5a9d15e8c46e23928a70a51c3078bc1426adb1a1a54c685
7
+ data.tar.gz: f67035e4e34f940c2a5b5c2fae14cda001e8185e20e2aa17db7d38574bf3ddcd5bccf47bd6ccf3a96e6325582a88b52cd8594df4a30f080d3eb712863b51ee6f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 3.0.0
2
+ * Remove manifest features to prevent Github API dependency and simplify the gem to focus on Buildkite features.
3
+
4
+ ## 2.4.1
5
+ * Fix pipeline upload as artifact logic.
6
+
7
+ ## 2.4.0
8
+ * Upload custom pipeline artifacts in a single command.
9
+ * Only upload the pipeline as an artifact when the pipeline upload fails.
10
+
1
11
  ## 2.3.0
2
12
  * Improve BKB step idempotency.
3
13
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 3.0.0
@@ -5,7 +5,6 @@ module Buildkite
5
5
  module Commands
6
6
  using Rainbow
7
7
  COMMANDS = {
8
- 'files' => :Files,
9
8
  'preview' => :Preview,
10
9
  'run' => :Run
11
10
  }.freeze
@@ -4,7 +4,6 @@ module Buildkite
4
4
  module Builder
5
5
  module Loaders
6
6
  autoload :Abstract, File.expand_path('loaders/abstract', __dir__)
7
- autoload :Manifests, File.expand_path('loaders/manifests', __dir__)
8
7
  autoload :Templates, File.expand_path('loaders/templates', __dir__)
9
8
  autoload :Extensions, File.expand_path('loaders/extensions', __dir__)
10
9
  end
@@ -37,7 +37,6 @@ module Buildkite
37
37
  use(Extensions::Env)
38
38
  use(Extensions::Notify)
39
39
  use(Extensions::Steps)
40
- load_manifests
41
40
  end
42
41
 
43
42
  def upload
@@ -51,10 +50,12 @@ module Buildkite
51
50
  file.sync = true
52
51
  file.write(contents)
53
52
 
54
- logger.info '+++ :paperclip: Uploading pipeline.yml as artifact'
55
- Buildkite::Pipelines::Command.artifact!(:upload, file.path)
56
- logger.info '+++ :pipeline: Uploading pipeline'
57
- Buildkite::Pipelines::Command.pipeline!(:upload, file.path)
53
+ logger.info "+++ :pipeline: Uploading pipeline"
54
+ unless Buildkite::Pipelines::Command.pipeline(:upload, file.path)
55
+ logger.info "Pipeline upload failed, saving as artifact…"
56
+ Buildkite::Pipelines::Command.artifact!(:upload, file.path)
57
+ abort
58
+ end
58
59
  logger.info "+++ :toolbox: Setting job meta-data to #{Buildkite.env.job_id.color(:yellow)}"
59
60
  Buildkite::Pipelines::Command.meta_data!(:set, Builder::META_DATA.fetch(:job), Buildkite.env.job_id)
60
61
  end
@@ -80,22 +81,11 @@ module Buildkite
80
81
 
81
82
  attr_reader :extensions
82
83
 
83
- def load_manifests
84
- Loaders::Manifests.load(root).each do |name, asset|
85
- Manifest[name] = asset
86
- end
87
- end
88
-
89
84
  def upload_artifacts
90
85
  return if artifacts.empty?
91
86
 
92
- logger.info "+++ :paperclip: Uploading #{artifacts.size.to_s.color(:yellow)} artifact#{'s' if artifacts.size != 1}"
93
-
94
- artifacts.each do |path|
95
- if File.exist?(path)
96
- Buildkite::Pipelines::Command.artifact!(:upload, path)
97
- end
98
- end
87
+ logger.info "+++ :paperclip: Uploading artifacts"
88
+ Buildkite::Pipelines::Command.artifact!(:upload, artifacts.join(";"))
99
89
  end
100
90
 
101
91
  def pipeline_definition
@@ -13,11 +13,8 @@ module Buildkite
13
13
  autoload :Extension, File.expand_path('builder/extension', __dir__)
14
14
  autoload :ExtensionManager, File.expand_path('builder/extension_manager', __dir__)
15
15
  autoload :Extensions, File.expand_path('builder/extensions', __dir__)
16
- autoload :FileResolver, File.expand_path('builder/file_resolver', __dir__)
17
- autoload :Github, File.expand_path('builder/github', __dir__)
18
16
  autoload :Loaders, File.expand_path('builder/loaders', __dir__)
19
17
  autoload :LoggingUtils, File.expand_path('builder/logging_utils', __dir__)
20
- autoload :Manifest, File.expand_path('builder/manifest', __dir__)
21
18
  autoload :Processors, File.expand_path('builder/processors', __dir__)
22
19
  autoload :Rainbow, File.expand_path('builder/rainbow', __dir__)
23
20
  autoload :Plugin, File.expand_path('builder/plugin', __dir__)
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: 2.3.0
4
+ version: 3.0.0
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-11-12 00:00:00.000000000 Z
12
+ date: 2022-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rainbow
@@ -116,7 +116,6 @@ files:
116
116
  - lib/buildkite/builder.rb
117
117
  - lib/buildkite/builder/commands.rb
118
118
  - lib/buildkite/builder/commands/abstract.rb
119
- - lib/buildkite/builder/commands/files.rb
120
119
  - lib/buildkite/builder/commands/preview.rb
121
120
  - lib/buildkite/builder/commands/run.rb
122
121
  - lib/buildkite/builder/data.rb
@@ -130,17 +129,12 @@ files:
130
129
  - lib/buildkite/builder/extensions/notify.rb
131
130
  - lib/buildkite/builder/extensions/steps.rb
132
131
  - lib/buildkite/builder/extensions/use.rb
133
- - lib/buildkite/builder/file_resolver.rb
134
- - lib/buildkite/builder/github.rb
135
132
  - lib/buildkite/builder/group.rb
136
133
  - lib/buildkite/builder/loaders.rb
137
134
  - lib/buildkite/builder/loaders/abstract.rb
138
135
  - lib/buildkite/builder/loaders/extensions.rb
139
- - lib/buildkite/builder/loaders/manifests.rb
140
136
  - lib/buildkite/builder/loaders/templates.rb
141
137
  - lib/buildkite/builder/logging_utils.rb
142
- - lib/buildkite/builder/manifest.rb
143
- - lib/buildkite/builder/manifest/rule.rb
144
138
  - lib/buildkite/builder/pipeline.rb
145
139
  - lib/buildkite/builder/plugin.rb
146
140
  - lib/buildkite/builder/plugin_collection.rb
@@ -181,7 +175,7 @@ metadata:
181
175
  source_code_uri: https://github.com/Gusto/buildkite-builder
182
176
  changelog_uri: https://github.com/Gusto/buildkite-builder/blob/master/CHANGELOG.md
183
177
  bug_tracker_uri: https://github.com/Gusto/buildkite-builder/issues
184
- post_install_message:
178
+ post_install_message:
185
179
  rdoc_options: []
186
180
  require_paths:
187
181
  - lib
@@ -196,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
190
  - !ruby/object:Gem::Version
197
191
  version: '0'
198
192
  requirements: []
199
- rubygems_version: 3.1.6
200
- signing_key:
193
+ rubygems_version: 3.3.13
194
+ signing_key:
201
195
  specification_version: 4
202
196
  summary: A gem for programmatically creating Buildkite pipelines.
203
197
  test_files: []
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Buildkite
4
- module Builder
5
- module Commands
6
- class Files < Abstract
7
- private
8
-
9
- self.description = 'Outputs files that match the specified manifest.'
10
-
11
- def run
12
- manifests = Loaders::Manifests.load(pipeline_path)
13
- puts manifests[options[:manifest]].files.sort.join("\n")
14
- end
15
-
16
- def parse_options(opts)
17
- opts.on('--manifest MANIFEST', 'The manifest to use') do |manifest|
18
- options[:manifest] = manifest
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'open3'
4
- require 'set'
5
-
6
- module Buildkite
7
- module Builder
8
- class FileResolver
9
- @cache = true
10
-
11
- attr_reader :modified_files
12
-
13
- class << self
14
- attr_accessor :cache
15
-
16
- def resolve(reset = false)
17
- @resolve = nil if !cache || reset
18
- @resolve ||= new
19
- end
20
- end
21
-
22
- def initialize
23
- @modified_files = Set.new(pull_request? ? files_from_pull_request.sort! : files_from_git.sort!)
24
- end
25
-
26
- private
27
-
28
- def files_from_pull_request
29
- Github.pull_request_files.map { |f| f.fetch('filename') }
30
- end
31
-
32
- def files_from_git
33
- if Buildkite.env
34
- changed_files = command("git diff-tree --no-commit-id --name-only -r #{Buildkite.env.commit}")
35
- else
36
- default_branch = command('git symbolic-ref refs/remotes/origin/HEAD').strip
37
- changed_files = command("git diff --name-only #{default_branch}")
38
- changed_files << command('git diff --name-only')
39
- end
40
-
41
- changed_files.split.uniq.sort
42
- end
43
-
44
- def pull_request?
45
- Buildkite.env&.pull_request
46
- end
47
-
48
- def command(cmd)
49
- output, status = Open3.capture2(*cmd.split)
50
-
51
- if status.success?
52
- output
53
- else
54
- raise "Command failed (exit #{status.exitstatus}): #{cmd}"
55
- end
56
- end
57
- end
58
- end
59
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
- require 'net/http'
5
- require 'uri'
6
-
7
- module Buildkite
8
- module Builder
9
- class Github
10
- BASE_URI = URI('https://api.github.com').freeze
11
- ACCEPT_HEADER = 'application/vnd.github.v3+json'
12
- LINK_HEADER = 'link'
13
- NEXT_LINK_REGEX = /<(?<uri>.+)>; rel="next"/.freeze
14
- REPO_REGEX = /github\.com(?::|\/)(.*?)(?:\.git)?\z/.freeze
15
- PER_PAGE = 100
16
-
17
- def self.pull_request_files
18
- new.pull_request_files
19
- end
20
-
21
- def initialize(env = ENV)
22
- @env = env
23
- end
24
-
25
- def pull_request_files
26
- files = []
27
- next_uri = URI.join(BASE_URI, "repos/#{repo}/pulls/#{pull_request_number}/files?per_page=#{PER_PAGE}")
28
-
29
- while next_uri
30
- response = request(next_uri)
31
- files.concat(JSON.parse(response.body))
32
- next_uri = parse_next_uri(response)
33
- end
34
-
35
- files
36
- end
37
-
38
- private
39
-
40
- def repo
41
- Buildkite.env.repo[REPO_REGEX, 1]
42
- end
43
-
44
- def token
45
- @env.fetch('GITHUB_API_TOKEN')
46
- end
47
-
48
- def pull_request_number
49
- Buildkite.env.pull_request
50
- end
51
-
52
- def request(uri)
53
- Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
54
- request = Net::HTTP::Get.new(uri)
55
- request['Authorization'] = "token #{token}"
56
- request['Accept'] = ACCEPT_HEADER
57
-
58
- http.request(request)
59
- end
60
- end
61
-
62
- def parse_next_uri(response)
63
- links = response[LINK_HEADER]
64
- return unless links
65
-
66
- matches = links.match(NEXT_LINK_REGEX)
67
- URI.parse(matches[:uri]) if matches
68
- end
69
- end
70
- end
71
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Buildkite
4
- module Builder
5
- module Loaders
6
- class Manifests < Abstract
7
- MANIFESTS_PATH = Pathname.new('manifests').freeze
8
-
9
- def load
10
- return unless manifests_path.directory?
11
-
12
- manifests_path.children.map do |file|
13
- add(file.basename, Manifest.new(Buildkite::Builder.root, file.readlines))
14
- end
15
- end
16
-
17
- def manifests_path
18
- root.join(MANIFESTS_PATH)
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'set'
4
- require 'pathname'
5
-
6
- module Buildkite
7
- module Builder
8
- class Manifest::Rule
9
- GLOB_OPTIONS = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
10
-
11
- attr_reader :exclude
12
- attr_reader :glob
13
-
14
- def initialize(root, pattern)
15
- @root = Pathname.new(root)
16
- @exclude = false
17
- @glob = @root
18
-
19
- if pattern[0] == '!'
20
- @exclude = true
21
- pattern = pattern[1..-1]
22
- end
23
-
24
- if pattern.start_with?('/')
25
- pattern = pattern[1..-1]
26
- else
27
- @glob = @glob.join('**')
28
- end
29
-
30
- @glob = @glob.join(pattern).to_s
31
- end
32
-
33
- def files
34
- @files ||= begin
35
- matched = Dir.glob(glob, GLOB_OPTIONS)
36
- matched.map! { |file| Pathname.new(file) }
37
- matched.reject!(&:directory?)
38
- matched.map! { |file| file.relative_path_from(Builder.root) }
39
- Set.new(matched.sort!)
40
- end
41
- end
42
-
43
- def match?(file)
44
- file = Pathname.new(file)
45
- file = @root.join(file) unless file.absolute?
46
-
47
- File.fnmatch?(glob, file.to_s, GLOB_OPTIONS)
48
- end
49
- end
50
- end
51
- end
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'digest/md5'
4
- require 'pathname'
5
-
6
- module Buildkite
7
- module Builder
8
- class Manifest
9
- autoload :Rule, File.expand_path('manifest/rule', __dir__)
10
-
11
- class << self
12
- def resolve(root, patterns)
13
- new(root, Array(patterns)).modified?
14
- end
15
-
16
- def manifests
17
- @manifests ||= {}
18
- end
19
-
20
- def [](name)
21
- manifests[name.to_s]
22
- end
23
-
24
- def []=(name, manifest)
25
- name = name.to_s
26
- if manifests.key?(name)
27
- raise ArgumentError, "manifest #{name} already exists"
28
- end
29
-
30
- manifests[name] = manifest
31
- end
32
- end
33
-
34
- attr_reader :root
35
-
36
- def initialize(root, patterns)
37
- @root = Pathname.new(root)
38
- @root = Buildkite::Builder.root.join(@root) unless @root.absolute?
39
- @patterns = patterns.map(&:to_s)
40
- end
41
-
42
- def modified?
43
- # DO NOT intersect FileResolver with manifest files. If the manifest is
44
- # large, the operation can be expensive. It's always cheaper to loop
45
- # through the changed files and compare them against the rules.
46
- unless defined?(@modified)
47
- @modified = FileResolver.resolve.modified_files.any? do |file|
48
- file = Buildkite::Builder.root.join(file)
49
- inclusion_rules.any? { |rule| rule.match?(file) } &&
50
- exclusion_rules.none? { |rule| rule.match?(file) }
51
- end
52
- end
53
-
54
- @modified
55
- end
56
-
57
- def files
58
- @files ||= (inclusion_rules.map(&:files).reduce(Set.new, :merge) - exclusion_rules.map(&:files).reduce(Set.new, :merge)).sort.to_set
59
- end
60
-
61
- def digest
62
- @digest ||= begin
63
- digests = files.map { |file| Digest::MD5.file(Buildkite::Builder.root.join(file)).hexdigest }
64
- Digest::MD5.hexdigest(digests.join)
65
- end
66
- end
67
-
68
- private
69
-
70
- def rules
71
- @rules ||= @patterns.each_with_object([]) do |pattern, rules|
72
- pattern = pattern.strip
73
- unless pattern.match?(/\A(#|\z)/)
74
- rules << Rule.new(root, pattern)
75
- end
76
- end
77
- end
78
-
79
- def inclusion_rules
80
- @inclusion_rules ||= rules.reject(&:exclude)
81
- end
82
-
83
- def exclusion_rules
84
- @exclusion_rules ||= rules.select(&:exclude)
85
- end
86
- end
87
- end
88
- end