Compare commits

..

1 Commits

Author SHA1 Message Date
Hiro Asari
bcdee3e941 Update travis-core
In particular, to have https://github.com/travis-ci/travis-core/pull/499
2015-12-02 08:52:09 -05:00
530 changed files with 3189 additions and 21603 deletions

View File

@ -1,2 +1,3 @@
https://github.com/heroku/heroku-buildpack-ruby.git
https://github.com/drogus/last-commit-sha-buildpack.git
https://github.com/ryandotsmith/nginx-buildpack.git

4
.gitignore vendored
View File

@ -4,9 +4,11 @@ config/nginx.conf
config/skylight.yml
tmp/
log/
logs/
vendor
.yardoc
.coverage
*.env
.ruby-gemset

3
.rspec
View File

@ -1,3 +0,0 @@
--require spec_helper
--colour
--tty

View File

@ -1 +1 @@
2.2.3
2.1.5

View File

@ -2,7 +2,7 @@ language: ruby
sudo: false
rvm: 2.2.3
rvm: 2.1.5
env:
global:
@ -18,4 +18,4 @@ services:
- redis
before_script:
- 'RAILS_ENV=test bundle exec rake db:create --trace'
- 'RAILS_ENV=test bundle exec rake db:create db:migrate --trace'

22
Gemfile
View File

@ -1,14 +1,14 @@
source 'https://rubygems.org'
gemspec
ruby '2.1.6' if ENV.key?('DYNO')
gem 's3', github: 'travis-ci/s3'
gem 'travis-core', github: 'travis-ci/travis-core'
gem 'travis-support', github: 'travis-ci/travis-support'
gem 'travis-amqp', github: 'travis-ci/travis-amqp'
gem 'travis-config', '~> 0.1.0'
gem 'travis-settings', github: 'travis-ci/travis-settings'
gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs'
gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs', require: nil
gem 'travis-yaml', github: 'travis-ci/travis-yaml'
gem 'mustermann', github: 'rkh/mustermann'
gem 'sinatra'
@ -16,11 +16,11 @@ gem 'sinatra-contrib', require: nil #github: 'sinatra/sinatra-contrib', require:
gem 'active_model_serializers'
gem 'unicorn'
gem 'sentry-raven'
gem 'sentry-raven', github: 'getsentry/raven-ruby'
gem 'yard-sinatra', github: 'rkh/yard-sinatra'
gem 'rack-contrib'
gem 'rack-contrib', github: 'rack/rack-contrib'
gem 'rack-cache', github: 'rtomayko/rack-cache'
gem 'rack-attack', '5.0.0.beta1'
gem 'rack-attack'
gem 'gh'
gem 'bunny', '~> 0.8.0'
gem 'dalli'
@ -31,22 +31,14 @@ gem 'micro_migrations'
gem 'simplecov'
gem 'skylight', '~> 0.6.0.beta.1'
gem 'stackprof'
gem 'netaddr'
gem 'jemalloc'
gem 'customerio'
group :development, :test do
gem 'travis-migrations', github: 'travis-ci/travis-migrations'
end
group :test do
gem 'rspec', '~> 2.13'
gem 'rspec-its'
gem 'factory_girl', '~> 2.4.0'
gem 'mocha', '~> 0.12'
gem 'database_cleaner', '~> 0.8.0'
gem 'timecop', '~> 0.8.0'
end
group :development do

View File

@ -1,13 +1,28 @@
GIT
remote: git://github.com/eric/metriks-librato_metrics.git
revision: 2c124f024fd2e34378260cd24b0e8687ff9bd196
revision: ccbeb751ec5fc4edfe446d8a67a423b96ebe86c7
specs:
metriks-librato_metrics (1.0.5)
metriks-librato_metrics (1.0.2)
metriks (>= 0.9.9.6)
GIT
remote: git://github.com/getsentry/raven-ruby.git
revision: 84392e5db701f0b5c66802aab9cc82ef9a5ad830
specs:
sentry-raven (0.10.1)
faraday (>= 0.7.6)
uuidtools
GIT
remote: git://github.com/rack/rack-contrib.git
revision: 1b11346d729efd88b274cd7f704e0bca9eb3de7a
specs:
rack-contrib (1.2.0)
rack (>= 0.9.1)
GIT
remote: git://github.com/rkh/mustermann.git
revision: 9611951c5c789ad8227a740ae142c157a8bf7401
revision: fa22e2cf4cfdb57f452c366eac66f241827b7e9c
specs:
mustermann (0.4.0)
tool (~> 0.2)
@ -21,9 +36,9 @@ GIT
GIT
remote: git://github.com/rtomayko/rack-cache.git
revision: 2d6618172c39c53dceab2e2946d87496154f3e52
revision: f96febebed7700337e8c362403b081e45b8e4f13
specs:
rack-cache (1.6.1)
rack-cache (1.5.1)
rack (>= 0.4)
GIT
@ -34,31 +49,34 @@ GIT
proxies (~> 0.2.0)
GIT
remote: git://github.com/travis-ci/travis-amqp.git
revision: 3966b3651adfd1c544f53d49d5986ac16cd9c4bc
remote: git://github.com/travis-ci/travis-core.git
revision: 6ce83e05afc07d412195d226b77a896e2b652146
specs:
travis-amqp (0.0.1)
GIT
remote: git://github.com/travis-ci/travis-migrations.git
revision: dc432e45354287c617c3ae07a72e9e3c4be012cd
specs:
travis-migrations (0.0.2)
GIT
remote: git://github.com/travis-ci/travis-settings.git
revision: d510e63b6c6f059cccae141c265e7a0c7236d1fd
specs:
travis-settings (0.0.1)
activemodel
virtus
travis-core (0.0.1)
actionmailer (~> 3.2.19)
activerecord (~> 3.2.19)
coder (~> 0.4.0)
data_migrations (~> 0.0.1)
gh
hashr (~> 0.0.19)
metriks (~> 0.9.7)
multi_json
pusher (~> 0.14.0)
railties (~> 3.2.19)
rake
redis (~> 3.0)
rollout (~> 1.1.0)
s3 (~> 0.3)
simple_states (~> 1.0.0)
thor (~> 0.14.6)
travis-config (~> 0.1.0)
virtus (~> 1.0.0)
GIT
remote: git://github.com/travis-ci/travis-sidekiqs.git
revision: c5d4a4abc6c3737f9c43d3333efb94daa18b9fbb
revision: 21a2fee158e25252dd78f5fa31e81b4f6583be23
specs:
travis-sidekiqs (0.0.1)
redis-namespace
sidekiq
GIT
@ -69,7 +87,7 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-yaml.git
revision: 032caed23af8ed1ed55e9204bb91316f3ada2f74
revision: 9ebe328e7546c696dd374a8cf773d93276f98e4f
specs:
travis-yaml (0.2.0)
@ -77,36 +95,28 @@ PATH
remote: .
specs:
travis-api (0.0.1)
activerecord (~> 3.2.19)
coder (~> 0.4.0)
composite_primary_keys (~> 5.0)
google-api-client (~> 0.9.4)
hashr
memcachier
multi_json
mustermann (~> 0.4)
pg
pusher (~> 0.14.0)
rack-contrib (~> 1.1)
rack-ssl (~> 1.3, >= 1.3.3)
railties (~> 3.2.19)
redcarpet (~> 2.1)
redis (~> 3.0)
rollout (~> 1.1.0)
simple_states (~> 1.0.0)
sinatra (~> 1.3)
sinatra-contrib (~> 1.3)
tool
travis-core
travis-support
useragent
virtus (~> 1.0.0)
GEM
remote: https://rubygems.org/
specs:
actionpack (3.2.22.2)
activemodel (= 3.2.22.2)
activesupport (= 3.2.22.2)
actionmailer (3.2.22)
actionpack (= 3.2.22)
mail (~> 2.5.4)
actionpack (3.2.22)
activemodel (= 3.2.22)
activesupport (= 3.2.22)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
@ -114,20 +124,20 @@ GEM
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
active_model_serializers (0.9.5)
active_model_serializers (0.9.0)
activemodel (>= 3.2)
activemodel (3.2.22.2)
activesupport (= 3.2.22.2)
activemodel (3.2.22)
activesupport (= 3.2.22)
builder (~> 3.0.0)
activerecord (3.2.22.2)
activemodel (= 3.2.22.2)
activesupport (= 3.2.22.2)
activerecord (3.2.22)
activemodel (= 3.2.22)
activesupport (= 3.2.22)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activesupport (3.2.22.2)
activesupport (3.2.22)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
addressable (2.4.0)
addressable (2.3.8)
arel (3.0.3)
atomic (1.1.99)
avl_tree (1.1.3)
@ -135,34 +145,38 @@ GEM
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
backports (3.6.8)
backports (3.6.7)
builder (3.0.4)
bunny (0.8.0)
celluloid (0.16.0)
timers (~> 4.0.0)
coder (0.4.0)
coderay (1.1.1)
coderay (1.1.0)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
composite_primary_keys (5.0.14)
activerecord (~> 3.2.0, >= 3.2.9)
concurrent-ruby (1.0.2)
connection_pool (2.2.0)
customerio (1.0.0)
multi_json (~> 1.0)
dalli (2.7.6)
connection_pool (2.1.1)
dalli (2.7.2)
data_migrations (0.0.1)
activerecord
rake
database_cleaner (0.8.0)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.2.5)
docile (1.1.5)
dotenv (0.7.0)
equalizer (0.0.11)
erubis (2.7.0)
factory_girl (2.4.2)
activesupport
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
foreman (0.82.0)
thor (~> 0.19.1)
ffi (1.9.6)
foreman (0.64.0)
dotenv (~> 0.7.0)
thor (>= 0.13.6)
gh (0.14.0)
addressable
backports
@ -170,47 +184,24 @@ GEM
multi_json (~> 1.0)
net-http-persistent (>= 2.7)
net-http-pipeline
git-version-bump (0.15.1)
google-api-client (0.9.8)
addressable (~> 2.3)
googleauth (~> 0.5)
httpclient (~> 2.7)
hurley (~> 0.1)
memoist (~> 0.11)
mime-types (>= 1.6)
representable (~> 2.3.0)
retriable (~> 2.0)
thor (~> 0.19)
googleauth (0.5.1)
faraday (~> 0.9)
jwt (~> 1.4)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
hashr (0.0.22)
hike (1.2.3)
hitimes (1.2.4)
httpclient (2.8.0)
hurley (0.2)
hitimes (1.2.3)
httpclient (2.7.0.1)
i18n (0.7.0)
ice_nine (0.11.2)
ice_nine (0.11.1)
jemalloc (1.0.1)
journey (1.0.4)
json (1.8.3)
jwt (1.5.4)
kgio (2.10.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
little-plugger (1.1.4)
logging (2.1.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
kgio (2.9.2)
listen (1.0.3)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
memcachier (0.0.2)
memoist (0.14.0)
metaclass (0.0.4)
method_source (0.8.2)
metriks (0.9.9.6)
@ -223,15 +214,14 @@ GEM
mime-types (1.25.1)
mocha (0.14.0)
metaclass (~> 0.0.1)
multi_json (1.12.1)
multi_json (1.11.2)
multipart-post (2.0.0)
net-http-persistent (2.9.4)
net-http-pipeline (1.0.1)
netaddr (1.5.1)
os (0.9.6)
pg (0.18.4)
pg (0.18.2)
polyglot (0.3.5)
proxies (0.2.1)
pry (0.10.3)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
@ -241,40 +231,36 @@ GEM
pusher-signature (~> 0.1.8)
pusher-signature (0.1.8)
rack (1.4.7)
rack-attack (5.0.0.beta1)
rack-attack (4.2.0)
rack
rack-contrib (1.4.0)
git-version-bump (~> 0.15)
rack (~> 1.4)
rack-protection (1.5.3)
rack
rack-ssl (1.3.4)
rack
rack-test (0.6.3)
rack (>= 1.0)
railties (3.2.22.2)
actionpack (= 3.2.22.2)
activesupport (= 3.2.22.2)
railties (3.2.22)
actionpack (= 3.2.22)
activesupport (= 3.2.22)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.16.0)
raindrops (0.13.0)
rake (0.9.6)
rb-fsevent (0.9.7)
rb-inotify (0.9.7)
rb-fsevent (0.9.4)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rb-kqueue (0.2.3)
ffi (>= 0.5.0)
rdoc (3.12.2)
json (~> 1.4)
redcarpet (2.3.0)
redis (3.3.0)
redis-namespace (1.5.2)
redis (3.2.2)
redis-namespace (1.5.1)
redis (~> 3.0, >= 3.0.4)
representable (2.3.0)
uber (~> 0.0.7)
rerun (0.11.0)
listen (~> 3.0)
retriable (2.1.0)
rerun (0.8.2)
listen (~> 1.0.3)
rollout (1.1.0)
rspec (2.99.0)
rspec-core (~> 2.99.0)
@ -283,42 +269,33 @@ GEM
rspec-core (2.99.2)
rspec-expectations (2.99.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-its (1.0.1)
rspec-core (>= 2.99.0.beta1)
rspec-expectations (>= 2.99.0.beta1)
rspec-mocks (2.99.4)
ruby_dep (1.3.1)
sentry-raven (1.0.0)
faraday (>= 0.7.6)
sidekiq (4.1.2)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
redis (~> 3.2, >= 3.2.1)
signet (0.7.2)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
rspec-mocks (2.99.2)
sidekiq (3.3.0)
celluloid (>= 0.16.0)
connection_pool (>= 2.0.0)
json
redis (>= 3.0.6)
redis-namespace (>= 1.3.1)
simple_states (1.0.1)
activesupport
hashr (~> 0.0.10)
simplecov (0.11.2)
simplecov (0.9.1)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
multi_json (~> 1.0)
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
sinatra (1.4.6)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
sinatra-contrib (1.4.7)
sinatra-contrib (1.4.2)
backports (>= 2.0)
multi_json
rack-protection
rack-test
sinatra (~> 1.4.0)
tilt (>= 1.3, < 3)
skylight (0.6.2.beta.2)
tilt (~> 1.3)
skylight (0.6.0.beta.1)
activesupport (>= 3.0.0)
slop (3.6.0)
sprockets (2.2.3)
@ -326,20 +303,25 @@ GEM
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
stackprof (0.2.9)
thor (0.19.1)
stackprof (0.2.7)
thor (0.14.6)
thread_safe (0.3.5)
tilt (1.4.1)
timecop (0.8.1)
timers (4.0.1)
hitimes
tool (0.2.3)
travis-config (0.1.4)
hashr (~> 0.0)
tzinfo (0.3.49)
uber (0.0.15)
unicorn (5.1.0)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.45)
unicorn (4.8.3)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
useragent (0.16.7)
useragent (0.13.3)
uuidtools (2.1.5)
virtus (1.0.5)
axiom-types (~> 0.1)
coercible (~> 1.0)
@ -353,7 +335,6 @@ PLATFORMS
DEPENDENCIES
active_model_serializers
bunny (~> 0.8.0)
customerio
dalli
database_cleaner (~> 0.8.0)
factory_girl (~> 2.4.0)
@ -365,34 +346,26 @@ DEPENDENCIES
micro_migrations
mocha (~> 0.12)
mustermann!
netaddr
pry
rack-attack (= 5.0.0.beta1)
rack-attack
rack-cache!
rack-contrib
rack-contrib!
rake (~> 0.9.2)
rb-fsevent (~> 0.9.1)
rerun
rspec (~> 2.13)
rspec-its
s3!
sentry-raven
sentry-raven!
simplecov
sinatra
sinatra-contrib
skylight (~> 0.6.0.beta.1)
stackprof
timecop (~> 0.8.0)
travis-amqp!
travis-api!
travis-config (~> 0.1.0)
travis-migrations!
travis-settings!
travis-core!
travis-sidekiqs!
travis-support!
travis-yaml!
unicorn
yard-sinatra!
BUNDLED WITH
1.12.5

View File

@ -1,4 +1,3 @@
web: ./script/server
console: bundle exec je ./script/console
sidekiq: bundle exec je sidekiq -c 4 -r ./lib/travis/sidekiq.rb -q build_cancellations, -q build_restarts, -q job_cancellations, -q job_restarts
start_crons: ./script/start_crons

View File

@ -4,68 +4,49 @@ This is the app running on https://api.travis-ci.org/
## Requirements
You will need the following packages to get travis-api to work:
1. PostgreSQL 9.3 or higher
2. Bundler
3. Redis Server
4. *Optional:* RabbitMQ Server
5. Nginx -
*If working in Ubuntu please install nginx manually from source: Download and extract latest nginx version, open a terminal in extracted folder and then run the following:*
```sh-session
$ sudo apt-get install libpcre3 libpcre3-dev
$ auto/configure --user=$USER
$ make
$ sudo make install
$ sudo ln -s /usr/local/nginx/sbin/nginx /bin/nginx
```
1. Redis
1. RabbitMQ
1. Nginx *NB: If working on Ubuntu please install Nginx manually from source. [This guide](http://www.rackspace.com/knowledge_center/article/ubuntu-and-debian-installing-nginx-from-source) is helpful but make sure you install the [latest stable version](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/#stable), include the user name on your ubuntu machine when compiling (add `--user=[yourusername]` as an option when running `./configure`), and don't follow any subsequent server configuration steps. Travis-api will start and configure its own nginx server when run locally.
## Installation
### Setup
```sh-session
$ bundle install
```
$ bundle install
### Database setup
*You might need to create a role first. For this you should run the following:*
1. `rake db:create db:migrate`
2. for testing 'RAILS_ENV=test bundle exec rake db:create db:migrate --trace'
1. Clone `travis-logs` and copy the `logs` database (assume the PostgreSQL user is `postgres`):
```sh-session
$ sudo -u postgres psql -c "CREATE USER yourusername WITH SUPERUSER PASSWORD 'yourpassword'"
cd ..
git clone https://github.com/travis-ci/travis-logs.git
cd travis-logs
rvm jruby do bundle exec rake db:migrate # `travis-logs` requires JRuby
psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_development
pg_dump -t logs travis_logs_development | psql -U postgres travis_development
```
NB detail for how `rake` sets up the database can be found in the `Rakefile`. In the `namespace :db` block you will see the database name is configured using the environment variable RAILS_ENV. If you are using a different configuration you will have to make your own adjustments.
Repeat the database steps for `RAILS_ENV=test`.
```sh-session
$ RAILS_ENV=development bundle exec rake db:create
$ RAILS_ENV=test bundle exec rake db:create
```
#### Optional
Clone `travis-logs` and copy the `logs` database (assume the PostgreSQL user is `postgres`):
```sh-session
$ cd ..
$ git clone https://github.com/travis-ci/travis-logs.git
$ cd travis-logs
$ rvm jruby do bundle exec rake db:migrate # `travis-logs` requires JRuby
$ psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_development
$ pg_dump -t logs travis_logs_development | psql -U postgres travis_development
$ RAILS_ENV=test bundle exec rake db:create
$ pushd ../travis-logs
$ RAILS_ENV=test rvm jruby do bundle exec rake db:migrate
$ psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_test
$ pg_dump -t logs travis_logs_test | psql -U postgres travis_test
$ popd
RAILS_ENV=test rake db:create db:structure:load
pushd ../travis-logs
RAILS_ENV=test rvm jruby do bundle exec rake db:migrate
psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_test
pg_dump -t logs travis_logs_test | psql -U postgres travis_test
popd
```
### Run tests
```sh-session
$ bundle exec rake
```
$ rake spec
### Run the server
```sh-session
$ bundle exec script/server
```
If you have problems with Nginx because the websocket is already in use, try restarting your computer.
$ bundle exec script/server
## Contributing
@ -77,4 +58,5 @@ If you have problems with Nginx because the websocket is already in use, try res
### API documentation
v3 documentation can be found at https://developer.travis-ci.org which is a repository that can be found at https://github.com/travis-pro/developer
We use source code comments to add documentation. If the server is running, you
can browse an HTML documenation at [`/docs`](http://localhost:5000/docs).

149
Rakefile
View File

@ -1,34 +1,127 @@
namespace :db do
env = ENV["RAILS_ENV"]
if env != 'production'
desc "Create and migrate the #{env} database"
task :create do
sh "createdb travis_#{env}" rescue nil
sh "psql -q travis_#{env} < #{Gem.loaded_specs['travis-migrations'].full_gem_path}/db/structure.sql"
require 'bundler/setup'
require 'travis'
require 'travis/engine'
begin
ENV['SCHEMA'] = File.expand_path('../db/schema.rb', $:.detect { |p| p.include?('travis-core') })
require 'micro_migrations'
rescue LoadError
# we can't load micro migrations on production
end
require 'travis'
begin
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new
task default: :spec
rescue LoadError
warn "could not load rspec"
end
desc "generate gemspec"
task 'travis-api.gemspec' do
content = File.read 'travis-api.gemspec'
fields = {
authors: `git shortlog -sn`.scan(/[^\d\s].*/),
email: `git shortlog -sne`.scan(/[^<]+@[^>]+/),
files: `git ls-files`.split("\n").reject { |f| f =~ /^(\.|Gemfile)/ }
}
fields.each do |field, values|
updated = " s.#{field} = ["
updated << values.map { |v| "\n %p" % v }.join(',')
updated << "\n ]"
content.sub!(/ s\.#{field} = \[\n( .*\n)* \]/, updated)
end
File.open('travis-api.gemspec', 'w') { |f| f << content }
end
task default: 'travis-api.gemspec'
tasks_path = File.expand_path('../lib/tasks/*.rake', __FILE__)
Dir.glob(tasks_path).each { |r| import r }
module ActiveRecord
class Migration
class << self
attr_accessor :disable_ddl_transaction
end
# Disable DDL transactions for this migration.
def self.disable_ddl_transaction!
@disable_ddl_transaction = true
end
def disable_ddl_transaction # :nodoc:
self.class.disable_ddl_transaction
end
end
end
# begin
# require 'rspec'
# require 'rspec/core/rake_task'
# RSpec::Core::RakeTask.new(:spec)
#
# RSpec::Core::RakeTask.new(:spec_core) do |t|
# t.pattern = 'spec_core/**{,/*/**}/*_spec.rb'
# end
#
# task :default => [:spec]
# rescue LoadError => e
# puts e.inspect
# end
class Migrator
def use_transaction?(migration)
!migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
end
# not sure how else to include the spec_helper
namespace :spec do
desc 'Run all specs'
task :all do
sh 'bundle exec rspec -r spec_helper spec'
def ddl_transaction(migration, &block)
if use_transaction?(migration)
Base.transaction { block.call }
else
block.call
end
end
def migrate(&block)
current = migrations.detect { |m| m.version == current_version }
target = migrations.detect { |m| m.version == @target_version }
if target.nil? && @target_version && @target_version > 0
raise UnknownMigrationVersionError.new(@target_version)
end
start = up? ? 0 : (migrations.index(current) || 0)
finish = migrations.index(target) || migrations.size - 1
runnable = migrations[start..finish]
# skip the last migration if we're headed down, but not ALL the way down
runnable.pop if down? && target
ran = []
runnable.each do |migration|
if block && !block.call(migration)
next
end
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
seen = migrated.include?(migration.version.to_i)
# On our way up, we skip migrating the ones we've already migrated
next if up? && seen
# On our way down, we skip reverting the ones we've never migrated
if down? && !seen
migration.announce 'never migrated, skipping'; migration.write
next
end
begin
ddl_transaction(migration) do
migration.migrate(@direction)
record_version_state_after_migrating(migration.version)
end
ran << migration
rescue => e
canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace
end
end
ran
end
end
class MigrationProxy
delegate :disable_ddl_transaction, to: :migration
end
end
task :default => :'spec:all'

View File

@ -20,3 +20,4 @@ development:
test:
<<: *defaults
database: travis_test

View File

@ -9,9 +9,9 @@ events {
}
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 512;
gzip on;
gzip_comp_level 2;
gzip_min_length 512;
server_tokens off;

Binary file not shown.

View File

@ -1,67 +0,0 @@
require 'pusher'
require 'travis/support'
require 'travis/support/database'
require 'travis/redis_pool'
require 'travis/errors'
module Travis
class << self
def services=(services)
@services = services
end
def services
@services ||= Travis::Services
end
end
require 'travis/model'
require 'travis/task'
require 'travis/event'
require 'travis/api/serialize'
require 'travis/config/defaults'
require 'travis/features'
require 'travis/github'
require 'travis/notification'
require 'travis/services'
class UnknownRepository < StandardError; end
class GithubApiError < StandardError; end
class AdminMissing < StandardError; end
class RepositoryMissing < StandardError; end
class LogAlreadyRemoved < StandardError; end
class AuthorizationDenied < StandardError; end
class JobUnfinished < StandardError; end
class << self
def setup(options = {})
@config = Config.load(*options[:configs])
@redis = Travis::RedisPool.new(config.redis.to_h)
Travis.logger.info('Setting up Travis::Core')
Github.setup
Services.register
Github::Services.register
end
attr_accessor :redis, :config
def pusher
@pusher ||= ::Pusher.tap do |pusher|
pusher.app_id = config.pusher.app_id
pusher.key = config.pusher.key
pusher.secret = config.pusher.secret
pusher.scheme = config.pusher.scheme if config.pusher.scheme
pusher.host = config.pusher.host if config.pusher.host
pusher.port = config.pusher.port if config.pusher.port
end
end
def states_cache
@states_cache ||= Travis::StatesCache.new
end
end
setup
end

View File

@ -4,14 +4,12 @@ require 'active_record_postgres_variables'
# now actually load travis
require 'travis'
require 'travis/amqp'
require 'travis/model'
require 'travis/support/amqp'
require 'travis/states_cache'
require 'rack'
require 'rack/protection'
require 'rack/contrib/config'
require 'rack/contrib/jsonp'
require 'rack/contrib/post_body_content_type_parser'
require 'rack/contrib'
require 'dalli'
require 'memcachier'
require 'rack/cache'
@ -20,21 +18,13 @@ require 'active_record'
require 'redis'
require 'gh'
require 'raven'
require 'raven/integrations/rack'
require 'sidekiq'
require 'metriks/reporter/logger'
require 'metriks/librato_metrics_reporter'
require 'travis/support/log_subscriber/active_record_metrics'
require 'fileutils'
require 'securerandom'
module Travis::Api
end
require 'travis/api/app/endpoint'
require 'travis/api/app/middleware'
require 'travis/api/instruments'
require 'travis/api/serialize/v2'
require 'travis/api/v2/http'
require 'travis/api/v3'
require 'travis/api/app/stack_instrumentation'
require 'travis/api/app/error_handling'
@ -82,27 +72,32 @@ module Travis::Api
end
def self.deploy_sha
@deploy_sha ||= ENV['HEROKU_SLUG_COMMIT'] || SecureRandom.hex(5)
@deploy_sha ||= File.exist?(deploy_sha_path) ? File.read(deploy_sha_path)[0..7] : 'deploy-sha'
end
def self.deploy_sha_path
File.expand_path('../../../../.deploy-sha', __FILE__)
end
attr_accessor :app
def initialize
@app = Rack::Builder.app do
# if stackprof = ENV['STACKPROF']
# require 'stackprof'
# modes = ['wall', 'cpu', 'object', 'custom']
# mode = modes.include?(stackprof) ? stackprof.to_sym : :cpu
# Travis.logger.info "Setting up profiler: #{mode}"
# use StackProf::Middleware, enabled: true, save_every: 1, mode: mode
# end
if stackprof = ENV['STACKPROF']
require 'stackprof'
modes = ['wall', 'cpu', 'object', 'custom']
mode = modes.include?(stackprof) ? stackprof.to_sym : :cpu
Travis.logger.info "Setting up profiler: #{mode}"
use StackProf::Middleware, enabled: true, save_every: 1, mode: mode
end
extend StackInstrumentation
use Travis::Api::App::Middleware::Skylight
use(Rack::Config) { |env| env['metriks.request.start'] ||= Time.now.utc }
use Travis::Api::App::Cors # if Travis.env == 'development' ???
use Raven::Rack if Travis::Api::App.use_monitoring?
use Raven::Rack if Travis.env == 'production' || Travis.env == 'staging'
use Rack::SSL if Endpoint.production?
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
@ -127,9 +122,10 @@ module Travis::Api
use Travis::Api::App::Middleware::Logging
use Travis::Api::App::Middleware::ScopeCheck
use Travis::Api::App::Middleware::UserAgentTracker
use Travis::Api::App::Middleware::Metriks
# make sure this is below ScopeCheck so we have the token
use Rack::Attack if Endpoint.production? and not Travis.config.enterprise
use Rack::Attack if Endpoint.production?
# if this is a v3 API request, ignore everything after
use Travis::API::V3::OptIn
@ -137,9 +133,6 @@ module Travis::Api
# rewrite should come after V3 hook
use Travis::Api::App::Middleware::Rewrite
# v3 has its own metriks
use Travis::Api::App::Middleware::Metriks
SettingsEndpoint.subclass :env_vars
if Travis.config.endpoints.ssh_key
SingletonSettingsEndpoint.subclass :ssh_key
@ -176,13 +169,14 @@ module Travis::Api
def self.setup!
setup_travis
load_endpoints
setup_endpoints
@setup = true
end
def self.setup_travis
Travis::Async.enabled = true
Travis::Amqp.setup(Travis.config.amqp)
Travis::Amqp.config = Travis.config.amqp
setup_database_connections
@ -192,7 +186,7 @@ module Travis::Api
end
end
if use_monitoring? && !console?
if use_monitoring? and not console?
setup_monitoring
end
end
@ -203,10 +197,8 @@ module Travis::Api
Travis::Database.connect
if Travis.config.logs_database
pool_size = ENV['DATABASE_POOL_SIZE']
Travis.config.logs_database[:pool] = pool_size.to_i if pool_size
Travis::LogsModel.establish_connection 'logs_database'
Log.establish_connection 'logs_database'
Log::Part.establish_connection 'logs_database'
end
end
@ -218,6 +210,11 @@ module Travis::Api
Travis::Metrics.setup
end
def self.load_endpoints
Dir.glob("#{__dir__}/app/middleware/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
Dir.glob("#{__dir__}/app/endpoint/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
end
def self.setup_endpoints
Base.subclasses.each(&:setup)
end

View File

@ -1,8 +1,6 @@
require 'travis/api/app'
require 'sinatra/base'
require 'mustermann'
require 'travis/api/app'
require 'travis/api/app/extensions'
require 'travis/api/app/helpers'
class Travis::Api::App
# Superclass for any endpoint and middleware.

View File

@ -15,11 +15,6 @@ class Travis::Api::App
options // do
headers['Access-Control-Allow-Methods'] = "HEAD, GET, POST, PATCH, PUT, DELETE"
headers['Access-Control-Allow-Headers'] = "Content-Type, Authorization, Accept, If-None-Match, If-Modified-Since, X-User-Agent, Travis-API-Version"
# cache OPTIONS for 24 hours to avoid excessive preflight requests and speed up access
# browsers might still limit this value to 10 minutes, see caveats
# http://stackoverflow.com/a/12021982
headers['Access-Control-Max-Age'] = "86400"
end
end
end

View File

@ -1,7 +1,6 @@
require 'travis/api/app'
require 'addressable/uri'
require 'active_record/base'
require 'travis/api/app'
require 'travis/api/app/base'
class Travis::Api::App
# Superclass for HTTP endpoints. Takes care of prefixing.
@ -49,23 +48,3 @@ class Travis::Api::App
end
end
end
require 'travis/api/app/endpoint/accounts'
require 'travis/api/app/endpoint/authorization'
require 'travis/api/app/endpoint/branches'
require 'travis/api/app/endpoint/broadcasts'
require 'travis/api/app/endpoint/builds'
require 'travis/api/app/endpoint/documentation'
require 'travis/api/app/endpoint/endpoints'
require 'travis/api/app/endpoint/env_vars'
require 'travis/api/app/endpoint/home'
require 'travis/api/app/endpoint/hooks'
require 'travis/api/app/endpoint/jobs'
require 'travis/api/app/endpoint/lint'
require 'travis/api/app/endpoint/logs'
require 'travis/api/app/endpoint/repos'
require 'travis/api/app/endpoint/requests'
require 'travis/api/app/endpoint/setting_endpoint'
require 'travis/api/app/endpoint/singleton_settings_endpoint'
require 'travis/api/app/endpoint/uptime'
require 'travis/api/app/endpoint/users'

View File

@ -1,10 +1,7 @@
require 'travis/api/app'
require 'addressable/uri'
require 'faraday'
require 'securerandom'
require 'customerio'
require 'travis/api/app'
require 'travis/github/education'
require 'travis/github/oauth'
class Travis::Api::App
class Endpoint
@ -98,7 +95,6 @@ class Travis::Api::App
# * **redirect_uri**: URI to redirect to after handshake.
get '/handshake' do
handshake do |user, token, redirect_uri|
if target_ok? redirect_uri
content_type :html
data = { user: user, token: token, uri: redirect_uri }
@ -114,7 +110,7 @@ class Travis::Api::App
# access token and user payload to the parent window via postMessage.
#
# However, the endpoint to send the payload to has to be explicitely
# safelisted in production, as this is endpoint is only meant to be used
# whitelisted in production, as this is endpoint is only meant to be used
# with the official Travis CI client at the moment.
#
# Example usage:
@ -160,36 +156,8 @@ class Travis::Api::App
halt 403, "you are currently not allowed to perform this request. please contact support@travis-ci.com."
end
# update first login date if not set
def update_first_login(user)
unless user.first_logged_in_at
user.update_attributes(first_logged_in_at: Time.now)
end
end
def update_customerio(user)
return unless Travis.config.customerio.site_id
# send event to customer.io
payload = {
:id => user.id,
:name => user.name,
:login => user.login,
:email => primary_email_for_user(user.github_oauth_token),
:created_at => user.created_at.to_i,
:github_id => user.github_id,
:education => user.education,
:first_logged_in_at => user.first_logged_in_at.to_i,
:travis_domain => Travis.config.client_domain
}
customerio.identify(payload)
rescue StandardError => e
Travis.logger.error "Could not update Customer.io for User: #{user.id}:#{user.login} with message:#{e.message}"
end
def serialize_user(user)
rendered = Travis::Api::Serialize.data(user, version: :v2)
rendered = Travis::Api.data(user, version: :v2)
rendered['user'].merge('token' => user.tokens.first.try(:token).to_s)
end
@ -217,8 +185,6 @@ class Travis::Api::App
user = user_for_github_token(github_token)
token = generate_token(user: user, app_id: 0)
payload = params[:state].split(":::", 2)[1]
update_first_login(user)
update_customerio(user)
yield serialize_user(user), token, payload
else
values[:state] = create_state
@ -228,7 +194,6 @@ class Travis::Api::App
end
end
def create_state
state = SecureRandom.urlsafe_base64(16)
redis.sadd('github:states', state)
@ -258,7 +223,6 @@ class Travis::Api::App
super
@user = ::User.find_by_github_id(data['id'])
end
def info(attributes = {})
@ -290,11 +254,8 @@ class Travis::Api::App
user.update_attributes info
else
self.user = ::User.create! info
Travis.run_service(:sync_user, user)
end
Travis::Github::Oauth.update_scopes(user) # unless Travis.env == 'test'
nullify_logins(user.github_id, user.login)
end
@ -346,7 +307,7 @@ class Travis::Api::App
end
def acceptable?(scopes, lossy = false)
Travis::Github::Oauth.wanted_scopes.all? do |scope|
User::Oauth.wanted_scopes.all? do |scope|
acceptable_scopes_for(scope, lossy).any? { |s| scopes.include? s }
end
end
@ -392,15 +353,6 @@ class Travis::Api::App
def allowed_https_targets
@allowed_https_targets ||= Travis.config.auth.target_origin.to_s.split(',')
end
def primary_email_for_user(oauth_token)
# check for the users primary email address (we don't store this info)
GH.with(token: oauth_token, client_id: nil) { GH['user/emails'] }.select { |e| e['primary'] }.first['email']
end
def customerio
Customerio::Client.new(Travis.config.customerio.site_id, Travis.config.customerio.api_key, :json => true)
end
end
end
end
@ -409,7 +361,7 @@ __END__
@@ invalid_target
<script>
console.log('refusing to send a token to <%= target_origin.inspect %>, not safelisted!');
console.log('refusing to send a token to <%= target_origin.inspect %>, not whitelisted!');
</script>
@@ common

View File

@ -1,8 +1,6 @@
require 'travis/api/app'
require 'travis/api/workers/build_cancellation'
require 'travis/api/workers/build_restart'
require 'travis/api/enqueue/services/restart_model'
require 'travis/api/enqueue/services/cancel_model'
class Travis::Api::App
class Endpoint
@ -22,8 +20,7 @@ class Travis::Api::App
post '/:id/cancel' do
Metriks.meter("api.request.cancel_build").mark
service = Travis::Enqueue::Services::CancelModel.new(current_user, { build_id: params[:id] })
service = self.service(:cancel_build, params.merge(source: 'api'))
if !service.authorized?
json = { error: {
message: "You don't have access to cancel build(#{params[:id]})"
@ -42,9 +39,7 @@ class Travis::Api::App
status 422
respond_with json
else
payload = { id: params[:id], user_id: current_user.id, source: 'api' }
service.push("build:cancel", payload)
Travis::Sidekiq::BuildCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api')
Metriks.meter("api.request.cancel_build.success").mark
status 204
@ -53,18 +48,16 @@ class Travis::Api::App
post '/:id/restart' do
Metriks.meter("api.request.restart_build").mark
service = Travis::Enqueue::Services::RestartModel.new(current_user, build_id: params[:id])
result = if !service.accept?
service = self.service(:reset_model, build_id: params[:id])
if !service.accept?
status 400
false
result = false
else
payload = { id: params[:id], user_id: current_user.id }
service.push("build:restart", payload)
Travis::Sidekiq::BuildRestart.perform_async(id: params[:id], user_id: current_user.id)
status 202
true
result = true
end
respond_with(result: result, flash: service.messages)
end
end

View File

@ -1,8 +1,6 @@
require 'travis/api/app'
require 'travis/api/workers/job_cancellation'
require 'travis/api/workers/job_restart'
require 'travis/api/enqueue/services/restart_model'
require 'travis/api/enqueue/services/cancel_model'
class Travis::Api::App
class Endpoint
@ -29,8 +27,7 @@ class Travis::Api::App
post '/:id/cancel' do
Metriks.meter("api.request.cancel_job").mark
service = Travis::Enqueue::Services::CancelModel.new(current_user, { job_id: params[:id] })
service = self.service(:cancel_job, params.merge(source: 'api'))
if !service.authorized?
json = { error: {
message: "You don't have access to cancel job(#{params[:id]})"
@ -49,8 +46,7 @@ class Travis::Api::App
status 422
respond_with json
else
payload = { id: params[:id], user_id: current_user.id, source: 'api' }
service.push("job:cancel", payload)
Travis::Sidekiq::JobCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api')
Metriks.meter("api.request.cancel_job.success").mark
status 204
@ -60,18 +56,15 @@ class Travis::Api::App
post '/:id/restart' do
Metriks.meter("api.request.restart_job").mark
service = Travis::Enqueue::Services::RestartModel.new(current_user, { job_id: params[:id] })
result = if !service.accept?
service = self.service(:reset_model, job_id: params[:id])
if !service.accept?
status 400
false
result = false
else
payload = {id: params[:id], user_id: current_user.id}
service.push("job:restart", payload)
Travis::Sidekiq::JobRestart.perform_async(id: params[:id], user_id: current_user.id)
status 202
true
result = true
end
respond_with(result: result, flash: service.messages)
end

View File

@ -1,6 +1,5 @@
require 'travis/api/app'
require 'travis/api/app/services/schedule_request'
require 'travis/api/enqueue/services/restart_model'
class Travis::Api::App
class Endpoint
@ -23,22 +22,11 @@ class Travis::Api::App
status 404
else
# DEPRECATED: this will be removed by 1st of December
#
# TODO It seems this endpoint is still in use, quite a bit:
# https://metrics.librato.com/s/metrics/api.request.restart?duration=2419200&q=api.request.restart
#
# I think we need to properly deprecate this by publishing a blog post.
Metriks.meter("api.request.restart").mark
service = Travis::Enqueue::Services::RestartModel.new(current_user, params)
params[:user_id] = service.target.repository.owner.id
type = params[:build_id] ? 'build' : 'job'
params[:id] = params[:build_id] || params[:job_id]
service.push("#{type}:restart", params)
respond_with(result: true, flash: service.messages)
respond_with service(:reset_model, params)
end
end
end
end
end

View File

@ -9,7 +9,7 @@ class Travis::Api::App
Thread.new do
loop do
begin
Raven.send_event queue.pop
Raven.send queue.pop
rescue Exception => e
puts e.message, e.backtrace
end

View File

@ -1,4 +1,8 @@
require 'travis/api/app/extensions/expose_pattern'
require 'travis/api/app/extensions/scoping'
require 'travis/api/app/extensions/smart_constants'
require 'travis/api/app/extensions/subclass_tracker'
require 'travis/api/app'
class Travis::Api::App
# Namespace for Sinatra extensions.
module Extensions
Dir.glob("#{__dir__}/extensions/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
end
end

View File

@ -1,7 +1,8 @@
require 'travis/api/app'
require 'travis/api/app/helpers/accept'
require 'travis/api/app/helpers/current_user'
require 'travis/api/app/helpers/db_follower'
require 'travis/api/app/helpers/flash'
require 'travis/api/app/helpers/mime_types'
require 'travis/api/app/helpers/respond_with'
class Travis::Api::App
# Namespace for helpers.
module Helpers
Dir.glob("#{__dir__}/helpers/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
end
end

View File

@ -53,8 +53,6 @@ class Travis::Api::App
if params
params = Hash[*params.split(';').map { |p| p.scan /(#{TOKEN})=(#{TOKEN})/ }.flatten]
quality = params.delete('q').to_f if params['q']
else
params = {}
end
if subtype =~ HEADER_FORMAT

View File

@ -3,11 +3,5 @@ require 'travis/api/app'
class Travis::Api::App
# Superclass for all middleware.
class Middleware < Base
require 'travis/api/app/middleware/logging'
require 'travis/api/app/middleware/metriks'
require 'travis/api/app/middleware/rewrite'
require 'travis/api/app/middleware/scope_check'
require 'travis/api/app/middleware/skylight'
require 'travis/api/app/middleware/user_agent_tracker'
end
end

View File

@ -4,15 +4,15 @@ module Travis::Api::App::Responders
class Atom < Base
ATOM_FEED_ERB = ERB.new <<-EOF
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><%= resource.first.repository.slug %> Builds</title>
<link href="<%= endpoint.url %>" type="application/atom+xml" rel = "self" />
<id>repo:<%= resource.first.repository.id %></id>
<rights>Copyright (c) <%= DateTime.now.strftime("%Y") %> Travis CI GmbH</rights>
<updated><%= DateTime.now.rfc3339 %></updated>
<% resource.each do |build| %>
<entry>
<title><%= build.repository.slug %> Build #<%= build.number %></title>
@ -21,7 +21,7 @@ module Travis::Api::App::Responders
<updated><%= ::DateTime.parse(build.updated_at.to_s).rfc3339 %></updated>
<summary type="html">
&lt;p&gt;
<%= build.commit.message.encode(:xml => :text) if build.commit.message %> (<%= build.commit.committer_name %>)
<%= build.commit.message.encode(:xml => :text) %> (<%= build.commit.committer_name %>)
&lt;br/&gt;&lt;br/&gt;
State: <%= build.state %>
&lt;br/&gt;
@ -36,7 +36,7 @@ module Travis::Api::App::Responders
</author>
</entry>
<% end %>
</feed>
EOF

View File

@ -1,5 +1,3 @@
require 'travis/api/serialize'
class Travis::Api::App
module Responders
class Json < Base
@ -48,7 +46,7 @@ class Travis::Api::App
if defined?(@builder)
@builder
else
@builder = Travis::Api::Serialize.builder(resource, { :version => version }.merge(options))
@builder = Travis::Api.builder(resource, { :version => version }.merge(options))
end
end

View File

@ -1,5 +1,4 @@
require 'rack/attack'
require 'netaddr'
class Rack::Attack
class Request
@ -26,57 +25,38 @@ class Rack::Attack
end
end
POST_SAFELIST = [
POST_WHITELISTED = [
"/auth/handshake",
"/auth/post_message",
"/auth/post_message/iframe"
]
GITHUB_CIDR = NetAddr::CIDR.create('192.30.252.0/22')
safelist('safelist build status images') do |request|
/\.(png|svg)$/.match(request.path)
end
# https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-safelist/
safelist('safelist anything coming from github') do |request|
request.ip && GITHUB_CIDR.contains?(request.ip)
end
####
# Whitelisted IP addresses
safelist('safelist client requesting from redis') do |request|
# TODO: deprecate :api_whitelisted_ips in favour of api_safelisted_ips
Travis.redis.sismember(:api_whitelisted_ips, request.ip) || Travis.redis.sismember(:api_safelisted_ips, request.ip)
end
####
# Ban based on: IP address
# Ban time: indefinite
# Ban after: manually banned
blocklist('block client requesting from redis') do |request|
# TODO: deprecate :api_blacklisted_ips in favour of api_blocklisted_ips
Travis.redis.sismember(:api_blacklisted_ips, request.ip) || Travis.redis.sismember(:api_blocklisted_ips, request.ip)
blacklist('block client requesting from redis') do |request|
Travis.redis.sismember(:api_blacklisted_ips, request.ip)
end
####
# Ban based on: IP address or access token
# Ban time: 5 hours
# Ban after: 10 POST requests within five minutes to /auth/github
blocklist('hammering /auth/github') do |request|
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 2, findtime: 5.minutes, bantime: bantime(5.hours)) do
request.post? and request.path == '/auth/github'
end
blacklist('hammering /auth/github') do |request|
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 2, findtime: 5.minutes, bantime: bantime(5.hours)) do
request.post? and request.path == '/auth/github'
end
end
####
# Ban based on: IP address or access token
# Ban time: 1 hour
# Ban after: 10 POST requests within 30 seconds
blocklist('spamming with POST requests') do |request|
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 10, findtime: 30.seconds, bantime: bantime(1.hour)) do
request.post? and not POST_SAFELIST.include? request.path
end
blacklist('spamming with POST requests') do |request|
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 10, findtime: 30.seconds, bantime: bantime(1.hour)) do
request.post? and not POST_WHITELISTED.include? '/auth/github'
end
end

View File

@ -1,59 +0,0 @@
module Travis
module Enqueue
module Services
class CancelModel
attr_reader :current_user, :target
def initialize(current_user, params)
@current_user = current_user
@params = params
target
end
def messages
messages = []
messages << { :notice => "The #{type} was successfully cancelled." } if can_cancel?
messages << { :error => "You are not authorized to cancel this #{type}." } unless authorized?
messages << { :error => "The #{type} could not be cancelled." } unless build.cancelable?
messages
end
def push(event, payload)
# target may have been retrieved with a :join query, so we need to reset the readonly status
if can_cancel?
::Sidekiq::Client.push(
'queue' => 'hub',
'class' => 'Travis::Hub::Sidekiq::Worker',
#'args' => ["#{type}:cancel", @params]
'args' => [event, payload]
)
end
end
def type
@type ||= @params[:build_id] ? :build : :job
end
def target
if type == :build
@target = Build.find(@params[:build_id])
else
@target = Job.find(@params[:job_id])
end
end
def can_cancel?
authorized? && target.cancelable?
end
# check on web
def authorized?
current_user.permission?(:pull, :repository_id => target.repository_id)
end
end
end
end
end

View File

@ -1,64 +0,0 @@
module Travis
module Enqueue
module Services
class RestartModel
attr_reader :current_user, :target
def initialize(current_user, params)
@current_user = current_user
@params = params
target
end
def push(event, payload)
if current_user && target && accept?
::Sidekiq::Client.push(
'queue' => 'hub',
'class' => 'Travis::Hub::Sidekiq::Worker',
'args' => [event, payload]
)
end
end
def accept?
current_user && permission? && resetable?
end
def messages
messages = []
messages << { notice: "The #{type} was successfully restarted." } if accept?
messages << { error: 'You do not seem to have sufficient permissions.' } unless permission?
messages << { error: "This #{type} currently can not be restarted." } unless resetable?
messages
end
def type
@type ||= @params[:build_id] ? :build : :job
end
def target
if type == :build
@target = Build.find(@params[:build_id])
else
@target = Job.find(@params[:job_id])
end
end
private
def permission?
current_user.permission?(required_role, repository_id: target.repository_id)
end
def resetable?
target.resetable?
end
def required_role
Travis.config.roles.reset_model
end
end
end
end
end

View File

@ -1,68 +0,0 @@
require 'travis/api/serialize/formats'
require 'travis/api/serialize/v0'
require 'travis/api/serialize/v1'
module Travis
module Api
module Serialize
DEFAULT_VERSION = 'v2'
class << self
def data(resource, options = {})
new(resource, options).data
end
def builder(resource, options = {})
target = (options[:for] || 'http').to_s.camelize
version = (options[:version] || default_version(options)).to_s.camelize
type = (options[:type] || type_for(resource)).to_s.camelize.split('::')
([version, target] + type).inject(self) do |const, name|
begin
if const && const.const_defined?(name.to_s.camelize, false)
const.const_get(name, false)
else
nil
end
rescue NameError
nil
end
end
end
def new(resource, options = {})
builder = builder(resource, options) || raise(ArgumentError, "cannot serialize #{resource.inspect}, options: #{options.inspect}")
builder.new(resource, options[:params] || {})
end
private
def type_for(resource)
if arel_relation?(resource)
type = resource.klass.name.pluralize
else
type = resource.class
type = type.base_class if active_record?(type)
type = type.name
end
type.split('::').last
end
def arel_relation?(object)
object.respond_to?(:klass)
end
def active_record?(object)
object.respond_to?(:base_class)
end
def default_version(options)
if options[:for].to_s.downcase == "pusher"
"v0"
else
DEFAULT_VERSION
end
end
end
end
end
end

View File

@ -1,11 +0,0 @@
module Travis
module Api
module Serialize
module Formats
def format_date(date)
date && date.strftime('%Y-%m-%dT%H:%M:%SZ')
end
end
end
end
end

View File

@ -1,25 +0,0 @@
require 'active_model_serializers'
module Travis
module Api
module Serialize
class ObjectSerializer < ActiveModel::Serializer
def data
as_json
end
end
class ArraySerializer < ActiveModel::ArraySerializer
def data
as_json
end
def initialize(resource, options)
options[:each_serializer] ||= V2::Http.const_get(options[:root].to_s.singularize.camelize)
super(resource, options)
end
end
end
end
end

View File

@ -1,6 +0,0 @@
# V0 is an internal api that we can change at any time
require 'travis/api/serialize/v0/event'
require 'travis/api/serialize/v0/notification'
require 'travis/api/serialize/v0/pusher'
require 'travis/api/serialize/v0/worker'

View File

@ -1,2 +0,0 @@
require 'travis/api/serialize/v0/event/build'
require 'travis/api/serialize/v0/event/job'

View File

@ -1,96 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Event
class Build
include Formats
attr_reader :build, :repository, :request, :commit, :options
def initialize(build, options = {})
@build = build
@repository = build.repository
@request = build.request
@commit = build.commit
# @options = options
end
def data(extra = {})
{
'repository' => repository_data,
'request' => request_data,
'commit' => commit_data,
'build' => build_data,
'jobs' => build.matrix.map { |job| job_data(job) }
}
end
private
def build_data
{
'id' => build.id,
'repository_id' => build.repository_id,
'commit_id' => build.commit_id,
'number' => build.number,
'pull_request' => build.pull_request?,
'pull_request_number' => build.pull_request_number,
'config' => build.config.try(:except, :source_key),
'state' => build.state.to_s,
'previous_state' => build.previous_state.to_s,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'job_ids' => build.matrix_ids
}
end
def repository_data
{
'id' => repository.id,
'key' => repository.key.try(:public_key),
'slug' => repository.slug,
'name' => repository.name,
'owner_email' => repository.owner_email,
'owner_avatar_url' => repository.owner.try(:avatar_url)
}
end
def request_data
{
'token' => request.token,
'head_commit' => (request.head_commit || '')
}
end
def commit_data
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
def job_data(job)
{
'id' => job.id,
'number' => job.number,
'state' => job.state.to_s,
'tags' => job.tags
}
end
end
end
end
end
end
end

View File

@ -1,37 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Event
class Job
include Formats
attr_reader :job
def initialize(job, options = {})
@job = job
# @options = options
end
def data(extra = {})
{
'job' => job_data,
}
end
private
def job_data
{
'queue' => job.queue,
'created_at' => job.created_at,
'started_at' => job.started_at,
'finished_at' => job.finished_at,
}
end
end
end
end
end
end
end

View File

@ -1,3 +0,0 @@
require 'travis/api/serialize/v0/notification/build'
require 'travis/api/serialize/v0/notification/repository'
require 'travis/api/serialize/v0/notification/user'

View File

@ -1,29 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Notification
class Build
attr_reader :build
def initialize(build, options = {})
@build = build
end
def data
{
'build' => build_data
}
end
def build_data
{
'id' => build.id
}
end
end
end
end
end
end
end

View File

@ -1,30 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Notification
class Repository
attr_reader :repository
def initialize(repository, options = {})
@repository = repository
end
def data
{
'repository' => repository_data
}
end
def repository_data
{
'id' => repository.id,
'slug' => repository.slug
}
end
end
end
end
end
end
end

View File

@ -1,30 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Notification
class User
attr_reader :user
def initialize(user, options = {})
@user = user
end
def data
{
'user' => user_data
}
end
def user_data
{
'id' => user.id,
'login' => user.login
}
end
end
end
end
end
end
end

View File

@ -1,3 +0,0 @@
require 'travis/api/serialize/v0/pusher/annotation'
require 'travis/api/serialize/v0/pusher/build'
require 'travis/api/serialize/v0/pusher/job'

View File

@ -1,35 +0,0 @@
require 'travis/api/serialize/v0/pusher/annotation/created'
require 'travis/api/serialize/v0/pusher/annotation/updated'
module Travis
module Api
module Serialize
module V0
module Pusher
class Annotation
include Formats
attr_reader :annotation
def initialize(annotation, options = {})
@annotation = annotation
end
def data
{
"annotation" => {
"id" => annotation.id,
"job_id" => annotation.job_id,
"description" => annotation.description,
"url" => annotation.url,
"status" => annotation.status,
"provider_name" => annotation.annotation_provider.name,
}
}
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Annotation
class Created < Annotation
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Annotation
class Updated < Annotation
end
end
end
end
end
end
end

View File

@ -1,112 +0,0 @@
require 'travis/api/serialize/v0/pusher/build/canceled'
require 'travis/api/serialize/v0/pusher/build/created'
require 'travis/api/serialize/v0/pusher/build/received'
require 'travis/api/serialize/v0/pusher/build/started'
require 'travis/api/serialize/v0/pusher/build/finished'
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
include Formats
attr_reader :build, :options
def initialize(build, options = {})
@build = build
@options = options
end
def data
{
'build' => build_data(build),
'commit' => commit_data(build.commit),
'repository' => repository_data(build.repository)
}
end
private
def build_data(build)
commit = build.commit
{
'id' => build.id,
'repository_id' => build.repository_id,
'commit_id' => build.commit_id,
'number' => build.number,
'pull_request' => build.pull_request?,
'pull_request_title' => build.pull_request_title,
'pull_request_number' => build.pull_request_number,
'state' => build.state.to_s,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'job_ids' => build.matrix_ids,
'event_type' => build.event_type,
# this is a legacy thing, we should think about removing it
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'compare_url' => commit.compare_url,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email
}
end
def commit_data(commit)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
def repository_data(repository)
{
'id' => repository.id,
'slug' => repository.slug,
'description' => repository.description,
'private' => repository.private,
'last_build_id' => repository.last_build_id,
'last_build_number' => repository.last_build_number,
'last_build_state' => repository.last_build_state.to_s,
'last_build_duration' => repository.last_build_duration,
'last_build_language' => nil,
'last_build_started_at' => format_date(repository.last_build_started_at),
'last_build_finished_at' => format_date(repository.last_build_finished_at),
'github_language' => repository.github_language,
'default_branch' => {
'name' => repository.default_branch,
'last_build_id' => last_build_on_default_branch_id(repository)
},
'active' => repository.active,
'current_build_id' => repository.current_build_id
}
end
def last_build_on_default_branch_id(repository)
default_branch = Branch.where(repository_id: repository.id, name: repository.default_branch).first
if default_branch
default_branch.last_build_id
end
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Canceled < Build
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Created < Build
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Finished < Build
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Received < Build
end
end
end
end
end
end
end

View File

@ -1,49 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Received < Build
class Job
include Formats, V1::Helpers::Legacy
attr_reader :job, :commit
def initialize(job)
@job = job
@commit = job.commit
end
def data
{
'id' => job.id,
'repository_id' => job.repository_id,
'repository_private' => repository.private,
'parent_id' => job.source_id,
'number' => job.number,
'state' => job.state.to_s,
'result' => legacy_job_result(job),
'config' => job.obfuscated_config,
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'compare_url' => commit.compare_url,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'allow_failure' => job.allow_failure
}
end
end
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Started < Build
end
end
end
end
end
end
end

View File

@ -1,49 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Build
class Started < Build
class Job
include Formats, V1::Helpers::Legacy
attr_reader :job, :commit
def initialize(job)
@job = job
@commit = job.commit
end
def data
{
'id' => job.id,
'repository_id' => job.repository_id,
'repository_private' => repository.private,
'parent_id' => job.source_id,
'number' => job.number,
'state' => job.state.to_s,
'result' => legacy_job_result(job),
'config' => job.obfuscated_config,
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'compare_url' => commit.compare_url,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'allow_failure' => job.allow_failure
}
end
end
end
end
end
end
end
end
end

View File

@ -1,69 +0,0 @@
require 'travis/api/serialize/v0/pusher/job/canceled'
require 'travis/api/serialize/v0/pusher/job/created'
require 'travis/api/serialize/v0/pusher/job/log'
require 'travis/api/serialize/v0/pusher/job/received'
require 'travis/api/serialize/v0/pusher/job/started'
require 'travis/api/serialize/v0/pusher/job/finished'
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
include Formats
attr_reader :job, :options
def initialize(job, options = {})
@job = job
@options = options
end
def data
job_data(job).merge(
'commit' => commit_data(job.commit)
)
end
private
def job_data(job)
{
'id' => job.id,
'repository_id' => job.repository_id,
'repository_slug' => job.repository.slug,
'repository_private' => job.repository.private,
'build_id' => job.source_id,
'commit_id' => job.commit_id,
'log_id' => job.log_id,
'number' => job.number,
'state' => job.state.to_s,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'queue' => job.queue,
'allow_failure' => job.allow_failure,
'annotation_ids' => job.annotation_ids
}
end
def commit_data(commit)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Canceled < Job
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Created < Job
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Finished < Job
end
end
end
end
end
end
end

View File

@ -1,32 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Log
attr_reader :job, :options
def initialize(job, options = {})
@job = job
@options = options
end
def data
{
'id' => job.id,
'build_id' => job.source_id,
'repository_id' => job.repository_id,
'repository_private' => repository.private,
'_log' => options[:_log],
'number' => options[:number],
'final' => options[:final]
}
end
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Received < Job
end
end
end
end
end
end
end

View File

@ -1,14 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Pusher
class Job
class Started < Job
end
end
end
end
end
end
end

View File

@ -1 +0,0 @@
require 'travis/api/serialize/v0/worker/job'

View File

@ -1,35 +0,0 @@
require 'travis/api/serialize/v0/worker/job/test'
module Travis
module Api
module Serialize
module V0
module Worker
class Job
attr_reader :job
def initialize(job, options = {})
@job = job
end
def commit
job.commit
end
def repository
job.repository
end
def request
build.request
end
def build
job.source
end
end
end
end
end
end
end

View File

@ -1,120 +0,0 @@
module Travis
module Api
module Serialize
module V0
module Worker
class Job
class Test < Job
include Formats
def data
{
'type' => 'test',
# TODO legacy. remove this once workers respond to a 'job' key
'build' => job_data,
'job' => job_data,
'source' => build_data,
'repository' => repository_data,
'pull_request' => commit.pull_request? ? pull_request_data : false,
'config' => job.decrypted_config,
'queue' => job.queue,
'uuid' => Travis.uuid,
'ssh_key' => ssh_key,
'env_vars' => env_vars,
'timeouts' => timeouts
}
end
def build_data
{
'id' => build.id,
'number' => build.number
}
end
def job_data
data = {
'id' => job.id,
'number' => job.number,
'commit' => commit.commit,
'commit_range' => commit.range,
'commit_message' => commit.message,
'branch' => commit.branch,
'ref' => commit.pull_request? ? commit.ref : nil,
'state' => job.state.to_s,
'secure_env_enabled' => job.secure_env_enabled?
}
data['tag'] = request.tag_name if include_tag_name?
data['pull_request'] = commit.pull_request? ? commit.pull_request_number : false
data
end
def repository_data
{
'id' => repository.id,
'slug' => repository.slug,
'github_id' => repository.github_id,
'source_url' => repository.source_url,
'api_url' => repository.api_url,
'last_build_id' => repository.last_build_id,
'last_build_number' => repository.last_build_number,
'last_build_started_at' => format_date(repository.last_build_started_at),
'last_build_finished_at' => format_date(repository.last_build_finished_at),
'last_build_duration' => repository.last_build_duration,
'last_build_state' => repository.last_build_state.to_s,
'description' => repository.description,
'default_branch' => repository.default_branch
}
end
def pull_request_data
{
'number' => commit.pull_request_number,
'head_repo' => request.head_repo,
'base_repo' => request.base_repo,
'head_branch' => request.head_branch,
'base_branch' => request.base_branch
}
end
def ssh_key
nil
end
def env_vars
vars = settings.env_vars
vars = vars.public unless job.secure_env_enabled?
vars.map do |var|
{
'name' => var.name,
'value' => var.value.decrypt,
'public' => var.public
}
end
end
def timeouts
{ 'hard_limit' => timeout(:hard_limit), 'log_silence' => timeout(:log_silence) }
end
def timeout(type)
timeout = settings.send(:"timeout_#{type}")
timeout = timeout * 60 if timeout # worker handles timeouts in seconds
timeout
end
def include_tag_name?
Travis.config.include_tag_name_in_worker_payload && request.tag_name.present?
end
def settings
repository.settings
end
end
end
end
end
end
end
end

View File

@ -1,4 +0,0 @@
require 'travis/api/serialize/v1/archive'
require 'travis/api/serialize/v1/http'
require 'travis/api/serialize/v1/helpers'
require 'travis/api/serialize/v1/webhook'

View File

@ -1 +0,0 @@
require 'travis/api/serialize/v1/archive/build'

View File

@ -1,52 +0,0 @@
require 'travis/api/serialize/v1/archive/build/job'
module Travis
module Api
module Serialize
module V1
module Archive
class Build
include Formats
attr_reader :build, :commit, :repository
def initialize(build, options = {})
@build = build
@commit = build.commit
@repository = build.repository
end
def data
{
'id' => build.id,
'number' => build.number,
'config' => build.obfuscated_config.stringify_keys,
'result' => 0,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'matrix' => build.matrix.map { |job| Job.new(job).data },
'repository' => repository_data
}
end
def repository_data
{
'id' => repository.id,
'slug' => repository.slug
}
end
end
end
end
end
end
end

View File

@ -1,33 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Archive
class Build
class Job
include Formats
attr_reader :job, :commit
def initialize(job)
@job = job
@commit = job.commit
end
def data
{
'id' => job.id,
'number' => job.number,
'config' => job.obfuscated_config,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'log' => job.log_content
}
end
end
end
end
end
end
end
end

View File

@ -1 +0,0 @@
require 'travis/api/serialize/v1/helpers/legacy'

View File

@ -1,36 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Helpers
module Legacy
RESULTS = {
passed: 0,
failed: 1
}
def legacy_repository_last_build_result(repository)
RESULTS[repository.last_build_state.try(:to_sym)]
end
def legacy_build_state(build)
build.finished? ? 'finished' : build.state.to_s
end
def legacy_build_result(build)
RESULTS[build.state.try(:to_sym)]
end
def legacy_job_state(job)
job.finished? ? 'finished' : job.state.to_s
end
def legacy_job_result(job)
RESULTS[job.state.try(:to_sym)]
end
end
end
end
end
end
end

View File

@ -1,9 +0,0 @@
require 'travis/api/serialize/v1/http/branches'
require 'travis/api/serialize/v1/http/build'
require 'travis/api/serialize/v1/http/builds'
require 'travis/api/serialize/v1/http/hooks'
require 'travis/api/serialize/v1/http/job'
require 'travis/api/serialize/v1/http/jobs'
require 'travis/api/serialize/v1/http/repositories'
require 'travis/api/serialize/v1/http/repository'
require 'travis/api/serialize/v1/http/user'

View File

@ -1,45 +0,0 @@
require 'travis/api/serialize/v1/helpers/legacy'
module Travis
module Api
module Serialize
module V1
module Http
class Branches
include Formats, Helpers::Legacy
attr_reader :builds, :options
def initialize(builds, options = {})
builds = builds.last_finished_builds_by_branches if builds.is_a?(Repository) # TODO remove, bc
@builds = builds
end
def cache_key
"branches-#{builds.map(&:id).join('-')}"
end
def updated_at
builds.compact.map(&:finished_at).compact.sort.first
end
def data
builds.compact.map do |build|
{
'repository_id' => build.repository_id,
'build_id' => build.id,
'commit' => build.commit.commit,
'branch' => build.commit.branch,
'message' => build.commit.message,
'result' => legacy_build_result(build),
'finished_at' => format_date(build.finished_at),
'started_at' => format_date(build.started_at)
}
end
end
end
end
end
end
end
end

View File

@ -1,49 +0,0 @@
require 'travis/api/serialize/v1/http/build/job'
module Travis
module Api
module Serialize
module V1
module Http
class Build
include Formats, Helpers::Legacy
attr_reader :build, :commit, :request
def initialize(build, options = {})
@build = build
@commit = build.commit
@request = build.request
end
def data
{
'id' => build.id,
'repository_id' => build.repository_id,
'number' => build.number,
'config' => build.obfuscated_config.stringify_keys,
'state' => legacy_build_state(build),
'result' => legacy_build_result(build),
'status' => legacy_build_result(build),
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
'event_type' => build.event_type,
'matrix' => build.matrix.map { |job| Job.new(job).data },
}
end
end
end
end
end
end
end

View File

@ -1,34 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Http
class Build
class Job
include Formats, Helpers::Legacy
attr_reader :job
def initialize(job)
@job = job
end
def data
{
'id' => job.id,
'repository_id' => job.repository_id,
'number' => job.number,
'config' => job.obfuscated_config.stringify_keys,
'result' => legacy_job_result(job),
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'allow_failure' => job.allow_failure
}
end
end
end
end
end
end
end
end

View File

@ -1,40 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Http
class Builds
include Formats, Helpers::Legacy
attr_reader :builds
def initialize(builds, options = {})
@builds = builds
end
def data
builds.map { |build| build_data(build) }
end
def build_data(build)
{
'id' => build.id,
'repository_id' => build.repository_id,
'number' => build.number,
'state' => legacy_build_state(build),
'result' => legacy_build_result(build),
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'commit' => build.commit.commit,
'branch' => build.commit.branch,
'message' => build.commit.message,
'event_type' => build.event_type,
}
end
end
end
end
end
end
end

View File

@ -1,36 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Http
class Hooks
attr_reader :repos, :options
def initialize(repos, options = {})
@repos = repos
@options = options
end
def data
repos.map { |repo| repo_data(repo) }
end
private
def repo_data(repo)
{
'uid' => [repo.owner_name, repo.name].join(':'),
'url' => "https://github.com/#{repo.owner_name}/#{repo.name}",
'name' => repo.name,
'owner_name' => repo.owner_name,
'description' => repo.description,
'active' => repo.active,
'private' => repo.private
}
end
end
end
end
end
end
end

View File

@ -1,36 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Http
class Jobs
include Formats, Helpers::Legacy
attr_reader :jobs
def initialize(jobs, options = {})
@jobs = jobs
end
def data
jobs.map { |job| job_data(job) }
end
def job_data(job)
commit = job.commit
{
'id' => job.id,
'repository_id' => job.repository_id,
'number' => job.number,
'state' => legacy_job_state(job),
'queue' => job.queue,
'allow_failure' => job.allow_failure
}
end
end
end
end
end
end
end

View File

@ -1,33 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Http
class User
include Formats
attr_reader :user, :options
def initialize(user, options = {})
@user = user
@options = options
end
def data
{
'login' => user.login,
'name' => user.name,
'email' => user.email,
'gravatar_id' => user.gravatar_id,
'locale' => user.locale,
'is_syncing' => user.is_syncing,
'synced_at' => format_date(user.synced_at)
}
end
end
end
end
end
end
end

View File

@ -1 +0,0 @@
require 'travis/api/serialize/v1/webhook/build'

View File

@ -1,29 +0,0 @@
require 'travis/api/serialize/v1/webhook/build/finished'
module Travis
module Api
module Serialize
module V1
module Webhook
class Build
attr_reader :build, :commit, :request, :repository, :options
def initialize(build, options = {})
@build = build
@commit = build.commit
@request = build.request
@repository = build.repository
@options = options
end
private
def build_url
["https://#{Travis.config.host}", repository.slug, 'builds', build.id].join('/')
end
end
end
end
end
end
end

View File

@ -1,72 +0,0 @@
require 'travis/api/serialize/v1/webhook/build/finished/job'
module Travis
module Api
module Serialize
module V1
module Webhook
class Build
class Finished < Build
include Formats
def data
data = {
'id' => build.id,
'repository' => repository_data,
'number' => build.number,
'config' => build.obfuscated_config.stringify_keys,
'status' => build.result,
'result' => build.result,
'status_message' => result_message,
'result_message' => result_message,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'build_url' => build_url,
'commit_id' => commit.id,
'commit' => commit.commit,
'base_commit' => request.base_commit,
'head_commit' => request.head_commit,
'branch' => commit.branch,
'message' => commit.message,
'compare_url' => commit.compare_url,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'matrix' => build.matrix.map { |job| Job.new(job, options).data },
'type' => build.event_type,
'state' => build.state.to_s,
'pull_request' => build.pull_request?,
'pull_request_number' => build.pull_request_number,
'pull_request_title' => build.pull_request_title,
'tag' => request.tag_name
}
if commit.pull_request?
data['pull_request_number'] = commit.pull_request_number
end
data
end
def repository_data
{
'id' => repository.id,
'name' => repository.name,
'owner_name' => repository.owner_name,
'url' => repository.url
}
end
def result_message
@result_message ||= ::Build::ResultMessage.new(build).short
end
end
end
end
end
end
end
end

View File

@ -1,52 +0,0 @@
module Travis
module Api
module Serialize
module V1
module Webhook
class Build
class Finished < Build
class Job
include Formats
attr_reader :job, :commit, :options
def initialize(job, options = {})
@job = job
@commit = job.commit
@options = options
end
def data
data = {
'id' => job.id,
'repository_id' => job.repository_id,
'parent_id' => job.source_id,
'number' => job.number,
'state' => job.finished? ? 'finished' : job.state.to_s,
'config' => job.obfuscated_config,
'status' => job.result,
'result' => job.result,
'commit' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'compare_url' => commit.compare_url,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'allow_failure' => job.allow_failure
}
data['log'] = job.log_content || '' if options[:include_logs]
data['started_at'] = format_date(job.started_at) if job.started?
data['finished_at'] = format_date(job.finished_at) if job.finished?
data
end
end
end
end
end
end
end
end
end

View File

@ -1 +0,0 @@
require 'travis/api/serialize/v2/http'

View File

@ -1,24 +0,0 @@
require 'travis/api/serialize/serializer'
require 'travis/api/serialize/v2/http/accounts'
require 'travis/api/serialize/v2/http/annotations'
require 'travis/api/serialize/v2/http/broadcasts'
require 'travis/api/serialize/v2/http/branch'
require 'travis/api/serialize/v2/http/branches'
require 'travis/api/serialize/v2/http/build'
require 'travis/api/serialize/v2/http/builds'
require 'travis/api/serialize/v2/http/caches'
require 'travis/api/serialize/v2/http/hooks'
require 'travis/api/serialize/v2/http/job'
require 'travis/api/serialize/v2/http/jobs'
require 'travis/api/serialize/v2/http/log'
require 'travis/api/serialize/v2/http/permissions'
require 'travis/api/serialize/v2/http/repositories'
require 'travis/api/serialize/v2/http/repository'
require 'travis/api/serialize/v2/http/requests'
require 'travis/api/serialize/v2/http/request'
require 'travis/api/serialize/v2/http/ssl_key'
require 'travis/api/serialize/v2/http/env_var'
require 'travis/api/serialize/v2/http/env_vars'
require 'travis/api/serialize/v2/http/user'
require 'travis/api/serialize/v2/http/validation_error'
require 'travis/api/serialize/v2/http/ssh_key'

View File

@ -1,44 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Accounts
include Formats
attr_reader :accounts, :options
def initialize(accounts, options = {})
@accounts = accounts
@options = options
end
def data
{
:accounts => accounts.map { |account| account_data(account) }
}
end
private
def account_data(account)
data = {
'id' => account.id,
'name' => account.name,
'login' => account.login,
'type' => account.type.underscore,
'repos_count' => account.repos_count
}
data['avatar_url'] = account.avatar_url if account.respond_to?(:avatar_url)
data
end
end
end
end
end
end
end

View File

@ -1,38 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Annotations
include Formats
def initialize(annotations, options = {})
@annotations = annotations
end
def data
{
"annotations" => @annotations.map { |annotation| build_annotation(annotation) },
}
end
private
def build_annotation(annotation)
{
"id" => annotation.id,
"job_id" => annotation.job_id,
"description" => annotation.description,
"url" => annotation.url,
"status" => annotation.status,
"provider_name" => annotation.annotation_provider.name,
}
end
end
end
end
end
end
end

View File

@ -1,31 +0,0 @@
require 'travis/api/serialize/formats'
require 'travis/api/serialize/v2/http/branches'
module Travis
module Api
module Serialize
module V2
module Http
class Branch < Branches
include Formats
attr_reader :build, :commit, :options
def initialize(build, options = {})
@build = build
@commit = build.commit
@options = options
end
def data
{
'branch' => build_data(build),
'commit' => commit_data(commit)
}
end
end
end
end
end
end
end

View File

@ -1,64 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Branches
include Formats
attr_reader :builds, :commits, :options
def initialize(builds, options = {})
builds = builds.last_finished_builds_by_branches if builds.is_a?(Repository) # TODO remove, bc
@builds = builds
@commits = builds.map(&:commit)
@options = options
end
def data
{
'branches' => builds.map { |build| build_data(build) },
'commits' => commits.map { |commit| commit_data(commit) }
}
end
private
def build_data(build)
{
'id' => build.id,
'repository_id' => build.repository_id,
'commit_id' => build.commit_id,
'number' => build.number,
'config' => build.obfuscated_config.stringify_keys,
'state' => build.state.to_s,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'job_ids' => build.matrix.map { |job| job.id },
'pull_request' => build.pull_request?
}
end
def commit_data(commit)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
end
end
end
end
end
end

View File

@ -1,33 +0,0 @@
module Travis
module Api
module Serialize
module V2
module Http
class Broadcasts
attr_reader :broadcasts, :options
def initialize(broadcasts, options = {})
@broadcasts = broadcasts
@options = options
end
def data
{
'broadcasts' => broadcasts.map { |broadcast| broadcast_data(broadcast) }
}
end
private
def broadcast_data(broadcast)
{
'id' => broadcast.id,
'message' => broadcast.message
}
end
end
end
end
end
end
end

View File

@ -1,97 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Build
include Formats
attr_reader :build, :options
def initialize(build, options = {})
options[:include_jobs] = true unless options.key?(:include_jobs)
@build = build
@options = options
end
def data
{
'build' => build_data(build),
'commit' => commit_data(build.commit, build.repository),
'jobs' => options[:include_jobs] ? build.matrix.map { |job| job_data(job) } : [],
'annotations' => options[:include_jobs] ? Annotations.new(annotations(build), @options).data["annotations"] : [],
}
end
private
def build_data(build)
{
'id' => build.id,
'repository_id' => build.repository_id,
'commit_id' => build.commit_id,
'number' => build.number,
'event_type' => build.event_type,
'pull_request' => build.pull_request?,
'pull_request_title' => build.pull_request_title,
'pull_request_number' => build.pull_request_number,
'config' => build.obfuscated_config.stringify_keys,
'state' => build.state.to_s,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'job_ids' => build.matrix_ids
}
end
def commit_data(commit, repository)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'branch_is_default' => branch_is_default(commit, repository),
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
def job_data(job)
{
'id' => job.id,
'repository_id' => job.repository_id,
'build_id' => job.source_id,
'commit_id' => job.commit_id,
'log_id' => job.log_id,
'state' => job.state.to_s,
'number' => job.number,
'config' => job.obfuscated_config.stringify_keys,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'queue' => job.queue,
'allow_failure' => job.allow_failure,
'tags' => job.tags,
'annotation_ids' => job.annotation_ids,
}
end
def branch_is_default(commit, repository)
repository.default_branch == commit.branch
end
def annotations(build)
build.matrix.map(&:annotations).flatten
end
end
end
end
end
end
end

View File

@ -1,71 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Builds
include Formats
attr_reader :builds, :commits, :options
def initialize(builds, options = {})
@builds = builds
@commits = builds.map(&:commit)
@options = options
end
def data
{
'builds' => builds.map { |build| build_data(build) },
'commits' => commits.map { |commit| commit_data(commit) }
}
end
private
def build_data(build)
{
'id' => build.id,
'repository_id' => build.repository_id,
'commit_id' => build.commit_id,
'number' => build.number,
'event_type' => build.event_type,
'pull_request' => build.pull_request?,
'pull_request_title' => build.pull_request_title,
'pull_request_number' => build.pull_request_number,
'config' => build.obfuscated_config.stringify_keys,
'state' => build.state.to_s,
'started_at' => format_date(build.started_at),
'finished_at' => format_date(build.finished_at),
'duration' => build.duration,
'job_ids' => matrix_ids(build)
}
end
def matrix_ids(build)
build.cached_matrix_ids || build.matrix_ids
end
def commit_data(commit)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
'pull_request_number' => commit.pull_request_number
}
end
end
end
end
end
end
end

View File

@ -1,37 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Caches
include Formats
attr_reader :caches, :options
def initialize(caches, options = {})
@caches = caches
@options = options
end
def data
{ 'caches' => caches.map { |cache| cache_data(cache) } }
end
private
def cache_data(cache)
{
'repository_id' => cache.repository.id,
'size' => cache.size,
'slug' => cache.slug,
'branch' => cache.branch,
'last_modified' => format_date(cache.last_modified)
}
end
end
end
end
end
end
end

View File

@ -1,25 +0,0 @@
module Travis
module Api
module Serialize
module V2
module Http
class EnvVar < Travis::Api::Serialize::ObjectSerializer
attributes :id, :name, :value, :public, :repository_id
def value
if object.public?
object.value.decrypt
end
end
def serializable_hash
hash = super
hash.delete :value unless object.public?
hash
end
end
end
end
end
end
end

View File

@ -1,2 +0,0 @@
class Travis::Api::Serialize::V2::Http::EnvVars < Travis::Api::Serialize::ArraySerializer
end

View File

@ -1,38 +0,0 @@
module Travis
module Api
module Serialize
module V2
module Http
class Hooks
attr_reader :hooks, :options
def initialize(hooks, options = {})
@hooks = hooks
@options = options
end
def data
{
'hooks' => hooks.map { |hook| hook_data(hook) },
}
end
private
def hook_data(hook)
{
'id' => hook.id,
'name' => hook.name,
'owner_name' => hook.owner_name,
'description' => hook.description,
'active' => hook.active,
'private' => hook.private,
'admin' => hook.admin?
}
end
end
end
end
end
end
end

View File

@ -1,72 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Job
include Formats
attr_reader :job, :options
def initialize(job, options = {})
@job = job
@options = options
end
def data
{
'job' => job_data(job),
'commit' => commit_data(job.commit, job.repository),
'annotations' => Annotations.new(job.annotations, @options).data["annotations"],
}
end
private
def job_data(job)
{
'id' => job.id,
'repository_id' => job.repository_id,
'repository_slug' => job.repository.slug,
'build_id' => job.source_id,
'commit_id' => job.commit_id,
'log_id' => job.log_id,
'number' => job.number,
'config' => job.obfuscated_config.stringify_keys,
'state' => job.state.to_s,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'queue' => job.queue,
'allow_failure' => job.allow_failure,
'tags' => job.tags,
'annotation_ids' => job.annotation_ids,
}
end
def commit_data(commit, repository)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'branch_is_default' => branch_is_default(commit, repository),
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
def branch_is_default(commit, repository)
repository.default_branch == commit.branch
end
end
end
end
end
end
end

View File

@ -1,65 +0,0 @@
require 'travis/api/serialize/formats'
module Travis
module Api
module Serialize
module V2
module Http
class Jobs
include Formats
attr_reader :jobs, :options
def initialize(jobs, options = {})
@jobs = jobs
@options = options
end
def data
{
'jobs' => jobs.map { |job| job_data(job) },
'commits' => jobs.map { |job| commit_data(job.commit) }
}
end
private
def job_data(job)
{
'id' => job.id,
'repository_id' => job.repository_id,
'repository_slug' => job.repository.slug,
'build_id' => job.source_id,
'commit_id' => job.commit_id,
'log_id' => job.log_id,
'number' => job.number,
'config' => job.obfuscated_config.stringify_keys,
'state' => job.state.to_s,
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'queue' => job.queue,
'allow_failure' => job.allow_failure,
'tags' => job.tags
}
end
def commit_data(commit)
{
'id' => commit.id,
'sha' => commit.commit,
'branch' => commit.branch,
'message' => commit.message,
'committed_at' => format_date(commit.committed_at),
'author_name' => commit.author_name,
'author_email' => commit.author_email,
'committer_name' => commit.committer_name,
'committer_email' => commit.committer_email,
'compare_url' => commit.compare_url,
}
end
end
end
end
end
end
end

View File

@ -1,80 +0,0 @@
module Travis
module Api
module Serialize
module V2
module Http
class Log
attr_reader :log, :options
def initialize(log, options = {})
@log = log
@options = options
end
def data
log_hash = options[:chunked] ? chunked_log_data : log_data
if log.removed_at
log_hash['removed_at'] = log.removed_at
log_hash['removed_by'] = log.removed_by.name || log.removed_by.login
end
{
'log' => log_hash,
}
end
private
def log_data
{
'id' => log.id,
'job_id' => log.job_id,
'type' => log.class.name.demodulize,
'body' => log.content
}
end
def chunked_log_data
{
'id' => log.id,
'job_id' => log.job_id,
'type' => log.class.name.demodulize,
'parts' => log_parts
}
end
def log_parts
if log.removed_at
# if log is removed we don't have actual parts
parts = [{ 'number' => 1, 'content' => log.content, 'final' => true }]
else
parts = log.parts
parts = parts.where(number: part_numbers) if part_numbers
parts = parts.where(["number > ?", after]) if after
parts.sort_by(&:number).map do |part|
{
'id' => part.id,
'number' => part.number,
'content' => part.content,
'final' => part.final
}
end
end
end
def after
after = options['after'].to_i
after == 0 ? nil : after
end
def part_numbers
if numbers = options['part_numbers']
numbers.is_a?(String) ? numbers.split(',').map(&:to_i) : numbers
end
end
end
end
end
end
end
end

View File

@ -1,52 +0,0 @@
module Travis
module Api
module Serialize
module V2
module Http
class Permissions
attr_reader :permissions, :options
def initialize(permissions, options = {})
@permissions = permissions
@options = options
end
def data
{
'permissions' => repo_ids,
'admin' => admin_ids,
'pull' => pull_ids,
'push' => push_ids
}
end
private
def filtered_ids(perm = nil)
if perm
permissions.find_all { |p| p.send("#{perm}?") }.map { |permission| permission.repository_id }
else
permissions.map { |permission| permission.repository_id }
end
end
def repo_ids
filtered_ids
end
def admin_ids
filtered_ids(:admin)
end
def pull_ids
filtered_ids(:pull)
end
def push_ids
filtered_ids(:push)
end
end
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show More