module Hoe::Travis
The travis plugin for Hoe
manages your .travis.yml file for you in a clean and extensible way you can use across projects or by through integration with other Hoe
plugins.
Setup¶ ↑
The travis plugin can be used without this setup. By following these instructions you can enable and disable a travis-ci hook for your ruby projects from rake through rake travis:enable
and rake travis:disable
.
Github API access¶ ↑
Set your github username and password in your ~/.gitconfig:
git config --global github.user username git config --global github.password password chmod 600 ~/.gitconfig
Travis
token¶ ↑
As of this writing there isn't an easy way to retrieve the travis token programmatically. You can find your travis token at travis-ci.org/profile underneath your github username and email address.
To set this in your hoerc run rake config_hoe
and edit the “token:” entry.
Tasks¶ ↑
You can extend the following tasks in your Rakefile or Hoe
plugins to add extra checks to travis-ci.
- travis
-
Run by travis-ci. Defaults to running your tests and checking your manifest file. You can run this locally to check what travis-ci will do.
- travis:before
-
Runs as the before_script on travis-ci. Defaults to installing your development dependencies.
- travis:check
-
Lints your .travis.yml.
- travis:edit
-
Pulls up your .travis.yml in your EDITOR and lints your configuration upon saving. Does not allow you to save a bad .travis.yml.
- travis:generate
-
Generates a .travis.yml based on your
Hoe
spec and .hoerc then brings it up in your EDITOR and lints upon saving. Does not allow you to save a bad .travis.yml. - travis:enable
-
Enables the travis hook on github.com. Requires further setup as described below.
- travis:disable
-
Disables the travis hook on github.com. Requires further setup as described below.
- travis:force
-
Forces a travis-ci run, equivalent to clicking the “test” button on the travis-ci hook page.
Hoe
Configuration¶ ↑
The Hoe
configuration is used to generate the .travis.yml. After you've generated a .travis.yml you may any changes you wish to it and the following defaults will not apply. If you have multiple projects, setting up a common custom configuration in ~/.hoerc can save you time.
The following default configuration options are provided under the “travis” key of the Hoe
configuration (accessible from Hoe#with_config):
- before_script
-
Array of commands run before the test script. Defaults to installing hoe-travis and its dependencies (rake and hoe) followed by running the travis:before rake task.
- script
-
Runs the travis rake task.
- token
-
Your travis-ci token. See @Setup above
- versions
-
The versions of ruby used to run your tests. Note that if you have multiruby installed, your installed versions will be preferred over the defaults that come with hoe-travis.
In your .hoerc you may provide a “notifications” key such as:
travis: notifications: irc: "irc.example#your_channel"
Notifications specified in a .hoerc will override the default email notifications created from the Hoe
spec.
Constants
- VERSION
This version of
Hoe::Travis
Public Instance Methods
Adds travis tasks to rake
# File lib/hoe/travis.rb, line 152 def define_travis_tasks desc "Runs your tests for travis" task :travis => %w[test check_manifest] namespace :travis do desc "Run by travis-ci after running the default checks" task :after => %w[ travis:fake_config ] desc "Run by travis-ci before running the default checks" task :before => %w[ install_plugins travis:install_deps ] desc "Lint your .travis.yml" task :check do abort unless travis_yml_check '.travis.yml' end desc "Disables the travis-ci hook" task :disable do travis_disable end desc "Brings .travis.yml up in your EDITOR then checks it on save" task :edit do Tempfile.open 'travis.yml' do |io| io.write File.read '.travis.yml' io.rewind ok = travis_yml_edit io.path travis_yml_write io.path if ok end end desc "Enables the travis-ci hook" task :enable do travis_enable end desc "Triggers the travis-ci hook" task :force do travis_force end task :fake_config do travis_fake_config end desc "Generates a new .travis.yml and allows you to customize it with your EDITOR" task :generate do Tempfile.open 'travis.yml' do |io| io.write travis_yml_generate io.rewind ok = travis_yml_edit io.path travis_yml_write io.path if ok end end task :install_deps do (extra_deps + extra_dev_deps).each do |dep| begin gem(*dep) rescue Gem::LoadError name, req, = dep install_gem name, req, false end end end end end
Extracts the travis after_script from your .hoerc
# File lib/hoe/travis.rb, line 233 def travis_after_script with_config { |config, _| config['travis']['after_script'] or Hoe::DEFAULT_CONFIG['travis']['after_script'] } end
Extracts the travis before_script from your .hoerc
# File lib/hoe/travis.rb, line 243 def travis_before_script with_config { |config, _| config['travis']['before_script'] or Hoe::DEFAULT_CONFIG['travis']['before_script'] } end
Disables travis-ci for this repository.
# File lib/hoe/travis.rb, line 253 def travis_disable _, repo, = travis_github_check if hook = travis_have_hook?(repo) then travis_edit_hook repo, hook, false if hook['active'] end end
Edits the travis hook
definition for repo
(from the github URL) to enable
(default) or disable it.
# File lib/hoe/travis.rb, line 265 def travis_edit_hook repo, hook, enable = true patch = unless Net::HTTP.const_defined? :Patch then # Ruby 1.8 Class.new Net::HTTPRequest do |c| c.const_set :METHOD, 'PATCH' c.const_set :REQUEST_HAS_BODY, true c.const_set :RESPONSE_HAS_BODY, true end else Net::HTTP::Patch end id = hook['id'] body = { 'name' => hook['name'], 'active' => enable, 'config' => hook['config'] } travis_github_request "/repos/#{repo}/hooks/#{id}", body, patch end
Enables travis-ci for this repository.
# File lib/hoe/travis.rb, line 292 def travis_enable user, repo, token = travis_github_check if hook = travis_have_hook?(repo) then travis_edit_hook repo, hook unless hook['active'] else travis_make_hook repo, user, token end end
Creates a fake config file for use on travis-ci. Running this with a pre-existing .hoerc has no effect.
# File lib/hoe/travis.rb, line 306 def travis_fake_config fake_hoerc = File.expand_path '~/.hoerc' return if File.exist? fake_hoerc config = { 'exclude' => /\.(git|travis)/ } open fake_hoerc, 'w' do |io| YAML.dump config, io end end
Forces the travis-ci hook
# File lib/hoe/travis.rb, line 321 def travis_force user, repo, token = travis_github_check unless hook = travis_have_hook?(repo) hook = travis_make_hook repo, user, token end travis_github_request "/repos/#{repo}/hooks/#{hook['id']}/test", {} end
Ensures you have proper setup for editing the github travis hook
# File lib/hoe/travis.rb, line 334 def travis_github_check user = `git config github.user`.chomp abort <<-ABORT unless user Set your github user and token in ~/.gitconfig See: ri Hoe::Travis and \thttp://help.github.com/set-your-user-name-email-and-github-token/ ABORT `git config remote.origin.url` =~ /^git@github\.com:(.*).git$/ repo = $1 abort <<-ABORT unless repo Unable to determine your github repository. Expected \"git@github.com:[repo].git\" as your remote origin ABORT token = with_config do |config, _| config['travis']['token'] end abort 'Please set your travis token via `rake config_hoe` - ' \ 'See: ri Hoe::Travis' if token =~ /FIX/ return user, repo, token end
Makes a github request at path
with an optional body
Hash which will be sent as JSON. The default method
without a body is a GET request, otherwise POST.
# File lib/hoe/travis.rb, line 367 def travis_github_request(path, body = nil, method = body ? Net::HTTP::Post : Net::HTTP::Get) begin require 'json' rescue LoadError => e raise unless e.message.end_with? 'json' abort 'Please gem install json like modern ruby versions have' end uri = @github_api + path http = Net::HTTP.new uri.host, uri.port http.use_ssl = uri.scheme.downcase == 'https' http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.cert_store = OpenSSL::X509::Store.new http.cert_store.set_default_paths req = method.new uri.request_uri if body then req.content_type = 'application/json' req.body = JSON.dump body end user = `git config github.user`.chomp pass = `git config github.password`.chomp req.basic_auth user, pass res = http.request req body = JSON.parse res.body if res.class.body_permitted? unless Net::HTTPSuccess === res then message = ": #{res['message']}" if body raise "github API error #{res.code}#{message}" end body end
Returns the github hook definition for the “travis” hook on repo
(from the github URL), if it exists.
# File lib/hoe/travis.rb, line 412 def travis_have_hook? repo body = travis_github_request "/repos/#{repo}/hooks" body.find { |hook| hook['name'] == 'travis' } end
Creates a travis hook for user
on the given repo
(from the github URL) that uses the users token
.
# File lib/hoe/travis.rb, line 422 def travis_make_hook repo, user, token body = { "name" => "travis", "active" => true, "config" => { "domain" => "", "token" => token, "user" => user, } } travis_github_request "/repos/#{repo}/hooks", body end
Creates the travis notifications hash from the developers for your project. The developer will be merged with the travis notifications from your .hoerc.
# File lib/hoe/travis.rb, line 441 def travis_notifications email = @email.compact email.delete '' default_notifications = { 'email' => email } notifications = with_config do |config, _| config['travis']['notifications'] or Hoe::DEFAULT_CONFIG['travis']['notifications'] end || {} default_notifications.merge notifications end
Extracts the travis script from your .hoerc
# File lib/hoe/travis.rb, line 457 def travis_script with_config { |config, _| config['travis']['script'] or Hoe::DEFAULT_CONFIG['travis']['script'] } end
Determines the travis versions from multiruby, if available, or your .hoerc.
# File lib/hoe/travis.rb, line 468 def travis_versions if have_gem? 'ZenTest' and File.exist?(File.expand_path('~/.multiruby')) then `multiruby -v` =~ /^Passed: (.*)/ $1.split(', ').map do |ruby_release| ruby_release.sub(/-.*/, '') end else with_config do |config, _| config['travis']['versions'] or Hoe::DEFAULT_CONFIG['travis']['versions'] end end.sort end
Submits the travis.yml in path
to travis-ci.org for linting. If the file is OK true is returned, otherwise the issues are displayed on $stderr and false is returned.
# File lib/hoe/travis.rb, line 489 def travis_yml_check path require 'net/http' post_body = { 'content' => File.read(path), } req = Net::HTTP::Post.new '/lint' req.set_form post_body, 'multipart/form-data' cert_store = OpenSSL::X509::Store.new cert_store.set_default_paths http = Net::HTTP.new 'api.travis-ci.org', 443 http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.cert_store = cert_store res = http.request req unless Net::HTTPOK === res then warn "Unable to lint #{path}: #{res.body}" return false end require 'json' response = JSON.parse res.body lint = response.fetch 'lint' warnings = lint.fetch 'warnings' return true if warnings.empty? warnings.each do |warning| keys = warning.fetch 'key' message = warning.fetch 'message' if keys.empty? then warn message else warn "For #{keys.join ', '}: #{message}" end end return false rescue Net::HTTPError => e warn "Unable to lint #{path}: #{e.message}" return false end
Loads the travis.yml in path
in your EDITOR (or vi if unset). Upon saving the travis.yml is checked by linting. If any problems are found you will be asked to retry the edit.
If the edited travis.yml is OK true is returned, otherwise false.
# File lib/hoe/travis.rb, line 550 def travis_yml_edit path loop do editor = ENV['EDITOR'] || 'vi' system "#{editor} #{path}" break true if travis_yml_check path abort unless $stdout.tty? print "\nRetry edit? [Yn]\n> " $stdout.flush break false if $stdin.gets =~ /\An/i end end
Generates a travis.yml from .hoerc, the Hoe
spec and the default configuration.
# File lib/hoe/travis.rb, line 571 def travis_yml_generate travis_yml = { 'after_script' => travis_after_script, 'before_script' => travis_before_script, 'language' => 'ruby', 'notifications' => travis_notifications, 'rvm' => travis_versions, 'script' => travis_script, } travis_yml.each do |key, value| travis_yml.delete key unless value end YAML.dump travis_yml end
Writes the travis.yml in source_file
to .travis.yml in the current directory. Overwrites an existing .travis.yml.
# File lib/hoe/travis.rb, line 592 def travis_yml_write source_file open source_file do |source_io| open '.travis.yml', 'w' do |dest_io| dest_io.write source_io.read end end end