diff --git a/.gitignore b/.gitignore index 8b53bba0b..499bd7753 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ tmp .envrc #IDEs folders .idea -.vscode \ No newline at end of file +.vscode +.history \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 948296a8d..14187b378 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,15 +24,12 @@ services: before_install: - bundle config https://gems.contribsys.com/ $BUNDLE_GEMS__CONTRIBSYS__COM - - 'gem install bundler:1.16.2' + - 'gem install bundler' jobs: include: - stage: "testing time" script: bundle exec rspec - before_install: - - "gem update --system" - - "gem install bundler -v 1.16.2" - stage: ":ship: it to quay.io" dist: bionic ruby: @@ -45,4 +42,4 @@ jobs: install: echo "skipping" before_sript: skip script: make ship - if: (branch = master and type = push ) OR commit_message =~ /ship:docker/ OR env(SHIP_DOCKER) = true \ No newline at end of file + if: (branch = master and type = push ) OR commit_message =~ /ship:docker/ OR env(SHIP_DOCKER) = true diff --git a/Gemfile b/Gemfile index c51cca394..60ed9117b 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,6 @@ gem 'activerecord' gem 'faraday' gem 'faraday_middleware' -gem 'gh' gem 'keen' gem 'sentry-raven' gem 'simple_states', git: 'https://github.com/svenfuchs/simple_states' diff --git a/Gemfile.lock b/Gemfile.lock index c049a4dd6..4a2eac0d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,13 +113,6 @@ GEM multipart-post (>= 1.2, < 3) faraday_middleware (0.12.2) faraday (>= 0.7.4, < 1.0) - gh (0.15.1) - addressable (~> 2.4.0) - backports - faraday (~> 0.8) - multi_json (~> 1.0) - net-http-persistent (~> 2.9) - net-http-pipeline hashdiff (0.3.0) hashr (2.0.0) hitimes (1.2.6) @@ -147,8 +140,6 @@ GEM metaclass (~> 0.0.1) multi_json (1.12.1) multipart-post (2.0.0) - net-http-persistent (2.9.4) - net-http-pipeline (1.0.1) nio4r (2.5.2) pg (0.19.0) pry (0.11.3) @@ -231,7 +222,6 @@ DEPENDENCIES factory_girl faraday faraday_middleware - gh jemalloc jwt keen diff --git a/lib/travis/addons/handlers.rb b/lib/travis/addons/handlers.rb index 42642e8aa..f531f58a4 100644 --- a/lib/travis/addons/handlers.rb +++ b/lib/travis/addons/handlers.rb @@ -16,4 +16,5 @@ require 'travis/addons/handlers/slack' require 'travis/addons/handlers/pushover' require 'travis/addons/handlers/metrics' +require 'travis/addons/handlers/intercom' require 'travis/addons/handlers/billing' diff --git a/lib/travis/addons/handlers/billing.rb b/lib/travis/addons/handlers/billing.rb index fff631c3f..5fe440510 100644 --- a/lib/travis/addons/handlers/billing.rb +++ b/lib/travis/addons/handlers/billing.rb @@ -1,11 +1,12 @@ require 'travis/addons/handlers/base' require 'travis/addons/config' +require 'raven' module Travis module Addons module Handlers class Billing < Base - EVENTS = ['job:finished', 'job:canceled'].freeze + EVENTS = ['job:started', 'job:finished', 'job:canceled'].freeze KEY = :billing MSGS = { @@ -37,8 +38,13 @@ def publish end def send_usage(data) - response = connection.post('/usage/executions', data) - handle_usage_executions_response(response) unless response.success? + logger.info "Hub usage #{data}" + response = connection.put('/usage/executions', data) + logger.info "Hub usage repsonse #{response.success?} => #{response.inspect}" + return true if response.success? + + Raven.capture_exception BillingError.new("Data: #{data.inpect} => #{response.inspect}") + handle_usage_executions_response(response) if Travis::Hub.context.config.sentry.dsn end def data @@ -63,7 +69,8 @@ def job_data started_at: object.started_at, finished_at: object.finished_at, virt_type: config['virt'] || config['vm'], - queue: object.queue + queue: object.queue, + finished: finished? } end @@ -131,6 +138,10 @@ def logger Addons.logger end + def finished? + event != 'job:started' + end + # EventHandler class EventHandler < Addons::Instrument def notify_completed @@ -138,6 +149,8 @@ def notify_completed end end EventHandler.attach_to(self) + + class BillingError < StandardError; end end end end diff --git a/lib/travis/addons/handlers/intercom.rb b/lib/travis/addons/handlers/intercom.rb new file mode 100644 index 000000000..444361f78 --- /dev/null +++ b/lib/travis/addons/handlers/intercom.rb @@ -0,0 +1,53 @@ +require 'travis/addons/handlers/base' +require 'travis/addons/handlers/task' + +module Travis + module Addons + module Handlers + class Intercom < Base + include Handlers::Task + + EVENTS = /(build):(created|started|restarted)/ + + def handle? + owner_type.downcase == 'user' + end + + def handle + params = { + event: :report_build, + owner_id: owner_id, + last_build_at: last_build_at + } + run_task(:intercom, {}, params) + end + + class Instrument < Addons::Instrument + def notify_completed + publish + end + end + Instrument.attach_to(self) + + private + + def last_build_at + DateTime.now + end + + def owner + object.owner || nil + end + + def owner_id + owner.id.to_s if owner + end + + def owner_type + owner ? owner.class.name : '' + end + + end + end + end +end diff --git a/lib/travis/addons/serializer/tasks/build.rb b/lib/travis/addons/serializer/tasks/build.rb index 042e542ee..0e4ab9285 100644 --- a/lib/travis/addons/serializer/tasks/build.rb +++ b/lib/travis/addons/serializer/tasks/build.rb @@ -64,7 +64,7 @@ def owner_data def repository_data { id: repository.id, - github_id: repository.github_id, + github_id: repository.vcs_id.to_i, vcs_id: repository.vcs_id, vcs_type: repository.vcs_type, key: repository.key.try(:public_key), diff --git a/lib/travis/hub/service/notify_workers.rb b/lib/travis/hub/service/notify_workers.rb index 7f53bb626..a8dc5057e 100644 --- a/lib/travis/hub/service/notify_workers.rb +++ b/lib/travis/hub/service/notify_workers.rb @@ -11,9 +11,9 @@ class NotifyWorkers < Struct.new(:context) job_board_cancel: 'Canceling via Job Board delete for ' } - def cancel(job) + def cancel(job, reason = '') cancel_via_job_board(job) - cancel_via_amqp(job) + cancel_via_amqp(job, reason) end private @@ -25,11 +25,15 @@ def cancel_via_job_board(job) job_board.cancel(job.id) end - def cancel_via_amqp(job) + def cancel_via_amqp(job, reason) info :amqp_cancel, job.id, job.state + context.amqp.fanout( 'worker.commands', - type: 'cancel_job', job_id: job.id, source: 'hub' + type: 'cancel_job', + job_id: job.id, + source: 'hub', + reason: reason ) end diff --git a/lib/travis/hub/service/update_job.rb b/lib/travis/hub/service/update_job.rb index 41157f142..7d8eead69 100644 --- a/lib/travis/hub/service/update_job.rb +++ b/lib/travis/hub/service/update_job.rb @@ -109,7 +109,7 @@ def error_job end def notify - NotifyWorkers.new(context).cancel(job) if job.reload.state == :canceled + NotifyWorkers.new(context).cancel(job, data[:reason]) if job.reload.state == :canceled NotifyTraceProcessor.new(context).notify(job, data) if event == :finish end diff --git a/spec/travis/addons/handlers/billing_spec.rb b/spec/travis/addons/handlers/billing_spec.rb index d430a5d1e..4639d482e 100644 --- a/spec/travis/addons/handlers/billing_spec.rb +++ b/spec/travis/addons/handlers/billing_spec.rb @@ -3,17 +3,39 @@ let(:job_config) { FactoryGirl.create(:job_config, repository_id: build.repository_id) } let(:job) { FactoryGirl.create(:job, owner: owner, config_id: job_config.id) } let(:owner) { FactoryGirl.create(:user) } - - before do - stub_request(:post, 'http://localhost:9292/usage/executions') + let!(:request) do + stub_request(:put, 'http://localhost:9292/usage/executions') .to_return(status: 200, body: '', headers: {}) end describe 'handle' do - let(:handler) { described_class.new('job:finished', id: job.id) } + let(:handler) { described_class.new(event_name, id: job.id) } + + context 'job:finished' do + let(:event_name) { 'job:finished' } + + it 'publishes event to billing' do + handler.handle + expect(request).to have_been_made + end + end + + context 'job:canceled' do + let(:event_name) { 'job:canceled' } + + it 'publishes event to billing' do + handler.handle + expect(request).to have_been_made + end + end + + context 'job:started' do + let(:event_name) { 'job:started' } - it 'publishes to billing' do - handler.handle + it 'publishes event to billing' do + handler.handle + expect(request).to have_been_made + end end end end diff --git a/spec/travis/addons/serializer/generic/build_spec.rb b/spec/travis/addons/serializer/generic/build_spec.rb index 774f992ce..1b154a780 100644 --- a/spec/travis/addons/serializer/generic/build_spec.rb +++ b/spec/travis/addons/serializer/generic/build_spec.rb @@ -1,6 +1,6 @@ describe Travis::Addons::Serializer::Tasks::Build do let(:owner) { FactoryGirl.create(:user, login: 'login') } - let(:repo) { FactoryGirl.create(:repository, github_id: 12345, vcs_id: '12345', vcs_type: 'GithubRepository') } + let(:repo) { FactoryGirl.create(:repository, vcs_id: '12345', vcs_type: 'GithubRepository') } let(:build) { FactoryGirl.create(:build, owner: owner, repository: repo, pull_request: pull, tag: tag, jobs: [job]) } let(:stage) { FactoryGirl.create(:stage, number: 1, name: 'example') } let(:job) { FactoryGirl.create(:job, repository: repo, stage: stage) } @@ -39,7 +39,7 @@ it 'repository data' do expect(data[:repository]).to eql( id: repo.id, - github_id: 12345, + github_id: repo.vcs_id.to_i, vcs_id: '12345', vcs_type: 'GithubRepository', key: nil, diff --git a/spec/travis/hub/service/update_build_spec.rb b/spec/travis/hub/service/update_build_spec.rb index 87a5f904b..0206346b2 100644 --- a/spec/travis/hub/service/update_build_spec.rb +++ b/spec/travis/hub/service/update_build_spec.rb @@ -135,7 +135,7 @@ end it 'notifies workers' do - amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub') + amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub', reason: '') subject.run end @@ -168,7 +168,7 @@ end it 'notifies workers' do - amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub') + amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub', reason: '') subject.run end diff --git a/spec/travis/hub/service/update_job_spec.rb b/spec/travis/hub/service/update_job_spec.rb index 59a53994b..8219b5924 100644 --- a/spec/travis/hub/service/update_job_spec.rb +++ b/spec/travis/hub/service/update_job_spec.rb @@ -47,7 +47,7 @@ end it 'broadcasts a cancel message' do - amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub') + amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub', reason: '') subject.run end end @@ -77,7 +77,7 @@ end it 'broadcasts a cancel message' do - amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub') + amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub', reason: '') subject.run end end @@ -102,7 +102,7 @@ describe 'cancel event' do let(:state) { :created } let(:event) { :cancel } - let(:data) { { id: job.id } } + let(:data) { { id: job.id, reason: 'Insufficient funds' } } let(:now) { Time.now } it 'updates the job' do @@ -112,7 +112,7 @@ end it 'notifies workers' do - amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub') + amqp.expects(:fanout).with('worker.commands', type: 'cancel_job', job_id: job.id, source: 'hub', reason: 'Insufficient funds') subject.run end