buildkit 1.1.1 → 1.4.2

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
- SHA1:
3
- metadata.gz: 64e7a9271c0e2d717b54e94d2376bcbe9d2b0874
4
- data.tar.gz: 74bcd8f4013c4e67bc898047b277dd05632f2ff0
2
+ SHA256:
3
+ metadata.gz: cb6ca6eafcc3ad71c019207e36894e60ee31b31053ec2e3aee60930a5d6998b0
4
+ data.tar.gz: 9eb250b35103fad340404e0b08ece58be85e76158c8ece673cc9e8d733654374
5
5
  SHA512:
6
- metadata.gz: 85841d9c8a376d667c05a32cf805ede8e078f1b4056d20e07069354f132d155a0e9df10d0ec62f790974120c6d556aeae75c94617b8745044d7105d4fee13789
7
- data.tar.gz: 2df8497a6f244a38fa314886ecbeae14c2a7b3033daba366495fde6e875e523b33854eeb30c2d15227c3f44daffd06cd5f9456e8275be41dadd465a8e48010ea
6
+ metadata.gz: fd6916b102128b7bd3d6b0627d9f57462a14c565811732d56137691faf96778078536c1011ef3a633c06b499daf0711a9ea3edff4bd7d6689c9342f33ac98cc0
7
+ data.tar.gz: e5caef77cd0cb5016a7794b040445562456daab5b29a3f344598fe04345d47e259e674a6b3ff0964d22e6dc5e89958004cb6a4dccc1695caefcb9e2b3228cc0c
@@ -0,0 +1,21 @@
1
+ on: push
2
+ name: Test Buildkit Gem
3
+
4
+ jobs:
5
+ build:
6
+ runs-on: ubuntu-20.04
7
+ strategy:
8
+ matrix:
9
+ ruby: [ '2.5', '2.6', '2.7' ]
10
+ name: Ruby ${{ matrix.ruby }}
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: ${{ matrix.ruby }}
16
+ - name: bundle install
17
+ run: |
18
+ gem install bundler
19
+ bundle install --jobs 4 --retry 3
20
+ - name: Run rspec
21
+ run: 'bundle exec rspec spec'
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.1
4
+ TargetRubyVersion: 2.3
5
5
 
6
6
  Metrics/LineLength:
7
7
  Max: 120
@@ -9,6 +9,9 @@ Metrics/LineLength:
9
9
  Metrics/MethodLength:
10
10
  Max: 25
11
11
 
12
+ Metrics/ClassLength:
13
+ Enabled: false
14
+
12
15
  Metrics/BlockLength:
13
16
  Enabled: false # RSpec ... :facepalm:
14
17
 
@@ -36,10 +39,13 @@ Lint/AssignmentInCondition:
36
39
  Style/PerlBackrefs:
37
40
  Enabled: false
38
41
 
39
- Style/SpaceInsideHashLiteralBraces:
42
+ Layout/SpaceInsideHashLiteralBraces:
40
43
  EnforcedStyle: no_space
41
44
 
42
- Style/TrailingCommaInLiteral:
45
+ Style/TrailingCommaInArrayLiteral:
46
+ EnforcedStyleForMultiline: comma
47
+
48
+ Style/TrailingCommaInHashLiteral:
43
49
  EnforcedStyleForMultiline: comma
44
50
 
45
51
  Style/TrailingCommaInArguments:
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gem 'byebug'
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  Ruby toolkit for the Buildkite API.
4
4
 
5
- [![Build Status](https://secure.travis-ci.org/Shopify/buildkit.png)](http://travis-ci.org/Shopify/buildkit)
6
5
  [![Gem Version](https://badge.fury.io/rb/buildkit.png)](http://badge.fury.io/rb/buildkit)
7
6
 
8
7
  ## Installation
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
 
3
5
  require 'rspec/core/rake_task'
@@ -7,13 +9,13 @@ require 'rubocop/rake_task'
7
9
  RuboCop::RakeTask.new
8
10
 
9
11
  task test: :spec
10
- task default: [:spec, :rubocop]
12
+ task default: %i[spec rubocop]
11
13
 
12
14
  namespace :doc do
13
15
  require 'yard'
14
16
  YARD::Rake::YardocTask.new do |task|
15
- task.files = %w(LICENSE.md lib/**/*.rb)
16
- task.options = %w(--output-dir doc/yard --markup markdown)
17
+ task.files = %w[LICENSE.md lib/**/*.rb]
18
+ task.options = %w[--output-dir doc/yard --markup markdown]
17
19
  end
18
20
  task default: :yard
19
21
  end
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'buildkit'
data/buildkit.gemspec CHANGED
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'buildkit/version'
5
6
 
@@ -18,8 +19,10 @@ Gem::Specification.new do |spec|
18
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
20
  spec.require_paths = ['lib']
20
21
 
21
- spec.required_ruby_version = '>= 2.0'
22
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
23
+
24
+ spec.required_ruby_version = '>= 2.3'
22
25
 
23
- spec.add_dependency 'sawyer', '~> 0.6'
26
+ spec.add_dependency 'sawyer', '>= 0.6'
24
27
  spec.add_development_dependency 'bundler'
25
28
  end
data/dev.yml ADDED
@@ -0,0 +1,11 @@
1
+ name: buildkit
2
+
3
+ type: ruby
4
+
5
+ up:
6
+ - ruby: 2.5.5
7
+ - bundler
8
+
9
+ commands:
10
+ test:
11
+ run: bundle exec rake
data/lib/buildkit.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'buildkit/version'
2
4
  require 'buildkit/client'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sawyer'
2
4
  require 'buildkit/client/agents'
3
5
  require 'buildkit/client/builds'
@@ -6,6 +8,7 @@ require 'buildkit/client/pipelines'
6
8
  require 'buildkit/client/jobs'
7
9
  require 'buildkit/client/artifacts'
8
10
  require 'buildkit/response/raise_error'
11
+ require 'buildkit/header_link_parser'
9
12
 
10
13
  module Buildkit
11
14
  class Client
@@ -15,15 +18,18 @@ module Buildkit
15
18
  include Pipelines
16
19
  include Jobs
17
20
  include Artifacts
21
+ include HeaderLinkParser
18
22
 
19
- DEFAULT_ENDPOINT = 'https://api.buildkite.com/v2/'.freeze
23
+ DEFAULT_ENDPOINT = 'https://api.buildkite.com/v2/'
20
24
 
21
25
  # Header keys that can be passed in options hash to {#get},{#head}
22
- CONVENIENCE_HEADERS = Set.new([:accept, :content_type])
26
+ CONVENIENCE_HEADERS = Set.new(%i[accept content_type])
23
27
 
24
28
  # In Faraday 0.9, Faraday::Builder was renamed to Faraday::RackBuilder
25
29
  RACK_BUILDER_CLASS = defined?(Faraday::RackBuilder) ? Faraday::RackBuilder : Faraday::Builder
26
30
 
31
+ attr_accessor :auto_paginate
32
+
27
33
  class << self
28
34
  def build_middleware
29
35
  RACK_BUILDER_CLASS.new do |builder|
@@ -36,10 +42,11 @@ module Buildkit
36
42
 
37
43
  def initialize(endpoint: ENV.fetch('BUILDKITE_API_ENDPOINT', DEFAULT_ENDPOINT),
38
44
  token: ENV.fetch('BUILDKITE_API_TOKEN'),
39
- middleware: self.class.build_middleware)
45
+ middleware: self.class.build_middleware, auto_paginate: false)
40
46
  @middleware = middleware
41
47
  @endpoint = endpoint
42
48
  @token = token
49
+ @auto_paginate = auto_paginate
43
50
  end
44
51
 
45
52
  # Make a HTTP GET request
@@ -48,7 +55,11 @@ module Buildkit
48
55
  # @param options [Hash] Query and header params for request
49
56
  # @return [Sawyer::Resource]
50
57
  def get(url, options = {})
51
- request :get, url, parse_query_and_convenience_headers(options)
58
+ if @auto_paginate
59
+ paginate :get, url, parse_query_and_convenience_headers(options)
60
+ else
61
+ request :get, url, parse_query_and_convenience_headers(options)
62
+ end
52
63
  end
53
64
 
54
65
  # Make a HTTP POST request
@@ -109,19 +120,51 @@ module Buildkit
109
120
 
110
121
  def request(method, path, data, options = {})
111
122
  if data.is_a?(Hash)
112
- options[:query] = data.delete(:query) || {}
113
- options[:headers] = data.delete(:headers) || {}
123
+ options = extract_query_and_headers_from data
114
124
  if accept = data.delete(:accept)
115
125
  options[:headers][:accept] = accept
116
126
  end
117
127
  end
118
128
 
119
- @last_response = response = sawyer_agent.call(method, URI::Parser.new.escape(path.to_s), data, options)
129
+ @last_response = response = sawyer_agent.call(method, URI::DEFAULT_PARSER.escape(path.to_s), data, options)
120
130
  response.data
121
131
  end
122
132
 
133
+ def extract_query_and_headers_from(data)
134
+ {
135
+ query: data.delete(:query) || {},
136
+ headers: data.delete(:headers) || {},
137
+ }
138
+ end
139
+
140
+ def paginate(method, path, data, options = {})
141
+ response = []
142
+ loop do
143
+ request method, path, data, options
144
+
145
+ # Paginated API calls always return Arrays.
146
+ return last_response.data unless @last_response.data.is_a?(Array)
147
+
148
+ response.concat @last_response.data
149
+
150
+ link_header = parse_link_header(@last_response.headers[:link])
151
+ break if link_header[:next].nil?
152
+
153
+ path = next_page(link_header[:next])
154
+ end
155
+ response
156
+ end
157
+
158
+ def next_page(next_page)
159
+ build_path URI(next_page)
160
+ end
161
+
162
+ def build_path(uri)
163
+ "#{uri.path}?#{uri.query}"
164
+ end
165
+
123
166
  def sawyer_agent
124
- @agent ||= Sawyer::Agent.new(@endpoint, sawyer_options) do |http|
167
+ @sawyer_agent ||= Sawyer::Agent.new(@endpoint, sawyer_options) do |http|
125
168
  http.headers[:accept] = 'application/json'
126
169
  http.headers[:content_type] = 'application/json'
127
170
  http.headers[:user_agent] = "Buildkit v#{Buildkit::VERSION}"
@@ -145,7 +188,7 @@ module Buildkit
145
188
  end
146
189
  query = options.delete(:query)
147
190
  opts = {query: options}
148
- opts[:query].merge!(query) if query && query.is_a?(Hash)
191
+ opts[:query].merge!(query) if query&.is_a?(Hash)
149
192
  opts[:headers] = headers unless headers.empty?
150
193
 
151
194
  opts
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the Agents API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the Artifacts API
@@ -13,6 +15,16 @@ module Buildkit
13
15
  def artifacts(org, pipeline, build, options = {})
14
16
  get("/v2/organizations/#{org}/pipelines/#{pipeline}/builds/#{build}/artifacts", options)
15
17
  end
18
+
19
+ # List all artifacts for a job
20
+ #
21
+ # @return [Array<Sawyer::Resource>] Array of hashes representing Buildkite artifacts.
22
+ # @see https://buildkite.com/docs/rest-api/artifacts#list-artifacts-for-a-job
23
+ # @example
24
+ # Buildkit.job_artifacts('my-great-org', 'great-pipeline', 42, '76365070-34d5-4104-8b91-952780f8029f')
25
+ def job_artifacts(org, pipeline, build, job, options = {})
26
+ get("/v2/organizations/#{org}/pipelines/#{pipeline}/builds/#{build}/jobs/#{job}/artifacts", options)
27
+ end
16
28
  end
17
29
  end
18
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the Builds API
@@ -81,6 +83,18 @@ module Buildkit
81
83
  def create_build(org, pipeline, options = {})
82
84
  post("/v2/organizations/#{org}/pipelines/#{pipeline}/builds", options)
83
85
  end
86
+
87
+ # Cancel a build
88
+ #
89
+ # @param org [String] Organization slug.
90
+ # @param pipeline [String] pipeline slug.
91
+ # @param number [Integer] Build number.
92
+ # @see https://buildkite.com/docs/rest-api/builds#cancel-a-build
93
+ # @example
94
+ # Buildkit.cancel_build('my-great-org', 'great-pipeline', 42)
95
+ def cancel_build(org, pipeline, number, options = {})
96
+ put("/v2/organizations/#{org}/pipelines/#{pipeline}/builds/#{number}/cancel", options)
97
+ end
84
98
  end
85
99
  end
86
100
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the Jobs API
@@ -31,6 +33,20 @@ module Buildkit
31
33
  def job_env(org, pipeline, build, job, options = {})
32
34
  get("/v2/organizations/#{org}/pipelines/#{pipeline}/builds/#{build}/jobs/#{job}/env", options)
33
35
  end
36
+
37
+ # Get a job's log output
38
+ #
39
+ # @param org [String] Organization slug.
40
+ # @param pipeline [String] Pipeline slug.
41
+ # @param build [Integer] Build number.
42
+ # @param job [String] Job id.
43
+ # @return [Sawyer::Resource] Hash representing the Buildkit job log output.
44
+ # @see https://buildkite.com/docs/rest-api/jobs#get-a-jobs-log-output
45
+ # @example
46
+ # Buildkit.job_log('my-great-org', 'great-pipeline', 123, 'my-job-id')
47
+ def job_log(org, pipeline, build, job, options = {})
48
+ get("/v2/organizations/#{org}/pipelines/#{pipeline}/builds/#{build}/jobs/#{job}/log", options)
49
+ end
34
50
  end
35
51
  end
36
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the Organizations API
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  class Client
3
5
  # Methods for the pipelines API
@@ -31,7 +33,7 @@ module Buildkit
31
33
  # @param org [String] Organization slug.
32
34
  # @see https://buildkite.com/docs/api/pipelines#create-a-pipeline
33
35
  # @example
34
- # Buildkit.create_build('my-great-org', {
36
+ # Buildkit.create_pipeline('my-great-org', {
35
37
  # name: 'My pipeline',
36
38
  # repository: 'git@github.com:acme/pipeline.git',
37
39
  # steps: [
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
4
  # Custom error class for rescuing from all Buildkite errors
3
5
  class Error < StandardError
@@ -44,7 +46,7 @@ module Buildkit
44
46
  # Array of validation errors
45
47
  # @return [Array<Hash>] Error info
46
48
  def errors
47
- if data && data.is_a?(Hash)
49
+ if data&.is_a?(Hash)
48
50
  data[:errors] || []
49
51
  else
50
52
  []
@@ -98,14 +100,14 @@ module Buildkit
98
100
  def build_error_message
99
101
  return nil if @response.nil?
100
102
 
101
- message = "#{@response[:method].to_s.upcase} #{redact_url(@response[:url].to_s)}: #{@response[:status]} - "
103
+ message = +"#{@response[:method].to_s.upcase} #{redact_url(@response[:url].to_s)}: #{@response[:status]} - "
102
104
  message << "#{response_message}#{response_error}#{response_error_summary}"
103
105
  message << " // See: #{documentation_url}" unless documentation_url.nil?
104
106
  message
105
107
  end
106
108
 
107
109
  def redact_url(url_string)
108
- %w(client_secret access_token).each do |token|
110
+ %w[client_secret access_token].each do |token|
109
111
  url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)") if url_string.include? token
110
112
  end
111
113
  url_string
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Buildkit
4
+ module HeaderLinkParser
5
+ module_function
6
+
7
+ def parse_link_header(link_header)
8
+ {}.tap do |hash_link|
9
+ link_header.split(',').each do |link|
10
+ link_obj = LinkParser.new(link)
11
+ hash_link[link_obj.name] = link_obj.link
12
+ end
13
+ end
14
+ end
15
+
16
+ class LinkParser
17
+ def initialize(value)
18
+ @value = value
19
+ end
20
+
21
+ def name
22
+ @name ||= @value[/rel="(.*)"/, 1].to_sym
23
+ end
24
+
25
+ def link
26
+ @link ||= @value[/<(.+)>/, 1]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'buildkit/error'
3
5
 
@@ -7,8 +9,6 @@ module Buildkit
7
9
  # This class raises an Buildkit-flavored exception based
8
10
  # HTTP status codes returned by the API
9
11
  class RaiseError < Faraday::Response::Middleware
10
- private
11
-
12
12
  def on_complete(response)
13
13
  if error = Buildkit::Error.from_response(response)
14
14
  raise error
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Buildkit
2
- VERSION = '1.1.1'.freeze
4
+ VERSION = '1.4.2'
3
5
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-19 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sawyer
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.6'
27
27
  - !ruby/object:Gem::Dependency
@@ -45,11 +45,11 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/workflows/ci.yml"
48
49
  - ".gitignore"
49
50
  - ".rspec"
50
51
  - ".rubocop.yml"
51
52
  - ".rubocop_todo.yml"
52
- - ".travis.yml"
53
53
  - Gemfile
54
54
  - LICENSE.txt
55
55
  - README.md
@@ -57,6 +57,7 @@ files:
57
57
  - bin/console
58
58
  - bin/setup
59
59
  - buildkit.gemspec
60
+ - dev.yml
60
61
  - lib/buildkit.rb
61
62
  - lib/buildkit/client.rb
62
63
  - lib/buildkit/client/agents.rb
@@ -66,12 +67,14 @@ files:
66
67
  - lib/buildkit/client/organizations.rb
67
68
  - lib/buildkit/client/pipelines.rb
68
69
  - lib/buildkit/error.rb
70
+ - lib/buildkit/header_link_parser.rb
69
71
  - lib/buildkit/response/raise_error.rb
70
72
  - lib/buildkit/version.rb
71
73
  homepage: https://github.com/shopify/buildkit
72
74
  licenses:
73
75
  - MIT
74
- metadata: {}
76
+ metadata:
77
+ allowed_push_host: https://rubygems.org
75
78
  post_install_message:
76
79
  rdoc_options: []
77
80
  require_paths:
@@ -80,15 +83,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
83
  requirements:
81
84
  - - ">="
82
85
  - !ruby/object:Gem::Version
83
- version: '2.0'
86
+ version: '2.3'
84
87
  required_rubygems_version: !ruby/object:Gem::Requirement
85
88
  requirements:
86
89
  - - ">="
87
90
  - !ruby/object:Gem::Version
88
91
  version: '0'
89
92
  requirements: []
90
- rubyforge_project:
91
- rubygems_version: 2.5.1
93
+ rubygems_version: 3.0.3
92
94
  signing_key:
93
95
  specification_version: 4
94
96
  summary: Ruby toolkit for working with the Buildkite API
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- sudo: false
2
- before_install: gem install bundler
3
- rvm:
4
- - '2.1'
5
- - '2.2'
6
-