Skip to content

Commit

Permalink
Cache the test app to S3 on Travis
Browse files Browse the repository at this point in the history
  • Loading branch information
seanlinsley committed Apr 22, 2014
1 parent f83e222 commit 0412f48
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 88 deletions.
9 changes: 5 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
language: ruby
install:
- time ./script/bundle_cache download
- time bundle install --without development --path=~/.bundle
- time ./script/bundle_cache upload
script:
- time ./script/travis_cache download_bundle
- time bundle install --without development --path=./bundle
- time ./script/travis_cache download_app
- time bundle exec rake setup
- time ./script/travis_cache upload
script:
- time bundle exec rake test_with_coveralls
rvm:
- 1.9.3
Expand Down
84 changes: 0 additions & 84 deletions script/bundle_cache

This file was deleted.

99 changes: 99 additions & 0 deletions script/travis_cache
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env ruby

require 'base64'
require 'digest'
require 'openssl'
require 'shellwords'

URL = 'https://s3.amazonaws.com/ActiveAdmin'
PREFIX = "ruby_#{RUBY_VERSION}-rails_#{ENV.fetch 'RAILS'}-"
ID = ENV.fetch 'AWS_S3_ID'
SECRET = ENV.fetch 'AWS_S3_SECRET'

def download_bundle
s3 :save, file: 'bundle.sha2', as: 'remote_bundle.sha2'
s3 :save, file: 'bundle.tgz', as: 'remote_bundle.tgz', untar: true
end

# Don't use an existing archive if the Gemfile.lock changed
def download_app
s3 :save, file: 'app.sha2', as: 'remote_app.sha2'
if !digest_changed?('Gemfile.lock', 'remote_bundle.sha2', 'bundle.sha2') &&
!digest_changed?('spec/support', 'remote_app.sha2', 'app.sha2')
s3 :save, file: 'app.tgz', as: 'remote_app.tgz', untar: 'spec'
end
end

def upload
[ ['Gemfile.lock', 'bundle', 'bundle'],
['spec/support', 'app', 'spec/rails']
].each do |to_check, name, to_save|
puts "=> Checking #{to_check} for changes"
if digest_changed? to_check, "remote_#{name}.sha2", "#{name}.sha2"
puts " => Changes found"

puts " => Creating an archive"
`tar -cjf #{to_save} #{name}.tgz`

puts " => Uploading a new archive"
s3 :upload, file: "#{name}.tgz"
s3 :upload, file: "#{name}.sha2"
else
puts " => There were no changes, doing nothing"
end
end
end

def digest_changed?(to_check, old_digest_file, new_digest_file)
if File.exists? new_digest_file
digest = File.read new_digest_file
else
# Supports a single file, as well as a folder
files = Dir[to_check, "#{to_check}/**/*"].reject{ |f| File.directory? f }
content = files.map{ |f| File.read f }.join
digest = Digest::SHA2.hexdigest content
File.write new_digest_file, digest
end

old_digest = File.read old_digest_file if File.exists? old_digest_file

digest != old_digest
end

def sign(secret, to_sign, digest = 'sha1')
Base64.strict_encode64 OpenSSL::HMAC.digest OpenSSL::Digest.new(digest), secret, to_sign
end

# s3 :list
# s3 :upload, file: 'foo'
# s3 :find, file: 'foo'
# s3 :save, file: 'foo', as: 'bar'
# s3 :save, file: 'foo', untar: true
# s3 :save, file: 'foo', untar: 'another_directory'
def s3(action, options = {})
verb = {list: :get, upload: :put, find: :get, save: :get}.fetch action
file = PREFIX + options.fetch(:file) unless action == :list
extra_arg = {
upload: ->{ %[-T "#{file}"] },
save: ->{ %[-o "#{options[:as]}"] if options[:as] }
}[action].call
if options[:untar]
do_after = "&& tar -xf #{options[:as] || file}"
do_after << " -C #{options[:untar]}" if options[:untar].is_a? String
end

now = Time.now.strftime "%a, %d %b %Y %H:%M:%S %z"
signature = sign SECRET, "#{verb.upcase}\n\n\n#{now}\n/ActiveAdmin/#{file}"
headers = ["Authorization: AWS #{ID}:#{signature}", "Date: #{now}"].map do |h|
"-H #{Shellwords.escape h}"
end.join ' '

output = `curl -f #{headers} #{extra_arg} #{URL}/#{file} #{do_after}`
[$?.success?, output]
end

if %w[download_bundle download_app upload].include? ARGV[0]
send ARGV[0]
else
raise "unexpected argument(s): #{ARGV}"
end

0 comments on commit 0412f48

Please sign in to comment.