Acelere o tempo de preparação da compilação do Travis-CI em 800%

/// ===

atualização 2013-10-22

Travis-Ci introduz cache – http://about.travis-ci.org/docs/user/caching/
Até agora, só está disponível para repositórios privados, ainda vale a pena olhar para isso em vez da solução personalizada que eu tenho redigidos nesse documento. Obrigado por pessoal do Travis-CI por finalmente implementá-lo 🙂

/// ===

Queremos começar a usar os projetos travis-ci de nossos clientes. Infelizmente, a preparação da compilação estava demorando 8 minutos e é o tempo antes do início do teste. Outra desvantagem disso é o fato de que as compilações de paralelismo não têm valor (cada instância levará 8 minutos antes de executar os testes), e realmente queremos usar esse recurso Travis-Ci ( http://about.travis-ci.org/ blog / 2012-11-28-acelerando-seus-testes-paralelizando-os / )

Então, gastei o último dia para melhorar isso – resultado: a preparação está levando menos de um minuto 🙂

aqui está nosso arquivo travis.yml final

language: ruby
rvm
:
- 1.9.3
env
:
- TAG_FILTER=~js DB=postgres RAILS_ENV=test
- TAG_FILTER=js DB=postgres RAILS_ENV=test
install
: touch ~/do_not_run_bundle
before_script
:
- "./script/travis/setup_database.sh &"
- "./script/travis/configure_rspec.sh &"
- "./script/travis/bundle_install.sh"
- "bundle exec ruby script/travis/bundle_cache.rb &"
script
: "bundle exec rspec --tag $TAG_FILTER && sleep 1"
notifications
:
email
: false

1) Caching .bundle directory

a tarefa mais demorada era instalar gems (6 minutos), então pensamos como seria se armazenássemos em cache o diretório .bundle 🙂 O diretório compactado tem cerca de 110 MB – baixá-lo de us-west-1 leva 30 segundos em média, de eu-west-1 50 segundos. O mais rápido é manter seu arquivo no servidor hetzner, se você tiver algum (5 segundos em média).
Caso deseje criptografar suas credenciais, leia – http://about.travis-ci.org/docs/user/encryption-keys/

script / travis / bundle _ cache.sh

require 'fog/storage'
file_name
= 'bundle.tgz'
s3_file_path
= "travis/#{file_name}"
local_file_path
= file_name
storage
= Fog::Storage.new({
:provider => 'AWS',
:aws_access_key_id => '<KEY>',
:aws_secret_access_key => '<ACCESS_KEY>',
:region => 'us-west-1'
})

# prepare archive

`rm -rf #{local_file_path}`
`tar -cjf bundle.tgz .bundle`

# put on s3

bucket
= storage.directories.new(key: '<YOUR_BUCKET>')
file
= File.open(local_file_path)
bucket
.files.create(body: file.read, key: s3_file_path, public: true)

3 coisas que vale a pena observar são
* fazemos upload do arquivo com permissão pública, graças a isso podemos fazer download do arquivo com autorização (o diretório .bundle geralmente não é segredo)
* preparamos o cache em segundo plano – para não atrasar o início dos testes
* pulamos instalação de gemas que são usadas apenas em desenvolvimento

script / travis / bundle _ install.sh

#!/bin/sh

curl
-o bundle.tgz https://<HOST_NAME>/travis/bundle.tgz
tar
-xf bundle.tgz

bundle install
--path .bundle --quiet --without=development

exit 0

2) carregar banco de dados sem rake

apenas configure para despejar seu esquema no formato sql e você economizará outros 60 segundos 🙂

config / application.rb

config.active_record.schema_format = :sql

script / travis / setup _ database.sh

#!/bin/sh

psql
-c 'create database <DB_NAME>;' -U postgres
psql
-U postgres -q -d <DB_NAME> -f db/structure.sql
cp
-f config/travis/database.yml config/database.yml

3) configuração separada para rspec (spec_helper.rb .rspec)

em desenvolvimento, usamos spork – para ci não usamos, então removemos algumas linhas desnecessárias de spec_helper e preparamos um arquivo separado (mais legível do que muitos ifs) – isso lhe dará alguns segundos a mais de velocidade

É definitivamente possível escrever melhor – ainda vejo que vale a pena compartilhar essa ideia. Espero que em algum dia travis-ci dê a possibilidade de usar algum tipo de diretório de cache entre compilações prontas para uso 🙂 (para usuários Pro – peça suporte se você ainda não tiver: support@travis-ci.com )

Há mais um desafio que eu tenho com o Travis-CI, mas isso é algo para o próximo feriado 🙂