veyor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|