veyor 0.1.0
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 +7 -0
- data/.gitignore +48 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +3 -0
- data/CONDUCT.md +25 -0
- data/Gemfile +3 -0
- data/LICENSE +7 -0
- data/README.md +101 -0
- data/Rakefile +41 -0
- data/bin/veyor +478 -0
- data/lib/veyor.rb +206 -0
- data/lib/veyor/error.rb +22 -0
- data/lib/veyor/faraday.rb +71 -0
- data/lib/veyor/helpers/configuration.rb +26 -0
- data/lib/veyor/request.rb +105 -0
- data/lib/veyor/utils.rb +32 -0
- data/lib/veyor/version.rb +3 -0
- data/veyor.gemspec +35 -0
- metadata +213 -0
data/lib/veyor.rb
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
require "veyor/version"
|
2
|
+
require "veyor/request"
|
3
|
+
require 'veyor/utils'
|
4
|
+
require 'rexml/document'
|
5
|
+
require 'rexml/xpath'
|
6
|
+
|
7
|
+
# @!macro veyor_params
|
8
|
+
# @param account [String] An Appveyor account name
|
9
|
+
# @param project [String] An Appveyor project name
|
10
|
+
# @param verbose [Boolean] Print request headers to stdout. Default: false
|
11
|
+
|
12
|
+
# @!macro history_params
|
13
|
+
# @param limit [Fixnum] Records per page
|
14
|
+
# @param start_build [String] Build version to start at
|
15
|
+
# @param branch [String] Branch name
|
16
|
+
|
17
|
+
# @!macro veyor_options
|
18
|
+
# @param options [Hash] Hash of options for configuring the request, passed on to Faraday.new
|
19
|
+
# - timeout [Fixnum] open/read timeout Integer in seconds
|
20
|
+
# - open_timeout [Fixnum] read timeout Integer in seconds
|
21
|
+
# - proxy [Hash] hash of proxy options
|
22
|
+
# - uri [String] Proxy Server URI
|
23
|
+
# - user [String] Proxy server username
|
24
|
+
# - password [String] Proxy server password
|
25
|
+
# - params_encoder [Hash] not sure what this is
|
26
|
+
# - bind [Hash] A hash with host and port values
|
27
|
+
# - boundary [String] of the boundary value
|
28
|
+
# - oauth [Hash] A hash with OAuth details
|
29
|
+
|
30
|
+
##
|
31
|
+
# `Veyor` - The top level module for using methods
|
32
|
+
# to access veyor APIs
|
33
|
+
#
|
34
|
+
# The following methods are provided:
|
35
|
+
# * `Veyor.project` - get project by name, branch, or build version
|
36
|
+
# * `Veyor.projects` - get all projects
|
37
|
+
# * `Veyor.project_history` - get project history
|
38
|
+
# * `Veyor.project_deployments` - get project deployments
|
39
|
+
# * `Veyor.project_settings` - get project settings
|
40
|
+
# * `Veyor.build_start` - start a build
|
41
|
+
# * `Veyor.build_cancel` - cancel a build
|
42
|
+
#
|
43
|
+
# More will be added in future `veyor` versions
|
44
|
+
#
|
45
|
+
# @see https://www.appVeyor.com/docs/api/ for
|
46
|
+
# detailed description of the Appveyor API
|
47
|
+
|
48
|
+
module Veyor
|
49
|
+
extend Configuration
|
50
|
+
|
51
|
+
define_setting :account_name, ENV['APPVEYOR_ACCOUNT_NAME']
|
52
|
+
define_setting :account_token, ENV['APPVEYOR_API_TOKEN']
|
53
|
+
define_setting :base_url, "https://ci.appVeyor.com"
|
54
|
+
|
55
|
+
##
|
56
|
+
# Fetch projects
|
57
|
+
#
|
58
|
+
# @!macro veyor_options
|
59
|
+
# @param verbose [Boolean] Print request headers to stdout. Default: false
|
60
|
+
# @return [Array] An array of hashes
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# require 'veyor'
|
64
|
+
# Veyor.projects()
|
65
|
+
def self.projects(options: nil, verbose: false)
|
66
|
+
route = prep_route('projects', nil, nil, nil, nil)
|
67
|
+
Request.new(route, nil, nil, options, verbose).get
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Get a single project - gets the latest build
|
72
|
+
#
|
73
|
+
# @!macro veyor_options
|
74
|
+
# @!macro veyor_params
|
75
|
+
# @param branch [String] Branch name
|
76
|
+
# @param version [String] Project version
|
77
|
+
# @return [Array] An array of hashes
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# require 'veyor'
|
81
|
+
# # if account_name already set up
|
82
|
+
# Veyor.project(project: 'cowsay')
|
83
|
+
#
|
84
|
+
# # if not, or to fetch a project not under your account
|
85
|
+
# Veyor.project(account: 'sckott', project: 'cowsay')
|
86
|
+
#
|
87
|
+
# # get by branch
|
88
|
+
# Veyor.project(project: 'cowsay', branch: 'changeback')
|
89
|
+
#
|
90
|
+
# # get by version
|
91
|
+
# Veyor.project(project: 'cowsay', version: '1.0.692')
|
92
|
+
def self.project(account: nil, project: nil, branch: nil,
|
93
|
+
version: nil, options: nil, verbose: false)
|
94
|
+
|
95
|
+
route = prep_route('projects', get_account(account), project, branch, version)
|
96
|
+
Request.new(route, nil, nil, options, verbose).get
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Get project history
|
101
|
+
#
|
102
|
+
# @!macro veyor_options
|
103
|
+
# @!macro veyor_params
|
104
|
+
# @!macro history_params
|
105
|
+
# @return [Array] An array of hashes
|
106
|
+
#
|
107
|
+
# @example
|
108
|
+
# require 'veyor'
|
109
|
+
# # get project history
|
110
|
+
# x = Veyor.project_history(project: 'cowsay')
|
111
|
+
# x['builds'].collect { |x| x['status'] }
|
112
|
+
#
|
113
|
+
# # limit results
|
114
|
+
# Veyor.project_history(project: 'cowsay', limit: 3)
|
115
|
+
#
|
116
|
+
# # start by a certain build version
|
117
|
+
# Veyor.project_history(project: 'cowsay', start_build: 2872582)
|
118
|
+
#
|
119
|
+
# # get by branch
|
120
|
+
# Veyor.project_history(project: 'cowsay', branch: 'changeback')
|
121
|
+
def self.project_history(account: nil, project: nil, limit: 10,
|
122
|
+
start_build: nil, branch: nil, options: nil, verbose: false)
|
123
|
+
|
124
|
+
route = sprintf('/projects/%s/%s/history', get_account(account), project)
|
125
|
+
args = prep_args(limit, start_build, branch)
|
126
|
+
Request.new(route, args, nil, options, verbose).get
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Get project deployments
|
131
|
+
#
|
132
|
+
# @!macro veyor_options
|
133
|
+
# @!macro veyor_params
|
134
|
+
# @return [Array] An array of hashes
|
135
|
+
#
|
136
|
+
# @example
|
137
|
+
# require 'veyor'
|
138
|
+
# # get project history
|
139
|
+
# x = Veyor.project_deployments(project: 'cowsay')
|
140
|
+
# x['deployments']
|
141
|
+
def self.project_deployments(account: nil, project: nil, options: nil, verbose: false)
|
142
|
+
route = sprintf('/projects/%s/%s/deployments', get_account(account), project)
|
143
|
+
Request.new(route, nil, nil, options, verbose).get
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Get project settings
|
148
|
+
#
|
149
|
+
# @!macro veyor_options
|
150
|
+
# @!macro veyor_params
|
151
|
+
# @param yaml [Boolean] Return yaml version of project settings. Default: false
|
152
|
+
# @return [Array] An array of hashes
|
153
|
+
#
|
154
|
+
# @example
|
155
|
+
# require 'veyor'
|
156
|
+
# # get project history
|
157
|
+
# x = Veyor.project_settings(project: 'cowsay')
|
158
|
+
# x['settings']
|
159
|
+
# x['settings']['configuration']
|
160
|
+
# # get yaml data
|
161
|
+
# x = Veyor.project_settings(project: 'cowsay', yaml: true)
|
162
|
+
def self.project_settings(account: nil, project: nil, yaml: false, options: nil, verbose: false)
|
163
|
+
route = sprintf('/projects/%s/%s/settings', get_account(account), project)
|
164
|
+
if yaml
|
165
|
+
route = route + '/yaml'
|
166
|
+
end
|
167
|
+
Request.new(route, nil, nil, options, verbose).get
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Start build of branch of most recent commit
|
172
|
+
#
|
173
|
+
# @!macro veyor_options
|
174
|
+
# @!macro veyor_params
|
175
|
+
# @param branch [String] Branch name
|
176
|
+
# @return [Array] An array of hashes
|
177
|
+
#
|
178
|
+
# @example
|
179
|
+
# require 'veyor'
|
180
|
+
# # start a build
|
181
|
+
# x = Veyor.build_start(project: 'cowsay')
|
182
|
+
def self.build_start(account: nil, project:, branch: 'master', options: nil, verbose: false)
|
183
|
+
body = { :accountName => get_account(account),
|
184
|
+
:projectSlug => project, :branch => branch }
|
185
|
+
Request.new('builds', nil, body, options, verbose).post
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# Cancel a build
|
190
|
+
#
|
191
|
+
# @!macro veyor_options
|
192
|
+
# @!macro veyor_params
|
193
|
+
# @param version [String] Project version
|
194
|
+
# @return [Array] An array of hashes
|
195
|
+
#
|
196
|
+
# @example
|
197
|
+
# require 'veyor'
|
198
|
+
# # start a build
|
199
|
+
# x = Veyor.build_start(project: 'cowsay')
|
200
|
+
# x = Veyor.build_cancel(project: 'cowsay', version: '1.0.697')
|
201
|
+
def self.build_cancel(account: nil, project:, version:, options: nil, verbose: false)
|
202
|
+
route = sprintf('/builds/%s/%s/%s', get_account(account), project, version)
|
203
|
+
Request.new(route, nil, nil, options, verbose).delete
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
data/lib/veyor/error.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Veyor
|
2
|
+
# Custom error class for rescuing from all Veyor errors
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# Raised when Crossref returns the HTTP status code 400
|
6
|
+
class BadRequest < Error; end
|
7
|
+
|
8
|
+
# Raised when Crossref returns the HTTP status code 404
|
9
|
+
class NotFound < Error; end
|
10
|
+
|
11
|
+
# Raised when Crossref returns the HTTP status code 500
|
12
|
+
class InternalServerError < Error; end
|
13
|
+
|
14
|
+
# Raised when Crossref returns the HTTP status code 502
|
15
|
+
class BadGateway < Error; end
|
16
|
+
|
17
|
+
# Raised when Crossref returns the HTTP status code 503
|
18
|
+
class ServiceUnavailable < Error; end
|
19
|
+
|
20
|
+
# Raised when Crossref returns the HTTP status code 504
|
21
|
+
class GatewayTimeout < Error; end
|
22
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
# @private
|
5
|
+
module FaradayMiddleware
|
6
|
+
# @private
|
7
|
+
class RaiseHttpException < Faraday::Middleware
|
8
|
+
def call(env)
|
9
|
+
@app.call(env).on_complete do |response|
|
10
|
+
case response[:status].to_i
|
11
|
+
when 400
|
12
|
+
raise Veyor::BadRequest, error_message_400(response)
|
13
|
+
when 404
|
14
|
+
raise Veyor::NotFound, error_message_400(response)
|
15
|
+
when 500
|
16
|
+
raise Veyor::InternalServerError, error_message_500(response, "Something is technically wrong.")
|
17
|
+
when 502
|
18
|
+
raise Veyor::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
|
19
|
+
when 503
|
20
|
+
raise Veyor::ServiceUnavailable, error_message_500(response, "Crossref is rate limiting your requests.")
|
21
|
+
when 504
|
22
|
+
raise Veyor::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(app)
|
28
|
+
super app
|
29
|
+
@parser = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def error_message_400(response)
|
35
|
+
"\n #{response[:method].to_s.upcase} #{response[:url].to_s}\n Status #{response[:status]}#{error_body(response[:body])}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def error_body(body)
|
39
|
+
if not body.nil? and not body.empty? and body.kind_of?(String)
|
40
|
+
if is_json?(body)
|
41
|
+
body = ::MultiJson.load(body)
|
42
|
+
if body['message'].nil?
|
43
|
+
body = nil
|
44
|
+
elseif body['message'].length == 1
|
45
|
+
body = body['message']
|
46
|
+
else
|
47
|
+
body = body['message'].collect { |x| x['message'] }.join('; ')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if body.nil?
|
53
|
+
nil
|
54
|
+
else
|
55
|
+
": #{body}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def error_message_500(response, body=nil)
|
60
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s}: #{[response[:status].to_s + ':', body].compact.join(' ')}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def is_json?(string)
|
64
|
+
MultiJson.load(string)
|
65
|
+
return true
|
66
|
+
rescue MultiJson::ParseError => e
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# taken from: https://viget.com/extend/easy-gem-configuration-variables-with-defaults
|
2
|
+
module Configuration
|
3
|
+
|
4
|
+
def configuration
|
5
|
+
yield self
|
6
|
+
end
|
7
|
+
|
8
|
+
def define_setting(name, default = nil)
|
9
|
+
class_variable_set("@@#{name}", default)
|
10
|
+
define_class_method "#{name}=" do |value|
|
11
|
+
class_variable_set("@@#{name}", value)
|
12
|
+
end
|
13
|
+
define_class_method name do
|
14
|
+
class_variable_get("@@#{name}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def define_class_method(name, &block)
|
21
|
+
(class << self; self; end).instance_eval do
|
22
|
+
define_method name, &block
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require "multi_json"
|
4
|
+
|
5
|
+
require 'veyor/faraday'
|
6
|
+
require "veyor/error"
|
7
|
+
require 'veyor/utils'
|
8
|
+
require 'veyor/helpers/configuration'
|
9
|
+
|
10
|
+
##
|
11
|
+
# veyor::Request
|
12
|
+
#
|
13
|
+
# Class to perform HTTP requests to the Appveyor API
|
14
|
+
module Veyor
|
15
|
+
class Request #:nodoc:
|
16
|
+
|
17
|
+
attr_accessor :route
|
18
|
+
attr_accessor :args
|
19
|
+
attr_accessor :body
|
20
|
+
attr_accessor :options
|
21
|
+
attr_accessor :verbose
|
22
|
+
|
23
|
+
def initialize(route, args, body, options, verbose)
|
24
|
+
self.route = route
|
25
|
+
self.args = args
|
26
|
+
self.body = body
|
27
|
+
self.options = options
|
28
|
+
self.verbose = verbose
|
29
|
+
|
30
|
+
self.perform
|
31
|
+
end
|
32
|
+
|
33
|
+
def get
|
34
|
+
res = _veyor_get(self.route, self.args)
|
35
|
+
return parse_result(res)
|
36
|
+
end
|
37
|
+
|
38
|
+
def post
|
39
|
+
res = _veyor_post(self.route, self.body)
|
40
|
+
return parse_result(res)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete
|
44
|
+
return _veyor_delete(self.route).status
|
45
|
+
end
|
46
|
+
|
47
|
+
def perform
|
48
|
+
if self.args.nil?
|
49
|
+
self.args = {}
|
50
|
+
end
|
51
|
+
|
52
|
+
if verbose
|
53
|
+
$conn = Faraday.new(:url => Veyor.base_url, :request => options) do |f|
|
54
|
+
f.request :url_encoded
|
55
|
+
f.response :logger
|
56
|
+
f.adapter Faraday.default_adapter
|
57
|
+
# f.use FaradayMiddleware::RaiseHttpException
|
58
|
+
end
|
59
|
+
else
|
60
|
+
$conn = Faraday.new(:url => Veyor.base_url, :request => options) do |f|
|
61
|
+
f.request :url_encoded
|
62
|
+
f.adapter Faraday.default_adapter
|
63
|
+
# f.use FaradayMiddleware::RaiseHttpException
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
$conn.headers[:user_agent] = make_ua
|
68
|
+
$conn.headers["X-USER-AGENT"] = make_ua
|
69
|
+
end
|
70
|
+
|
71
|
+
def _veyor_get(route, opts)
|
72
|
+
$conn.get do |req|
|
73
|
+
req.url '/api/' + route
|
74
|
+
req.params = opts
|
75
|
+
req.headers["Content-Type"] = "application/json"
|
76
|
+
req.headers["Authorization"] = "Bearer " + Veyor.account_token
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def _veyor_post(route, body)
|
81
|
+
$conn.post do |req|
|
82
|
+
req.url '/api/' + route
|
83
|
+
req.body = MultiJson.dump(body)
|
84
|
+
req.headers["Content-Type"] = "application/json"
|
85
|
+
req.headers["Authorization"] = "Bearer " + Veyor.account_token
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def _veyor_delete(route)
|
90
|
+
$conn.delete do |req|
|
91
|
+
req.url '/api/' + route
|
92
|
+
req.headers["Authorization"] = "Bearer " + Veyor.account_token
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_result(z)
|
97
|
+
if z.headers['content-type'].match('json').nil?
|
98
|
+
return z.body
|
99
|
+
else
|
100
|
+
return MultiJson.load(z.body)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/veyor/utils.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
def make_ua
|
2
|
+
requa = 'Faraday/v' + Faraday::VERSION
|
3
|
+
habua = 'Veyor/v' + Veyor::VERSION
|
4
|
+
return requa + ' ' + habua
|
5
|
+
end
|
6
|
+
|
7
|
+
def prep_args(limit, start_build, branch)
|
8
|
+
args = { recordsNumber: limit, startBuildId: start_build, branch: branch }
|
9
|
+
opts = args.delete_if { |k, v| v.nil? }
|
10
|
+
return opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_account(x)
|
14
|
+
if x.nil?
|
15
|
+
x = Veyor.account_name
|
16
|
+
if x.nil?
|
17
|
+
raise 'no account name found - one must be supplied'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
return x
|
21
|
+
end
|
22
|
+
|
23
|
+
def prep_route(route, account, project, branch, version)
|
24
|
+
if branch.nil? && version.nil?
|
25
|
+
route = sprintf('%s/%s/%s', route, account, project)
|
26
|
+
elsif !branch.nil? && version.nil?
|
27
|
+
route = sprintf('%s/%s/%s/branch/%s', route, account, project, branch)
|
28
|
+
elsif branch.nil? && !version.nil?
|
29
|
+
route = sprintf('%s/%s/%s/build/%s', route, account, project, version)
|
30
|
+
end
|
31
|
+
return route
|
32
|
+
end
|