travis 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class CloudControl < Service
7
+ description "automatic deployment to cloudControl"
8
+
9
+ def run
10
+ deploy 'cloudcontrol' do |config|
11
+ config['email'] = ask("cloudControl email: ").to_s
12
+ config['password'] = ask("cloudControl password: ") { |q| q.echo = "*" }.to_s
13
+ app = ask("cloudControl application: ") { |q| q.default = repository.name }.to_s
14
+ dep = ask("cloudControl deployment: ") { |q| q.default = "default" }.to_s
15
+ config['deployment'] = "#{app}/#{dep}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class CloudFoundry < Service
7
+ description "automatic deployment to Cloud Foundry"
8
+
9
+ def run
10
+ deploy 'provider' => 'cloudfoundry' do |config|
11
+ target_file = File.expand_path('.cf/target', Dir.home)
12
+ config['target'] ||= File.read(target_file).chomp if File.exist? target_file
13
+ config['target'] ||= ask("Cloud Foundry target: ").to_s
14
+ config['username'] ||= ask("Cloud Foundry user name: ").to_s
15
+ config['password'] ||= ask("Cloud Foundry password: ") { |q| q.echo = "*" }.to_s
16
+ config['organization'] ||= ask("Cloud Foundry organization: ").to_s
17
+ config['space'] ||= ask("Cloud Foundry space: ").to_s
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'travis/cli/setup'
2
+ require 'yaml'
3
+
4
+ module Travis
5
+ module CLI
6
+ class Setup
7
+ class EngineYard < Service
8
+ description "automatic deployment to Engine Yard"
9
+
10
+ def run
11
+ deploy 'provider' => 'engineyard' do |config|
12
+ eyrc = File.expand_path(".eyrc", Dir.home)
13
+ config['api_key'] = YAML.load_file(eyrc)["api_token"] if File.exists?(eyrc)
14
+ config['api_key'] = ask("API token: ") { |q| q.echo = "*" }.to_s unless config['api_key']
15
+ env = ask("Environment (optional): ").to_s
16
+ config['environment'] = env unless env.empty?
17
+ migrate = agree("Run migrations on deploy? ") { |q| q.default = 'yes' }
18
+ config['migrate'] = ask("Migration command: ") { |q| q.default = "rake db:migrate" } if migrate
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class Heroku < Service
7
+ description "automatic deployment to Heroku"
8
+
9
+ def run
10
+ deploy 'heroku' do |config|
11
+ config['api_key'] = `heroku auth:token 2>/dev/null`.strip
12
+ config['api_key'] = ask("Heroku API token: ") { |q| q.echo = "*" }.to_s if config['api_key'].empty?
13
+ config['app'] = `heroku apps:info 2>/dev/null`.scan(/^=== (.+)$/).flatten.first
14
+ config['app'] = ask("Heroku application name: ") { |q| q.default = repository.name }.to_s if config['app'].nil?
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'travis/cli/setup'
2
+ require 'json'
3
+
4
+ module Travis
5
+ module CLI
6
+ class Setup
7
+ class Nodejitsu < Service
8
+ description "automatic deployment to Nodejitsu"
9
+
10
+ def run
11
+ deploy 'nodejitsu' do |config|
12
+ jitsu_file = File.expand_path('.jitsuconf', ENV['HOME'])
13
+
14
+ if File.exist? jitsu_file
15
+ jitsu_conf = JSON.parse(File.read(jitsu_file))
16
+ config['user'] = jitsu_conf['username']
17
+ config['api_key'] = jitsu_conf['apiToken']
18
+ end
19
+
20
+ config['user'] ||= ask("Nodejitsu user: ").to_s
21
+ config['api_key'] ||= ask("Nodejitsu API token: ") { |q| q.echo = "*" }.to_s
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class OpenShift < Service
7
+ description "automatic deployment to OpenShfit"
8
+
9
+ def run
10
+ deploy 'openshift' do |config|
11
+ config['user'] = ask("OpenShift user: ").to_s
12
+ config['password'] = ask("OpenShift password: ") { |q| q.echo = "*" }.to_s
13
+ config['app'] = ask("OpenShift application name: ") { |q| q.default = repository.name }.to_s
14
+ config['domain'] = ask("OpenShift domain: ").to_s
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class RubyGems < Service
7
+ description "automatic release to RubyGems"
8
+
9
+ def run
10
+ deploy 'rubygems', 'release' do |config|
11
+ authorization_file = File.expand_path('.rubygems/authorization', ENV['HOME'])
12
+ credentials_file = File.expand_path('.gem/credentials', ENV['HOME'])
13
+
14
+ config['api_key'] ||= File.read(authorization_file) if File.exist? authorization_file
15
+ config['api_key'] ||= YAML.load_file(credentials_file)[:rubygems_api_key] if File.exist? credentials_file
16
+ config['api_key'] ||= ask("RubyGems API token: ") { |q| q.echo = "*" }.to_s
17
+ config['gem'] ||= ask("Gem name: ") { |q| q.default = repository.name }.to_s
18
+
19
+ on("Release only tagged commits? ", config, 'tags' => true)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class SauceConnect < Service
7
+ description "Sauce Connet addon for Sauce Labs integration"
8
+ service_name "sauce_connect"
9
+
10
+ def run
11
+ travis_config['addons'] ||= {}
12
+ configure 'sauce_connect', {}, travis_config['addons'] do |config|
13
+ config['username'] = ask("Sauce Labs user: ").to_s
14
+ config['access_key'] = ask("Sauce Labs access key: ") { |q| q.echo = "*" }.to_s
15
+ encrypt(config, 'access_key') if agree("Encrypt access key? ") { |q| q.default = 'yes' }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,73 @@
1
+ require 'travis/cli/setup'
2
+
3
+ module Travis
4
+ module CLI
5
+ class Setup
6
+ class Service
7
+ def self.normalized_name(string)
8
+ string.to_s.downcase.gsub(/[^a-z]/, '')
9
+ end
10
+
11
+ def self.description(description = nil)
12
+ @description ||= ""
13
+ @description = description if description
14
+ @description
15
+ end
16
+
17
+ def self.service_name(service_name = nil)
18
+ @service_name ||= normalized_name(name[/[^:]+$/])
19
+ @service_name = service_name if service_name
20
+ @service_name
21
+ end
22
+
23
+ def self.known_as?(name)
24
+ normalized_name(service_name) == normalized_name(name)
25
+ end
26
+
27
+ attr_accessor :command
28
+
29
+ def initialize(command)
30
+ @command = command
31
+ end
32
+
33
+ def method_missing(*args, &block)
34
+ @command.send(*args, &block)
35
+ end
36
+
37
+ private
38
+
39
+ def on(question, config, condition)
40
+ return unless agree(question) { |q| q.default = 'yes' }
41
+ config['on'] ||= {}
42
+ config['on'].merge! condition
43
+ end
44
+
45
+ def encrypt(config, key)
46
+ encrypted = repository.encrypt(config.fetch(key))
47
+ config[key] = { 'secure' => encrypted }
48
+ end
49
+
50
+ def configure(key, value = {}, config = travis_config)
51
+ error "#{key} section already exists in .travis.yml, run with --force to override" if config.include? key and not force?
52
+ yield(config[key] = value)
53
+ end
54
+
55
+ def branch
56
+ @branch ||= `git rev-parse --symbolic-full-name --abbrev-ref HEAD`.chomp
57
+ end
58
+
59
+ def deploy(provider, verb = "deploy")
60
+ configure('deploy', 'provider' => provider) do |config|
61
+ yield config
62
+
63
+ on("#{verb.capitalize} only from #{repository.slug}? ", config, 'repo' => repository.slug)
64
+ on("#{verb.capitalize} from #{branch} branch? ", config, 'branch' => branch) if branch != 'master' and branch != 'HEAD'
65
+
66
+ encrypt(config, 'password') if config['password'] and agree("Encrypt Password? ") { |q| q.default = 'yes' }
67
+ encrypt(config, 'api_key') if config['api_key'] and agree("Encrypt API key? ") { |q| q.default = 'yes' }
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -48,7 +48,7 @@ module Travis
48
48
  include States
49
49
 
50
50
  # @!parse attr_reader :slug, :description
51
- attributes :slug, :description, :last_build_id, :last_build_number, :last_build_state, :last_build_duration, :last_build_started_at, :last_build_finished_at
51
+ attributes :slug, :description, :last_build_id, :last_build_number, :last_build_state, :last_build_duration, :last_build_started_at, :last_build_finished_at, :github_language
52
52
  inspect_info :slug
53
53
 
54
54
  time :last_build_finished_at, :last_build_started_at
@@ -1,4 +1,5 @@
1
1
  require 'travis/client'
2
+ require 'travis/version'
2
3
 
3
4
  require 'faraday'
4
5
  require 'faraday_middleware'
@@ -16,12 +17,13 @@ module Travis
16
17
  class Session
17
18
  SSL_OPTIONS = { :ca_file => File.expand_path("../../cacert.pem", __FILE__) }
18
19
  include Methods
19
- attr_reader :connection, :headers, :access_token, :instruments, :faraday_adapter
20
+ attr_reader :connection, :headers, :access_token, :instruments, :faraday_adapter, :agent_info
20
21
 
21
22
  def initialize(options = Travis::Client::ORG_URI)
22
23
  @headers = {}
23
24
  @cache = {}
24
25
  @instruments = []
26
+ @agent_info = []
25
27
  @config = nil
26
28
  @faraday_adapter = defined?(Typhoeus) ? :typhoeus : :net_http
27
29
 
@@ -29,20 +31,26 @@ module Travis
29
31
  options.each_pair { |key, value| public_send("#{key}=", value) }
30
32
 
31
33
  raise ArgumentError, "neither :uri nor :connection specified" unless connection
32
- headers['Accept'] ||= 'application/json; version=2'
34
+ headers['Accept'] = 'application/json; version=2'
35
+ set_user_agent
33
36
  end
34
37
 
35
38
  def uri
36
39
  connection.url_prefix.to_s if connection
37
40
  end
38
41
 
42
+ def agent_info=(info)
43
+ @agent_info = [info].flatten.freeze
44
+ set_user_agent
45
+ end
46
+
39
47
  def uri=(uri)
40
48
  clear_cache!
41
49
  self.connection = Faraday.new(:url => uri, :ssl => SSL_OPTIONS) do |faraday|
42
50
  faraday.request :url_encoded
43
- faraday.response :json
44
- faraday.response :follow_redirects
45
- faraday.response :raise_error
51
+ faraday.response :json
52
+ faraday.response :follow_redirects
53
+ faraday.response :raise_error
46
54
  faraday.adapter(*faraday_adapter)
47
55
  end
48
56
  end
@@ -50,6 +58,7 @@ module Travis
50
58
  def faraday_adapter=(adapter)
51
59
  @faraday_adapter = adapter
52
60
  self.uri &&= uri
61
+ set_user_agent
53
62
  end
54
63
 
55
64
  def access_token=(token)
@@ -181,6 +190,19 @@ module Travis
181
190
 
182
191
  private
183
192
 
193
+ def set_user_agent
194
+ adapter = Array === faraday_adapter ? faraday_adapter.first : faraday_adapter
195
+ adapter = adapter.to_s.capitalize.gsub(/_http_(.)/) { "::HTTP::#{$1.upcase}" }.gsub(/_http/, '::HTTP')
196
+ headers['User-Agent'] = "Travis/#{Travis::VERSION} (#{Travis::Tools::System.description(agent_info)}) Faraday/#{Faraday::VERSION} #{adapter}/#{adapter_version(adapter)}"
197
+ end
198
+
199
+ def adapter_version(adapter)
200
+ version = Object.const_get(adapter).const_get("VERSION")
201
+ [*version].join('.')
202
+ rescue Exception
203
+ "unknown"
204
+ end
205
+
184
206
  def instrumented(name, *args)
185
207
  name = [name, *args.map(&:inspect)].join(" ") if args.any?
186
208
  result = nil
@@ -0,0 +1,69 @@
1
+ require "travis/tools/system"
2
+ require "terminal-notifier"
3
+ require "cgi"
4
+
5
+ module Travis
6
+ module Tools
7
+ module Notification
8
+ extend self
9
+ DEFAULT = [:osx, :growl, :libnotify]
10
+
11
+ def new(*list)
12
+ list.concat(DEFAULT) if list.empty?
13
+ notification = list.map { |n| get(n) }.detect { |n| n.available? }
14
+ raise ArgumentError, "no notification system found (looked for #{list.join(", ")})" unless notification
15
+ notification
16
+ end
17
+
18
+ def get(name)
19
+ const = constants.detect { |c| c.to_s[/[^:]+$/].downcase == name.to_s }
20
+ raise ArgumentError, "unknown notifications type %p" % name unless const
21
+ const_get(const).new
22
+ end
23
+
24
+ class Dummy
25
+ def notify(title, body)
26
+ end
27
+
28
+ def available?
29
+ true
30
+ end
31
+ end
32
+
33
+ class OSX
34
+ def notify(title, body)
35
+ TerminalNotifier.notify(body, :title => title)
36
+ end
37
+
38
+ def available?
39
+ System.mac? and TerminalNotifier.available?
40
+ end
41
+ end
42
+
43
+ class Growl
44
+ def initialize
45
+ @command = "growlnotify"
46
+ end
47
+
48
+ def notify(title, body)
49
+ system "%s -m %p %p >/dev/null" [@command, title, body]
50
+ end
51
+
52
+ def available?
53
+ system "which #{@command} >/dev/null 2>/dev/null" unless System.windows?
54
+ end
55
+ end
56
+
57
+ class LibNotify < Growl
58
+ def initialize
59
+ @command = "notify-send"
60
+ @expire_time = 10_000
61
+ end
62
+
63
+ def notify(title, body)
64
+ system @command, "--expire-time=#{@expire_time}", title, CGI.escapeHTML(body)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -6,6 +6,44 @@ module Travis
6
6
  def windows?
7
7
  File::ALT_SEPARATOR == "\\"
8
8
  end
9
+
10
+ def mac?
11
+ RUBY_PLATFORM =~ /darwin/i
12
+ end
13
+
14
+ def linux?
15
+ RUBY_PLATFORM =~ /linux/i
16
+ end
17
+
18
+ def os
19
+ @os ||= windows? ? "Windows" : `uname`.chomp
20
+ end
21
+
22
+ def ruby_engine
23
+ defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
24
+ end
25
+
26
+ def ruby_version
27
+ "%s-p%s" % [RUBY_VERSION, RUBY_PATCHLEVEL]
28
+ end
29
+
30
+ def ruby
31
+ case ruby_engine
32
+ when 'ruby' then "Ruby #{ruby_version}"
33
+ when 'jruby' then "JRuby #{JRUBY_VERSION} like Ruby #{ruby_version}"
34
+ when 'rbx' then "Rubinius #{Rubinius.version[/\d\S+/]} like Ruby #{ruby_version}"
35
+ else "#{ruby_engine} like Ruby #{ruby_version}"
36
+ end
37
+ end
38
+
39
+ def rubygems
40
+ return "no RubyGems" unless defined? Gem
41
+ "RubyGems #{Gem::VERSION}"
42
+ end
43
+
44
+ def description(*args)
45
+ [ os, ruby, rubygems, *args.flatten].compact.uniq.join("; ")
46
+ end
9
47
  end
10
48
  end
11
49
  end