diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb index abd59741e89ddbb6670efe38593b86bd833e1aaa..3726c05acd8b89b81bc0b9ad42a64f564e1cfd96 100644 --- a/app/models/ci/bridge.rb +++ b/app/models/ci/bridge.rb @@ -25,6 +25,14 @@ class Bridge < Ci::Processable # rubocop:enable Cop/ActiveRecordSerialize state_machine :status do + after_transition created: :pending do |bridge| + next unless bridge.downstream_project + + bridge.run_after_commit do + bridge.schedule_downstream_pipeline! + end + end + event :manual do transition all => :manual end @@ -38,6 +46,12 @@ def self.retry(bridge, current_user) raise NotImplementedError end + def schedule_downstream_pipeline! + raise InvalidBridgeTypeError unless downstream_project + + ::Ci::CreateCrossProjectPipelineWorker.perform_async(self.id) + end + def inherit_status_from_downstream!(pipeline) case pipeline.status when 'success' diff --git a/app/models/commit_status_enums.rb b/app/models/commit_status_enums.rb index 2ca6d15e6426998d56a8bb5906222c33315fdff0..dcf23d112d6ece446f778f620558df4c6676f174 100644 --- a/app/models/commit_status_enums.rb +++ b/app/models/commit_status_enums.rb @@ -17,7 +17,12 @@ def self.failure_reasons archived_failure: 9, unmet_prerequisites: 10, scheduler_failure: 11, - data_integrity_failure: 12 + data_integrity_failure: 12, + insufficient_bridge_permissions: 1_001, + downstream_bridge_project_not_found: 1_002, + invalid_bridge_trigger: 1_003, + bridge_pipeline_is_child_pipeline: 1_006, + downstream_pipeline_creation_failed: 1_007 } end end diff --git a/app/presenters/commit_status_presenter.rb b/app/presenters/commit_status_presenter.rb index 66ae840a619ff9e1b78263984ce8f2d53a610fda..ed76f95ac62024576325ffd1d8cfd015ee3f15b8 100644 --- a/app/presenters/commit_status_presenter.rb +++ b/app/presenters/commit_status_presenter.rb @@ -13,7 +13,12 @@ class CommitStatusPresenter < Gitlab::View::Presenter::Delegated archived_failure: 'The job is archived and cannot be run', unmet_prerequisites: 'The job failed to complete prerequisite tasks', scheduler_failure: 'The scheduler failed to assign job to the runner, please try again or contact system administrator', - data_integrity_failure: 'There has been a structural integrity problem detected, please contact system administrator' + data_integrity_failure: 'There has been a structural integrity problem detected, please contact system administrator', + invalid_bridge_trigger: 'This job could not be executed because downstream pipeline trigger definition is invalid', + downstream_bridge_project_not_found: 'This job could not be executed because downstream bridge project could not be found', + insufficient_bridge_permissions: 'This job could not be executed because of insufficient permissions to create a downstream pipeline', + bridge_pipeline_is_child_pipeline: 'This job belongs to a child pipeline and cannot create further child pipelines', + downstream_pipeline_creation_failed: 'The downstream pipeline could not be created' }.freeze private_constant :CALLOUT_FAILURE_MESSAGES diff --git a/ee/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb similarity index 100% rename from ee/app/services/ci/create_cross_project_pipeline_service.rb rename to app/services/ci/create_cross_project_pipeline_service.rb diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 51b91e8e8be6ebb612fa0442a0adfabacd2d8e21..e836dd927702037cffb46c7f6330a449bba153d6 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -531,6 +531,12 @@ :latency_sensitive: :resource_boundary: :unknown :weight: 3 +- :name: pipeline_default:ci_create_cross_project_pipeline + :feature_category: :continuous_integration + :has_external_dependencies: + :latency_sensitive: + :resource_boundary: :cpu + :weight: 3 - :name: pipeline_default:ci_pipeline_bridge_status :feature_category: :continuous_integration :has_external_dependencies: diff --git a/ee/app/workers/ci/create_cross_project_pipeline_worker.rb b/app/workers/ci/create_cross_project_pipeline_worker.rb similarity index 100% rename from ee/app/workers/ci/create_cross_project_pipeline_worker.rb rename to app/workers/ci/create_cross_project_pipeline_worker.rb diff --git a/ee/app/models/ee/ci/bridge.rb b/ee/app/models/ee/ci/bridge.rb index f00a9c11fdfb9f4f31f27bc8f5dc20df4ed30895..7933272153607919afd165a95be355e9cdcef5da 100644 --- a/ee/app/models/ee/ci/bridge.rb +++ b/ee/app/models/ee/ci/bridge.rb @@ -9,14 +9,6 @@ module Bridge belongs_to :upstream_pipeline, class_name: "::Ci::Pipeline" state_machine :status do - after_transition created: :pending do |bridge| - next unless bridge.downstream_project - - bridge.run_after_commit do - bridge.schedule_downstream_pipeline! - end - end - after_transition any => :pending do |bridge| next unless bridge.upstream_project @@ -27,12 +19,6 @@ module Bridge end end - def schedule_downstream_pipeline! - raise InvalidBridgeTypeError unless downstream_project - - ::Ci::CreateCrossProjectPipelineWorker.perform_async(self.id) - end - def subscribe_to_upstream! raise InvalidBridgeTypeError unless upstream_project diff --git a/ee/app/models/ee/commit_status_enums.rb b/ee/app/models/ee/commit_status_enums.rb index 9906d610252cc0f9c27fd73ddd3b2df1160f7a8b..be5503fb412a0861977210056a1f80857e147fea 100644 --- a/ee/app/models/ee/commit_status_enums.rb +++ b/ee/app/models/ee/commit_status_enums.rb @@ -10,13 +10,8 @@ module CommitStatusEnums override :failure_reasons def failure_reasons super.merge(protected_environment_failure: 1_000, - insufficient_bridge_permissions: 1_001, - downstream_bridge_project_not_found: 1_002, - invalid_bridge_trigger: 1_003, upstream_bridge_project_not_found: 1_004, - insufficient_upstream_permissions: 1_005, - bridge_pipeline_is_child_pipeline: 1_006, - downstream_pipeline_creation_failed: 1_007) + insufficient_upstream_permissions: 1_005) end end end diff --git a/ee/app/presenters/ee/commit_status_presenter.rb b/ee/app/presenters/ee/commit_status_presenter.rb index 698ff23d2386475f622c2274c736bb39926b4a9c..923b18d2a31039f540b40baa13c971f060d179f3 100644 --- a/ee/app/presenters/ee/commit_status_presenter.rb +++ b/ee/app/presenters/ee/commit_status_presenter.rb @@ -6,13 +6,8 @@ module CommitStatusPresenter prepended do EE_CALLOUT_FAILURE_MESSAGES = const_get(:CALLOUT_FAILURE_MESSAGES, false).merge( protected_environment_failure: 'The environment this job is deploying to is protected. Only users with permission may successfully run this job.', - insufficient_bridge_permissions: 'This job could not be executed because of insufficient permissions to create a downstream pipeline.', insufficient_upstream_permissions: 'This job could not be executed because of insufficient permissions to track the upstream project.', - downstream_bridge_project_not_found: 'This job could not be executed because downstream bridge project could not be found.', - upstream_bridge_project_not_found: 'This job could not be executed because upstream bridge project could not be found.', - invalid_bridge_trigger: 'This job could not be executed because downstream pipeline trigger definition is invalid.', - bridge_pipeline_is_child_pipeline: 'This job belongs to a child pipeline and cannot create further child pipelines.', - downstream_pipeline_creation_failed: 'The downstream pipeline could not be created.' + upstream_bridge_project_not_found: 'This job could not be executed because upstream bridge project could not be found.' ).freeze EE::CommitStatusPresenter.private_constant :EE_CALLOUT_FAILURE_MESSAGES diff --git a/ee/app/workers/all_queues.yml b/ee/app/workers/all_queues.yml index 456273eb13d396d17bfdd5acc147aa07e92b0c5c..33b28998389d60a1a72903f2dd200480a4bd45f5 100644 --- a/ee/app/workers/all_queues.yml +++ b/ee/app/workers/all_queues.yml @@ -339,12 +339,6 @@ :latency_sensitive: :resource_boundary: :unknown :weight: 1 -- :name: pipeline_default:ci_create_cross_project_pipeline - :feature_category: :continuous_integration - :has_external_dependencies: - :latency_sensitive: - :resource_boundary: :cpu - :weight: 3 - :name: pipeline_default:store_security_reports :feature_category: :continuous_integration :has_external_dependencies: diff --git a/ee/lib/ee/gitlab/ci/status/build/failed.rb b/ee/lib/ee/gitlab/ci/status/build/failed.rb index 93dfdf91ea298ec903c5154651357945f76a7ff2..10ab56ebb8a7c7cf30a46edd2d2a054402b40236 100644 --- a/ee/lib/ee/gitlab/ci/status/build/failed.rb +++ b/ee/lib/ee/gitlab/ci/status/build/failed.rb @@ -11,13 +11,8 @@ module Failed prepended do EE_REASONS = const_get(:REASONS, false).merge( protected_environment_failure: 'protected environment failure', - invalid_bridge_trigger: 'downstream pipeline trigger definition is invalid', - downstream_bridge_project_not_found: 'downstream project could not be found', upstream_bridge_project_not_found: 'upstream project could not be found', - insufficient_bridge_permissions: 'no permissions to trigger downstream pipeline', - insufficient_upstream_permissions: 'no permissions to read upstream project', - bridge_pipeline_is_child_pipeline: 'creation of child pipeline not allowed from another child pipeline', - downstream_pipeline_creation_failed: 'downstream pipeline can not be created' + insufficient_upstream_permissions: 'no permissions to read upstream project' ).freeze EE::Gitlab::Ci::Status::Build::Failed.private_constant :EE_REASONS end diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb index 910d93f54ce942bb4e7a9d1bf5ce5ef164a53c70..0915a98a0fa865ad0a44b5fefdf38be5a0caaf91 100644 --- a/lib/gitlab/ci/status/build/failed.rb +++ b/lib/gitlab/ci/status/build/failed.rb @@ -18,7 +18,12 @@ class Failed < Status::Extended archived_failure: 'archived failure', unmet_prerequisites: 'unmet prerequisites', scheduler_failure: 'scheduler failure', - data_integrity_failure: 'data integrity failure' + data_integrity_failure: 'data integrity failure', + invalid_bridge_trigger: 'downstream pipeline trigger definition is invalid', + downstream_bridge_project_not_found: 'downstream project could not be found', + insufficient_bridge_permissions: 'no permissions to trigger downstream pipeline', + bridge_pipeline_is_child_pipeline: 'creation of child pipeline not allowed from another child pipeline', + downstream_pipeline_creation_failed: 'downstream pipeline can not be created' }.freeze private_constant :REASONS diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb index 43c843b342077c35db7ca050e109b61558f40197..1a97dd60c0e3d51e79d327225e4d1f5c2d9b0bd9 100644 --- a/spec/models/ci/bridge_spec.rb +++ b/spec/models/ci/bridge_spec.rb @@ -53,6 +53,16 @@ end end + describe 'state machine transitions' do + context 'when bridge points towards downstream' do + it 'schedules downstream pipeline creation' do + expect(bridge).to receive(:schedule_downstream_pipeline!) + + bridge.enqueue! + end + end + end + describe '#inherit_status_from_downstream!' do let(:downstream_pipeline) { build(:ci_pipeline, status: downstream_status) } diff --git a/ee/spec/services/ci/create_cross_project_pipeline_service_spec.rb b/spec/services/ci/create_cross_project_pipeline_service_spec.rb similarity index 98% rename from ee/spec/services/ci/create_cross_project_pipeline_service_spec.rb rename to spec/services/ci/create_cross_project_pipeline_service_spec.rb index 8a1763b30edc66f0c14af92c60af4424a462e9a5..f90cdb55a7a89802d09c993d219fa4a622f78ff5 100644 --- a/ee/spec/services/ci/create_cross_project_pipeline_service_spec.rb +++ b/spec/services/ci/create_cross_project_pipeline_service_spec.rb @@ -342,7 +342,9 @@ let(:service) { described_class.new(upstream_project, upstream_project.owner) } context 'that include the bridge job' do - it 'creates the downstream pipeline' do + # TODO: this is skipped because `trigger` keyword does not exist yet. + # enabling it in the next MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24393 + xit 'creates the downstream pipeline' do expect { service.execute(bridge) } .to change(downstream_project.ci_pipelines, :count).by(1) end diff --git a/ee/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb b/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb similarity index 100% rename from ee/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb rename to spec/workers/ci/create_cross_project_pipeline_worker_spec.rb