Add current_build to repositories payload

current_build is the most recent build that is either completed or
running
This commit is contained in:
Piotr Sarnacki 2016-05-10 15:37:43 +02:00
parent 9d386efa4c
commit c9b93982c9
9 changed files with 141 additions and 4 deletions

View File

@ -20,6 +20,15 @@ module Travis::API::V3
update_attributes! default_branch_name: 'master'.freeze unless default_branch_name
end
def current_build
if self[:current_build_id]
Travis::API::V3::Models::Build.find(self[:current_build_id])
else
builds.where(state: ['started', 'passed', 'errored', 'failed', 'canceled'],
event_type: ['push', 'api', 'cron']).order("id DESC").first
end
end
def slug
@slug ||= "#{owner_name}/#{name}"
end

View File

@ -1,7 +1,7 @@
module Travis::API::V3
class Queries::Repositories < Query
params :active, :private, :starred, prefix: :repository
sortable_by :id, :github_id, :owner_name, :name, active: sort_condition(:active), :'default_branch.last_build' => 'builds.started_at'
sortable_by :id, :github_id, :owner_name, :name, active: sort_condition(:active), :'default_branch.last_build' => 'builds.started_at', :current_build => "current_build.id %{order} NULLS LAST"
def for_member(user, **options)
all(user: user, **options).joins(:users).where(users: user_condition(user), invalidated_at: nil)
@ -36,7 +36,25 @@ module Travis::API::V3
list = list.includes(default_branch: :last_build)
list = list.includes(default_branch: { last_build: :commit }) if includes? 'build.commit'.freeze
sort list
sort add_current_build list
end
# this will add SQL needed to fetch current_build along with the
# repositories list. It will probably go away soon, once we test the current
# build and use current_build_id column, just as we do with last_build for
# branches
def add_current_build(list)
join = "
LEFT OUTER JOIN builds as %{column_alias}
ON %{column_alias}.repository_id = repositories.id AND
%{column_alias}.event_type IN ('api', 'push', 'cron') AND
%{column_alias}.state IN ('started', 'errored', 'passed', 'finished', 'canceled')"
list = list.joins(join % { column_alias: 'current_build' })
list = list.joins(join % { column_alias: 'older_builds' }+ " AND current_build.id < older_builds.id")
list = list.where("older_builds.id IS NULL")
list.select("repositories.*, current_build.id as current_build_id")
end
end
end

View File

@ -150,7 +150,7 @@ module Travis::API::V3
def sort_by(collection, field, order: nil, first: false, sql: nil, **)
raise ArgumentError, 'cannot sort by that' unless sort_by?(field, order)
actual = sql || self.class.sort_by.fetch(field)
line = "#{actual} #{order.upcase}"
line = add_order(actual, order)
if sort_join?(collection, actual)
collection = collection.joins(actual.to_sym)
@ -181,5 +181,14 @@ module Travis::API::V3
else raise WrongParams
end
end
def add_order(field, order)
order = order.upcase
if field =~ /%{order}/
field % { order: order }
else
"#{field} #{order}"
end
end
end
end

View File

@ -2,5 +2,16 @@ module Travis::API::V3
class Renderer::Repositories < Renderer::CollectionRenderer
type :repositories
collection_key :repositories
def render
preload
super
end
def preload
# preload builds that we will need
current_build_ids = list.map { |r| r[:current_build_id] }.compact
Travis::API::V3::Models::Build.find(current_build_ids)
end
end
end

View File

@ -3,7 +3,7 @@ require 'travis/api/v3/renderer/model_renderer'
module Travis::API::V3
class Renderer::Repository < Renderer::ModelRenderer
representation(:minimal, :id, :name, :slug)
representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch, :starred)
representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch, :starred, :current_build)
def active
!!model.active

View File

@ -81,6 +81,7 @@ describe Travis::API::V3::Services::Owner::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => nil,
"starred" => false
}]
}}
@ -129,6 +130,7 @@ describe Travis::API::V3::Services::Owner::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation"=> "minimal",
"name" => "master"},
"current_build" => nil,
"starred" => false
}]
}}

View File

@ -3,6 +3,7 @@ require 'spec_helper'
describe Travis::API::V3::Services::Repositories::ForCurrentUser do
let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first }
let(:build) { repo.builds.first }
let(:current_build) { repo.current_build }
let(:jobs) { Travis::API::V3::Models::Build.find(build.id).jobs }
let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) }
@ -63,6 +64,18 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}]
}}

View File

@ -3,6 +3,7 @@ require 'spec_helper'
describe Travis::API::V3::Services::Repositories::ForOwner do
let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first }
let(:build) { repo.builds.first }
let(:current_build) { repo.current_build }
let(:jobs) { Travis::API::V3::Models::Build.find(build.id).jobs }
let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) }
@ -64,6 +65,18 @@ describe Travis::API::V3::Services::Repositories::ForOwner do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}]}}
end
@ -141,6 +154,18 @@ describe Travis::API::V3::Services::Repositories::ForOwner do
"@href" => "/v3/repo/1/branch/master",
"@representation"=>"minimal",
"name" => "master" },
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false }, {
"@type" => "repository",
"@href" => "/v3/repo/#{repo2.id}",
@ -170,6 +195,7 @@ describe Travis::API::V3::Services::Repositories::ForOwner do
"@href" => "/v3/repo/#{repo2.id}/branch/master",
"@representation"=>"minimal",
"name" =>"master" },
"current_build" => nil,
"starred"=>false}]}
end
end

View File

@ -3,6 +3,7 @@ require 'spec_helper'
describe Travis::API::V3::Services::Repository::Find do
let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first }
let(:build) { repo.builds.first }
let(:current_build) { repo.current_build }
let(:jobs) { Travis::API::V3::Models::Build.find(build.id).jobs }
let(:parsed_body) { JSON.load(body) }
@ -55,6 +56,18 @@ describe Travis::API::V3::Services::Repository::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}}
end
@ -133,6 +146,18 @@ describe Travis::API::V3::Services::Repository::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}}
end
@ -196,6 +221,18 @@ describe Travis::API::V3::Services::Repository::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}}
end
@ -265,6 +302,18 @@ describe Travis::API::V3::Services::Repository::Find do
"@href" => "/v3/repo/#{repo.id}/branch/master",
"@representation" => "minimal",
"name" => "master"},
"current_build" => {
"@type" => "build",
"@href" => "/v3/build/#{current_build.id}",
"@representation" => "minimal",
"id" => current_build.id.to_i,
"number" => current_build.number,
"state" => current_build.state,
"duration" => current_build.duration,
"event_type" => current_build.event_type,
"previous_state" => current_build.previous_state,
"started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
"finished_at" => current_build.finished_at.strftime("%Y-%m-%dT%H:%M:%SZ")},
"starred" => false
}}
end