moved travis-core to vendor

This commit is contained in:
Renée Hendricksen 2016-05-30 14:30:29 +02:00 committed by Tyranja
parent 7691d04de0
commit 4b6c177311
267 changed files with 13512 additions and 4 deletions

3
.gitignore vendored
View File

@ -6,8 +6,7 @@ config/skylight.yml
tmp/
log/
logs/
vendor
!vendor/travis-core/lib/travis/logs/
.yardoc
.coverage

View File

@ -49,9 +49,9 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-migrations.git
revision: bf360857ef7830f7e3ff12de181ab58c33fb29f1
revision: dc432e45354287c617c3ae07a72e9e3c4be012cd
specs:
travis-migrations (0.0.1)
travis-migrations (0.0.2)
GIT
remote: git://github.com/travis-ci/travis-sidekiqs.git

View File

@ -13,6 +13,24 @@ Gem::Specification.new do |s|
"Andre Arko",
"Brian Ford",
"Bryan Goldstein",
"Konstantin Haase",
"Piotr Sarnacki",
"carlad",
"Sven Fuchs",
"Hiro Asari",
"Mathias Meyer",
"Josh Kalderimis",
"Henrik Hodne",
"Steffen Kötte",
"Tyranja",
"Lennard Wolf",
"Renée Hendricksen",
"Ana Rosas",
"Steffen",
"Jonas Chromik",
"Dan Buch",
"Andre Arko",
"Erik Michaels-Ober",
"C. Scott Ananian",
"Christopher Weyand",
"Dan Buch",

99
vendor/travis-core/lib/travis.rb vendored Normal file
View File

@ -0,0 +1,99 @@
require 'pusher'
require 'travis/support'
require 'travis/support/database'
require 'travis_core/version'
require 'travis/redis_pool'
require 'travis/errors'
# travis-core holds the central parts of the model layer used in both travis-ci
# (i.e. the web application) as well as travis-hub (a non-rails ui-less JRuby
# application that receives, processes and distributes messages from/to the
# workers and issues various events like email, pusher, irc notifications and
# so on).
#
# travis/model - contains ActiveRecord models that and model the main
# parts of the domain logic (e.g. repository, build, job
# etc.) and issue events on state changes (e.g.
# build:created, job:test:finished etc.)
# travis/event - contains event handlers that register for certain
# events and send out such things as email, pusher, irc
# notifications, archive builds or queue jobs for the
# workers.
# travis/mailer - contains ActionMailers for sending out email
# notifications
#
# travis-core also contains some helper classes and modules like Travis::Database
# (needed in travis-hub in order to connect to the database) and Travis::Renderer
# (our inferior layer on top of Rabl).
module Travis
class << self
def services=(services)
# Travis.logger.info("Using services: #{services}")
@services = services
end
def services
@services ||= Travis::Services
end
end
require 'travis/model'
require 'travis/task'
require 'travis/event'
require 'travis/addons'
require 'travis/api'
require 'travis/config/defaults'
require 'travis/commit_command'
require 'travis/enqueue'
require 'travis/features'
require 'travis/github'
require 'travis/logs'
require 'travis/mailer'
require 'travis/notification'
require 'travis/requests'
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
Addons.register
Services.register
Enqueue::Services.register
Github::Services.register
Logs::Services.register
Requests::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

@ -0,0 +1,16 @@
# Travis Core directory overview
This folder, `lib/travis` contains the main code for the Travis Core repository. It contains several sub-section/subdirectories:
- [`addons`](addons): Event handlers that take events such as "build finished" and sends out notifications to GitHub, Pusher, Campfire, etc.
- [`api`](api): Serializers for models and events used in our API and in some other places (for example to generate Pusher payloads).
- [`enqueue`](enqueue): Logic for enqueueing jobs.
- [`event`](event): Code for sending and subscribing to events. Used by the `addons` code to subscribe to changes in the models.
- [`github`](github): Services for communicating with the GitHub API.
- [`mailer`](mailer): ActionMailer mailers.
- [`model`](model): All of our ActiveRecord models.
- [`notification`](notification): Code for adding instrumentation.
- [`requests`](requests): Handles requests received from GitHub.
- [`secure_config.rb`](secure_config.rb): Logic for encrypting and decrypting build/job configs.
- [`services`](services): Most of the business logic behind our [API](https://github.com/travis-ci/travis-api).
- [`testing`](testing): Code used by our tests, such as model stubs and factories.

31
vendor/travis-core/lib/travis/addons.rb vendored Normal file
View File

@ -0,0 +1,31 @@
require 'travis/notification'
module Travis
module Addons
require 'travis/addons/archive'
require 'travis/addons/campfire'
require 'travis/addons/email'
require 'travis/addons/flowdock'
require 'travis/addons/github_status'
require 'travis/addons/hipchat'
require 'travis/addons/irc'
require 'travis/addons/pusher'
require 'travis/addons/states_cache'
require 'travis/addons/sqwiggle'
require 'travis/addons/webhook'
require 'travis/addons/slack'
require 'travis/addons/pushover'
class << self
def register
constants(false).each do |name|
key = name.to_s.underscore
const = const_get(name)
handler = const.const_get(:EventHandler) rescue nil
Travis::Event::Subscription.register(key, handler) if handler
const.setup if const.respond_to?(:setup)
end
end
end
end
end

View File

@ -0,0 +1,17 @@
# Travis Core Addons
The Addons are event handlers that accepts events such as "build finished" and forwards them to different services. The different services are:
- Campfire
- E-mail
- Flowdock
- GitHub Commit Statuses
- Hipchat
- IRC
- Pusher: Used to update our Web UI automatically.
- Sqwiggle
- States cache: Caches the state of each branch in Memcached for status images.
- Webhook
- Pushover
To add a new notification service, an event handler and a task is needed. The event handler is run by [`travis-hub`](https://github.com/travis-ci/travis-hub) and has access to the database. This should check whether the event should be forwarded at all, and pull out any necessary configuration values. It should then asynchronously run the corresponding Task. The Task is run by [`travis-tasks`](https://github.com/travis-ci/travis-tasks) via Sidekiq and should do the actual API calls needed. The event handler should finish very quickly, while the task is allowed to take longer.

View File

@ -0,0 +1,8 @@
module Travis
module Addons
module Archive
require 'travis/addons/archive/event_handler'
require 'travis/addons/archive/task'
end
end
end

View File

@ -0,0 +1,36 @@
require 'travis/addons/archive/task'
require 'travis/event/handler'
require 'travis/features'
module Travis
module Addons
module Archive
class EventHandler < Event::Handler
EVENTS = /log:aggregated/
def handle?
Travis::Features.feature_active?(:log_archiving)
end
def handle
Travis::Addons::Archive::Task.run(:archive, payload)
end
def payload
@payload ||= { type: type, id: object.id, job_id: object.job_id }
end
def type
@type ||= event.split(':').first
end
class Instrument < Notification::Instrument::EventHandler
def notify_completed
publish(payload: handler.payload)
end
end
Instrument.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,24 @@
require 'travis/task'
module Travis
module Addons
module Archive
class Task < Travis::Task
def process
Travis.run_service(:"archive_#{payload[:type]}", id: payload[:id], job_id: payload[:job_id])
end
class Instrument < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<#{target.payload[:type].camelize} id=#{target.payload[:id]}>",
:object_type => target.payload[:type].camelize,
:object_id => target.payload[:id]
)
end
end
Instrument.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,13 @@
module Travis
module Addons
module Campfire
module Instruments
require 'travis/addons/campfire/instruments'
end
require 'travis/addons/campfire/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,33 @@
require 'travis/addons/campfire/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Campfire
# Publishes a build notification to campfire rooms as defined in the
# configuration (`.travis.yml`).
#
# Campfire credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:finished/
def handle?
!pull_request? && targets.present? && config.send_on_finished_for?(:campfire)
end
def handle
Travis::Addons::Campfire::Task.run(:campfire, payload, targets: targets)
end
def targets
@targets ||= config.notification_values(:campfire, :rooms)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,30 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Campfire
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request'][:id], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:targets => task.targets,
:message => task.message
)
end
end
end
end
end
end

View File

@ -0,0 +1,10 @@
module Travis
module Addons
module Email
require 'travis/addons/email/instruments'
require 'travis/addons/email/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,56 @@
require 'travis/addons/email/instruments'
require 'travis/event/handler'
require 'travis/model/broadcast'
module Travis
module Addons
module Email
# Sends out build notification emails using ActionMailer.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = ['build:finished', 'build:canceled']
def handle?
!pull_request? && config.enabled?(:email) && config.send_on_finished_for?(:email) && recipients.present?
end
def handle
Travis::Addons::Email::Task.run(:email, payload, recipients: recipients, broadcasts: broadcasts)
end
def recipients
@recipients ||= begin
recipients = config.notification_values(:email, :recipients)
recipients = config.notifications[:recipients] if recipients.blank? # TODO deprecate recipients
recipients = default_recipients if recipients.blank?
Array(recipients).join(',').split(',').map(&:strip).select(&:present?).uniq
end
end
private
def pull_request?
build['pull_request']
end
def broadcasts
Broadcast.by_repo(object.repository).map do |broadcast|
{ message: broadcast.message }
end
end
def default_recipients
recipients = object.repository.users.map {|u| u.emails.map(&:email)}.flatten
recipients.keep_if do |r|
r == object.commit.author_email or
r == object.commit.committer_email
end
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,30 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Email
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:recipients => handler.recipients)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request_id'], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:email => task.type,
:recipients => task.recipients
)
end
end
end
end
end
end

View File

@ -0,0 +1,10 @@
module Travis
module Addons
module Flowdock
require 'travis/addons/flowdock/instruments'
require 'travis/addons/flowdock/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,39 @@
require 'travis/addons/flowdock/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Flowdock
# Publishes a build notification to Flowdock rooms as defined in the
# configuration (`.travis.yml`).
#
# Flowdock credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:finished/
def initialize(*)
super
@payload = Api.data(object, for: 'event', version: 'v0', params: data)
end
def handle?
!pull_request? && targets.present? && config.send_on_finished_for?(:flowdock)
end
def handle
Travis::Addons::Flowdock::Task.run(:flowdock, payload, targets: targets)
end
def targets
@targets ||= config.notification_values(:flowdock, :rooms)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,31 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Flowdock
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request'][:id], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:targets => task.targets,
:message => task.message
)
end
end
end
end
end
end

View File

@ -0,0 +1,10 @@
module Travis
module Addons
module GithubStatus
require 'travis/addons/github_status/instruments'
require 'travis/addons/github_status/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,74 @@
require 'travis/addons/github_status/instruments'
require 'travis/event/handler'
module Travis
module Addons
module GithubStatus
# Adds a comment with a build notification to the pull-request the request
# belongs to.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:(created|started|finished|canceled)/
def handle?
return token.present? unless multi_token?
unless tokens.any?
error "No GitHub OAuth tokens found for #{object.repository.slug}"
end
tokens.any?
end
def handle
if multi_token?
Travis::Addons::GithubStatus::Task.run(:github_status, payload, tokens: tokens)
else
Travis::Addons::GithubStatus::Task.run(:github_status, payload, token: token)
end
end
private
def token
admin.try(:github_oauth_token)
end
def tokens
@tokens ||= users.map { |user| { user.login => user.github_oauth_token } }.inject({}, :merge)
end
def users
@users ||= [
build_committer,
admin,
users_with_push_access,
].flatten.compact
end
def build_committer
user = User.with_email(object.commit.committer_email)
user if user && user.permission?(repository_id: object.repository.id, push: true)
end
def admin
@admin ||= Travis.run_service(:find_admin, repository: object.repository)
rescue Travis::AdminMissing
nil
end
def users_with_push_access
object.repository.users_with_permission(:push)
end
def multi_token?
!Travis::Features.feature_deactivated?(:github_status_multi_tokens)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,30 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module GithubStatus
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request_id'], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:url => task.url.to_s
)
end
end
end
end
end
end

View File

@ -0,0 +1,10 @@
module Travis
module Addons
module Hipchat
require 'travis/addons/hipchat/instruments'
require 'travis/addons/hipchat/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,40 @@
require 'travis/addons/hipchat/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Hipchat
# Publishes a build notification to hipchat rooms as defined in the
# configuration (`.travis.yml`).
#
# Hipchat credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:finished/
def handle?
enabled? && targets.present? && config.send_on_finished_for?(:hipchat)
end
def handle
Travis::Addons::Hipchat::Task.run(:hipchat, payload, targets: targets)
end
def enabled?
enabled = config.notification_values(:hipchat, :on_pull_requests)
enabled = true if enabled.nil?
pull_request? ? enabled : true
end
def targets
@targets ||= config.notification_values(:hipchat, :rooms)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,31 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Hipchat
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request'][:id], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:targets => task.targets,
:message => task.message
)
end
end
end
end
end
end

View File

@ -0,0 +1,10 @@
module Travis
module Addons
module Irc
require 'travis/addons/irc/instruments'
require 'travis/addons/irc/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,32 @@
require 'travis/addons/irc/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Irc
# Publishes a build notification to IRC channels as defined in the
# configuration (`.travis.yml`).
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = 'build:finished'
def handle?
!pull_request? && channels.present? && config.send_on_finished_for?(:irc)
end
def handle
Travis::Addons::Irc::Task.run(:irc, payload, channels: channels)
end
def channels
@channels ||= config.notification_values(:irc, :channels)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,31 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Irc
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:channels => handler.channels)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request_id'], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:channels => task.channels,
:messages => task.messages
)
end
end
end
end
end
end

View File

@ -0,0 +1,11 @@
module Travis
module Addons
module Pusher
require 'travis/addons/pusher/instruments'
require 'travis/addons/pusher/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,57 @@
require 'travis/addons/pusher/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Pusher
# Notifies registered clients about various state changes through Pusher.
class EventHandler < Event::Handler
EVENTS = [
/^build:(created|received|started|finished|canceled)/,
/^job:test:(created|received|started|log|finished|canceled)/
]
attr_reader :channels, :pusher_payload
def initialize(*)
super
@pusher_payload = Api.data(object, :for => 'pusher', :type => type, :params => data) if handle?
end
def handle?
true
end
def handle
Travis::Addons::Pusher::Task.run(queue, pusher_payload, :event => event)
end
private
def type
event.sub('test:', '').sub(':', '/')
end
def queue
if Travis::Features.enabled_for_all?(:"pusher-live") ||
Travis::Features.repository_active?(:"pusher-live", repository_id)
:"pusher-live"
else
:pusher
end
end
def repository_id
if payload && payload['repository'] && payload['repository']['id']
payload['repository']['id']
elsif object && object.repository && object.repository.id
object.repository.id
end
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,42 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Pusher
module Instruments
def self.publish?(event)
event.to_s != 'job:test:log'
end
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish if Instruments.publish?(handler.event)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<#{type.camelize} id=#{id}> (event: #{task.event}, channels: #{task.channels.join(', ')})",
:object_type => type.camelize,
:object_id => id,
:event => task.event,
:client_event => task.client_event,
:channels => task.channels
) if Instruments.publish?(task.event)
end
def type
@type ||= task.event.split(':').first
end
def id
payload.key?(type.to_sym) ? payload[type.to_sym][:id] : payload[:id]
end
end
end
end
end
end

View File

@ -0,0 +1,13 @@
module Travis
module Addons
module Pushover
module Instruments
require 'travis/addons/pushover/instruments'
end
require 'travis/addons/pushover/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,37 @@
require 'travis/addons/pushover/instruments'
require 'travis/event/handler'
module Travis
module Addons
module Pushover
# Publishes a build notification to pushover users as defined in the
# configuration (`.travis.yml`).
#
# Credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:finished/
def handle?
!pull_request? && users.present? && api_key.present? && config.send_on_finished_for?(:pushover)
end
def handle
Travis::Addons::Pushover::Task.run(:pushover, payload, users: users, api_key: api_key)
end
def users
@users ||= config.notification_values(:pushover, :users)
end
def api_key
@api_key ||= config.notifications[:pushover][:api_key]
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,30 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Pushover
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:users => handler.users, :api_key => handler.api_key)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
:object_type => 'Build',
:object_id => payload[:build][:id],
:users => task.users,
:message => task.message,
:api_key => task.api_key
)
end
end
end
end
end
end

View File

@ -0,0 +1,11 @@
module Travis
module Addons
module Slack
require 'travis/addons/slack/instruments'
require 'travis/addons/slack/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,30 @@
module Travis
module Addons
module Slack
# Publishes a build notification to Slack rooms as defined in the
# configuration (`.travis.yml`).
#
# Slack credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
API_VERSION = 'v2'
EVENTS = /build:finished/
def handle?
targets.present? && config.send_on_finished_for?(:slack)
end
def handle
Travis::Addons::Slack::Task.run(:slack, payload, targets: targets)
end
def targets
@targets ||= config.notification_values(:slack, :rooms)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,25 @@
module Travis
module Addons
module Slack
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
:object_type => 'Build',
:object_id => payload[:build][:id],
:targets => task.targets
)
end
end
end
end
end
end

View File

@ -0,0 +1,11 @@
module Travis
module Addons
module Sqwiggle
require 'travis/addons/sqwiggle/instruments'
require 'travis/addons/sqwiggle/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,30 @@
module Travis
module Addons
module Sqwiggle
# Publishes a build notification to sqwiggle rooms as defined in the
# configuration (`.travis.yml`).
#
# sqwiggle credentials are encrypted using the repository's ssl key.
class EventHandler < Event::Handler
EVENTS = /build:finished/
def handle?
!pull_request? && targets.present? && config.send_on_finished_for?(:sqwiggle)
end
def handle
Travis::Addons::Sqwiggle::Task.run(:sqwiggle, payload, targets: targets)
end
def targets
@targets ||= config.notification_values(:sqwiggle, :rooms)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,29 @@
module Travis
module Addons
module Sqwiggle
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:build][:id]}>",
:repository => payload[:repository][:slug],
# :request_id => payload['request'][:id], # TODO
:object_type => 'Build',
:object_id => payload[:build][:id],
:targets => task.targets,
:message => task.message
)
end
end
end
end
end
end

View File

@ -0,0 +1,7 @@
module Travis
module Addons
module StatesCache
require 'travis/addons/states_cache/event_handler'
end
end
end

View File

@ -0,0 +1,47 @@
require 'travis/event/handler'
module Travis
module Addons
module StatesCache
class EventHandler < Event::Handler
EVENTS = /build:finished/
def handle?
states_cache_enabled = Travis::Features.feature_active?(:states_cache)
result = !pull_request? && states_cache_enabled
Travis.logger.info("[states-cache] Checking if event handler should be run for " +
"repo_id=#{repository_id} branch=#{branch} build_id=#{build['id']}, result: #{result}, " +
"pull_request: #{pull_request?} states_cache_enabled: #{states_cache_enabled}")
result
end
def handle
Travis.logger.info("[states-cache] Running event handler for repo_id=#{repository_id} build_id=#{build['id']} branch=#{branch}")
cache.write(repository_id, branch, data)
rescue Exception => e
Travis.logger.error("[states-cache] An error occurred while trying to handle states cache update: #{e.message}\n#{e.backtrace}")
raise
end
def cache
Travis.states_cache
end
def repository_id
build['repository_id']
end
def branch
commit['branch']
end
def data
{
'id' => build['id'],
'state' => build['state']
}
end
end
end
end
end

View File

@ -0,0 +1,7 @@
module Travis
module Addons
module Util
require 'travis/addons/util/template'
end
end
end

View File

@ -0,0 +1,11 @@
module Travis
module Addons
module Webhook
require 'travis/addons/webhook/instruments'
require 'travis/addons/webhook/event_handler'
class Task < ::Travis::Task; end
end
end
end

View File

@ -0,0 +1,39 @@
require 'travis/addons/webhook/instruments'
require 'travis/event/handler'
# TODO include_logs? has been removed. gotta be deprecated!
#
module Travis
module Addons
module Webhook
# Sends build notifications to webhooks as defined in the configuration
# (`.travis.yml`).
class EventHandler < Event::Handler
EVENTS = /build:(started|finished)/
def initialize(*)
super
end
def handle?
targets.present? && config.send_on?(:webhooks, event.split(':').last)
end
def handle
Travis::Addons::Webhook::Task.run(:webhook, webhook_payload, targets: targets, token: request['token'])
end
def webhook_payload
Api.data(object, :for => 'webhook', :type => 'build/finished', :version => 'v1')
end
def targets
@targets ||= config.notification_values(:webhooks, :urls)
end
Instruments::EventHandler.attach_to(self)
end
end
end
end

View File

@ -0,0 +1,29 @@
require 'travis/notification/instrument/event_handler'
require 'travis/notification/instrument/task'
module Travis
module Addons
module Webhook
module Instruments
class EventHandler < Notification::Instrument::EventHandler
def notify_completed
publish(:targets => handler.targets)
end
end
class Task < Notification::Instrument::Task
def run_completed
publish(
:msg => "for #<Build id=#{payload[:id]}>",
:repository => payload[:repository].values_at(:owner_name, :name).join('/'),
:object_type => 'Build',
:object_id => payload[:id],
:targets => task.targets
)
end
end
end
end
end
end

View File

@ -0,0 +1,59 @@
require 'zlib'
module Travis
# http://hashrocket.com/blog/posts/advisory-locks-in-postgres
# https://github.com/mceachen/with_advisory_lock
# 13.3.4. Advisory Locks : http://www.postgresql.org/docs/9.3/static/explicit-locking.html
# http://www.postgresql.org/docs/9.3/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
class AdvisoryLocks
attr_reader :lock_name, :transactional
def initialize(lock_name, transactional = false)
if lock_name.blank?
raise StandardError, "lock name cannot be blank"
end
@lock_name = lock_name
end
# must be used within a transaction
def self.exclusive(lock_name, timeout = 30, transactional = false)
al = self.new(lock_name, transactional)
al.exclusive(timeout) { yield }
end
# must be used within a transaction
def exclusive(timeout = 30)
give_up_at = Time.now + timeout if timeout
while timeout.nil? || Time.now < give_up_at do
if obtained_lock?
return yield
else
# Randomizing sleep time may help reduce contention.
sleep(rand(0.1..0.2))
end
end
ensure
release_lock unless transactional
end
private
def obtained_lock?
xact = transactional ? "_xact" : nil
result = connection.select_value("select pg_try_advisory#{xact}_lock(#{lock_code});")
result == 't' || result == 'true'
end
def release_lock
connection.execute("select pg_advisory_unlock(#{lock_code});")
end
def connection
ActiveRecord::Base.connection
end
def lock_code
Zlib.crc32(lock_name)
end
end
end

67
vendor/travis-core/lib/travis/api.rb vendored Normal file
View File

@ -0,0 +1,67 @@
module Travis
module Api
require 'travis/api/formats'
require 'travis/api/v0'
require 'travis/api/v1'
require 'travis/api/v2'
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(Travis::Api) 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

View File

@ -0,0 +1,10 @@
This directory contains serializers for events and models.
- `v0/event`: Payloads used by [`Travis::Event::Handler`](../event/handler.rb). These are the payloads that the [addons](../addons) will get.
- `v0/pusher`: Payloads used to send events to the web UI using Pusher.
- `v0/worker`: Payloads sent to [travis-worker](https://github.com/travis-ci/travis-worker).
- `v1/http`: Payloads for the v1 [API](https://github.com/travis-ci/travis-api).
- `v1/webhook`: Payloads for the webhook notifications.
- `v2/http`: Payloads for the v2 [API](https://github.com/travis-ci/travis-api).

View File

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

11
vendor/travis-core/lib/travis/api/v0.rb vendored Normal file
View File

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

View File

@ -0,0 +1,12 @@
module Travis
module Api
module V0
module Event
require 'travis/api/v0/event/build'
require 'travis/api/v0/event/job'
end
end
end
end

View File

@ -0,0 +1,95 @@
module Travis
module Api
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

View File

@ -0,0 +1,38 @@
module Travis
module Api
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

View File

@ -0,0 +1,12 @@
module Travis
module Api
module V0
module Notification
require 'travis/api/v0/notification/build'
require 'travis/api/v0/notification/repository'
require 'travis/api/v0/notification/user'
end
end
end
end

View File

@ -0,0 +1,28 @@
module Travis
module Api
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

View File

@ -0,0 +1,28 @@
module Travis
module Api
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

View File

@ -0,0 +1,28 @@
module Travis
module Api
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

View File

@ -0,0 +1,11 @@
module Travis
module Api
module V0
module Pusher
require 'travis/api/v0/pusher/annotation'
require 'travis/api/v0/pusher/build'
require 'travis/api/v0/pusher/job'
end
end
end
end

View File

@ -0,0 +1,33 @@
module Travis
module Api
module V0
module Pusher
class Annotation
require 'travis/api/v0/pusher/annotation/created'
require 'travis/api/v0/pusher/annotation/updated'
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

View File

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

View File

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

View File

@ -0,0 +1,111 @@
module Travis
module Api
module V0
module Pusher
class Build
require 'travis/api/v0/pusher/build/canceled'
require 'travis/api/v0/pusher/build/created'
require 'travis/api/v0/pusher/build/received'
require 'travis/api/v0/pusher/build/started'
require 'travis/api/v0/pusher/build/finished'
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

View File

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

View File

@ -0,0 +1,15 @@
require 'travis/api/v1'
module Travis
module Api
module V0
module Pusher
class Build
class Created < Build
end
end
end
end
end
end

View File

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

View File

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

View File

@ -0,0 +1,47 @@
module Travis
module Api
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

View File

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

View File

@ -0,0 +1,47 @@
module Travis
module Api
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

View File

@ -0,0 +1,67 @@
module Travis
module Api
module V0
module Pusher
class Job
require 'travis/api/v0/pusher/job/canceled'
require 'travis/api/v0/pusher/job/created'
require 'travis/api/v0/pusher/job/log'
require 'travis/api/v0/pusher/job/received'
require 'travis/api/v0/pusher/job/started'
require 'travis/api/v0/pusher/job/finished'
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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,31 @@
module Travis
module Api
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

View File

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

View File

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

View File

@ -0,0 +1,9 @@
module Travis
module Api
module V0
module Worker
require 'travis/api/v0/worker/job'
end
end
end
end

View File

@ -0,0 +1,33 @@
module Travis
module Api
module V0
module Worker
class Job
require 'travis/api/v0/worker/job/test'
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

View File

@ -0,0 +1,118 @@
module Travis
module Api
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

10
vendor/travis-core/lib/travis/api/v1.rb vendored Normal file
View File

@ -0,0 +1,10 @@
module Travis
module Api
module V1
require 'travis/api/v1/archive'
require 'travis/api/v1/http'
require 'travis/api/v1/helpers'
require 'travis/api/v1/webhook'
end
end
end

View File

@ -0,0 +1,9 @@
module Travis
module Api
module V1
module Archive
require 'travis/api/v1/archive/build'
end
end
end
end

View File

@ -0,0 +1,50 @@
module Travis
module Api
module V1
module Archive
class Build
autoload :Job, 'travis/api/v1/archive/build/job'
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

View File

@ -0,0 +1,31 @@
module Travis
module Api
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

View File

@ -0,0 +1,9 @@
module Travis
module Api
module V1
module Helpers
require 'travis/api/v1/helpers/legacy'
end
end
end
end

View File

@ -0,0 +1,34 @@
module Travis
module Api
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

View File

@ -0,0 +1,17 @@
module Travis
module Api
module V1
module Http
require 'travis/api/v1/http/branches'
require 'travis/api/v1/http/build'
require 'travis/api/v1/http/builds'
require 'travis/api/v1/http/hooks'
require 'travis/api/v1/http/job'
require 'travis/api/v1/http/jobs'
require 'travis/api/v1/http/repositories'
require 'travis/api/v1/http/repository'
require 'travis/api/v1/http/user'
end
end
end
end

View File

@ -0,0 +1,43 @@
require 'travis/api/v1/helpers/legacy'
module Travis
module Api
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

View File

@ -0,0 +1,47 @@
module Travis
module Api
module V1
module Http
class Build
require 'travis/api/v1/http/build/job'
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

View File

@ -0,0 +1,32 @@
module Travis
module Api
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

View File

@ -0,0 +1,38 @@
module Travis
module Api
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

View File

@ -0,0 +1,34 @@
module Travis
module Api
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

View File

@ -0,0 +1,44 @@
module Travis
module Api
module V1
module Http
class Job
include Formats, Helpers::Legacy
attr_reader :job, :commit
def initialize(job, options = {})
@job = job
@commit = job.commit
end
def data
{
'id' => job.id,
'number' => job.number,
'config' => job.obfuscated_config.stringify_keys,
'repository_id' => job.repository_id,
'build_id' => job.source_id,
'state' => job.finished? ? 'finished' : job.state.to_s,
'result' => legacy_job_result(job),
'status' => legacy_job_result(job),
'started_at' => format_date(job.started_at),
'finished_at' => format_date(job.finished_at),
'log' => job.log_content,
'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,
'worker' => job.worker
}
end
end
end
end
end
end

View File

@ -0,0 +1,34 @@
module Travis
module Api
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

View File

@ -0,0 +1,37 @@
module Travis
module Api
module V1
module Http
class Repositories
include Formats, Helpers::Legacy
attr_reader :repositories
def initialize(repositories, options = {})
@repositories = repositories
end
def data
repositories.map { |repository| repository_data(repository) }
end
def repository_data(repository)
{
'id' => repository.id,
'slug' => repository.slug,
'description' => repository.description,
'last_build_id' => repository.last_build_id,
'last_build_number' => repository.last_build_number,
'last_build_status' => legacy_repository_last_build_result(repository),
'last_build_result' => legacy_repository_last_build_result(repository),
'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),
}
end
end
end
end
end
end

View File

@ -0,0 +1,34 @@
module Travis
module Api
module V1
module Http
class Repository
include Formats, Helpers::Legacy
attr_reader :repository, :options
def initialize(repository, options = {})
@repository = repository
end
def data
{
'id' => repository.id,
'slug' => repository.slug,
'description' => repository.description,
'public_key' => repository.key.public_key,
'last_build_id' => repository.last_build_id,
'last_build_number' => repository.last_build_number,
'last_build_status' => legacy_repository_last_build_result(repository),
'last_build_result' => legacy_repository_last_build_result(repository),
'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),
}
end
end
end
end
end
end

View File

@ -0,0 +1,31 @@
module Travis
module Api
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

View File

@ -0,0 +1,9 @@
module Travis
module Api
module V1
module Webhook
require 'travis/api/v1/webhook/build'
end
end
end
end

View File

@ -0,0 +1,27 @@
module Travis
module Api
module V1
module Webhook
class Build
require 'travis/api/v1/webhook/build/finished'
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

View File

@ -0,0 +1,70 @@
module Travis
module Api
module V1
module Webhook
class Build
class Finished < Build
require 'travis/api/v1/webhook/build/finished/job'
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

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