From 046a63b60ad5d068704853e06241974a99b3dd06 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 11:43:58 +0100 Subject: [PATCH 01/54] add find for cron --- lib/travis/api/v3/queries/cron.rb | 12 ++++++ lib/travis/api/v3/renderer/cron.rb | 55 +++++++++++++++++++++++++ lib/travis/api/v3/routes.rb | 8 ++++ lib/travis/api/v3/services.rb | 1 + lib/travis/api/v3/services/cron/find.rb | 9 ++++ 5 files changed, 85 insertions(+) create mode 100644 lib/travis/api/v3/queries/cron.rb create mode 100644 lib/travis/api/v3/renderer/cron.rb create mode 100644 lib/travis/api/v3/services/cron/find.rb diff --git a/lib/travis/api/v3/queries/cron.rb b/lib/travis/api/v3/queries/cron.rb new file mode 100644 index 00000000..4bc66967 --- /dev/null +++ b/lib/travis/api/v3/queries/cron.rb @@ -0,0 +1,12 @@ +module Travis::API::V3 + class Queries::Cron < Query + params :id + + sortable_by :id + + def find + return Models::Repository.find_by_id(id) if id + raise WrongParams, 'missing job.id'.freeze + end + end +end diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb new file mode 100644 index 00000000..9a2b28bc --- /dev/null +++ b/lib/travis/api/v3/renderer/cron.rb @@ -0,0 +1,55 @@ +require 'travis/api/v3/renderer/model_renderer' + +module Travis::API::V3 + class Renderer::Cron < Renderer::ModelRenderer + representation(:minimal, :id, :name, :slug) + representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch) + + def active + !!model.active + end + + def default_branch + return model.default_branch if include_default_branch? + { + :@type => 'branch'.freeze, + :@href => Renderer.href(:branch, name: model.default_branch_name, repository_id: id, script_name: script_name), + :@representation => 'minimal'.freeze, + :name => model.default_branch_name + } + end + + def include_default_branch? + return true if include? 'repository.default_branch'.freeze + return true if include.any? { |i| i.start_with? 'branch'.freeze } + return true if included.any? { |i| i.is_a? Models::Branch and i.respository_id == id and i.name == i.default_branch_name } + end + + def owner + return model.owner if include_owner? + owner_href = Renderer.href(owner_type.to_sym, id: model.owner_id, script_name: script_name) + + if included_owner? and owner_href + { :@href => owner_href } + else + result = { :@type => owner_type, :id => model.owner_id, :login => model.owner_name } + result[:@href] = owner_href if owner_href + result + end + end + + def include_owner? + return false if included_owner? + return true if include? 'repository.owner'.freeze + return true if include.any? { |i| i.start_with? owner_type or i.start_with? 'owner'.freeze } + end + + def included_owner? + included.any? { |i| i.is_a? Model and i.class.polymorphic_name == model.owner_type and i.id == model.owner_id } + end + + def owner_type + @owner_type ||= model.owner_type.downcase if model.owner_type + end + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 988a5e96..6482c1d4 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -27,6 +27,14 @@ module Travis::API::V3 end end + + resource :cron do + capture id: :digit + route '/cron/{cron.id}' + get :find + + end + resource :job do capture id: :digit route '/job/{job.id}' diff --git a/lib/travis/api/v3/services.rb b/lib/travis/api/v3/services.rb index ffb67158..be4eb721 100644 --- a/lib/travis/api/v3/services.rb +++ b/lib/travis/api/v3/services.rb @@ -9,6 +9,7 @@ module Travis::API::V3 Broadcasts = Module.new { extend Services } Build = Module.new { extend Services } Builds = Module.new { extend Services } + Cron = Module.new { extend Services } Job = Module.new { extend Services } Jobs = Module.new { extend Services } Organization = Module.new { extend Services } diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb new file mode 100644 index 00000000..6a191d7a --- /dev/null +++ b/lib/travis/api/v3/services/cron/find.rb @@ -0,0 +1,9 @@ +module Travis::API::V3 + class Services::Cron::Find < Service + #params :id + + def run! + find + end + end +end From 772e797aae98a56db14a76277c8beb04120941e3 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 13:31:36 +0100 Subject: [PATCH 02/54] add /cron/cron.id/ GET endpoint --- lib/travis/api/v3/access_control/generic.rb | 4 ++ lib/travis/api/v3/models/cron.rb | 7 +++ lib/travis/api/v3/models/repository.rb | 1 + lib/travis/api/v3/queries/cron.rb | 4 +- lib/travis/api/v3/renderer/cron.rb | 50 +-------------------- lib/travis/api/v3/services/cron/find.rb | 1 + 6 files changed, 17 insertions(+), 50 deletions(-) create mode 100644 lib/travis/api/v3/models/cron.rb diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb index a8a6dab5..a00a6c58 100644 --- a/lib/travis/api/v3/access_control/generic.rb +++ b/lib/travis/api/v3/access_control/generic.rb @@ -59,6 +59,10 @@ module Travis::API::V3 visible? branch.repository end + def cron_visible?(cron) + visible? cron.repository + end + def job_visible?(job) visible? job.repository end diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb new file mode 100644 index 00000000..11c50eea --- /dev/null +++ b/lib/travis/api/v3/models/cron.rb @@ -0,0 +1,7 @@ +module Travis::API::V3 + class Models::Cron < Model + + belongs_to :repository + + end +end diff --git a/lib/travis/api/v3/models/repository.rb b/lib/travis/api/v3/models/repository.rb index 6bf8f4de..b58fde6a 100644 --- a/lib/travis/api/v3/models/repository.rb +++ b/lib/travis/api/v3/models/repository.rb @@ -6,6 +6,7 @@ module Travis::API::V3 has_many :builds, dependent: :delete_all, order: 'builds.id DESC'.freeze has_many :permissions, dependent: :delete_all has_many :users, through: :permissions + has_many :crons, dependent: :delete_all belongs_to :owner, polymorphic: true belongs_to :last_build, class_name: 'Travis::API::V3::Models::Build'.freeze diff --git a/lib/travis/api/v3/queries/cron.rb b/lib/travis/api/v3/queries/cron.rb index 4bc66967..25c38191 100644 --- a/lib/travis/api/v3/queries/cron.rb +++ b/lib/travis/api/v3/queries/cron.rb @@ -5,8 +5,8 @@ module Travis::API::V3 sortable_by :id def find - return Models::Repository.find_by_id(id) if id - raise WrongParams, 'missing job.id'.freeze + return Models::Cron.find_by_id(id) if id + raise WrongParams, 'missing cron.id'.freeze end end end diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index 9a2b28bc..7f4c93fc 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -2,54 +2,8 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer - representation(:minimal, :id, :name, :slug) - representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch) + representation(:minimal, :id) + representation(:standard, :id, :repository) - def active - !!model.active - end - - def default_branch - return model.default_branch if include_default_branch? - { - :@type => 'branch'.freeze, - :@href => Renderer.href(:branch, name: model.default_branch_name, repository_id: id, script_name: script_name), - :@representation => 'minimal'.freeze, - :name => model.default_branch_name - } - end - - def include_default_branch? - return true if include? 'repository.default_branch'.freeze - return true if include.any? { |i| i.start_with? 'branch'.freeze } - return true if included.any? { |i| i.is_a? Models::Branch and i.respository_id == id and i.name == i.default_branch_name } - end - - def owner - return model.owner if include_owner? - owner_href = Renderer.href(owner_type.to_sym, id: model.owner_id, script_name: script_name) - - if included_owner? and owner_href - { :@href => owner_href } - else - result = { :@type => owner_type, :id => model.owner_id, :login => model.owner_name } - result[:@href] = owner_href if owner_href - result - end - end - - def include_owner? - return false if included_owner? - return true if include? 'repository.owner'.freeze - return true if include.any? { |i| i.start_with? owner_type or i.start_with? 'owner'.freeze } - end - - def included_owner? - included.any? { |i| i.is_a? Model and i.class.polymorphic_name == model.owner_type and i.id == model.owner_id } - end - - def owner_type - @owner_type ||= model.owner_type.downcase if model.owner_type - end end end diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb index 6a191d7a..a7ea8958 100644 --- a/lib/travis/api/v3/services/cron/find.rb +++ b/lib/travis/api/v3/services/cron/find.rb @@ -5,5 +5,6 @@ module Travis::API::V3 def run! find end + end end From 5295d0c3ee8f561cedee8b9f729dbfea661b1da2 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 15:11:31 +0100 Subject: [PATCH 03/54] add nonworking implementation of /cron/cron.id/delete --- lib/travis/api/v3/access_control/generic.rb | 4 ++++ lib/travis/api/v3/permissions/cron.rb | 9 +++++++++ lib/travis/api/v3/routes.rb | 2 ++ lib/travis/api/v3/services/cron/delete.rb | 12 ++++++++++++ lib/travis/api/v3/services/cron/find.rb | 1 + 5 files changed, 28 insertions(+) create mode 100644 lib/travis/api/v3/permissions/cron.rb create mode 100644 lib/travis/api/v3/services/cron/delete.rb diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb index a00a6c58..634d44dd 100644 --- a/lib/travis/api/v3/access_control/generic.rb +++ b/lib/travis/api/v3/access_control/generic.rb @@ -63,6 +63,10 @@ module Travis::API::V3 visible? cron.repository end + def cron_writable?(cron) + writable? cron.repository + end + def job_visible?(job) visible? job.repository end diff --git a/lib/travis/api/v3/permissions/cron.rb b/lib/travis/api/v3/permissions/cron.rb new file mode 100644 index 00000000..815dd17c --- /dev/null +++ b/lib/travis/api/v3/permissions/cron.rb @@ -0,0 +1,9 @@ +require 'travis/api/v3/permissions/generic' + +module Travis::API::V3 + class Permissions::Cron < Permissions::Generic + def delete? + write? + end + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 6482c1d4..afb6b910 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -33,6 +33,8 @@ module Travis::API::V3 route '/cron/{cron.id}' get :find + get :delete, '/delete' + end resource :job do diff --git a/lib/travis/api/v3/services/cron/delete.rb b/lib/travis/api/v3/services/cron/delete.rb new file mode 100644 index 00000000..24753439 --- /dev/null +++ b/lib/travis/api/v3/services/cron/delete.rb @@ -0,0 +1,12 @@ +module Travis::API::V3 + class Services::Cron::Delete < Service + #params :id + + def run! + raise LoginRequired unless access_control.logged_in? or access_control.full_access? + + access_control.permissions(cron).delete! + find.destroy + end + end +end diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb index a7ea8958..6a028079 100644 --- a/lib/travis/api/v3/services/cron/find.rb +++ b/lib/travis/api/v3/services/cron/find.rb @@ -3,6 +3,7 @@ module Travis::API::V3 #params :id def run! + find end From ec37deb17c021cf430e2175198f418357bd2cb55 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 15:22:10 +0100 Subject: [PATCH 04/54] add /repo/repo.id/crons GET endpoint --- lib/travis/api/v3/queries/crons.rb | 8 ++++++++ lib/travis/api/v3/renderer/crons.rb | 6 ++++++ lib/travis/api/v3/routes.rb | 5 +++++ lib/travis/api/v3/services.rb | 1 + lib/travis/api/v3/services/crons/find.rb | 9 +++++++++ 5 files changed, 29 insertions(+) create mode 100644 lib/travis/api/v3/queries/crons.rb create mode 100644 lib/travis/api/v3/renderer/crons.rb create mode 100644 lib/travis/api/v3/services/crons/find.rb diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb new file mode 100644 index 00000000..b642ba3b --- /dev/null +++ b/lib/travis/api/v3/queries/crons.rb @@ -0,0 +1,8 @@ +module Travis::API::V3 + class Queries::Crons < Query + + def find(repository) + repository.crons + end + end +end diff --git a/lib/travis/api/v3/renderer/crons.rb b/lib/travis/api/v3/renderer/crons.rb new file mode 100644 index 00000000..89215f16 --- /dev/null +++ b/lib/travis/api/v3/renderer/crons.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Renderer::Crons < Renderer::CollectionRenderer + type :crons + collection_key :crons + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index afb6b910..8340a0d9 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -95,6 +95,11 @@ module Travis::API::V3 get :find end + resource :crons do + route '/crons' + get :find + end + resource :requests do route '/requests' get :find diff --git a/lib/travis/api/v3/services.rb b/lib/travis/api/v3/services.rb index be4eb721..9fb812b6 100644 --- a/lib/travis/api/v3/services.rb +++ b/lib/travis/api/v3/services.rb @@ -10,6 +10,7 @@ module Travis::API::V3 Build = Module.new { extend Services } Builds = Module.new { extend Services } Cron = Module.new { extend Services } + Crons = Module.new { extend Services } Job = Module.new { extend Services } Jobs = Module.new { extend Services } Organization = Module.new { extend Services } diff --git a/lib/travis/api/v3/services/crons/find.rb b/lib/travis/api/v3/services/crons/find.rb new file mode 100644 index 00000000..22099794 --- /dev/null +++ b/lib/travis/api/v3/services/crons/find.rb @@ -0,0 +1,9 @@ +module Travis::API::V3 + class Services::Crons::Find < Service + paginate + + def run! + query.find(find(:repository)) + end + end +end From 208dfb9a93f864c58f40a2623842be4fe6225ff5 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 16:04:08 +0100 Subject: [PATCH 05/54] add /repo/repository.id/crons/create endpoint, all working with our access_control --- lib/travis/api/v3/permissions/cron.rb | 4 ++++ lib/travis/api/v3/routes.rb | 2 ++ lib/travis/api/v3/services/cron/find.rb | 2 -- lib/travis/api/v3/services/crons/create.rb | 15 +++++++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 lib/travis/api/v3/services/crons/create.rb diff --git a/lib/travis/api/v3/permissions/cron.rb b/lib/travis/api/v3/permissions/cron.rb index 815dd17c..2db1f10c 100644 --- a/lib/travis/api/v3/permissions/cron.rb +++ b/lib/travis/api/v3/permissions/cron.rb @@ -5,5 +5,9 @@ module Travis::API::V3 def delete? write? end + + def create? + write? + end end end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 8340a0d9..95bf0a0a 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -98,6 +98,8 @@ module Travis::API::V3 resource :crons do route '/crons' get :find + + get :create, '/create' end resource :requests do diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb index 6a028079..6a191d7a 100644 --- a/lib/travis/api/v3/services/cron/find.rb +++ b/lib/travis/api/v3/services/cron/find.rb @@ -3,9 +3,7 @@ module Travis::API::V3 #params :id def run! - find end - end end diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb new file mode 100644 index 00000000..09a7b077 --- /dev/null +++ b/lib/travis/api/v3/services/crons/create.rb @@ -0,0 +1,15 @@ +module Travis::API::V3 + class Services::Crons::Create < Service + + + def run! + #raise LoginRequired unless access_control.logged_in? or access_control.full_access? + raise NotFound unless repository = find(:repository) + #access_control.permissions(cron).create! + + Models::Cron.create(repository: repository) + query.find(find(:repository)) + end + + end +end From c08f8243fb7fe755e684258af83d0845e31de404 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Thu, 5 Nov 2015 16:08:08 +0100 Subject: [PATCH 06/54] fix .../crons/create endpoint --- lib/travis/api/v3/services/crons/create.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb index 09a7b077..d2a25089 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/crons/create.rb @@ -1,14 +1,13 @@ module Travis::API::V3 class Services::Crons::Create < Service - + result_type :cron def run! - #raise LoginRequired unless access_control.logged_in? or access_control.full_access? + raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) - #access_control.permissions(cron).create! + access_control.permissions(cron).create! Models::Cron.create(repository: repository) - query.find(find(:repository)) end end From d1dd965b32ecfacabece2808e95641e4e57c7473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 9 Nov 2015 12:51:07 +0100 Subject: [PATCH 07/54] fix permissions --- lib/travis/api/v3/permissions/cron.rb | 4 ---- lib/travis/api/v3/permissions/repository.rb | 4 ++++ lib/travis/api/v3/services/cron/delete.rb | 4 ++-- lib/travis/api/v3/services/crons/create.rb | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/travis/api/v3/permissions/cron.rb b/lib/travis/api/v3/permissions/cron.rb index 2db1f10c..815dd17c 100644 --- a/lib/travis/api/v3/permissions/cron.rb +++ b/lib/travis/api/v3/permissions/cron.rb @@ -5,9 +5,5 @@ module Travis::API::V3 def delete? write? end - - def create? - write? - end end end diff --git a/lib/travis/api/v3/permissions/repository.rb b/lib/travis/api/v3/permissions/repository.rb index 75f47597..53bfb9ae 100644 --- a/lib/travis/api/v3/permissions/repository.rb +++ b/lib/travis/api/v3/permissions/repository.rb @@ -13,5 +13,9 @@ module Travis::API::V3 def create_request? write? end + + def create_cron? + write? + end end end diff --git a/lib/travis/api/v3/services/cron/delete.rb b/lib/travis/api/v3/services/cron/delete.rb index 24753439..c5d9287d 100644 --- a/lib/travis/api/v3/services/cron/delete.rb +++ b/lib/travis/api/v3/services/cron/delete.rb @@ -4,9 +4,9 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? - + cron = find access_control.permissions(cron).delete! - find.destroy + cron.destroy end end end diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb index d2a25089..0ec47ca1 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/crons/create.rb @@ -5,7 +5,7 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) - access_control.permissions(cron).create! + access_control.permissions(repository).create_cron! Models::Cron.create(repository: repository) end From c6556977faea01c401807b2930650375ae7fb193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 9 Nov 2015 13:42:01 +0100 Subject: [PATCH 08/54] Change create and delete to POST --- lib/travis/api/v3/routes.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 95bf0a0a..6b766280 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -33,8 +33,7 @@ module Travis::API::V3 route '/cron/{cron.id}' get :find - get :delete, '/delete' - + post :delete, '/delete' end resource :job do @@ -99,7 +98,7 @@ module Travis::API::V3 route '/crons' get :find - get :create, '/create' + post :create, '/create' end resource :requests do From a2a47370999e3194cbac590b0fb3e5fc6025b4cf Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 14:03:30 +0100 Subject: [PATCH 09/54] Fixed tests broken by cron --- lib/travis/api/v3/models/token.rb | 4 ++-- spec/v3/services/owner/find_spec.rb | 6 ++++-- .../services/repositories/for_current_user_spec.rb | 3 ++- spec/v3/services/repositories/for_owner_spec.rb | 3 ++- spec/v3/services/repository/find_spec.rb | 12 ++++++++---- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/travis/api/v3/models/token.rb b/lib/travis/api/v3/models/token.rb index 90965d0b..5108cf08 100644 --- a/lib/travis/api/v3/models/token.rb +++ b/lib/travis/api/v3/models/token.rb @@ -2,13 +2,13 @@ module Travis::API::V3 class Models::Token < Model belongs_to :user validate :token, presence: true - serialize :token, Extensions::EncryptedColumn.new(disable: true) + serialize :token#, Extensions::EncryptedColumn.new(disable: true) before_validation :generate_token, on: :create protected def generate_token - self.token = SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') + self.token = "christopher"#SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') end end end diff --git a/spec/v3/services/owner/find_spec.rb b/spec/v3/services/owner/find_spec.rb index 5442e545..9189fe0f 100644 --- a/spec/v3/services/owner/find_spec.rb +++ b/spec/v3/services/owner/find_spec.rb @@ -64,7 +64,8 @@ describe Travis::API::V3::Services::Owner::Find do "read" => true, "enable" => false, "disable" => false, - "create_request" => false}, + "create_request" => false, + "create_cron" => false }, "id" => repo.id, "name" => "example-repo", "slug" => "example-org/example-repo", @@ -108,7 +109,8 @@ describe Travis::API::V3::Services::Owner::Find do "read" => true, "enable" => false, "disable" => false, - "create_request"=> false}, + "create_request"=> false, + "create_cron" => false }, "id" => repo.id, "name" => "example-repo", "slug" => "example-org/example-repo", diff --git a/spec/v3/services/repositories/for_current_user_spec.rb b/spec/v3/services/repositories/for_current_user_spec.rb index d696df18..5e4c4e32 100644 --- a/spec/v3/services/repositories/for_current_user_spec.rb +++ b/spec/v3/services/repositories/for_current_user_spec.rb @@ -42,7 +42,8 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser do "read" => true, "enable" => true, "disable" => true, - "create_request" => true}, + "create_request" => true, + "create_cron" => true }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", diff --git a/spec/v3/services/repositories/for_owner_spec.rb b/spec/v3/services/repositories/for_owner_spec.rb index dd639697..9cdb6f44 100644 --- a/spec/v3/services/repositories/for_owner_spec.rb +++ b/spec/v3/services/repositories/for_owner_spec.rb @@ -42,7 +42,8 @@ describe Travis::API::V3::Services::Repositories::ForOwner do "read" => true, "enable" => false, "disable" => false, - "create_request" => false}, + "create_request" => false, + "create_cron" => false }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", diff --git a/spec/v3/services/repository/find_spec.rb b/spec/v3/services/repository/find_spec.rb index 2ea112d5..903d4552 100644 --- a/spec/v3/services/repository/find_spec.rb +++ b/spec/v3/services/repository/find_spec.rb @@ -34,7 +34,8 @@ describe Travis::API::V3::Services::Repository::Find do "read" => true, "enable" => false, "disable" => false, - "create_request" => false}, + "create_request" => false, + "create_cron" => false }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", @@ -108,7 +109,8 @@ describe Travis::API::V3::Services::Repository::Find do "read" => true, "enable" => false, "disable" => false, - "create_request" => false}, + "create_request" => false, + "create_cron" => false }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", @@ -167,7 +169,8 @@ describe Travis::API::V3::Services::Repository::Find do "read" => true, "enable" => true, "disable" => true, - "create_request" => true}, + "create_request" => true, + "create_cron" => true }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", @@ -232,7 +235,8 @@ describe Travis::API::V3::Services::Repository::Find do "read" => true, "enable" => true, "disable" => true, - "create_request" => true}, + "create_request" => true, + "create_cron" => true }, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", From f5f4b3b0b177e8aff60bcd8310818181d9d710b4 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 14:50:44 +0100 Subject: [PATCH 10/54] add test for /cron/{cron.id} endpoint --- spec/v3/services/cron/find_spec.rb | 79 ++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 spec/v3/services/cron/find_spec.rb diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb new file mode 100644 index 00000000..ba6b6dc1 --- /dev/null +++ b/spec/v3/services/cron/find_spec.rb @@ -0,0 +1,79 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Cron::Find do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:parsed_body) { JSON.load(body) } + + describe "fetching a cron job by id" do + before { get("/v3/cron/#{cron.id}") } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => false }, + "id" => cron.id, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} + end + + describe "fetching a non-existing cron job by id" do + before { get("/v3/cron/999999999999999") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} + end + + describe "private cron, not authenticated" do + before { repo.update_attribute(:private, true) } + before { get("/v3/cron/#{cron.id}") } + after { repo.update_attribute(:private, false) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} + end + + describe "private cron, authenticated as user with access" do + let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, pull: true) } + before { repo.update_attribute(:private, true) } + before { get("/v3/cron/#{cron.id}", {}, headers) } + after { repo.update_attribute(:private, false) } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => false }, + "id" => cron.id, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} + end + +end From b3eb2f33981e18d5f73235c26578190045f6dd93 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 16:04:41 +0100 Subject: [PATCH 11/54] add test for /cron/{cron.id}/delete endpoint --- spec/v3/services/cron/delete_spec.rb | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 spec/v3/services/cron/delete_spec.rb diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb new file mode 100644 index 00000000..a39f8c0f --- /dev/null +++ b/spec/v3/services/cron/delete_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Cron::Delete do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + let(:parsed_body) { JSON.load(body) } + + describe "deleting a cron job by id" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + before { post("/v3/cron/#{cron.id}/delete", {}, headers) } + example { expect(last_response).to be_ok } + example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to be_empty } + example { expect(parsed_body).to be == { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => true }, + "id" => cron.id, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} + end + + describe "try deleting a cron job without login" do + before { post("/v3/cron/#{cron.id}/delete") } + example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to exist } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "login_required", + "error_message" => "login required" + }} + end + + describe "try deleting a cron job with a user without permissions" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } + before { post("/v3/cron/#{cron.id}/delete", {}, headers) } + example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to exist } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "insufficient_access", + "error_message" => "operation requires delete access to cron", + "resource_type" => "cron", + "permission" => "delete", + "cron" => { + "@type" => "cron", + "@href" => "/cron/#{cron.id}", + "@representation" => "minimal", + "id" => cron.id } + }} + end + + describe "try deleting a non-existing cron job" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } + before { post("/v3/cron/999999999999999/delete", {}, headers) } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} + end + +end From 0e1b266e9bfcdd083f52ae0edfd1d5da932d783e Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 16:23:01 +0100 Subject: [PATCH 12/54] add test for /repo/{repo.id}/crons endpoint --- spec/v3/services/crons/find_spec.rb | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 spec/v3/services/crons/find_spec.rb diff --git a/spec/v3/services/crons/find_spec.rb b/spec/v3/services/crons/find_spec.rb new file mode 100644 index 00000000..00a06e28 --- /dev/null +++ b/spec/v3/services/crons/find_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Crons::Find do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:parsed_body) { JSON.load(body) } + + describe "fetching all crons by repo id" do + before { get("/v3/repo/#{repo.id}/crons") } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "crons", + "@href" => "/v3/repo/#{repo.id}/crons", + "@representation" => "standard", + "@pagination" => { + "limit" => 25, + "offset" => 0, + "count" => 0, + "is_first" => true, + "is_last" => true, + "next" => nil, + "prev" => nil, + "first" => { + "@href" => "/v3/repo/#{repo.id}/crons", + "offset" => 0, + "limit" => 25}, + "last" => { + "@href" => "/v3/repo/#{repo.id}/crons?limit=25&offset=-25", + "offset" => -25, + "limit" => 25 }}, + "crons" => [] + }} + end + + describe "fetching crons on a non-existing repository by slug" do + before { get("/v3/repo/svenfuchs%2Fminimal1/crons") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + +end From b1408583ddd749198aeb8bfa32e6d77b2110c6ed Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 16:25:03 +0100 Subject: [PATCH 13/54] fix test for /repo/{repo.id}/crons endpoint --- spec/v3/services/crons/find_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/v3/services/crons/find_spec.rb b/spec/v3/services/crons/find_spec.rb index 00a06e28..31e14e43 100644 --- a/spec/v3/services/crons/find_spec.rb +++ b/spec/v3/services/crons/find_spec.rb @@ -43,4 +43,17 @@ describe Travis::API::V3::Services::Crons::Find do }} end + describe "fetching crons from private repo, not authenticated" do + before { repo.update_attribute(:private, true) } + before { get("/v3/repo/#{repo.id}/crons") } + after { repo.update_attribute(:private, false) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + end From e8ab7c0be639080ef0d2aadb073fd5f7c340a692 Mon Sep 17 00:00:00 2001 From: Lennard Wolf Date: Mon, 9 Nov 2015 16:55:53 +0100 Subject: [PATCH 14/54] add test for /repo/{repo.id}/crons/create endpoint --- spec/v3/services/cron/delete_spec.rb | 2 +- spec/v3/services/crons/create_spec.rb | 75 +++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 spec/v3/services/crons/create_spec.rb diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index a39f8c0f..9db7c6b2 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -52,7 +52,7 @@ describe Travis::API::V3::Services::Cron::Delete do "permission" => "delete", "cron" => { "@type" => "cron", - "@href" => "/cron/#{cron.id}", + "@href" => "/v3/cron/#{cron.id}", "@representation" => "minimal", "id" => cron.id } }} diff --git a/spec/v3/services/crons/create_spec.rb b/spec/v3/services/crons/create_spec.rb new file mode 100644 index 00000000..311fbdd7 --- /dev/null +++ b/spec/v3/services/crons/create_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Crons::Create do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:last_cron) {Travis::API::V3::Models::Cron.where(repository_id: repo.id).last} + let(:current_cron) {Travis::API::V3::Models::Cron.where(repository_id: repo.id).last} + let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + let(:parsed_body) { JSON.load(body) } + + describe "creating a cron job" do + before { last_cron } + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + before { post("/v3/repo/#{repo.id}/crons/create", {}, headers) } + example { expect(current_cron == last_cron).to be_falsey } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "cron", + "@href" => "/v3/cron/#{current_cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => true }, + "id" => current_cron.id, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} + end + + describe "try creating a cron job without login" do + before { post("/v3/repo/#{repo.id}/crons/create") } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "login_required", + "error_message" => "login required" + }} + end + + describe "try creating a cron job with a user without permissions" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } + before { post("/v3/repo/#{repo.id}/crons/create", {}, headers) } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "insufficient_access", + "error_message" => "operation requires create_cron access to repository", + "resource_type" => "repository", + "permission" => "create_cron", + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} + end + + describe "creating cron on a non-existing repository by slug" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } + before { post("/v3/repo/svenfuchs%2Fminimal1/crons/create", {}, headers) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + +end From 0a91a69d0d2f4fb6fb8d1c4aceb215912b7310e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 9 Nov 2015 16:59:10 +0100 Subject: [PATCH 15/54] remove debug code --- lib/travis/api/v3/models/token.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/travis/api/v3/models/token.rb b/lib/travis/api/v3/models/token.rb index 5108cf08..90965d0b 100644 --- a/lib/travis/api/v3/models/token.rb +++ b/lib/travis/api/v3/models/token.rb @@ -2,13 +2,13 @@ module Travis::API::V3 class Models::Token < Model belongs_to :user validate :token, presence: true - serialize :token#, Extensions::EncryptedColumn.new(disable: true) + serialize :token, Extensions::EncryptedColumn.new(disable: true) before_validation :generate_token, on: :create protected def generate_token - self.token = "christopher"#SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') + self.token = SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') end end end From aca632ed154d60153c9e90434170f07b5fa874c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 16 Nov 2015 14:24:11 +0100 Subject: [PATCH 16/54] use branch for storing cron --- lib/travis/api/v3/access_control/generic.rb | 4 ++-- lib/travis/api/v3/models/branch.rb | 1 + lib/travis/api/v3/models/cron.rb | 2 +- lib/travis/api/v3/models/repository.rb | 1 - lib/travis/api/v3/queries/crons.rb | 4 ++-- lib/travis/api/v3/renderer/cron.rb | 6 +++++- lib/travis/api/v3/routes.rb | 11 ++++++++--- lib/travis/api/v3/services/crons/create.rb | 3 ++- lib/travis/api/v3/services/crons/find.rb | 2 +- lib/travis/api/v3/services/crons/for_repository.rb | 9 +++++++++ 10 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 lib/travis/api/v3/services/crons/for_repository.rb diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb index 634d44dd..0e31d723 100644 --- a/lib/travis/api/v3/access_control/generic.rb +++ b/lib/travis/api/v3/access_control/generic.rb @@ -60,11 +60,11 @@ module Travis::API::V3 end def cron_visible?(cron) - visible? cron.repository + visible? cron.branch.repository end def cron_writable?(cron) - writable? cron.repository + writable? cron.branch.repository end def job_visible?(job) diff --git a/lib/travis/api/v3/models/branch.rb b/lib/travis/api/v3/models/branch.rb index df66788e..8768c9de 100644 --- a/lib/travis/api/v3/models/branch.rb +++ b/lib/travis/api/v3/models/branch.rb @@ -4,6 +4,7 @@ module Travis::API::V3 belongs_to :last_build, class_name: 'Travis::API::V3::Models::Build'.freeze has_many :builds, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'builds.id DESC'.freeze, conditions: { event_type: 'push' } has_many :commits, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'commits.id DESC'.freeze + has_many :crons, dependent: :delete_all def default_branch name == repository.default_branch_name diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 11c50eea..1ef46459 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -1,7 +1,7 @@ module Travis::API::V3 class Models::Cron < Model - belongs_to :repository + belongs_to :branch end end diff --git a/lib/travis/api/v3/models/repository.rb b/lib/travis/api/v3/models/repository.rb index b58fde6a..6bf8f4de 100644 --- a/lib/travis/api/v3/models/repository.rb +++ b/lib/travis/api/v3/models/repository.rb @@ -6,7 +6,6 @@ module Travis::API::V3 has_many :builds, dependent: :delete_all, order: 'builds.id DESC'.freeze has_many :permissions, dependent: :delete_all has_many :users, through: :permissions - has_many :crons, dependent: :delete_all belongs_to :owner, polymorphic: true belongs_to :last_build, class_name: 'Travis::API::V3::Models::Build'.freeze diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index b642ba3b..6ca4cfff 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -1,8 +1,8 @@ module Travis::API::V3 class Queries::Crons < Query - def find(repository) - repository.crons + def find(branch) + branch.crons end end end diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index 7f4c93fc..6a760fa9 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -3,7 +3,11 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer representation(:minimal, :id) - representation(:standard, :id, :repository) + representation(:standard, :id, :branch, :repository) + + def repository + model.branch.repository + end end end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 6b766280..37eb7699 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -82,6 +82,13 @@ module Travis::API::V3 resource :branch do route '/branch/{branch.name}' get :find + + resource :crons do + route '/crons' + get :find + + post :create, '/create' + end end resource :branches do @@ -96,9 +103,7 @@ module Travis::API::V3 resource :crons do route '/crons' - get :find - - post :create, '/create' + get :for_repository end resource :requests do diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb index 0ec47ca1..c7f6d229 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/crons/create.rb @@ -5,9 +5,10 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) + raise NotFound unless branch = find(:branch, repository) access_control.permissions(repository).create_cron! - Models::Cron.create(repository: repository) + Models::Cron.create(branch: branch) end end diff --git a/lib/travis/api/v3/services/crons/find.rb b/lib/travis/api/v3/services/crons/find.rb index 22099794..ab475f8c 100644 --- a/lib/travis/api/v3/services/crons/find.rb +++ b/lib/travis/api/v3/services/crons/find.rb @@ -3,7 +3,7 @@ module Travis::API::V3 paginate def run! - query.find(find(:repository)) + query.find(find(:branch, find(:repository))) end end end diff --git a/lib/travis/api/v3/services/crons/for_repository.rb b/lib/travis/api/v3/services/crons/for_repository.rb new file mode 100644 index 00000000..4d912cdc --- /dev/null +++ b/lib/travis/api/v3/services/crons/for_repository.rb @@ -0,0 +1,9 @@ +module Travis::API::V3 + class Services::Crons::ForRepository < Service + paginate + + def run! + Models::Cron.where(:branch_id => find(:repository).branches) + end + end +end From 75449baacd1636e682e99eb140572a2bd5765ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 16 Nov 2015 15:52:05 +0100 Subject: [PATCH 17/54] fix and add tests for crons --- spec/v3/services/cron/delete_spec.rb | 10 ++- spec/v3/services/cron/find_spec.rb | 13 ++- spec/v3/services/crons/create_spec.rb | 32 +++++-- spec/v3/services/crons/find_spec.rb | 57 ++++++++++--- spec/v3/services/crons/for_repository_spec.rb | 83 +++++++++++++++++++ 5 files changed, 174 insertions(+), 21 deletions(-) create mode 100644 spec/v3/services/crons/for_repository_spec.rb diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index 9db7c6b2..0613a0bb 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' describe Travis::API::V3::Services::Cron::Delete do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } - let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} let(:parsed_body) { JSON.load(body) } @@ -20,6 +21,11 @@ describe Travis::API::V3::Services::Cron::Delete do "read" => true, "delete" => true }, "id" => cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", @@ -52,7 +58,7 @@ describe Travis::API::V3::Services::Cron::Delete do "permission" => "delete", "cron" => { "@type" => "cron", - "@href" => "/v3/cron/#{cron.id}", + "@href" => "/cron/#{cron.id}", # should be /v3/cron/#{cron.id} "@representation" => "minimal", "id" => cron.id } }} diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index ba6b6dc1..3ee0af53 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' describe Travis::API::V3::Services::Cron::Find do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } - let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } let(:parsed_body) { JSON.load(body) } describe "fetching a cron job by id" do @@ -16,6 +17,11 @@ describe Travis::API::V3::Services::Cron::Find do "read" => true, "delete" => false }, "id" => cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", @@ -66,6 +72,11 @@ describe Travis::API::V3::Services::Cron::Find do "read" => true, "delete" => false }, "id" => cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", diff --git a/spec/v3/services/crons/create_spec.rb b/spec/v3/services/crons/create_spec.rb index 311fbdd7..c4b710b5 100644 --- a/spec/v3/services/crons/create_spec.rb +++ b/spec/v3/services/crons/create_spec.rb @@ -2,8 +2,9 @@ require 'spec_helper' describe Travis::API::V3::Services::Crons::Create do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } - let(:last_cron) {Travis::API::V3::Models::Cron.where(repository_id: repo.id).last} - let(:current_cron) {Travis::API::V3::Models::Cron.where(repository_id: repo.id).last} + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:last_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} + let(:current_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} let(:parsed_body) { JSON.load(body) } @@ -11,7 +12,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "creating a cron job" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/repo/#{repo.id}/crons/create", {}, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", {}, headers) } example { expect(current_cron == last_cron).to be_falsey } example { expect(last_response).to be_ok } example { expect(parsed_body).to be == { @@ -22,6 +23,11 @@ describe Travis::API::V3::Services::Crons::Create do "read" => true, "delete" => true }, "id" => current_cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", @@ -33,7 +39,7 @@ describe Travis::API::V3::Services::Crons::Create do end describe "try creating a cron job without login" do - before { post("/v3/repo/#{repo.id}/crons/create") } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create") } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "login_required", @@ -43,7 +49,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "try creating a cron job with a user without permissions" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/#{repo.id}/crons/create", {}, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", {}, headers) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "insufficient_access", @@ -52,7 +58,7 @@ describe Travis::API::V3::Services::Crons::Create do "permission" => "create_cron", "repository" => { "@type" => "repository", - "@href" => "/v3/repo/#{repo.id}", + "@href" => "/repo/#{repo.id}", # should be /v3/repo/#{repo.id} "@representation" => "minimal", "id" => repo.id, "name" => "minimal", @@ -62,7 +68,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "creating cron on a non-existing repository by slug" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/svenfuchs%2Fminimal1/crons/create", {}, headers) } + before { post("/v3/repo/svenfuchs%2Fminimal1/branch/master/crons/create", {}, headers) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", @@ -72,4 +78,16 @@ describe Travis::API::V3::Services::Crons::Create do }} end + describe "creating cron on a non-existing branch" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } + before { post("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/crons/create", {}, headers) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "branch not found (or insufficient access)", + "resource_type" => "branch" + }} + end + end diff --git a/spec/v3/services/crons/find_spec.rb b/spec/v3/services/crons/find_spec.rb index 31e14e43..7a8b36ab 100644 --- a/spec/v3/services/crons/find_spec.rb +++ b/spec/v3/services/crons/find_spec.rb @@ -2,38 +2,62 @@ require 'spec_helper' describe Travis::API::V3::Services::Crons::Find do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } - let(:cron) { Travis::API::V3::Models::Cron.create(repository: repo) } + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } let(:parsed_body) { JSON.load(body) } describe "fetching all crons by repo id" do - before { get("/v3/repo/#{repo.id}/crons") } + before { cron } + before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/crons") } example { expect(last_response).to be_ok } example { expect(parsed_body).to be == { "@type" => "crons", - "@href" => "/v3/repo/#{repo.id}/crons", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", "@representation" => "standard", "@pagination" => { "limit" => 25, "offset" => 0, - "count" => 0, + "count" => 1, "is_first" => true, "is_last" => true, "next" => nil, "prev" => nil, "first" => { - "@href" => "/v3/repo/#{repo.id}/crons", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", "offset" => 0, "limit" => 25}, - "last" => { - "@href" => "/v3/repo/#{repo.id}/crons?limit=25&offset=-25", - "offset" => -25, + "last" => { + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", + "offset" => 0, "limit" => 25 }}, - "crons" => [] + "crons" => [ + { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => false }, + "id" => cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + } + ] }} end describe "fetching crons on a non-existing repository by slug" do - before { get("/v3/repo/svenfuchs%2Fminimal1/crons") } + before { get("/v3/repo/svenfuchs%2Fminimal1/branch/master/crons") } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", @@ -43,9 +67,20 @@ describe Travis::API::V3::Services::Crons::Find do }} end + describe "fetching crons on a non-existing branch" do + before { get("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/crons") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "branch not found (or insufficient access)", + "resource_type" => "branch" + }} + end + describe "fetching crons from private repo, not authenticated" do before { repo.update_attribute(:private, true) } - before { get("/v3/repo/#{repo.id}/crons") } + before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/crons") } after { repo.update_attribute(:private, false) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb new file mode 100644 index 00000000..1174c5ea --- /dev/null +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Crons::ForRepository do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } + let(:parsed_body) { JSON.load(body) } + + describe "fetching all crons by repo id" do + before { cron } + before { get("/v3/repo/#{repo.id}/crons") } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "crons", + "@href" => "/v3/repo/#{repo.id}/crons", + "@representation" => "standard", + "@pagination" => { + "limit" => 25, + "offset" => 0, + "count" => 1, + "is_first" => true, + "is_last" => true, + "next" => nil, + "prev" => nil, + "first" => { + "@href" => "/v3/repo/#{repo.id}/crons", + "offset" => 0, + "limit" => 25}, + "last" => { + "@href" => "/v3/repo/#{repo.id}/crons", + "offset" => 0, + "limit" => 25 }}, + "crons" => [ + { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => false }, + "id" => cron.id, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + } + ] + }} + end + + describe "fetching crons on a non-existing repository by slug" do + before { get("/v3/repo/svenfuchs%2Fminimal1/crons") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + + describe "fetching crons from private repo, not authenticated" do + before { repo.update_attribute(:private, true) } + before { get("/v3/repo/#{repo.id}/crons") } + after { repo.update_attribute(:private, false) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + +end From f356beaccfd59a4c7a54945d0b2efe91aed828f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 19 Nov 2015 13:39:13 +0100 Subject: [PATCH 18/54] add time and disable_by_push options for cron --- lib/travis/api/v3/renderer/cron.rb | 2 +- lib/travis/api/v3/services/crons/create.rb | 17 +++++++- spec/v3/services/cron/delete_spec.rb | 21 +++++++--- spec/v3/services/cron/find_spec.rb | 42 +++++++++++++------ spec/v3/services/crons/create_spec.rb | 26 ++++++++---- spec/v3/services/crons/find_spec.rb | 21 +++++++--- spec/v3/services/crons/for_repository_spec.rb | 21 +++++++--- 7 files changed, 109 insertions(+), 41 deletions(-) diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index 6a760fa9..4d337e74 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -3,7 +3,7 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer representation(:minimal, :id) - representation(:standard, :id, :branch, :repository) + representation(:standard, :id, :repository, :branch, :hour, :mon, :tue, :wed, :thu, :fri, :sat, :sun, :disable_by_push) def repository model.branch.repository diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb index c7f6d229..b5fba683 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/crons/create.rb @@ -1,15 +1,28 @@ module Travis::API::V3 class Services::Crons::Create < Service result_type :cron + params :mon, :tue, :wed, :thu, :fri, :sat, :sun, :disable_by_push, :hour def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) access_control.permissions(repository).create_cron! + Models::Cron.create(branch: branch, + mon: value("mon"), + tue: value("tue"), + wed: value("wed"), + thu: value("thu"), + fri: value("fri"), + sat: value("sat"), + sun: value("sun"), + hour: params["hour"], + disable_by_push: value("disable_by_push")) + end - Models::Cron.create(branch: branch) - end + def value s + params[s] ? params[s] : false + end end end diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index 0613a0bb..f97c68bc 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -21,18 +21,27 @@ describe Travis::API::V3::Services::Cron::Delete do "read" => true, "delete" => true }, "id" => cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, + "hour" => nil, + "mon" => false, + "tue" => false, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => false, + "sun" => false, + "disable_by_push" => true }} end diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 3ee0af53..64c62461 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -17,18 +17,27 @@ describe Travis::API::V3::Services::Cron::Find do "read" => true, "delete" => false }, "id" => cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, + "hour" => nil, + "mon" => false, + "tue" => false, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => false, + "sun" => false, + "disable_by_push" => true }} end @@ -72,18 +81,27 @@ describe Travis::API::V3::Services::Cron::Find do "read" => true, "delete" => false }, "id" => cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => branch.name }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, + "hour" => nil, + "mon" => false, + "tue" => false, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => false, + "sun" => false, + "disable_by_push" => true }} end diff --git a/spec/v3/services/crons/create_spec.rb b/spec/v3/services/crons/create_spec.rb index c4b710b5..79fbd15e 100644 --- a/spec/v3/services/crons/create_spec.rb +++ b/spec/v3/services/crons/create_spec.rb @@ -6,13 +6,14 @@ describe Travis::API::V3::Services::Crons::Create do let(:last_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:current_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } - let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}", "Content-Type" => "application/json" }} + let(:options) {{ "tue" => true, "sat" => true, "sun" => false, "disable_by_push" => true, "hour" => 12 }} let(:parsed_body) { JSON.load(body) } describe "creating a cron job" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", {}, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", options, headers) } example { expect(current_cron == last_cron).to be_falsey } example { expect(last_response).to be_ok } example { expect(parsed_body).to be == { @@ -23,18 +24,27 @@ describe Travis::API::V3::Services::Crons::Create do "read" => true, "delete" => true }, "id" => current_cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => "#{branch.name}" }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, + "hour" => 12, + "mon" => false, + "tue" => true, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => true, + "sun" => false, + "disable_by_push" => true }} end diff --git a/spec/v3/services/crons/find_spec.rb b/spec/v3/services/crons/find_spec.rb index 7a8b36ab..3738cece 100644 --- a/spec/v3/services/crons/find_spec.rb +++ b/spec/v3/services/crons/find_spec.rb @@ -39,18 +39,27 @@ describe Travis::API::V3::Services::Crons::Find do "read" => true, "delete" => false }, "id" => cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => "#{branch.name}" }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, + "hour" => nil, + "mon" => false, + "tue" => false, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => false, + "sun" => false, + "disable_by_push" => true } ] }} diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index 1174c5ea..97b713d2 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -39,18 +39,27 @@ describe Travis::API::V3::Services::Crons::ForRepository do "read" => true, "delete" => false }, "id" => cron.id, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => "#{branch.name}" }, "repository" => { "@type" => "repository", "@href" => "/v3/repo/#{repo.id}", "@representation" => "minimal", "id" => repo.id, "name" => "minimal", - "slug" => "svenfuchs/minimal" } + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => "#{branch.name}" }, + "hour" => nil, + "mon" => false, + "tue" => false, + "wed" => false, + "thu" => false, + "fri" => false, + "sat" => false, + "sun" => false, + "disable_by_push" => true } ] }} From b45b3fadf7ad1e6e24420c6db3af074129952c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 7 Jan 2016 15:00:08 +0100 Subject: [PATCH 19/54] changes for new db structure --- lib/travis/api/v3/models/branch.rb | 2 +- lib/travis/api/v3/routes.rb | 2 +- lib/travis/api/v3/services/crons/create.rb | 13 +++---------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/travis/api/v3/models/branch.rb b/lib/travis/api/v3/models/branch.rb index 8768c9de..fa0d1682 100644 --- a/lib/travis/api/v3/models/branch.rb +++ b/lib/travis/api/v3/models/branch.rb @@ -4,7 +4,7 @@ module Travis::API::V3 belongs_to :last_build, class_name: 'Travis::API::V3::Models::Build'.freeze has_many :builds, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'builds.id DESC'.freeze, conditions: { event_type: 'push' } has_many :commits, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'commits.id DESC'.freeze - has_many :crons, dependent: :delete_all + has_one :crons, dependent: :delete def default_branch name == repository.default_branch_name diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 6215ad48..5fdc8a89 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -86,7 +86,7 @@ module Travis::API::V3 get :find resource :crons do - route '/crons' + route '/cron' get :find post :create, '/create' diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/crons/create.rb index b5fba683..a8aa1de4 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/crons/create.rb @@ -1,7 +1,7 @@ module Travis::API::V3 class Services::Crons::Create < Service result_type :cron - params :mon, :tue, :wed, :thu, :fri, :sat, :sun, :disable_by_push, :hour + params :type, :disable_by_build def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? @@ -9,15 +9,8 @@ module Travis::API::V3 raise NotFound unless branch = find(:branch, repository) access_control.permissions(repository).create_cron! Models::Cron.create(branch: branch, - mon: value("mon"), - tue: value("tue"), - wed: value("wed"), - thu: value("thu"), - fri: value("fri"), - sat: value("sat"), - sun: value("sun"), - hour: params["hour"], - disable_by_push: value("disable_by_push")) + type: params["type"], + disable_by_build: value("disable_by_build")) end def value s From 0920041375e10187f54e38db9392d482ec76c5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 11 Jan 2016 14:14:00 +0100 Subject: [PATCH 20/54] further changes for new structure with only one cron per branch --- lib/travis/api/v3/models/branch.rb | 2 +- lib/travis/api/v3/queries/crons.rb | 2 +- lib/travis/api/v3/renderer/cron.rb | 2 +- lib/travis/api/v3/routes.rb | 4 ++-- lib/travis/api/v3/services/{crons => cron}/create.rb | 12 ++++-------- lib/travis/api/v3/services/cron/for_branch.rb | 8 ++++++++ 6 files changed, 17 insertions(+), 13 deletions(-) rename lib/travis/api/v3/services/{crons => cron}/create.rb (60%) create mode 100644 lib/travis/api/v3/services/cron/for_branch.rb diff --git a/lib/travis/api/v3/models/branch.rb b/lib/travis/api/v3/models/branch.rb index fa0d1682..147a8bfe 100644 --- a/lib/travis/api/v3/models/branch.rb +++ b/lib/travis/api/v3/models/branch.rb @@ -4,7 +4,7 @@ module Travis::API::V3 belongs_to :last_build, class_name: 'Travis::API::V3::Models::Build'.freeze has_many :builds, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'builds.id DESC'.freeze, conditions: { event_type: 'push' } has_many :commits, foreign_key: [:repository_id, :branch], primary_key: [:repository_id, :name], order: 'commits.id DESC'.freeze - has_one :crons, dependent: :delete + has_one :cron, dependent: :delete def default_branch name == repository.default_branch_name diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 6ca4cfff..463336b3 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -2,7 +2,7 @@ module Travis::API::V3 class Queries::Crons < Query def find(branch) - branch.crons + branch.cron end end end diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index 4d337e74..fec14f5c 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -3,7 +3,7 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer representation(:minimal, :id) - representation(:standard, :id, :repository, :branch, :hour, :mon, :tue, :wed, :thu, :fri, :sat, :sun, :disable_by_push) + representation(:standard, :id, :repository, :branch, :interval, :disable_by_build) def repository model.branch.repository diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 5fdc8a89..d71f0e53 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -85,9 +85,9 @@ module Travis::API::V3 route '/branch/{branch.name}' get :find - resource :crons do + resource :cron do route '/cron' - get :find + get :for_branch post :create, '/create' end diff --git a/lib/travis/api/v3/services/crons/create.rb b/lib/travis/api/v3/services/cron/create.rb similarity index 60% rename from lib/travis/api/v3/services/crons/create.rb rename to lib/travis/api/v3/services/cron/create.rb index a8aa1de4..a9ae54a4 100644 --- a/lib/travis/api/v3/services/crons/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -1,7 +1,7 @@ module Travis::API::V3 - class Services::Crons::Create < Service + class Services::Cron::Create < Service result_type :cron - params :type, :disable_by_build + params :interval, :disable_by_build def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? @@ -9,12 +9,8 @@ module Travis::API::V3 raise NotFound unless branch = find(:branch, repository) access_control.permissions(repository).create_cron! Models::Cron.create(branch: branch, - type: params["type"], - disable_by_build: value("disable_by_build")) - end - - def value s - params[s] ? params[s] : false + interval: params["interval"], + disable_by_build: params["disable_by_build"] ? params["disable_by_build"] : false) end end diff --git a/lib/travis/api/v3/services/cron/for_branch.rb b/lib/travis/api/v3/services/cron/for_branch.rb new file mode 100644 index 00000000..478e4b2c --- /dev/null +++ b/lib/travis/api/v3/services/cron/for_branch.rb @@ -0,0 +1,8 @@ +module Travis::API::V3 + class Services::Cron::ForBranch < Service + + def run! + Models::Cron.where(:branch_id => find(:branch, find(:repository))).first + end + end +end From 68ba4b9fce6acbaf11fc6a060966e98d07033a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 11 Jan 2016 14:54:02 +0100 Subject: [PATCH 21/54] check for correct interval allow only one cronjob per branch --- lib/travis/api/v3/services/cron/create.rb | 7 +++++++ lib/travis/api/v3/services/crons/find.rb | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 lib/travis/api/v3/services/crons/find.rb diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index a9ae54a4..f3ceb0e8 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -7,7 +7,14 @@ module Travis::API::V3 raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) + raise ArgumentError, 'interval must be "daily", "weekly" or "monthly"' unless ["daily", "weekly", "monthly"].include?(params["interval"]) access_control.permissions(repository).create_cron! + + if branch.cron + access_control.permissions(branch.cron).delete! + branch.cron.destroy + end + Models::Cron.create(branch: branch, interval: params["interval"], disable_by_build: params["disable_by_build"] ? params["disable_by_build"] : false) diff --git a/lib/travis/api/v3/services/crons/find.rb b/lib/travis/api/v3/services/crons/find.rb deleted file mode 100644 index ab475f8c..00000000 --- a/lib/travis/api/v3/services/crons/find.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Travis::API::V3 - class Services::Crons::Find < Service - paginate - - def run! - query.find(find(:branch, find(:repository))) - end - end -end From 587ed37395e7bfddc0fe909fe5cc64398488b2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 11 Jan 2016 15:11:48 +0100 Subject: [PATCH 22/54] fix specs for new structure --- .../services/{crons => cron}/create_spec.rb | 25 ++--- spec/v3/services/cron/delete_spec.rb | 13 +-- spec/v3/services/cron/find_spec.rb | 24 +--- spec/v3/services/cron/for_branch_spec.rb | 73 +++++++++++++ spec/v3/services/crons/find_spec.rb | 103 ------------------ spec/v3/services/crons/for_repository_spec.rb | 13 +-- 6 files changed, 93 insertions(+), 158 deletions(-) rename spec/v3/services/{crons => cron}/create_spec.rb (86%) create mode 100644 spec/v3/services/cron/for_branch_spec.rb delete mode 100644 spec/v3/services/crons/find_spec.rb diff --git a/spec/v3/services/crons/create_spec.rb b/spec/v3/services/cron/create_spec.rb similarity index 86% rename from spec/v3/services/crons/create_spec.rb rename to spec/v3/services/cron/create_spec.rb index 79fbd15e..1d1da662 100644 --- a/spec/v3/services/crons/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -1,19 +1,19 @@ require 'spec_helper' -describe Travis::API::V3::Services::Crons::Create do +describe Travis::API::V3::Services::Cron::Create do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } let(:last_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:current_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}", "Content-Type" => "application/json" }} - let(:options) {{ "tue" => true, "sat" => true, "sun" => false, "disable_by_push" => true, "hour" => 12 }} + let(:options) {{ "interval" => "monthly", "disable_by_build" => false }} let(:parsed_body) { JSON.load(body) } describe "creating a cron job" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } example { expect(current_cron == last_cron).to be_falsey } example { expect(last_response).to be_ok } example { expect(parsed_body).to be == { @@ -36,20 +36,13 @@ describe Travis::API::V3::Services::Crons::Create do "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", "@representation" => "minimal", "name" => "#{branch.name}" }, - "hour" => 12, - "mon" => false, - "tue" => true, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => true, - "sun" => false, - "disable_by_push" => true + "interval" => "monthly", + "disable_by_build" => false }} end describe "try creating a cron job without login" do - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create") } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "login_required", @@ -59,7 +52,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "try creating a cron job with a user without permissions" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/crons/create", {}, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "insufficient_access", @@ -78,7 +71,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "creating cron on a non-existing repository by slug" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/svenfuchs%2Fminimal1/branch/master/crons/create", {}, headers) } + before { post("/v3/repo/svenfuchs%2Fminimal1/branch/master/cron/create", options, headers) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", @@ -90,7 +83,7 @@ describe Travis::API::V3::Services::Crons::Create do describe "creating cron on a non-existing branch" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/crons/create", {}, headers) } + before { post("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/cron/create", options, headers) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index f97c68bc..bb45eab9 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Travis::API::V3::Services::Cron::Delete do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } - let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} let(:parsed_body) { JSON.load(body) } @@ -33,15 +33,8 @@ describe Travis::API::V3::Services::Cron::Delete do "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", "@representation" => "minimal", "name" => branch.name }, - "hour" => nil, - "mon" => false, - "tue" => false, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => false, - "sun" => false, - "disable_by_push" => true + "interval" => "daily", + "disable_by_build" => true }} end diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 64c62461..2f494ec1 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Travis::API::V3::Services::Cron::Find do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } - let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:parsed_body) { JSON.load(body) } describe "fetching a cron job by id" do @@ -29,15 +29,8 @@ describe Travis::API::V3::Services::Cron::Find do "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", "@representation" => "minimal", "name" => branch.name }, - "hour" => nil, - "mon" => false, - "tue" => false, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => false, - "sun" => false, - "disable_by_push" => true + "interval" => "daily", + "disable_by_build" => true }} end @@ -93,15 +86,8 @@ describe Travis::API::V3::Services::Cron::Find do "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", "@representation" => "minimal", "name" => branch.name }, - "hour" => nil, - "mon" => false, - "tue" => false, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => false, - "sun" => false, - "disable_by_push" => true + "interval" => "daily", + "disable_by_build" => true }} end diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb new file mode 100644 index 00000000..72507362 --- /dev/null +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::Cron::ForBranch do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } + let(:parsed_body) { JSON.load(body) } + + describe "fetching all crons by repo id" do + before { cron } + before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } + example { expect(last_response).to be_ok } + example { expect(parsed_body).to be == { + "@type" => "cron", + "@href" => "/v3/cron/#{cron.id}", + "@representation" => "standard", + "@permissions" => { + "read" => true, + "delete" => false }, + "id" => cron.id, + "repository" => { + "@type" => "repository", + "@href" => "/v3/repo/#{repo.id}", + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" }, + "branch" => { + "@type" => "branch", + "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", + "@representation" => "minimal", + "name" => branch.name }, + "interval" => "daily", + "disable_by_build" => true + }} + end + + describe "fetching crons on a non-existing repository by slug" do + before { get("/v3/repo/svenfuchs%2Fminimal1/branch/master/cron") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + + describe "fetching crons on a non-existing branch" do + before { get("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/cron") } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "branch not found (or insufficient access)", + "resource_type" => "branch" + }} + end + + describe "fetching crons from private repo, not authenticated" do + before { repo.update_attribute(:private, true) } + before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } + after { repo.update_attribute(:private, false) } + example { expect(last_response).to be_not_found } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "repository not found (or insufficient access)", + "resource_type" => "repository" + }} + end + +end diff --git a/spec/v3/services/crons/find_spec.rb b/spec/v3/services/crons/find_spec.rb deleted file mode 100644 index 3738cece..00000000 --- a/spec/v3/services/crons/find_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'spec_helper' - -describe Travis::API::V3::Services::Crons::Find do - let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } - let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } - let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } - let(:parsed_body) { JSON.load(body) } - - describe "fetching all crons by repo id" do - before { cron } - before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/crons") } - example { expect(last_response).to be_ok } - example { expect(parsed_body).to be == { - "@type" => "crons", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", - "@representation" => "standard", - "@pagination" => { - "limit" => 25, - "offset" => 0, - "count" => 1, - "is_first" => true, - "is_last" => true, - "next" => nil, - "prev" => nil, - "first" => { - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", - "offset" => 0, - "limit" => 25}, - "last" => { - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}/crons", - "offset" => 0, - "limit" => 25 }}, - "crons" => [ - { - "@type" => "cron", - "@href" => "/v3/cron/#{cron.id}", - "@representation" => "standard", - "@permissions" => { - "read" => true, - "delete" => false }, - "id" => cron.id, - "repository" => { - "@type" => "repository", - "@href" => "/v3/repo/#{repo.id}", - "@representation" => "minimal", - "id" => repo.id, - "name" => "minimal", - "slug" => "svenfuchs/minimal" }, - "branch" => { - "@type" => "branch", - "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", - "@representation" => "minimal", - "name" => "#{branch.name}" }, - "hour" => nil, - "mon" => false, - "tue" => false, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => false, - "sun" => false, - "disable_by_push" => true - } - ] - }} - end - - describe "fetching crons on a non-existing repository by slug" do - before { get("/v3/repo/svenfuchs%2Fminimal1/branch/master/crons") } - example { expect(last_response).to be_not_found } - example { expect(parsed_body).to be == { - "@type" => "error", - "error_type" => "not_found", - "error_message" => "repository not found (or insufficient access)", - "resource_type" => "repository" - }} - end - - describe "fetching crons on a non-existing branch" do - before { get("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/crons") } - example { expect(last_response).to be_not_found } - example { expect(parsed_body).to be == { - "@type" => "error", - "error_type" => "not_found", - "error_message" => "branch not found (or insufficient access)", - "resource_type" => "branch" - }} - end - - describe "fetching crons from private repo, not authenticated" do - before { repo.update_attribute(:private, true) } - before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/crons") } - after { repo.update_attribute(:private, false) } - example { expect(last_response).to be_not_found } - example { expect(parsed_body).to be == { - "@type" => "error", - "error_type" => "not_found", - "error_message" => "repository not found (or insufficient access)", - "resource_type" => "repository" - }} - end - -end diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index 97b713d2..64bf6acb 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Travis::API::V3::Services::Crons::ForRepository do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } - let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch) } + let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:parsed_body) { JSON.load(body) } describe "fetching all crons by repo id" do @@ -51,15 +51,8 @@ describe Travis::API::V3::Services::Crons::ForRepository do "@href" => "/v3/repo/#{repo.id}/branch/#{branch.name}", "@representation" => "minimal", "name" => "#{branch.name}" }, - "hour" => nil, - "mon" => false, - "tue" => false, - "wed" => false, - "thu" => false, - "fri" => false, - "sat" => false, - "sun" => false, - "disable_by_push" => true + "interval" => "daily", + "disable_by_build" => true } ] }} From ffcf8985c05d0920fb0831e207823a774ba22aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 11 Jan 2016 15:54:50 +0100 Subject: [PATCH 23/54] add tests for only one cron job per branch and interval value --- spec/v3/services/cron/create_spec.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 1d1da662..59b6504f 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -8,6 +8,7 @@ describe Travis::API::V3::Services::Cron::Create do let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}", "Content-Type" => "application/json" }} let(:options) {{ "interval" => "monthly", "disable_by_build" => false }} + let(:wrong_options) {{ "interval" => "notExisting", "disable_by_build" => false }} let(:parsed_body) { JSON.load(body) } describe "creating a cron job" do @@ -41,6 +42,25 @@ describe Travis::API::V3::Services::Cron::Create do }} end + describe "creating multiple cron jobs for one branch" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } + it "only stores one" do + expect(Travis::API::V3::Models::Cron.where(branch_id: branch.id).count).to eq(1) + end + end + + describe "creating a cron job with a wrong interval" do + before { last_cron } + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + it "raises an error" do + expect { + post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", wrong_options, headers) + }.to raise_error(ArgumentError, 'interval must be "daily", "weekly" or "monthly"') + end + end + describe "try creating a cron job without login" do before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options) } example { expect(parsed_body).to be == { From 00e15de083baf0cf82c0b1139ef538f9a1190ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 14 Jan 2016 15:46:34 +0100 Subject: [PATCH 24/54] show next build time for cron --- lib/travis/api/v3/models/cron.rb | 98 ++++++++++++++++++++++++++++++ lib/travis/api/v3/renderer.rb | 2 +- lib/travis/api/v3/renderer/cron.rb | 2 +- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 1ef46459..d3d4065f 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -3,5 +3,103 @@ module Travis::API::V3 belongs_to :branch + def next_build_time + + if disable_by_build + if last_non_cron_build_date > last_planned_time + return after_next_planned_time + else + return next_planned_time + end + else + if last_cron_build_date >= last_planned_time + return next_planned_time + else + return Time.now + end + end + end + + def next_planned_time + now = DateTime.now + created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) + case interval + when 'daily' + build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) + if now > build_today + return build_today + 1 + else + return build_today + end + when 'weekly' + build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) + in_days = (created_at.wday - now.wday) % 7 + next_time = build_today + in_days + if now > next_time + return build_today + 7 + else + return next_time + end + when 'monthly' + month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) + this_month = created >> month_since_creation + if now > this_month + return created >> (month_since_creation+1) + else + return this_month + end + end + end + + def last_planned_time + now = DateTime.now + created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) + case interval + when 'daily' + return next_planned_time - 1 + when 'weekly' + return next_planned_time - 7 + when 'monthly' + month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) + this_month = created >> month_since_creation + if now > this_month + return this_month + else + return created >> (month_since_creation-1) + end + end + end + + def after_next_planned_time + now = DateTime.now + created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) + case interval + when 'daily' + return next_planned_time + 1 + when 'weekly' + return next_planned_time + 7 + when 'monthly' + month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) + this_month = created >> month_since_creation + if now > this_month + return created >> (month_since_creation+2) + else + return created >> (month_since_creation+1) + end + end + end + + def last_cron_build_date + last_cron_build = Models::Build.where(:repository_id => branch.repository.id, :branch => branch.name, :event_type => 'cron').order("id DESC").first + return last_cron_build.created_at unless last_cron_build.nil? + return Time.at(0) + end + + def last_non_cron_build_date + last_build = Models::Build.where(:repository_id => branch.repository.id, :branch => branch.name).where(['event_type NOT IN (?)', ['cron']]).order("id DESC").first + return last_build.created_at unless last_build.nil? + return Time.at(0) + end + end end diff --git a/lib/travis/api/v3/renderer.rb b/lib/travis/api/v3/renderer.rb index 2ee8ca15..637f937d 100644 --- a/lib/travis/api/v3/renderer.rb +++ b/lib/travis/api/v3/renderer.rb @@ -45,7 +45,7 @@ module Travis::API::V3 when Hash then value.map { |k, v| [k, render_value(v, **options)] }.to_h when Array then value.map { |v | render_value(v, **options) } when *PRIMITIVE then value - when Time then value.strftime('%Y-%m-%dT%H:%M:%SZ') + when Time, DateTime then value.strftime('%Y-%m-%dT%H:%M:%SZ') when Model then render_model(value, **options) when ActiveRecord::Relation then render_value(value.to_a, **options) when ActiveRecord::Associations::CollectionProxy then render_value(value.to_a, **options) diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index fec14f5c..225033ec 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -3,7 +3,7 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer representation(:minimal, :id) - representation(:standard, :id, :repository, :branch, :interval, :disable_by_build) + representation(:standard, :id, :repository, :branch, :interval, :disable_by_build, :next_build_time) def repository model.branch.repository From e9356970f8de4cb89dcb54e841ed9b5cc04c100c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 14 Jan 2016 16:16:15 +0100 Subject: [PATCH 25/54] fix tests with output of next build date for cron jobs --- spec/v3/services/cron/create_spec.rb | 3 ++- spec/v3/services/cron/delete_spec.rb | 3 ++- spec/v3/services/cron/find_spec.rb | 6 ++++-- spec/v3/services/cron/for_branch_spec.rb | 3 ++- spec/v3/services/crons/for_repository_spec.rb | 3 ++- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 59b6504f..3c618100 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -38,7 +38,8 @@ describe Travis::API::V3::Services::Cron::Create do "@representation" => "minimal", "name" => "#{branch.name}" }, "interval" => "monthly", - "disable_by_build" => false + "disable_by_build" => false, + "next_build_time" => current_cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index bb45eab9..cec551d9 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -34,7 +34,8 @@ describe Travis::API::V3::Services::Cron::Delete do "@representation" => "minimal", "name" => branch.name }, "interval" => "daily", - "disable_by_build" => true + "disable_by_build" => true, + "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 2f494ec1..876b4940 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -30,7 +30,8 @@ describe Travis::API::V3::Services::Cron::Find do "@representation" => "minimal", "name" => branch.name }, "interval" => "daily", - "disable_by_build" => true + "disable_by_build" => true, + "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') }} end @@ -87,7 +88,8 @@ describe Travis::API::V3::Services::Cron::Find do "@representation" => "minimal", "name" => branch.name }, "interval" => "daily", - "disable_by_build" => true + "disable_by_build" => true, + "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb index 72507362..aa75537e 100644 --- a/spec/v3/services/cron/for_branch_spec.rb +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -31,7 +31,8 @@ describe Travis::API::V3::Services::Cron::ForBranch do "@representation" => "minimal", "name" => branch.name }, "interval" => "daily", - "disable_by_build" => true + "disable_by_build" => true, + "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index 64bf6acb..b1eab41c 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -52,7 +52,8 @@ describe Travis::API::V3::Services::Crons::ForRepository do "@representation" => "minimal", "name" => "#{branch.name}" }, "interval" => "daily", - "disable_by_build" => true + "disable_by_build" => true, + "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') } ] }} From 3f11b08a25dd227327c4afc6e7c1374d6724adfc Mon Sep 17 00:00:00 2001 From: Jonas Chromik Date: Mon, 18 Jan 2016 12:27:29 +0100 Subject: [PATCH 26/54] Add timecop gem to Gemfile. --- Gemfile | 1 + Gemfile.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index ce0fe1b8..d1c6f783 100644 --- a/Gemfile +++ b/Gemfile @@ -40,6 +40,7 @@ group :test do 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 diff --git a/Gemfile.lock b/Gemfile.lock index f4f974f9..ab8376ae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -314,6 +314,7 @@ GEM thor (0.14.6) thread_safe (0.3.5) tilt (1.4.1) + timecop (0.8.0) timers (4.0.1) hitimes tool (0.2.3) @@ -369,6 +370,7 @@ DEPENDENCIES sinatra-contrib skylight (~> 0.6.0.beta.1) stackprof + timecop (~> 0.8.0) travis-api! travis-config (~> 0.1.0) travis-core! @@ -377,3 +379,6 @@ DEPENDENCIES travis-yaml! unicorn yard-sinatra! + +BUNDLED WITH + 1.11.2 From 43a2806b3ba410fc5bf3b3956e01879c96690c5b Mon Sep 17 00:00:00 2001 From: Jonas Chromik Date: Mon, 18 Jan 2016 12:35:10 +0100 Subject: [PATCH 27/54] Remove 'BUNDLED WITH [...]' in Gemfile.lock. --- Gemfile.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ab8376ae..18b0ed04 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -379,6 +379,3 @@ DEPENDENCIES travis-yaml! unicorn yard-sinatra! - -BUNDLED WITH - 1.11.2 From 2566a7761c02c4f19129f236e8afdec38b23df42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 18 Jan 2016 13:50:53 +0100 Subject: [PATCH 28/54] add tests for next build time --- spec/v3/models/cron_spec.rb | 159 ++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 spec/v3/models/cron_spec.rb diff --git a/spec/v3/models/cron_spec.rb b/spec/v3/models/cron_spec.rb new file mode 100644 index 00000000..21a800db --- /dev/null +++ b/spec/v3/models/cron_spec.rb @@ -0,0 +1,159 @@ +require 'spec_helper' +require 'timecop' + +describe Travis::API::V3::Models::Cron do + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:branch) { Travis::API::V3::Models::Branch.create(repository: repo, name: 'cron test') } + + describe "next build time is calculated correctly on year changes" do + + before do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + end + + after do + Timecop.return + end + + it "for daily builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + build.destroy + cron.destroy + end + + it "for weekly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + build.destroy + cron.destroy + end + + it "for monthly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + build.destroy + cron.destroy + end + + end + + describe "push build is ignored if disable by build is false" do + + before do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + end + + after do + Timecop.return + end + + it "for daily builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) + cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + cron_build.destroy + push_build.destroy + cron.destroy + end + + it "for weekly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) + cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + cron_build.destroy + push_build.destroy + cron.destroy + end + + it "for monthly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) + cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + cron_build.destroy + push_build.destroy + cron.destroy + end + + end + + describe "disable by build works with build" do + + before do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + end + + after do + Timecop.return + end + + it "for daily builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 2, 16) + build.destroy + cron.destroy + end + + it "for weekly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 14, 16) + build.destroy + cron.destroy + end + + it "for monthly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') + expect(cron.next_build_time).to be == DateTime.new(2016, 2, 29, 16) # it's a leap year :-D + build.destroy + cron.destroy + end + + end + + describe "disable by build works without build" do + + before do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + end + + after do + Timecop.return + end + + it "for daily builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + build.destroy + cron.destroy + end + + it "for weekly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + build.destroy + cron.destroy + end + + it "for monthly builds" do + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + build.destroy + cron.destroy + end + + end + + +end From da33cff0eb0e533968e3313148a8fbb7df555f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 18 Jan 2016 16:59:10 +0100 Subject: [PATCH 29/54] add more tests add first version to start crons adjust code to return now if cron is overdue --- lib/travis/api/v3/models/cron.rb | 38 ++++++++++++----- spec/v3/models/cron_spec.rb | 72 ++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 11 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index d3d4065f..b784634a 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -3,20 +3,36 @@ module Travis::API::V3 belongs_to :branch + def self.start_all + self.all.each do |cron| + cron.start if cron.next_build_time <= Time.now + end + end + + def start + raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id + + payload = { + repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, + user: { id: user.id }, + message: '', + branch: branch, + config: {} + } + + token = "TODO: Figure out where to get this (branch.repository.owner ?)" + perform_async(:build_request, type: 'cron'.freeze, credentials: { token: token }, payload: JSON.dump(payload)) + payload + end + def next_build_time - if disable_by_build - if last_non_cron_build_date > last_planned_time - return after_next_planned_time - else - return next_planned_time - end + if (disable_by_build) && (last_non_cron_build_date > last_planned_time) + return after_next_planned_time + elsif last_cron_build_date >= last_planned_time + return next_planned_time else - if last_cron_build_date >= last_planned_time - return next_planned_time - else - return Time.now - end + return Time.now end end diff --git a/spec/v3/models/cron_spec.rb b/spec/v3/models/cron_spec.rb index 21a800db..a991301c 100644 --- a/spec/v3/models/cron_spec.rb +++ b/spec/v3/models/cron_spec.rb @@ -155,5 +155,77 @@ describe Travis::API::V3::Models::Cron do end + describe "build starts now if next build time is in the past" do + + before do + # nothing, this time + # time freeze is performed in examples + end + + after do + Timecop.return + end + + it "for daily builds with disable_by_build true" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 1, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + it "for daily builds with disable_by_build false" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 1, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + it "for weekly builds with disable_by_build true" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 7, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + it "for weekly builds with disable_by_build false" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 7, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + it "for monthly builds with disable_by_build true" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 31, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + it "for monthly builds with disable_by_build false" do + Timecop.travel(DateTime.new(2015, 12, 31, 16)) + cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) + build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') + Timecop.freeze(DateTime.new(2016, 1, 31, 19)) + expect(cron.next_build_time).to be == DateTime.now + build.destroy + cron.destroy + end + + end end From 4704992a18e23ffa82f7f2fe4f4d100d3df8793f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 21 Jan 2016 10:40:43 +0100 Subject: [PATCH 30/54] remove token from perform_async call --- lib/travis/api/v3/models/cron.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index b784634a..47eebed5 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -15,13 +15,10 @@ module Travis::API::V3 payload = { repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, user: { id: user.id }, - message: '', - branch: branch, - config: {} + branch: branch } - token = "TODO: Figure out where to get this (branch.repository.owner ?)" - perform_async(:build_request, type: 'cron'.freeze, credentials: { token: token }, payload: JSON.dump(payload)) + perform_async(:build_request, type: 'cron'.freeze, payload: JSON.dump(payload)) payload end From 2d2e7aa528d549d0cb7dd84161b9600d2236eb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 21 Jan 2016 13:11:18 +0100 Subject: [PATCH 31/54] fix job enqueueing --- lib/travis/api/v3/models/cron.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 47eebed5..ba792b6b 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -4,9 +4,16 @@ module Travis::API::V3 belongs_to :branch def self.start_all + started = [] + self.all.each do |cron| - cron.start if cron.next_build_time <= Time.now + if cron.next_build_time <= Time.now + cron.start + started.push cron + end end + + started end def start @@ -14,11 +21,11 @@ module Travis::API::V3 payload = { repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, - user: { id: user.id }, - branch: branch + branch: branch.name } - perform_async(:build_request, type: 'cron'.freeze, payload: JSON.dump(payload)) + class_name, queue = Query.sidekiq_queue(:build_request) + ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload)}]) payload end From 05d2e4767e960114b3d7e7cf0c7b8edca892a4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 28 Jan 2016 13:00:21 +0100 Subject: [PATCH 32/54] adjust cron API path --- lib/travis/api/v3/routes.rb | 6 ++---- lib/travis/api/v3/routes/dsl.rb | 4 ++++ spec/v3/services/cron/create_spec.rb | 16 ++++++++-------- spec/v3/services/cron/delete_spec.rb | 8 ++++---- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index d71f0e53..db62dced 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -32,8 +32,7 @@ module Travis::API::V3 capture id: :digit route '/cron/{cron.id}' get :find - - post :delete, '/delete' + delete :delete end resource :job do @@ -88,8 +87,7 @@ module Travis::API::V3 resource :cron do route '/cron' get :for_branch - - post :create, '/create' + post :create end end diff --git a/lib/travis/api/v3/routes/dsl.rb b/lib/travis/api/v3/routes/dsl.rb index e71723d7..9a98ada0 100644 --- a/lib/travis/api/v3/routes/dsl.rb +++ b/lib/travis/api/v3/routes/dsl.rb @@ -60,6 +60,10 @@ module Travis::API::V3 current_resource.add_service('POST'.freeze, *args) end + def delete(*args) + current_resource.add_service('DELETE'.freeze, *args) + end + def draw_routes resources.each do |resource| prefix = resource.route diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 3c618100..84efefd3 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -14,7 +14,7 @@ describe Travis::API::V3::Services::Cron::Create do describe "creating a cron job" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers) } example { expect(current_cron == last_cron).to be_falsey } example { expect(last_response).to be_ok } example { expect(parsed_body).to be == { @@ -45,8 +45,8 @@ describe Travis::API::V3::Services::Cron::Create do describe "creating multiple cron jobs for one branch" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers) } it "only stores one" do expect(Travis::API::V3::Models::Cron.where(branch_id: branch.id).count).to eq(1) end @@ -57,13 +57,13 @@ describe Travis::API::V3::Services::Cron::Create do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } it "raises an error" do expect { - post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", wrong_options, headers) + post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", wrong_options, headers) }.to raise_error(ArgumentError, 'interval must be "daily", "weekly" or "monthly"') end end describe "try creating a cron job without login" do - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "login_required", @@ -73,7 +73,7 @@ describe Travis::API::V3::Services::Cron::Create do describe "try creating a cron job with a user without permissions" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "insufficient_access", @@ -92,7 +92,7 @@ describe Travis::API::V3::Services::Cron::Create do describe "creating cron on a non-existing repository by slug" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/svenfuchs%2Fminimal1/branch/master/cron/create", options, headers) } + before { post("/v3/repo/svenfuchs%2Fminimal1/branch/master/cron", options, headers) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", @@ -104,7 +104,7 @@ describe Travis::API::V3::Services::Cron::Create do describe "creating cron on a non-existing branch" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/cron/create", options, headers) } + before { post("/v3/repo/#{repo.id}/branch/hopefullyNonExistingBranch/cron", options, headers) } example { expect(last_response).to be_not_found } example { expect(parsed_body).to be == { "@type" => "error", diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index cec551d9..cb09c415 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -10,7 +10,7 @@ describe Travis::API::V3::Services::Cron::Delete do describe "deleting a cron job by id" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - before { post("/v3/cron/#{cron.id}/delete", {}, headers) } + before { delete("/v3/cron/#{cron.id}", {}, headers) } example { expect(last_response).to be_ok } example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to be_empty } example { expect(parsed_body).to be == { @@ -40,7 +40,7 @@ describe Travis::API::V3::Services::Cron::Delete do end describe "try deleting a cron job without login" do - before { post("/v3/cron/#{cron.id}/delete") } + before { delete("/v3/cron/#{cron.id}") } example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to exist } example { expect(parsed_body).to be == { "@type" => "error", @@ -51,7 +51,7 @@ describe Travis::API::V3::Services::Cron::Delete do describe "try deleting a cron job with a user without permissions" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/cron/#{cron.id}/delete", {}, headers) } + before { delete("/v3/cron/#{cron.id}", {}, headers) } example { expect(Travis::API::V3::Models::Cron.where(id: cron.id)).to exist } example { expect(parsed_body).to be == { "@type" => "error", @@ -69,7 +69,7 @@ describe Travis::API::V3::Services::Cron::Delete do describe "try deleting a non-existing cron job" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: false) } - before { post("/v3/cron/999999999999999/delete", {}, headers) } + before { delete("/v3/cron/999999999999999", {}, headers) } example { expect(parsed_body).to be == { "@type" => "error", "error_type" => "not_found", From 24b0af35e9d85483f41e506552032cd12476f5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 28 Jan 2016 13:16:53 +0100 Subject: [PATCH 33/54] move start cronjob to services --- lib/travis/api/v3/models/cron.rb | 13 ------------- lib/travis/api/v3/services/crons/start.rb | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 lib/travis/api/v3/services/crons/start.rb diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index ba792b6b..90f208c4 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -3,19 +3,6 @@ module Travis::API::V3 belongs_to :branch - def self.start_all - started = [] - - self.all.each do |cron| - if cron.next_build_time <= Time.now - cron.start - started.push cron - end - end - - started - end - def start raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb new file mode 100644 index 00000000..2ee13131 --- /dev/null +++ b/lib/travis/api/v3/services/crons/start.rb @@ -0,0 +1,18 @@ +module Travis::API::V3 + class Services::Crons::Start < Service + + def run! + started = [] + + Models::Cron.all.each do |cron| + if cron.next_build_time <= Time.now + cron.start + started.push cron + end + end + + started + end + + end +end From 64478d50d1540bb40c153174870c32cfb1051cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 28 Jan 2016 13:46:35 +0100 Subject: [PATCH 34/54] rename next_build_time to next_enqueuing --- lib/travis/api/v3/models/cron.rb | 2 +- lib/travis/api/v3/renderer/cron.rb | 2 +- lib/travis/api/v3/services/crons/start.rb | 2 +- spec/v3/models/cron_spec.rb | 36 +++++++++---------- spec/v3/services/cron/create_spec.rb | 2 +- spec/v3/services/cron/delete_spec.rb | 2 +- spec/v3/services/cron/find_spec.rb | 4 +-- spec/v3/services/cron/for_branch_spec.rb | 2 +- spec/v3/services/crons/for_repository_spec.rb | 2 +- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 90f208c4..e0a75cd9 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -16,7 +16,7 @@ module Travis::API::V3 payload end - def next_build_time + def next_enqueuing if (disable_by_build) && (last_non_cron_build_date > last_planned_time) return after_next_planned_time diff --git a/lib/travis/api/v3/renderer/cron.rb b/lib/travis/api/v3/renderer/cron.rb index 225033ec..fdad9263 100644 --- a/lib/travis/api/v3/renderer/cron.rb +++ b/lib/travis/api/v3/renderer/cron.rb @@ -3,7 +3,7 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Cron < Renderer::ModelRenderer representation(:minimal, :id) - representation(:standard, :id, :repository, :branch, :interval, :disable_by_build, :next_build_time) + representation(:standard, :id, :repository, :branch, :interval, :disable_by_build, :next_enqueuing) def repository model.branch.repository diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb index 2ee13131..729d6a44 100644 --- a/lib/travis/api/v3/services/crons/start.rb +++ b/lib/travis/api/v3/services/crons/start.rb @@ -5,7 +5,7 @@ module Travis::API::V3 started = [] Models::Cron.all.each do |cron| - if cron.next_build_time <= Time.now + if cron.next_enqueuing <= Time.now cron.start started.push cron end diff --git a/spec/v3/models/cron_spec.rb b/spec/v3/models/cron_spec.rb index a991301c..0ce18c94 100644 --- a/spec/v3/models/cron_spec.rb +++ b/spec/v3/models/cron_spec.rb @@ -18,7 +18,7 @@ describe Travis::API::V3::Models::Cron do it "for daily builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 1, 16) build.destroy cron.destroy end @@ -26,7 +26,7 @@ describe Travis::API::V3::Models::Cron do it "for weekly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 7, 16) build.destroy cron.destroy end @@ -34,7 +34,7 @@ describe Travis::API::V3::Models::Cron do it "for monthly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 31, 16) build.destroy cron.destroy end @@ -55,7 +55,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 1, 16) cron_build.destroy push_build.destroy cron.destroy @@ -65,7 +65,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 7, 16) cron_build.destroy push_build.destroy cron.destroy @@ -75,7 +75,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) cron_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') push_build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 31, 16) cron_build.destroy push_build.destroy cron.destroy @@ -96,7 +96,7 @@ describe Travis::API::V3::Models::Cron do it "for daily builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 2, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 2, 16) build.destroy cron.destroy end @@ -104,7 +104,7 @@ describe Travis::API::V3::Models::Cron do it "for weekly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 14, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 14, 16) build.destroy cron.destroy end @@ -112,7 +112,7 @@ describe Travis::API::V3::Models::Cron do it "for monthly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'push') - expect(cron.next_build_time).to be == DateTime.new(2016, 2, 29, 16) # it's a leap year :-D + expect(cron.next_enqueuing).to be == DateTime.new(2016, 2, 29, 16) # it's a leap year :-D build.destroy cron.destroy end @@ -132,7 +132,7 @@ describe Travis::API::V3::Models::Cron do it "for daily builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 1, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 1, 16) build.destroy cron.destroy end @@ -140,7 +140,7 @@ describe Travis::API::V3::Models::Cron do it "for weekly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 7, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 7, 16) build.destroy cron.destroy end @@ -148,7 +148,7 @@ describe Travis::API::V3::Models::Cron do it "for monthly builds" do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') - expect(cron.next_build_time).to be == DateTime.new(2016, 1, 31, 16) + expect(cron.next_enqueuing).to be == DateTime.new(2016, 1, 31, 16) build.destroy cron.destroy end @@ -171,7 +171,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 1, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end @@ -181,7 +181,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'daily', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 1, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end @@ -191,7 +191,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 7, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end @@ -201,7 +201,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'weekly', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 7, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end @@ -211,7 +211,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: true) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 31, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end @@ -221,7 +221,7 @@ describe Travis::API::V3::Models::Cron do cron = Travis::API::V3::Models::Cron.create(branch_id: branch.id, interval: 'monthly', disable_by_build: false) build = Travis::API::V3::Models::Build.create(:repository_id => repo.id, :branch_name => branch.name, :event_type => 'cron') Timecop.freeze(DateTime.new(2016, 1, 31, 19)) - expect(cron.next_build_time).to be == DateTime.now + expect(cron.next_enqueuing).to be == DateTime.now build.destroy cron.destroy end diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 84efefd3..8b3b7a0c 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -39,7 +39,7 @@ describe Travis::API::V3::Services::Cron::Create do "name" => "#{branch.name}" }, "interval" => "monthly", "disable_by_build" => false, - "next_build_time" => current_cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => current_cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index cb09c415..cecf96d8 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -35,7 +35,7 @@ describe Travis::API::V3::Services::Cron::Delete do "name" => branch.name }, "interval" => "daily", "disable_by_build" => true, - "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 876b4940..36e1deb4 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -31,7 +31,7 @@ describe Travis::API::V3::Services::Cron::Find do "name" => branch.name }, "interval" => "daily", "disable_by_build" => true, - "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') }} end @@ -89,7 +89,7 @@ describe Travis::API::V3::Services::Cron::Find do "name" => branch.name }, "interval" => "daily", "disable_by_build" => true, - "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb index aa75537e..13ca127d 100644 --- a/spec/v3/services/cron/for_branch_spec.rb +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -32,7 +32,7 @@ describe Travis::API::V3::Services::Cron::ForBranch do "name" => branch.name }, "interval" => "daily", "disable_by_build" => true, - "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') }} end diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index b1eab41c..ad6d2ba3 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -53,7 +53,7 @@ describe Travis::API::V3::Services::Crons::ForRepository do "name" => "#{branch.name}" }, "interval" => "daily", "disable_by_build" => true, - "next_build_time" => cron.next_build_time.strftime('%Y-%m-%dT%H:%M:%SZ') + "next_enqueuing" => cron.next_enqueuing.strftime('%Y-%m-%dT%H:%M:%SZ') } ] }} From d75daab82f33f4be50519730fe66941c098ef00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 15:07:23 +0100 Subject: [PATCH 35/54] move cron start to query --- lib/travis/api/v3/models/cron.rb | 13 ------------- lib/travis/api/v3/queries/crons.rb | 13 +++++++++++++ lib/travis/api/v3/services/crons/start.rb | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index e0a75cd9..1300cbfa 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -3,19 +3,6 @@ module Travis::API::V3 belongs_to :branch - def start - raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id - - payload = { - repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, - branch: branch.name - } - - class_name, queue = Query.sidekiq_queue(:build_request) - ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload)}]) - payload - end - def next_enqueuing if (disable_by_build) && (last_non_cron_build_date > last_planned_time) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 463336b3..723bb7e5 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -4,5 +4,18 @@ module Travis::API::V3 def find(branch) branch.cron end + + def start(branch) + raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id + + payload = { + repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, + branch: branch.name + } + + class_name, queue = Query.sidekiq_queue(:build_request) + ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload)}]) + payload + end end end diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb index 729d6a44..1bef2f79 100644 --- a/lib/travis/api/v3/services/crons/start.rb +++ b/lib/travis/api/v3/services/crons/start.rb @@ -6,7 +6,7 @@ module Travis::API::V3 Models::Cron.all.each do |cron| if cron.next_enqueuing <= Time.now - cron.start + query.start(cron.branch) started.push cron end end From 98a75e593180dc08c464b3e3af000841d6eebc3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 15:23:15 +0100 Subject: [PATCH 36/54] move find cron for branch to correct query --- lib/travis/api/v3/queries/cron.rb | 4 ++++ lib/travis/api/v3/queries/crons.rb | 4 ---- lib/travis/api/v3/services/cron/for_branch.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/travis/api/v3/queries/cron.rb b/lib/travis/api/v3/queries/cron.rb index 25c38191..80ac2108 100644 --- a/lib/travis/api/v3/queries/cron.rb +++ b/lib/travis/api/v3/queries/cron.rb @@ -8,5 +8,9 @@ module Travis::API::V3 return Models::Cron.find_by_id(id) if id raise WrongParams, 'missing cron.id'.freeze end + + def find_for_branch(branch) + branch.cron + end end end diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 723bb7e5..77c5dc8a 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -1,10 +1,6 @@ module Travis::API::V3 class Queries::Crons < Query - def find(branch) - branch.cron - end - def start(branch) raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id diff --git a/lib/travis/api/v3/services/cron/for_branch.rb b/lib/travis/api/v3/services/cron/for_branch.rb index 478e4b2c..0290e112 100644 --- a/lib/travis/api/v3/services/cron/for_branch.rb +++ b/lib/travis/api/v3/services/cron/for_branch.rb @@ -2,7 +2,7 @@ module Travis::API::V3 class Services::Cron::ForBranch < Service def run! - Models::Cron.where(:branch_id => find(:branch, find(:repository))).first + query.find_for_branch(find(:branch, find(:repository))) end end end From 6fb0f7b6cef900e88c911a423805aad447b458dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 16:08:33 +0100 Subject: [PATCH 37/54] change error type --- lib/travis/api/v3/services/cron/create.rb | 2 +- spec/v3/services/cron/create_spec.rb | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index f3ceb0e8..c7ce0c03 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -7,7 +7,7 @@ module Travis::API::V3 raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) - raise ArgumentError, 'interval must be "daily", "weekly" or "monthly"' unless ["daily", "weekly", "monthly"].include?(params["interval"]) + raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) access_control.permissions(repository).create_cron! if branch.cron diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 8b3b7a0c..115d2f95 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -55,11 +55,12 @@ describe Travis::API::V3::Services::Cron::Create do describe "creating a cron job with a wrong interval" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } - it "raises an error" do - expect { - post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", wrong_options, headers) - }.to raise_error(ArgumentError, 'interval must be "daily", "weekly" or "monthly"') - end + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", wrong_options, headers) } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "error", + "error_message" => "Invalid value for interval. Interval must be \"daily\", \"weekly\" or \"monthly\"!" + }} end describe "try creating a cron job without login" do From be01b36f05c9a782587e491c1f9b0d9a15805d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 16:20:50 +0100 Subject: [PATCH 38/54] move find cron for repository to query --- lib/travis/api/v3/queries/crons.rb | 4 ++++ lib/travis/api/v3/services/crons/for_repository.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 77c5dc8a..9998097e 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -1,6 +1,10 @@ module Travis::API::V3 class Queries::Crons < Query + def find(repository) + Models::Cron.where(:branch_id => repository.branches) + end + def start(branch) raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id diff --git a/lib/travis/api/v3/services/crons/for_repository.rb b/lib/travis/api/v3/services/crons/for_repository.rb index 4d912cdc..48c488f6 100644 --- a/lib/travis/api/v3/services/crons/for_repository.rb +++ b/lib/travis/api/v3/services/crons/for_repository.rb @@ -3,7 +3,7 @@ module Travis::API::V3 paginate def run! - Models::Cron.where(:branch_id => find(:repository).branches) + query.find(find(:repository)) end end end From 0d1dbaadd7357871c690d352c03b160150ae0592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 16:25:14 +0100 Subject: [PATCH 39/54] move start all to query --- lib/travis/api/v3/queries/crons.rb | 13 +++++++++++++ lib/travis/api/v3/services/crons/start.rb | 11 +---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 9998097e..761da836 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -5,6 +5,19 @@ module Travis::API::V3 Models::Cron.where(:branch_id => repository.branches) end + def start_all() + started = [] + + Models::Cron.all.each do |cron| + if cron.next_enqueuing <= Time.now + start(cron.branch) + started.push cron + end + end + + started + end + def start(branch) raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb index 1bef2f79..104d43f5 100644 --- a/lib/travis/api/v3/services/crons/start.rb +++ b/lib/travis/api/v3/services/crons/start.rb @@ -2,16 +2,7 @@ module Travis::API::V3 class Services::Crons::Start < Service def run! - started = [] - - Models::Cron.all.each do |cron| - if cron.next_enqueuing <= Time.now - query.start(cron.branch) - started.push cron - end - end - - started + query.start_all() end end From 3fa9c09c0c1ac8524f8ad49d7980f46e26dbb4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 16:50:10 +0100 Subject: [PATCH 40/54] move cron creation to query --- lib/travis/api/v3/queries/cron.rb | 5 +++++ lib/travis/api/v3/services/cron/create.rb | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/queries/cron.rb b/lib/travis/api/v3/queries/cron.rb index 80ac2108..43d3cb5f 100644 --- a/lib/travis/api/v3/queries/cron.rb +++ b/lib/travis/api/v3/queries/cron.rb @@ -12,5 +12,10 @@ module Travis::API::V3 def find_for_branch(branch) branch.cron end + + def create(branch, interval, disable_by_build) + branch.cron.destroy unless branch.cron.nil? + Models::Cron.create(branch: branch, interval: interval, disable_by_build: disable_by_build) + end end end diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index c7ce0c03..32f245f3 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -12,12 +12,10 @@ module Travis::API::V3 if branch.cron access_control.permissions(branch.cron).delete! - branch.cron.destroy end - Models::Cron.create(branch: branch, - interval: params["interval"], - disable_by_build: params["disable_by_build"] ? params["disable_by_build"] : false) + query.create(branch, params["interval"], params["disable_by_build"] ? params["disable_by_build"] : false) + end end From 8a6f4066ae45d268a85caff0cd3c93da030c2c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 1 Feb 2016 17:08:11 +0100 Subject: [PATCH 41/54] refactor methods to calculate next build time --- lib/travis/api/v3/models/cron.rb | 60 ++++++-------------------------- 1 file changed, 11 insertions(+), 49 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 1300cbfa..7441e80c 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -5,80 +5,42 @@ module Travis::API::V3 def next_enqueuing - if (disable_by_build) && (last_non_cron_build_date > last_planned_time) - return after_next_planned_time - elsif last_cron_build_date >= last_planned_time - return next_planned_time + if (disable_by_build) && (last_non_cron_build_date > plannedTime(-1)) + return plannedTime(1) + elsif last_cron_build_date >= plannedTime(-1) + return plannedTime(0) else return Time.now end end - def next_planned_time + def plannedTime(in_builds = 0) # 0 equals next build, 1 after next build, -1 last build, ... now = DateTime.now created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) case interval when 'daily' build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) if now > build_today - return build_today + 1 + return build_today + 1 + in_builds else - return build_today + return build_today + in_builds end when 'weekly' build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) in_days = (created_at.wday - now.wday) % 7 next_time = build_today + in_days if now > next_time - return build_today + 7 + return build_today + 7 * (1 + in_builds) else - return next_time + return next_time + 7 * in_builds end when 'monthly' month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) this_month = created >> month_since_creation if now > this_month - return created >> (month_since_creation+1) + return created >> (month_since_creation + 1 + in_builds) else - return this_month - end - end - end - - def last_planned_time - now = DateTime.now - created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) - case interval - when 'daily' - return next_planned_time - 1 - when 'weekly' - return next_planned_time - 7 - when 'monthly' - month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) - this_month = created >> month_since_creation - if now > this_month - return this_month - else - return created >> (month_since_creation-1) - end - end - end - - def after_next_planned_time - now = DateTime.now - created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) - case interval - when 'daily' - return next_planned_time + 1 - when 'weekly' - return next_planned_time + 7 - when 'monthly' - month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) - this_month = created >> month_since_creation - if now > this_month - return created >> (month_since_creation+2) - else - return created >> (month_since_creation+1) + return created >> (month_since_creation + in_builds) end end end From 77ec852be674eff313774dd3a895e81ab3190ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 11 Feb 2016 14:43:33 +0100 Subject: [PATCH 42/54] send empty credentials hash --- lib/travis/api/v3/queries/crons.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 761da836..74de15c7 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -27,7 +27,7 @@ module Travis::API::V3 } class_name, queue = Query.sidekiq_queue(:build_request) - ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload)}]) + ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload), credentials: {}}]) payload end end From ca5820e2e30c98fa2ae862f58c30ed971162ff60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 25 Feb 2016 13:40:23 +0100 Subject: [PATCH 43/54] send user id with cron build payload --- lib/travis/api/v3/queries/crons.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 74de15c7..c69ec907 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -21,9 +21,12 @@ module Travis::API::V3 def start(branch) raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id + user_id = branch.repository.users.detect { |u| u.github_oauth_token }.id + payload = { repository: { id: branch.repository.github_id, owner_name: branch.repository.owner_name, name: branch.repository.name }, - branch: branch.name + branch: branch.name, + user: { id: user_id } } class_name, queue = Query.sidekiq_queue(:build_request) From 6c839aebece5ffe90cd216211b17d74b92708fc4 Mon Sep 17 00:00:00 2001 From: Christopher Weyand Date: Mon, 14 Mar 2016 11:03:41 +0100 Subject: [PATCH 44/54] feature flag test --- lib/travis/api/v3/services/cron/create.rb | 1 + lib/travis/api/v3/services/cron/delete.rb | 1 + lib/travis/api/v3/services/cron/find.rb | 1 + lib/travis/api/v3/services/cron/for_branch.rb | 1 + .../api/v3/services/crons/for_repository.rb | 1 + lib/travis/api/v3/services/crons/start.rb | 1 + spec/v3/services/cron/create_spec.rb | 14 ++ spec/v3/services/cron/delete_spec.rb | 14 ++ spec/v3/services/cron/find_spec.rb | 14 ++ spec/v3/services/cron/for_branch_spec.rb | 14 ++ spec/v3/services/crons/for_repository_spec.rb | 14 ++ travis-api.gemspec | 130 +++++++++++++++--- 12 files changed, 186 insertions(+), 20 deletions(-) diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index 32f245f3..e676c158 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -5,6 +5,7 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) diff --git a/lib/travis/api/v3/services/cron/delete.rb b/lib/travis/api/v3/services/cron/delete.rb index c5d9287d..256f97c7 100644 --- a/lib/travis/api/v3/services/cron/delete.rb +++ b/lib/travis/api/v3/services/cron/delete.rb @@ -4,6 +4,7 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) cron = find access_control.permissions(cron).delete! cron.destroy diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb index 6a191d7a..33a337d6 100644 --- a/lib/travis/api/v3/services/cron/find.rb +++ b/lib/travis/api/v3/services/cron/find.rb @@ -3,6 +3,7 @@ module Travis::API::V3 #params :id def run! + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) find end end diff --git a/lib/travis/api/v3/services/cron/for_branch.rb b/lib/travis/api/v3/services/cron/for_branch.rb index 0290e112..d2396e9b 100644 --- a/lib/travis/api/v3/services/cron/for_branch.rb +++ b/lib/travis/api/v3/services/cron/for_branch.rb @@ -2,6 +2,7 @@ module Travis::API::V3 class Services::Cron::ForBranch < Service def run! + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) query.find_for_branch(find(:branch, find(:repository))) end end diff --git a/lib/travis/api/v3/services/crons/for_repository.rb b/lib/travis/api/v3/services/crons/for_repository.rb index 48c488f6..2b746fc1 100644 --- a/lib/travis/api/v3/services/crons/for_repository.rb +++ b/lib/travis/api/v3/services/crons/for_repository.rb @@ -3,6 +3,7 @@ module Travis::API::V3 paginate def run! + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) query.find(find(:repository)) end end diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb index 104d43f5..0bfa3a16 100644 --- a/lib/travis/api/v3/services/crons/start.rb +++ b/lib/travis/api/v3/services/crons/start.rb @@ -2,6 +2,7 @@ module Travis::API::V3 class Services::Crons::Start < Service def run! + raise InsufficientAccess unless Travis::Features.feature_active?(:cron) query.start_all() end diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 115d2f95..f007f106 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -11,6 +11,20 @@ describe Travis::API::V3::Services::Cron::Create do let(:wrong_options) {{ "interval" => "notExisting", "disable_by_build" => false }} let(:parsed_body) { JSON.load(body) } + before do + Travis::Features.enable_for_all(:cron) + end + + describe "no Feature enabled" do + before { Travis::Features.disable_for_all(:cron) } + before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers)} + example { expect(parsed_body).to be == { + "@type"=> "error", + "error_type"=> "insufficient_access", + "error_message"=> "forbidden" + }} + end + describe "creating a cron job" do before { last_cron } before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index cecf96d8..ee920566 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -8,6 +8,20 @@ describe Travis::API::V3::Services::Cron::Delete do let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} let(:parsed_body) { JSON.load(body) } + before do + Travis::Features.enable_for_all(:cron) + end + + describe "no Feature enabled" do + before { Travis::Features.disable_for_all(:cron) } + before { delete("/v3/cron/#{cron.id}", {}, headers)} + example { expect(parsed_body).to be == { + "@type"=> "error", + "error_type"=> "insufficient_access", + "error_message"=> "forbidden" + }} + end + describe "deleting a cron job by id" do before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } before { delete("/v3/cron/#{cron.id}", {}, headers) } diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 36e1deb4..4f165e2b 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -6,6 +6,20 @@ describe Travis::API::V3::Services::Cron::Find do let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:parsed_body) { JSON.load(body) } + before do + Travis::Features.enable_for_all(:cron) + end + + describe "no Feature enabled" do + before { Travis::Features.disable_for_all(:cron) } + before { get("/v3/cron/#{cron.id}") } + example { expect(parsed_body).to be == { + "@type"=> "error", + "error_type"=> "insufficient_access", + "error_message"=> "forbidden" + }} + end + describe "fetching a cron job by id" do before { get("/v3/cron/#{cron.id}") } example { expect(last_response).to be_ok } diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb index 13ca127d..ad445b5a 100644 --- a/spec/v3/services/cron/for_branch_spec.rb +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -6,6 +6,20 @@ describe Travis::API::V3::Services::Cron::ForBranch do let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:parsed_body) { JSON.load(body) } + before do + Travis::Features.enable_for_all(:cron) + end + + describe "no Feature enabled" do + before { Travis::Features.disable_for_all(:cron) } + before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } + example { expect(parsed_body).to be == { + "@type"=> "error", + "error_type"=> "insufficient_access", + "error_message"=> "forbidden" + }} + end + describe "fetching all crons by repo id" do before { cron } before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index ad6d2ba3..2d005f24 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -6,6 +6,20 @@ describe Travis::API::V3::Services::Crons::ForRepository do let(:cron) { Travis::API::V3::Models::Cron.create(branch: branch, interval:'daily') } let(:parsed_body) { JSON.load(body) } + before do + Travis::Features.enable_for_all(:cron) + end + + describe "no Feature enabled" do + before { Travis::Features.disable_for_all(:cron) } + before { get("/v3/repo/#{repo.id}/crons") } + example { expect(parsed_body).to be == { + "@type"=> "error", + "error_type"=> "insufficient_access", + "error_message"=> "forbidden" + }} + end + describe "fetching all crons by repo id" do before { cron } before { get("/v3/repo/#{repo.id}/crons") } diff --git a/travis-api.gemspec b/travis-api.gemspec index 92ee8839..e07241d9 100644 --- a/travis-api.gemspec +++ b/travis-api.gemspec @@ -12,74 +12,90 @@ Gem::Specification.new do |s| "Konstantin Haase", "Piotr Sarnacki", "Sven Fuchs", + "carlad", "Hiro Asari", "Mathias Meyer", "Josh Kalderimis", "Henrik Hodne", - "carlad", + "Steffen Kötte", + "Lennard Wolf", "Tyranja", - "Andre Arko", "Dan Buch", + "Andre Arko", "C. Scott Ananian", "Erik Michaels-Ober", "Brian Ford", + "Jonas Chromik", + "Steffen", "Steve Richert", + "Bryan Goldstein", + "Dan Rice", + "James Dennes", + "María de Antón", + "Nick Schonning", + "Patrick Williams", "Puneeth Chaganti", "Thais Camilo and Konstantin Haase", "Tim Carey-Smith", - "Bryan Goldstein", "Zachary Scott", - "James Dennes", - "rainsun", - "Nick Schonning", - "Patrick Williams", - "Dan Rice" + "rainsun" ] s.email = [ "konstantin.mailinglists@googlemail.com", "drogus@gmail.com", "me@svenfuchs.com", + "carla@travis-ci.com", "asari.ruby@gmail.com", "meyer@paperplanes.de", "josh.kalderimis@gmail.com", + "steffen.koette@gmail.com", "me@henrikhodne.com", "henrik@hodne.io", + "carlad@users.noreply.github.com", "konstantin.haase@gmail.com", + "lennardwolf@live.de", "carla@travis-ci.org", "tyranja@cassiopeia.uberspace.de", "andre@arko.net", - "svenfuchs@artweb-design.de", "dan@travis-ci.org", - "sferik@gmail.com", + "svenfuchs@artweb-design.de", "cscott@cscott.net", - "henrik@travis-ci.com", - "steve.richert@gmail.com", + "sferik@gmail.com", "bford@engineyard.com", + "henrik@travis-ci.com", + "Jonas.Chromik@student.hpi.uni-potsdam.de", + "steffen.koette@gmail.com", + "steve.richert@gmail.com", + "brysgo@gmail.com", + "dan@meatballhat.com", + "dan@zoombody.com", + "jdennes@gmail.com", + "MariadeAnton@users.noreply.github.com", + "nschonni@gmail.com", "patrick@bittorrent.com", "punchagan@muse-amuse.in", - "carlad@users.noreply.github.com", - "dan@zoombody.com", - "rainsuner@gmail.com", "dev+narwen+rkh@rkh.im", "tim@spork.in", - "brysgo@gmail.com", "e@zzak.io", - "jdennes@gmail.com", - "nschonni@gmail.com", - "dan@meatballhat.com" + "rainsuner@gmail.com" ] s.files = [ "CONTRIBUTING.md", + "LICENSE", "Procfile", "README.md", "Rakefile", "bin/start-nginx", "config.ru", "config/database.yml", + "config/mime.types", + "config/nginx.conf.erb", "config/puma-config.rb", + "config/ruby_config.sh", "config/unicorn.rb", + "lib/active_record_postgres_variables.rb", "lib/conditional_skylight.rb", "lib/tasks/build_update_branch.rake", "lib/tasks/build_update_pull_request_data.rake", @@ -141,6 +157,7 @@ Gem::Specification.new do |s| "lib/travis/api/app/responders/xml.rb", "lib/travis/api/app/services/schedule_request.rb", "lib/travis/api/app/stack_instrumentation.rb", + "lib/travis/api/attack.rb", "lib/travis/api/instruments.rb", "lib/travis/api/serializer.rb", "lib/travis/api/v2.rb", @@ -191,6 +208,7 @@ Gem::Specification.new do |s| "lib/travis/api/v3/models/broadcast.rb", "lib/travis/api/v3/models/build.rb", "lib/travis/api/v3/models/commit.rb", + "lib/travis/api/v3/models/cron.rb", "lib/travis/api/v3/models/email.rb", "lib/travis/api/v3/models/job.rb", "lib/travis/api/v3/models/log.rb", @@ -201,14 +219,33 @@ Gem::Specification.new do |s| "lib/travis/api/v3/models/repository.rb", "lib/travis/api/v3/models/request.rb", "lib/travis/api/v3/models/ssl_key.rb", + "lib/travis/api/v3/models/star.rb", "lib/travis/api/v3/models/subscription.rb", "lib/travis/api/v3/models/token.rb", "lib/travis/api/v3/models/user.rb", "lib/travis/api/v3/opt_in.rb", + "lib/travis/api/v3/paginator.rb", + "lib/travis/api/v3/paginator/url_generator.rb", + "lib/travis/api/v3/permissions.rb", + "lib/travis/api/v3/permissions/account.rb", + "lib/travis/api/v3/permissions/build.rb", + "lib/travis/api/v3/permissions/cron.rb", + "lib/travis/api/v3/permissions/generic.rb", + "lib/travis/api/v3/permissions/job.rb", + "lib/travis/api/v3/permissions/organization.rb", + "lib/travis/api/v3/permissions/repository.rb", + "lib/travis/api/v3/permissions/user.rb", "lib/travis/api/v3/queries.rb", "lib/travis/api/v3/queries/accounts.rb", "lib/travis/api/v3/queries/branch.rb", + "lib/travis/api/v3/queries/branches.rb", + "lib/travis/api/v3/queries/broadcasts.rb", "lib/travis/api/v3/queries/build.rb", + "lib/travis/api/v3/queries/builds.rb", + "lib/travis/api/v3/queries/cron.rb", + "lib/travis/api/v3/queries/crons.rb", + "lib/travis/api/v3/queries/job.rb", + "lib/travis/api/v3/queries/jobs.rb", "lib/travis/api/v3/queries/organization.rb", "lib/travis/api/v3/queries/organizations.rb", "lib/travis/api/v3/queries/owner.rb", @@ -224,15 +261,25 @@ Gem::Specification.new do |s| "lib/travis/api/v3/renderer/accounts.rb", "lib/travis/api/v3/renderer/avatar_url.rb", "lib/travis/api/v3/renderer/branch.rb", + "lib/travis/api/v3/renderer/branches.rb", + "lib/travis/api/v3/renderer/broadcast.rb", + "lib/travis/api/v3/renderer/broadcasts.rb", "lib/travis/api/v3/renderer/build.rb", + "lib/travis/api/v3/renderer/builds.rb", "lib/travis/api/v3/renderer/collection_renderer.rb", + "lib/travis/api/v3/renderer/commit.rb", + "lib/travis/api/v3/renderer/cron.rb", + "lib/travis/api/v3/renderer/crons.rb", "lib/travis/api/v3/renderer/error.rb", + "lib/travis/api/v3/renderer/job.rb", + "lib/travis/api/v3/renderer/jobs.rb", "lib/travis/api/v3/renderer/model_renderer.rb", "lib/travis/api/v3/renderer/organization.rb", "lib/travis/api/v3/renderer/organizations.rb", "lib/travis/api/v3/renderer/owner.rb", "lib/travis/api/v3/renderer/repositories.rb", "lib/travis/api/v3/renderer/repository.rb", + "lib/travis/api/v3/renderer/request.rb", "lib/travis/api/v3/renderer/requests.rb", "lib/travis/api/v3/renderer/user.rb", "lib/travis/api/v3/result.rb", @@ -245,19 +292,38 @@ Gem::Specification.new do |s| "lib/travis/api/v3/services.rb", "lib/travis/api/v3/services/accounts/for_current_user.rb", "lib/travis/api/v3/services/branch/find.rb", + "lib/travis/api/v3/services/branches/find.rb", + "lib/travis/api/v3/services/broadcasts/for_current_user.rb", + "lib/travis/api/v3/services/build/cancel.rb", "lib/travis/api/v3/services/build/find.rb", + "lib/travis/api/v3/services/build/restart.rb", + "lib/travis/api/v3/services/builds/find.rb", + "lib/travis/api/v3/services/cron/create.rb", + "lib/travis/api/v3/services/cron/delete.rb", + "lib/travis/api/v3/services/cron/find.rb", + "lib/travis/api/v3/services/cron/for_branch.rb", + "lib/travis/api/v3/services/crons/for_repository.rb", + "lib/travis/api/v3/services/crons/start.rb", + "lib/travis/api/v3/services/job/cancel.rb", + "lib/travis/api/v3/services/job/find.rb", + "lib/travis/api/v3/services/job/restart.rb", + "lib/travis/api/v3/services/jobs/find.rb", "lib/travis/api/v3/services/organization/find.rb", "lib/travis/api/v3/services/organization/sync.rb", "lib/travis/api/v3/services/organizations/for_current_user.rb", "lib/travis/api/v3/services/owner/find.rb", "lib/travis/api/v3/services/repositories/for_current_user.rb", + "lib/travis/api/v3/services/repositories/for_owner.rb", "lib/travis/api/v3/services/repository/disable.rb", "lib/travis/api/v3/services/repository/enable.rb", "lib/travis/api/v3/services/repository/find.rb", + "lib/travis/api/v3/services/repository/star.rb", + "lib/travis/api/v3/services/repository/unstar.rb", "lib/travis/api/v3/services/requests/create.rb", "lib/travis/api/v3/services/requests/find.rb", "lib/travis/api/v3/services/user/current.rb", "lib/travis/api/v3/services/user/find.rb", + "lib/travis/api/v3/services/user/sync.rb", "lib/travis/api/workers/build_cancellation.rb", "lib/travis/api/workers/build_restart.rb", "lib/travis/api/workers/job_cancellation.rb", @@ -280,6 +346,8 @@ Gem::Specification.new do |s| "script/console", "script/repos_stats.rb", "script/server", + "script/web_concurrency", + "spec/active_record_postgres_variables_spec.rb", "spec/integration/error_handling_spec.rb", "spec/integration/formats_handling_spec.rb", "spec/integration/responders_spec.rb", @@ -344,7 +412,7 @@ Gem::Specification.new do |s| "spec/unit/endpoint/lint_spec.rb", "spec/unit/endpoint/logs_spec.rb", "spec/unit/endpoint/repos_spec.rb", - "spec/unit/endpoint/requests_spec.rb", + "spec/unit/endpoint/requests/throttle_spec.rb", "spec/unit/endpoint/users_spec.rb", "spec/unit/endpoint_spec.rb", "spec/unit/extensions/expose_pattern_spec.rb", @@ -359,19 +427,41 @@ Gem::Specification.new do |s| "spec/unit/responders/json_spec.rb", "spec/unit/responders/service_spec.rb", "spec/v3/extensions/belongs_to_spec.rb", + "spec/v3/models/cron_spec.rb", "spec/v3/renderer/avatar_url_spec.rb", "spec/v3/result_spec.rb", "spec/v3/service_index_spec.rb", "spec/v3/services/accounts/for_current_user_spec.rb", "spec/v3/services/branch/find_spec.rb", + "spec/v3/services/branches/find_spec.rb", + "spec/v3/services/broadcasts/for_current_user_spec.rb", + "spec/v3/services/build/cancel_spec.rb", + "spec/v3/services/build/find_spec.rb", + "spec/v3/services/build/restart_spec.rb", + "spec/v3/services/builds/find_spec.rb", + "spec/v3/services/cron/create_spec.rb", + "spec/v3/services/cron/delete_spec.rb", + "spec/v3/services/cron/find_spec.rb", + "spec/v3/services/cron/for_branch_spec.rb", + "spec/v3/services/crons/for_repository_spec.rb", + "spec/v3/services/job/cancel_spec.rb", + "spec/v3/services/job/find_spec.rb", + "spec/v3/services/job/restart_spec.rb", + "spec/v3/services/jobs/find_spec.rb", "spec/v3/services/organization/find_spec.rb", "spec/v3/services/organizations/for_current_user_spec.rb", "spec/v3/services/owner/find_spec.rb", "spec/v3/services/repositories/for_current_user_spec.rb", + "spec/v3/services/repositories/for_owner_spec.rb", + "spec/v3/services/repository/disable_spec.rb", + "spec/v3/services/repository/enable_spec.rb", "spec/v3/services/repository/find_spec.rb", + "spec/v3/services/repository/star_spec.rb", + "spec/v3/services/repository/unstar_spec.rb", "spec/v3/services/requests/create_spec.rb", "spec/v3/services/user/current_spec.rb", "spec/v3/services/user/find_spec.rb", + "spec/v3/services/user/sync_spec.rb", "tmp/.gitkeep", "travis-api.gemspec" ] From dd7e74950d273f039bcea13ee5f822ced278505e Mon Sep 17 00:00:00 2001 From: Christopher Weyand Date: Mon, 14 Mar 2016 11:11:18 +0100 Subject: [PATCH 45/54] revert gemspec --- travis-api.gemspec | 128 +++++++-------------------------------------- 1 file changed, 19 insertions(+), 109 deletions(-) diff --git a/travis-api.gemspec b/travis-api.gemspec index e07241d9..92ee8839 100644 --- a/travis-api.gemspec +++ b/travis-api.gemspec @@ -12,90 +12,74 @@ Gem::Specification.new do |s| "Konstantin Haase", "Piotr Sarnacki", "Sven Fuchs", - "carlad", "Hiro Asari", "Mathias Meyer", "Josh Kalderimis", "Henrik Hodne", - "Steffen Kötte", - "Lennard Wolf", + "carlad", "Tyranja", - "Dan Buch", "Andre Arko", + "Dan Buch", "C. Scott Ananian", "Erik Michaels-Ober", "Brian Ford", - "Jonas Chromik", - "Steffen", "Steve Richert", - "Bryan Goldstein", - "Dan Rice", - "James Dennes", - "María de Antón", - "Nick Schonning", - "Patrick Williams", "Puneeth Chaganti", "Thais Camilo and Konstantin Haase", "Tim Carey-Smith", + "Bryan Goldstein", "Zachary Scott", - "rainsun" + "James Dennes", + "rainsun", + "Nick Schonning", + "Patrick Williams", + "Dan Rice" ] s.email = [ "konstantin.mailinglists@googlemail.com", "drogus@gmail.com", "me@svenfuchs.com", - "carla@travis-ci.com", "asari.ruby@gmail.com", "meyer@paperplanes.de", "josh.kalderimis@gmail.com", - "steffen.koette@gmail.com", "me@henrikhodne.com", "henrik@hodne.io", - "carlad@users.noreply.github.com", "konstantin.haase@gmail.com", - "lennardwolf@live.de", "carla@travis-ci.org", "tyranja@cassiopeia.uberspace.de", "andre@arko.net", - "dan@travis-ci.org", "svenfuchs@artweb-design.de", - "cscott@cscott.net", + "dan@travis-ci.org", "sferik@gmail.com", - "bford@engineyard.com", + "cscott@cscott.net", "henrik@travis-ci.com", - "Jonas.Chromik@student.hpi.uni-potsdam.de", - "steffen.koette@gmail.com", "steve.richert@gmail.com", - "brysgo@gmail.com", - "dan@meatballhat.com", - "dan@zoombody.com", - "jdennes@gmail.com", - "MariadeAnton@users.noreply.github.com", - "nschonni@gmail.com", + "bford@engineyard.com", "patrick@bittorrent.com", "punchagan@muse-amuse.in", + "carlad@users.noreply.github.com", + "dan@zoombody.com", + "rainsuner@gmail.com", "dev+narwen+rkh@rkh.im", "tim@spork.in", + "brysgo@gmail.com", "e@zzak.io", - "rainsuner@gmail.com" + "jdennes@gmail.com", + "nschonni@gmail.com", + "dan@meatballhat.com" ] s.files = [ "CONTRIBUTING.md", - "LICENSE", "Procfile", "README.md", "Rakefile", "bin/start-nginx", "config.ru", "config/database.yml", - "config/mime.types", - "config/nginx.conf.erb", "config/puma-config.rb", - "config/ruby_config.sh", "config/unicorn.rb", - "lib/active_record_postgres_variables.rb", "lib/conditional_skylight.rb", "lib/tasks/build_update_branch.rake", "lib/tasks/build_update_pull_request_data.rake", @@ -157,7 +141,6 @@ Gem::Specification.new do |s| "lib/travis/api/app/responders/xml.rb", "lib/travis/api/app/services/schedule_request.rb", "lib/travis/api/app/stack_instrumentation.rb", - "lib/travis/api/attack.rb", "lib/travis/api/instruments.rb", "lib/travis/api/serializer.rb", "lib/travis/api/v2.rb", @@ -208,7 +191,6 @@ Gem::Specification.new do |s| "lib/travis/api/v3/models/broadcast.rb", "lib/travis/api/v3/models/build.rb", "lib/travis/api/v3/models/commit.rb", - "lib/travis/api/v3/models/cron.rb", "lib/travis/api/v3/models/email.rb", "lib/travis/api/v3/models/job.rb", "lib/travis/api/v3/models/log.rb", @@ -219,33 +201,14 @@ Gem::Specification.new do |s| "lib/travis/api/v3/models/repository.rb", "lib/travis/api/v3/models/request.rb", "lib/travis/api/v3/models/ssl_key.rb", - "lib/travis/api/v3/models/star.rb", "lib/travis/api/v3/models/subscription.rb", "lib/travis/api/v3/models/token.rb", "lib/travis/api/v3/models/user.rb", "lib/travis/api/v3/opt_in.rb", - "lib/travis/api/v3/paginator.rb", - "lib/travis/api/v3/paginator/url_generator.rb", - "lib/travis/api/v3/permissions.rb", - "lib/travis/api/v3/permissions/account.rb", - "lib/travis/api/v3/permissions/build.rb", - "lib/travis/api/v3/permissions/cron.rb", - "lib/travis/api/v3/permissions/generic.rb", - "lib/travis/api/v3/permissions/job.rb", - "lib/travis/api/v3/permissions/organization.rb", - "lib/travis/api/v3/permissions/repository.rb", - "lib/travis/api/v3/permissions/user.rb", "lib/travis/api/v3/queries.rb", "lib/travis/api/v3/queries/accounts.rb", "lib/travis/api/v3/queries/branch.rb", - "lib/travis/api/v3/queries/branches.rb", - "lib/travis/api/v3/queries/broadcasts.rb", "lib/travis/api/v3/queries/build.rb", - "lib/travis/api/v3/queries/builds.rb", - "lib/travis/api/v3/queries/cron.rb", - "lib/travis/api/v3/queries/crons.rb", - "lib/travis/api/v3/queries/job.rb", - "lib/travis/api/v3/queries/jobs.rb", "lib/travis/api/v3/queries/organization.rb", "lib/travis/api/v3/queries/organizations.rb", "lib/travis/api/v3/queries/owner.rb", @@ -261,25 +224,15 @@ Gem::Specification.new do |s| "lib/travis/api/v3/renderer/accounts.rb", "lib/travis/api/v3/renderer/avatar_url.rb", "lib/travis/api/v3/renderer/branch.rb", - "lib/travis/api/v3/renderer/branches.rb", - "lib/travis/api/v3/renderer/broadcast.rb", - "lib/travis/api/v3/renderer/broadcasts.rb", "lib/travis/api/v3/renderer/build.rb", - "lib/travis/api/v3/renderer/builds.rb", "lib/travis/api/v3/renderer/collection_renderer.rb", - "lib/travis/api/v3/renderer/commit.rb", - "lib/travis/api/v3/renderer/cron.rb", - "lib/travis/api/v3/renderer/crons.rb", "lib/travis/api/v3/renderer/error.rb", - "lib/travis/api/v3/renderer/job.rb", - "lib/travis/api/v3/renderer/jobs.rb", "lib/travis/api/v3/renderer/model_renderer.rb", "lib/travis/api/v3/renderer/organization.rb", "lib/travis/api/v3/renderer/organizations.rb", "lib/travis/api/v3/renderer/owner.rb", "lib/travis/api/v3/renderer/repositories.rb", "lib/travis/api/v3/renderer/repository.rb", - "lib/travis/api/v3/renderer/request.rb", "lib/travis/api/v3/renderer/requests.rb", "lib/travis/api/v3/renderer/user.rb", "lib/travis/api/v3/result.rb", @@ -292,38 +245,19 @@ Gem::Specification.new do |s| "lib/travis/api/v3/services.rb", "lib/travis/api/v3/services/accounts/for_current_user.rb", "lib/travis/api/v3/services/branch/find.rb", - "lib/travis/api/v3/services/branches/find.rb", - "lib/travis/api/v3/services/broadcasts/for_current_user.rb", - "lib/travis/api/v3/services/build/cancel.rb", "lib/travis/api/v3/services/build/find.rb", - "lib/travis/api/v3/services/build/restart.rb", - "lib/travis/api/v3/services/builds/find.rb", - "lib/travis/api/v3/services/cron/create.rb", - "lib/travis/api/v3/services/cron/delete.rb", - "lib/travis/api/v3/services/cron/find.rb", - "lib/travis/api/v3/services/cron/for_branch.rb", - "lib/travis/api/v3/services/crons/for_repository.rb", - "lib/travis/api/v3/services/crons/start.rb", - "lib/travis/api/v3/services/job/cancel.rb", - "lib/travis/api/v3/services/job/find.rb", - "lib/travis/api/v3/services/job/restart.rb", - "lib/travis/api/v3/services/jobs/find.rb", "lib/travis/api/v3/services/organization/find.rb", "lib/travis/api/v3/services/organization/sync.rb", "lib/travis/api/v3/services/organizations/for_current_user.rb", "lib/travis/api/v3/services/owner/find.rb", "lib/travis/api/v3/services/repositories/for_current_user.rb", - "lib/travis/api/v3/services/repositories/for_owner.rb", "lib/travis/api/v3/services/repository/disable.rb", "lib/travis/api/v3/services/repository/enable.rb", "lib/travis/api/v3/services/repository/find.rb", - "lib/travis/api/v3/services/repository/star.rb", - "lib/travis/api/v3/services/repository/unstar.rb", "lib/travis/api/v3/services/requests/create.rb", "lib/travis/api/v3/services/requests/find.rb", "lib/travis/api/v3/services/user/current.rb", "lib/travis/api/v3/services/user/find.rb", - "lib/travis/api/v3/services/user/sync.rb", "lib/travis/api/workers/build_cancellation.rb", "lib/travis/api/workers/build_restart.rb", "lib/travis/api/workers/job_cancellation.rb", @@ -346,8 +280,6 @@ Gem::Specification.new do |s| "script/console", "script/repos_stats.rb", "script/server", - "script/web_concurrency", - "spec/active_record_postgres_variables_spec.rb", "spec/integration/error_handling_spec.rb", "spec/integration/formats_handling_spec.rb", "spec/integration/responders_spec.rb", @@ -412,7 +344,7 @@ Gem::Specification.new do |s| "spec/unit/endpoint/lint_spec.rb", "spec/unit/endpoint/logs_spec.rb", "spec/unit/endpoint/repos_spec.rb", - "spec/unit/endpoint/requests/throttle_spec.rb", + "spec/unit/endpoint/requests_spec.rb", "spec/unit/endpoint/users_spec.rb", "spec/unit/endpoint_spec.rb", "spec/unit/extensions/expose_pattern_spec.rb", @@ -427,41 +359,19 @@ Gem::Specification.new do |s| "spec/unit/responders/json_spec.rb", "spec/unit/responders/service_spec.rb", "spec/v3/extensions/belongs_to_spec.rb", - "spec/v3/models/cron_spec.rb", "spec/v3/renderer/avatar_url_spec.rb", "spec/v3/result_spec.rb", "spec/v3/service_index_spec.rb", "spec/v3/services/accounts/for_current_user_spec.rb", "spec/v3/services/branch/find_spec.rb", - "spec/v3/services/branches/find_spec.rb", - "spec/v3/services/broadcasts/for_current_user_spec.rb", - "spec/v3/services/build/cancel_spec.rb", - "spec/v3/services/build/find_spec.rb", - "spec/v3/services/build/restart_spec.rb", - "spec/v3/services/builds/find_spec.rb", - "spec/v3/services/cron/create_spec.rb", - "spec/v3/services/cron/delete_spec.rb", - "spec/v3/services/cron/find_spec.rb", - "spec/v3/services/cron/for_branch_spec.rb", - "spec/v3/services/crons/for_repository_spec.rb", - "spec/v3/services/job/cancel_spec.rb", - "spec/v3/services/job/find_spec.rb", - "spec/v3/services/job/restart_spec.rb", - "spec/v3/services/jobs/find_spec.rb", "spec/v3/services/organization/find_spec.rb", "spec/v3/services/organizations/for_current_user_spec.rb", "spec/v3/services/owner/find_spec.rb", "spec/v3/services/repositories/for_current_user_spec.rb", - "spec/v3/services/repositories/for_owner_spec.rb", - "spec/v3/services/repository/disable_spec.rb", - "spec/v3/services/repository/enable_spec.rb", "spec/v3/services/repository/find_spec.rb", - "spec/v3/services/repository/star_spec.rb", - "spec/v3/services/repository/unstar_spec.rb", "spec/v3/services/requests/create_spec.rb", "spec/v3/services/user/current_spec.rb", "spec/v3/services/user/find_spec.rb", - "spec/v3/services/user/sync_spec.rb", "tmp/.gitkeep", "travis-api.gemspec" ] From 5663410c4591c37af25e1eecc10bc8580f2e5051 Mon Sep 17 00:00:00 2001 From: Jonas Chromik Date: Mon, 14 Mar 2016 12:50:39 +0100 Subject: [PATCH 46/54] minor changes --- lib/travis/api/v3/services/cron/create.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index e676c158..494f263e 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -6,8 +6,8 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise InsufficientAccess unless Travis::Features.feature_active?(:cron) - raise NotFound unless repository = find(:repository) - raise NotFound unless branch = find(:branch, repository) + raise NotFound unless repository = find(:repository) + raise NotFound unless branch = find(:branch, repository) raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) access_control.permissions(repository).create_cron! From 721515140346327b703626b12105185faaa9061c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 21 Mar 2016 10:37:06 +0100 Subject: [PATCH 47/54] adjust new test to include cron permission --- spec/v3/services/repositories/for_owner_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/v3/services/repositories/for_owner_spec.rb b/spec/v3/services/repositories/for_owner_spec.rb index f8300493..953f57e1 100644 --- a/spec/v3/services/repositories/for_owner_spec.rb +++ b/spec/v3/services/repositories/for_owner_spec.rb @@ -122,7 +122,8 @@ describe Travis::API::V3::Services::Repositories::ForOwner do "disable" => false, "star" => false, "unstar" => false, - "create_request"=> false }, + "create_request"=> false, + "create_cron" => false }, "id" => 1, "name" => "minimal", "slug" => "svenfuchs/minimal", @@ -150,7 +151,8 @@ describe Travis::API::V3::Services::Repositories::ForOwner do "disable" => false, "star" => false, "unstar" => false, - "create_request"=> false }, + "create_request"=> false, + "create_cron" => false }, "id" => repo2.id, "name" => "maximal", "slug" => "svenfuchs/maximal", From 462a3618e1d6bae5316fd28426c19df98a012ea4 Mon Sep 17 00:00:00 2001 From: Jonas Chromik Date: Mon, 21 Mar 2016 17:21:57 +0100 Subject: [PATCH 48/54] update Gemfile.lock to use new migrations --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f395c830..0886b992 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,7 +74,7 @@ GIT GIT remote: git://github.com/travis-ci/travis-migrations.git - revision: fcf6eea3e3122a7cbb857826db835de69974c54d + revision: 3f6bb84800b0222ceba95a4b1368969eb5ede8e0 specs: travis-migrations (0.0.1) From c037ec7aa3e46bd52be91b36ca9caac998625e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Tue, 22 Mar 2016 10:17:23 +0100 Subject: [PATCH 49/54] refactor planned time calculation into separate methods --- lib/travis/api/v3/models/cron.rb | 61 +++++++++++++++++--------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 7441e80c..2b768458 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -4,47 +4,50 @@ module Travis::API::V3 belongs_to :branch def next_enqueuing - - if (disable_by_build) && (last_non_cron_build_date > plannedTime(-1)) - return plannedTime(1) - elsif last_cron_build_date >= plannedTime(-1) - return plannedTime(0) + if (disable_by_build) && (last_non_cron_build_date > planned_time(-1)) + return planned_time(1) + elsif last_cron_build_date >= planned_time(-1) + return planned_time(0) else return Time.now end end - def plannedTime(in_builds = 0) # 0 equals next build, 1 after next build, -1 last build, ... - now = DateTime.now - created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) + def planned_time(in_builds = 0) # 0 equals next build, 1 after next build, -1 last build, ... case interval when 'daily' - build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) - if now > build_today - return build_today + 1 + in_builds - else - return build_today + in_builds - end + return planned_time_daily(in_builds) when 'weekly' - build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) - in_days = (created_at.wday - now.wday) % 7 - next_time = build_today + in_days - if now > next_time - return build_today + 7 * (1 + in_builds) - else - return next_time + 7 * in_builds - end + return planned_time_weekly(in_builds) when 'monthly' - month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) - this_month = created >> month_since_creation - if now > this_month - return created >> (month_since_creation + 1 + in_builds) - else - return created >> (month_since_creation + in_builds) - end + return planned_time_monthly(in_builds) end end + def planned_time_daily(in_builds = 0) + now = DateTime.now + build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) + return build_today + 1 + in_builds if (now > build_today) + return build_today + in_builds + end + + def planned_time_weekly(in_builds = 0) + now = DateTime.now + build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) + next_time = build_today + ((created_at.wday - now.wday) % 7) + return build_today + 7 * (1 + in_builds) if (now > next_time) + return next_time + 7 * in_builds + end + + def planned_time_monthly(in_builds = 0) + now = DateTime.now + created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) + month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) + this_month = created >> month_since_creation + return created >> (month_since_creation + 1 + in_builds) if (now > this_month) + return created >> (month_since_creation + in_builds) + end + def last_cron_build_date last_cron_build = Models::Build.where(:repository_id => branch.repository.id, :branch => branch.name, :event_type => 'cron').order("id DESC").first return last_cron_build.created_at unless last_cron_build.nil? From ca82725e5ef417b22ce7f3736b5dbd17f5924578 Mon Sep 17 00:00:00 2001 From: Jonas Chromik Date: Tue, 22 Mar 2016 13:48:51 +0100 Subject: [PATCH 50/54] move cron jobs feature flag to permissions --- lib/travis/api/v3/access_control/generic.rb | 4 +-- lib/travis/api/v3/permissions/cron.rb | 6 +++- lib/travis/api/v3/permissions/repository.rb | 2 +- lib/travis/api/v3/queries/crons.rb | 6 ++-- lib/travis/api/v3/services/cron/create.rb | 1 - lib/travis/api/v3/services/cron/delete.rb | 1 - lib/travis/api/v3/services/cron/find.rb | 1 - lib/travis/api/v3/services/cron/for_branch.rb | 1 - .../api/v3/services/crons/for_repository.rb | 5 ++-- lib/travis/api/v3/services/crons/start.rb | 1 - spec/v3/services/cron/create_spec.rb | 28 +++++++++++++------ spec/v3/services/cron/delete_spec.rb | 21 ++++++++------ spec/v3/services/cron/find_spec.rb | 23 ++++++++------- spec/v3/services/cron/for_branch_spec.rb | 18 ++++++------ spec/v3/services/crons/for_repository_spec.rb | 17 +++++------ .../repositories/for_current_user_spec.rb | 2 +- spec/v3/services/repository/find_spec.rb | 8 +++--- 17 files changed, 83 insertions(+), 62 deletions(-) diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb index c232f879..0344b35b 100644 --- a/lib/travis/api/v3/access_control/generic.rb +++ b/lib/travis/api/v3/access_control/generic.rb @@ -60,11 +60,11 @@ module Travis::API::V3 end def cron_visible?(cron) - visible? cron.branch.repository + Travis::Features.owner_active?(:cron, cron.branch.repository.owner) and visible? cron.branch.repository end def cron_writable?(cron) - writable? cron.branch.repository + Travis::Features.owner_active?(:cron, cron.branch.repository.owner) and writable? cron.branch.repository end def job_visible?(job) diff --git a/lib/travis/api/v3/permissions/cron.rb b/lib/travis/api/v3/permissions/cron.rb index 815dd17c..c94b5a70 100644 --- a/lib/travis/api/v3/permissions/cron.rb +++ b/lib/travis/api/v3/permissions/cron.rb @@ -3,7 +3,11 @@ require 'travis/api/v3/permissions/generic' module Travis::API::V3 class Permissions::Cron < Permissions::Generic def delete? - write? + write? and Travis::Features.owner_active?(:cron, object.branch.repository.owner) + end + + def start? + Travis::Features.owner_active?(:cron, object.branch.repository.owner) end end end diff --git a/lib/travis/api/v3/permissions/repository.rb b/lib/travis/api/v3/permissions/repository.rb index dcdddbfa..81fb91a1 100644 --- a/lib/travis/api/v3/permissions/repository.rb +++ b/lib/travis/api/v3/permissions/repository.rb @@ -23,7 +23,7 @@ module Travis::API::V3 end def create_cron? - write? + Travis::Features.owner_active?(:cron, object.owner) and write? end end end diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index c69ec907..9a9249fc 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -10,7 +10,7 @@ module Travis::API::V3 Models::Cron.all.each do |cron| if cron.next_enqueuing <= Time.now - start(cron.branch) + start(cron) started.push cron end end @@ -18,8 +18,10 @@ module Travis::API::V3 started end - def start(branch) + def start(cron) + branch = cron.branch raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id + access_control.permissions(cron).start! user_id = branch.repository.users.detect { |u| u.github_oauth_token }.id diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index 494f263e..cc8fc819 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -5,7 +5,6 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) diff --git a/lib/travis/api/v3/services/cron/delete.rb b/lib/travis/api/v3/services/cron/delete.rb index 256f97c7..c5d9287d 100644 --- a/lib/travis/api/v3/services/cron/delete.rb +++ b/lib/travis/api/v3/services/cron/delete.rb @@ -4,7 +4,6 @@ module Travis::API::V3 def run! raise LoginRequired unless access_control.logged_in? or access_control.full_access? - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) cron = find access_control.permissions(cron).delete! cron.destroy diff --git a/lib/travis/api/v3/services/cron/find.rb b/lib/travis/api/v3/services/cron/find.rb index 33a337d6..6a191d7a 100644 --- a/lib/travis/api/v3/services/cron/find.rb +++ b/lib/travis/api/v3/services/cron/find.rb @@ -3,7 +3,6 @@ module Travis::API::V3 #params :id def run! - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) find end end diff --git a/lib/travis/api/v3/services/cron/for_branch.rb b/lib/travis/api/v3/services/cron/for_branch.rb index d2396e9b..0290e112 100644 --- a/lib/travis/api/v3/services/cron/for_branch.rb +++ b/lib/travis/api/v3/services/cron/for_branch.rb @@ -2,7 +2,6 @@ module Travis::API::V3 class Services::Cron::ForBranch < Service def run! - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) query.find_for_branch(find(:branch, find(:repository))) end end diff --git a/lib/travis/api/v3/services/crons/for_repository.rb b/lib/travis/api/v3/services/crons/for_repository.rb index 2b746fc1..97fd4a81 100644 --- a/lib/travis/api/v3/services/crons/for_repository.rb +++ b/lib/travis/api/v3/services/crons/for_repository.rb @@ -3,8 +3,9 @@ module Travis::API::V3 paginate def run! - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) - query.find(find(:repository)) + repo = find(:repository) + raise InsufficientAccess unless Travis::Features.owner_active?(:cron, repo.owner) + query.find(repo) end end end diff --git a/lib/travis/api/v3/services/crons/start.rb b/lib/travis/api/v3/services/crons/start.rb index 0bfa3a16..104d43f5 100644 --- a/lib/travis/api/v3/services/crons/start.rb +++ b/lib/travis/api/v3/services/crons/start.rb @@ -2,7 +2,6 @@ module Travis::API::V3 class Services::Crons::Start < Service def run! - raise InsufficientAccess unless Travis::Features.feature_active?(:cron) query.start_all() end diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index f007f106..467f6bf1 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -12,17 +12,26 @@ describe Travis::API::V3::Services::Cron::Create do let(:parsed_body) { JSON.load(body) } before do - Travis::Features.enable_for_all(:cron) + Travis::Features.activate_owner(:cron, repo.owner) end - describe "no Feature enabled" do - before { Travis::Features.disable_for_all(:cron) } + describe "creating a cron job with feature flag disabled" do + before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options, headers)} - example { expect(parsed_body).to be == { - "@type"=> "error", - "error_type"=> "insufficient_access", - "error_message"=> "forbidden" - }} + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "insufficient_access", + "error_message" => "operation requires create_cron access to repository", + "resource_type" => "repository", + "permission" => "create_cron", + "repository" => { + "@type" => "repository", + "@href" => "/repo/#{repo.id}", # should be /v3/repo/#{repo.id} + "@representation" => "minimal", + "id" => repo.id, + "name" => "minimal", + "slug" => "svenfuchs/minimal" } + }} end describe "creating a cron job" do @@ -37,7 +46,8 @@ describe Travis::API::V3::Services::Cron::Create do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => true }, + "delete" => true, + "start" => true }, "id" => current_cron.id, "repository" => { "@type" => "repository", diff --git a/spec/v3/services/cron/delete_spec.rb b/spec/v3/services/cron/delete_spec.rb index ee920566..601d7bb9 100644 --- a/spec/v3/services/cron/delete_spec.rb +++ b/spec/v3/services/cron/delete_spec.rb @@ -9,17 +9,19 @@ describe Travis::API::V3::Services::Cron::Delete do let(:parsed_body) { JSON.load(body) } before do - Travis::Features.enable_for_all(:cron) + Travis::Features.activate_owner(:cron, repo.owner) end - describe "no Feature enabled" do - before { Travis::Features.disable_for_all(:cron) } + describe "deleting cron jobs with feature disabled" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { delete("/v3/cron/#{cron.id}", {}, headers)} - example { expect(parsed_body).to be == { - "@type"=> "error", - "error_type"=> "insufficient_access", - "error_message"=> "forbidden" - }} + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} end describe "deleting a cron job by id" do @@ -33,7 +35,8 @@ describe Travis::API::V3::Services::Cron::Delete do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => true }, + "delete" => true, + "start" => true }, "id" => cron.id, "repository" => { "@type" => "repository", diff --git a/spec/v3/services/cron/find_spec.rb b/spec/v3/services/cron/find_spec.rb index 4f165e2b..8ae7f2c6 100644 --- a/spec/v3/services/cron/find_spec.rb +++ b/spec/v3/services/cron/find_spec.rb @@ -7,17 +7,18 @@ describe Travis::API::V3::Services::Cron::Find do let(:parsed_body) { JSON.load(body) } before do - Travis::Features.enable_for_all(:cron) + Travis::Features.activate_owner(:cron, repo.owner) end - describe "no Feature enabled" do - before { Travis::Features.disable_for_all(:cron) } + describe "find cron job with feature disabled" do + before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { get("/v3/cron/#{cron.id}") } - example { expect(parsed_body).to be == { - "@type"=> "error", - "error_type"=> "insufficient_access", - "error_message"=> "forbidden" - }} + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} end describe "fetching a cron job by id" do @@ -29,7 +30,8 @@ describe Travis::API::V3::Services::Cron::Find do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => false }, + "delete" => false, + "start" => true }, "id" => cron.id, "repository" => { "@type" => "repository", @@ -87,7 +89,8 @@ describe Travis::API::V3::Services::Cron::Find do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => false }, + "delete" => false, + "start" => true }, "id" => cron.id, "repository" => { "@type" => "repository", diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb index ad445b5a..b698ebe1 100644 --- a/spec/v3/services/cron/for_branch_spec.rb +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -7,17 +7,18 @@ describe Travis::API::V3::Services::Cron::ForBranch do let(:parsed_body) { JSON.load(body) } before do - Travis::Features.enable_for_all(:cron) + Travis::Features.activate_owner(:cron, repo.owner) end - describe "no Feature enabled" do - before { Travis::Features.disable_for_all(:cron) } + describe "find cron job for branch with feature disabled" do + before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } example { expect(parsed_body).to be == { - "@type"=> "error", - "error_type"=> "insufficient_access", - "error_message"=> "forbidden" - }} + "@type" => "error", + "error_type" => "not_found", + "error_message" => "cron not found (or insufficient access)", + "resource_type" => "cron" + }} end describe "fetching all crons by repo id" do @@ -30,7 +31,8 @@ describe Travis::API::V3::Services::Cron::ForBranch do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => false }, + "delete" => false, + "start" => true }, "id" => cron.id, "repository" => { "@type" => "repository", diff --git a/spec/v3/services/crons/for_repository_spec.rb b/spec/v3/services/crons/for_repository_spec.rb index 2d005f24..05e37102 100644 --- a/spec/v3/services/crons/for_repository_spec.rb +++ b/spec/v3/services/crons/for_repository_spec.rb @@ -7,17 +7,17 @@ describe Travis::API::V3::Services::Crons::ForRepository do let(:parsed_body) { JSON.load(body) } before do - Travis::Features.enable_for_all(:cron) + Travis::Features.activate_owner(:cron, repo.owner) end - describe "no Feature enabled" do - before { Travis::Features.disable_for_all(:cron) } + describe "fetching all crons by repo id with feature disabled" do + before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { get("/v3/repo/#{repo.id}/crons") } example { expect(parsed_body).to be == { - "@type"=> "error", - "error_type"=> "insufficient_access", - "error_message"=> "forbidden" - }} + "@type" => "error", + "error_type" => "insufficient_access", + "error_message" => "forbidden" + }} end describe "fetching all crons by repo id" do @@ -51,7 +51,8 @@ describe Travis::API::V3::Services::Crons::ForRepository do "@representation" => "standard", "@permissions" => { "read" => true, - "delete" => false }, + "delete" => false, + "start" => true }, "id" => cron.id, "repository" => { "@type" => "repository", diff --git a/spec/v3/services/repositories/for_current_user_spec.rb b/spec/v3/services/repositories/for_current_user_spec.rb index b27d7ea9..d414783a 100644 --- a/spec/v3/services/repositories/for_current_user_spec.rb +++ b/spec/v3/services/repositories/for_current_user_spec.rb @@ -45,7 +45,7 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser do "star" => true, "unstar" => true, "create_request" => true, - "create_cron" => true}, + "create_cron" => false}, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", diff --git a/spec/v3/services/repository/find_spec.rb b/spec/v3/services/repository/find_spec.rb index 55c88ed0..b3c03556 100644 --- a/spec/v3/services/repository/find_spec.rb +++ b/spec/v3/services/repository/find_spec.rb @@ -152,7 +152,7 @@ describe Travis::API::V3::Services::Repository::Find do }} end - describe "private repository, authenticated as internal application with full access" do + describe "private repository without cron feature, authenticated as internal application with full access" do let(:app_name) { 'travis-example' } let(:app_secret) { '12345678' } let(:sign_opts) { "a=#{app_name}" } @@ -178,7 +178,7 @@ describe Travis::API::V3::Services::Repository::Find do "star" => true, "unstar" => true, "create_request" => true, - "create_cron" => true}, + "create_cron" => false}, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", @@ -221,7 +221,7 @@ describe Travis::API::V3::Services::Repository::Find do }} end - describe "private repository, authenticated as internal application with full access, scoped to the right org" do + describe "private repository without cron feature, authenticated as internal application with full access, scoped to the right org" do let(:app_name) { 'travis-example' } let(:app_secret) { '12345678' } let(:sign_opts) { "a=#{app_name}:s=#{repo.owner_name}" } @@ -247,7 +247,7 @@ describe Travis::API::V3::Services::Repository::Find do "star" => true, "unstar" => true, "create_request" => true, - "create_cron" => true}, + "create_cron" => false}, "id" => repo.id, "name" => "minimal", "slug" => "svenfuchs/minimal", From 9734e7133f3c9e17325e21e5679963741f965089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Tue, 29 Mar 2016 16:51:00 +0200 Subject: [PATCH 51/54] fix feature flag for_branch endpoint --- lib/travis/api/v3/services/cron/for_branch.rb | 4 +++- spec/v3/services/cron/for_branch_spec.rb | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/services/cron/for_branch.rb b/lib/travis/api/v3/services/cron/for_branch.rb index 0290e112..cdbc24db 100644 --- a/lib/travis/api/v3/services/cron/for_branch.rb +++ b/lib/travis/api/v3/services/cron/for_branch.rb @@ -2,7 +2,9 @@ module Travis::API::V3 class Services::Cron::ForBranch < Service def run! - query.find_for_branch(find(:branch, find(:repository))) + repo = find(:repository) + raise InsufficientAccess unless Travis::Features.owner_active?(:cron, repo.owner) + query.find_for_branch(find(:branch, repo)) end end end diff --git a/spec/v3/services/cron/for_branch_spec.rb b/spec/v3/services/cron/for_branch_spec.rb index b698ebe1..32b0f76b 100644 --- a/spec/v3/services/cron/for_branch_spec.rb +++ b/spec/v3/services/cron/for_branch_spec.rb @@ -11,13 +11,13 @@ describe Travis::API::V3::Services::Cron::ForBranch do end describe "find cron job for branch with feature disabled" do + before { cron } before { Travis::Features.deactivate_owner(:cron, repo.owner) } before { get("/v3/repo/#{repo.id}/branch/#{branch.name}/cron") } example { expect(parsed_body).to be == { "@type" => "error", - "error_type" => "not_found", - "error_message" => "cron not found (or insufficient access)", - "resource_type" => "cron" + "error_type" => "insufficient_access", + "error_message" => "forbidden" }} end From 31f6b5793a147d85de3c704ceb31c439c9b3681a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Mon, 4 Apr 2016 10:27:06 +0200 Subject: [PATCH 52/54] refactor cron model and create service --- lib/travis/api/v3/models/cron.rb | 51 ++++++++++++++--------- lib/travis/api/v3/services/cron/create.rb | 7 +--- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/lib/travis/api/v3/models/cron.rb b/lib/travis/api/v3/models/cron.rb index 2b768458..68f664f2 100644 --- a/lib/travis/api/v3/models/cron.rb +++ b/lib/travis/api/v3/models/cron.rb @@ -3,61 +3,72 @@ module Travis::API::V3 belongs_to :branch + LastBuild = -1 + ThisBuild = 0 + NextBuild = 1 + def next_enqueuing - if (disable_by_build) && (last_non_cron_build_date > planned_time(-1)) - return planned_time(1) - elsif last_cron_build_date >= planned_time(-1) - return planned_time(0) + if disable_by_build && last_non_cron_build_date > planned_time(LastBuild) + planned_time(NextBuild) + elsif last_cron_build_date >= planned_time(LastBuild) + planned_time(ThisBuild) else - return Time.now + Time.now end end - def planned_time(in_builds = 0) # 0 equals next build, 1 after next build, -1 last build, ... + def planned_time(in_builds = ThisBuild) case interval when 'daily' - return planned_time_daily(in_builds) + planned_time_daily(in_builds) when 'weekly' - return planned_time_weekly(in_builds) + planned_time_weekly(in_builds) when 'monthly' - return planned_time_monthly(in_builds) + planned_time_monthly(in_builds) end end - def planned_time_daily(in_builds = 0) + def planned_time_daily(in_builds) now = DateTime.now build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) return build_today + 1 + in_builds if (now > build_today) - return build_today + in_builds + build_today + in_builds end - def planned_time_weekly(in_builds = 0) + def planned_time_weekly(in_builds) now = DateTime.now build_today = DateTime.new(now.year, now.month, now.day, created_at.hour) next_time = build_today + ((created_at.wday - now.wday) % 7) return build_today + 7 * (1 + in_builds) if (now > next_time) - return next_time + 7 * in_builds + next_time + 7 * in_builds end - def planned_time_monthly(in_builds = 0) + def planned_time_monthly(in_builds) now = DateTime.now created = DateTime.new(created_at.year, created_at.month, created_at.day, created_at.hour) - month_since_creation = (now.year*12+now.month) - (created_at.year*12+created_at.month) + month_since_creation = (now.year * 12 + now.month) - (created_at.year * 12 + created_at.month) this_month = created >> month_since_creation return created >> (month_since_creation + 1 + in_builds) if (now > this_month) - return created >> (month_since_creation + in_builds) + created >> (month_since_creation + in_builds) end def last_cron_build_date - last_cron_build = Models::Build.where(:repository_id => branch.repository.id, :branch => branch.name, :event_type => 'cron').order("id DESC").first + last_cron_build = Models::Build.where( + :repository_id => branch.repository.id, + :branch => branch.name, + :event_type => 'cron' + ).order("id DESC").first return last_cron_build.created_at unless last_cron_build.nil? - return Time.at(0) + Time.at(0) end def last_non_cron_build_date - last_build = Models::Build.where(:repository_id => branch.repository.id, :branch => branch.name).where(['event_type NOT IN (?)', ['cron']]).order("id DESC").first + last_build = Models::Build.where( + :repository_id => branch.repository.id, + :branch => branch.name + ).where(['event_type NOT IN (?)', ['cron']]).order("id DESC").first return last_build.created_at unless last_build.nil? - return Time.at(0) + Time.at(0) end end diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index cc8fc819..3f3c24ec 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -9,13 +9,8 @@ module Travis::API::V3 raise NotFound unless branch = find(:branch, repository) raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) access_control.permissions(repository).create_cron! - - if branch.cron - access_control.permissions(branch.cron).delete! - end - + access_control.permissions(branch.cron).delete! if branch.cron query.create(branch, params["interval"], params["disable_by_build"] ? params["disable_by_build"] : false) - end end From 0b2585de45d7ac4e785c895ca9de479ba6894269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Tue, 12 Apr 2016 11:33:30 +0200 Subject: [PATCH 53/54] remove cronjobs and disallow creating if branch does no longer exist on GitHub --- lib/travis/api/v3/queries/crons.rb | 15 ++++++++----- lib/travis/api/v3/services/cron/create.rb | 1 + spec/v3/queries/cron_spec.rb | 27 +++++++++++++++++++++++ spec/v3/services/cron/create_spec.rb | 11 +++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 spec/v3/queries/cron_spec.rb diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index 9a9249fc..e702ca1f 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -6,22 +6,25 @@ module Travis::API::V3 end def start_all() - started = [] + started_crons = [] Models::Cron.all.each do |cron| if cron.next_enqueuing <= Time.now - start(cron) - started.push cron + started = start(cron) + started_crons.push cron if started end end - started + started_crons end def start(cron) branch = cron.branch raise ServerError, 'repository does not have a github_id'.freeze unless branch.repository.github_id - access_control.permissions(cron).start! + unless branch.exists_on_github + cron.destroy + return false + end user_id = branch.repository.users.detect { |u| u.github_oauth_token }.id @@ -33,7 +36,7 @@ module Travis::API::V3 class_name, queue = Query.sidekiq_queue(:build_request) ::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => [{type: 'cron'.freeze, payload: JSON.dump(payload), credentials: {}}]) - payload + true end end end diff --git a/lib/travis/api/v3/services/cron/create.rb b/lib/travis/api/v3/services/cron/create.rb index 3f3c24ec..dcbfffb8 100644 --- a/lib/travis/api/v3/services/cron/create.rb +++ b/lib/travis/api/v3/services/cron/create.rb @@ -7,6 +7,7 @@ module Travis::API::V3 raise LoginRequired unless access_control.logged_in? or access_control.full_access? raise NotFound unless repository = find(:repository) raise NotFound unless branch = find(:branch, repository) + raise Error.new('Crons can only be set up for branches existing on GitHub!', status: 422) unless branch.exists_on_github raise Error.new('Invalid value for interval. Interval must be "daily", "weekly" or "monthly"!', status: 422) unless ["daily", "weekly", "monthly"].include?(params["interval"]) access_control.permissions(repository).create_cron! access_control.permissions(branch.cron).delete! if branch.cron diff --git a/spec/v3/queries/cron_spec.rb b/spec/v3/queries/cron_spec.rb new file mode 100644 index 00000000..bb4c559a --- /dev/null +++ b/spec/v3/queries/cron_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe Travis::API::V3::Queries::Crons do + let(:user) { Travis::API::V3::Models::User.find_by_login('svenfuchs') } + let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } + let(:existing_branch) { Travis::API::V3::Models::Branch.create(repository: repo, name: 'cron-test-existing', exists_on_github: true) } + let(:non_existing_branch) { Travis::API::V3::Models::Branch.create(repository: repo, name: 'cron-test-non-existing', exists_on_github: false) } + let(:query) { Travis::API::V3::Queries::Crons.new({}, 'Overview') +} + + describe "start all" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + + it "starts crons on existing branches" do + cron = Travis::API::V3::Models::Cron.create(branch_id: existing_branch.id, interval: 'daily', disable_by_build: false) + expect(query.start_all).to include(cron) + + end + + it "delete crons on branches not existing on GitHub" do + cron = Travis::API::V3::Models::Cron.create(branch_id: non_existing_branch.id, interval: 'daily', disable_by_build: false) + expect(query.start_all).to_not include(cron) + expect(Travis::API::V3::Models::Cron.where(id: cron.id).length).to equal(0) + end + end + +end diff --git a/spec/v3/services/cron/create_spec.rb b/spec/v3/services/cron/create_spec.rb index 467f6bf1..dc578e80 100644 --- a/spec/v3/services/cron/create_spec.rb +++ b/spec/v3/services/cron/create_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe Travis::API::V3::Services::Cron::Create do let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:branch) { Travis::API::V3::Models::Branch.where(repository_id: repo).first } + let(:non_existing_branch) { Travis::API::V3::Models::Branch.create(repository: repo, name: 'cron-test', exists_on_github: false) } let(:last_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:current_cron) {Travis::API::V3::Models::Cron.where(branch_id: branch.id).last} let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } @@ -87,6 +88,16 @@ describe Travis::API::V3::Services::Cron::Create do }} end + describe "creating a cron job on a branch not existing on GitHub" do + before { Travis::API::V3::Models::Permission.create(repository: repo, user: repo.owner, push: true) } + before { post("/v3/repo/#{repo.id}/branch/#{non_existing_branch.name}/cron", options, headers) } + example { expect(parsed_body).to be == { + "@type" => "error", + "error_type" => "error", + "error_message" => "Crons can only be set up for branches existing on GitHub!" + }} + end + describe "try creating a cron job without login" do before { post("/v3/repo/#{repo.id}/branch/#{branch.name}/cron", options) } example { expect(parsed_body).to be == { From 7e7f1b212b896539cd34a315fe3eb18414d1efda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ko=CC=88tte?= Date: Thu, 14 Apr 2016 12:53:23 +0200 Subject: [PATCH 54/54] refactor cron start --- lib/travis/api/v3/queries/crons.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/travis/api/v3/queries/crons.rb b/lib/travis/api/v3/queries/crons.rb index e702ca1f..aec65134 100644 --- a/lib/travis/api/v3/queries/crons.rb +++ b/lib/travis/api/v3/queries/crons.rb @@ -6,16 +6,9 @@ module Travis::API::V3 end def start_all() - started_crons = [] - - Models::Cron.all.each do |cron| - if cron.next_enqueuing <= Time.now - started = start(cron) - started_crons.push cron if started - end + Models::Cron.all.select do |cron| + start(cron) if cron.next_enqueuing <= Time.now end - - started_crons end def start(cron)