diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/lib/graphql.js | 4 | ||||
-rw-r--r-- | app/controllers/projects/forks_controller.rb | 2 | ||||
-rw-r--r-- | app/finders/fork_targets_finder.rb | 2 | ||||
-rw-r--r-- | app/models/ci/bridge.rb | 4 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 7 | ||||
-rw-r--r-- | app/models/snippet.rb | 8 | ||||
-rw-r--r-- | app/services/ci/create_cross_project_pipeline_service.rb | 30 |
7 files changed, 46 insertions, 11 deletions
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index b49fe9362c2..8d3b87d5cc0 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -26,6 +26,10 @@ export default (resolvers = {}, config = {}) => { headers: { [csrf.headerKey]: csrf.token, }, + // fetch won’t send cookies in older browsers, unless you set the credentials init option. + // We set to `same-origin` which is default value in modern browsers. + // See https://github.com/whatwg/fetch/pull/585 for more information. + credentials: 'same-origin', }; return new ApolloClient({ diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index e0e8fb177ba..248b75d16ed 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -39,7 +39,7 @@ class Projects::ForksController < Projects::ApplicationController # rubocop: enable CodeReuse/ActiveRecord def new - @namespaces = fork_service.valid_fork_targets + @namespaces = fork_service.valid_fork_targets - [project.namespace] end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/finders/fork_targets_finder.rb b/app/finders/fork_targets_finder.rb index 9003c593757..7a08273fa0d 100644 --- a/app/finders/fork_targets_finder.rb +++ b/app/finders/fork_targets_finder.rb @@ -8,7 +8,7 @@ class ForkTargetsFinder # rubocop: disable CodeReuse/ActiveRecord def execute - ::Namespace.where(id: user.manageable_namespaces).where.not(id: project.namespace).sort_by_type + ::Namespace.where(id: user.manageable_namespaces).sort_by_type end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb index 39be26abc1d..a28e44d44c1 100644 --- a/app/models/ci/bridge.rb +++ b/app/models/ci/bridge.rb @@ -62,6 +62,10 @@ module Ci end end + def has_downstream_pipeline? + sourced_pipelines.exists? + end + def downstream_pipeline_params return child_params if triggers_child_pipeline? return cross_project_params if downstream_project.present? diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index e07abc20dcf..ff257c6cd68 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -227,6 +227,7 @@ module Ci end after_transition created: :pending do |pipeline| + next if Feature.enabled?(:ci_drop_bridge_on_downstream_errors, pipeline.project, default_enabled: true) next unless pipeline.bridge_triggered? next if pipeline.bridge_waiting? @@ -756,6 +757,8 @@ module Ci raise BridgeStatusError unless source_bridge.active? source_bridge.success! + rescue => e + Gitlab::ErrorTracking.track_exception(e, pipeline_id: id) end def bridge_triggered? @@ -774,6 +777,10 @@ module Ci child_pipelines.exists? end + def created_successfully? + persisted? && failure_reason.blank? + end + def detailed_status(current_user) Gitlab::Ci::Status::Pipeline::Factory .new(self, current_user) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 233834dbaf9..a927235317c 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -188,14 +188,6 @@ class Snippet < ApplicationRecord end end - def self.content_types - [ - ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java", - ".haml", ".html", ".sass", ".scss", ".xml", ".php", ".erb", - ".js", ".sh", ".coffee", ".yml", ".md" - ] - end - def blob @blob ||= Blob.decorate(SnippetBlob.new(self), self) end diff --git a/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb index 22b8e37a7e8..99f232bc892 100644 --- a/app/services/ci/create_cross_project_pipeline_service.rb +++ b/app/services/ci/create_cross_project_pipeline_service.rb @@ -5,9 +5,19 @@ module Ci class CreateCrossProjectPipelineService < ::BaseService include Gitlab::Utils::StrongMemoize + DuplicateDownstreamPipelineError = Class.new(StandardError) + def execute(bridge) @bridge = bridge + if bridge.has_downstream_pipeline? + Gitlab::ErrorTracking.track_exception( + DuplicateDownstreamPipelineError.new, + bridge_id: @bridge.id, project_id: @bridge.project_id + ) + return + end + pipeline_params = @bridge.downstream_pipeline_params target_ref = pipeline_params.dig(:target_revision, :ref) @@ -18,14 +28,32 @@ module Ci current_user, pipeline_params.fetch(:target_revision)) - service.execute( + downstream_pipeline = service.execute( pipeline_params.fetch(:source), pipeline_params[:execute_params]) do |pipeline| pipeline.variables.build(@bridge.downstream_variables) end + + downstream_pipeline.tap do |pipeline| + next if Feature.disabled?(:ci_drop_bridge_on_downstream_errors, project, default_enabled: true) + + update_bridge_status!(@bridge, pipeline) + end end private + def update_bridge_status!(bridge, pipeline) + Gitlab::OptimisticLocking.retry_lock(bridge) do |subject| + if pipeline.created_successfully? + # If bridge uses `strategy:depend` we leave it running + # and update the status when the downstream pipeline completes. + subject.success! unless subject.dependent? + else + subject.drop!(:downstream_pipeline_creation_failed) + end + end + end + def ensure_preconditions!(target_ref) unless downstream_project_accessible? @bridge.drop!(:downstream_bridge_project_not_found) |