diff --git a/app/services/ci/create_downstream_pipeline_service.rb b/app/services/ci/create_downstream_pipeline_service.rb index efce1604276ba51e04c480df346f363c112ab87e..098235816f67454b5c73998541af19e3204c898f 100644 --- a/app/services/ci/create_downstream_pipeline_service.rb +++ b/app/services/ci/create_downstream_pipeline_service.rb @@ -41,12 +41,17 @@ def execute(bridge) .payload log_downstream_pipeline_creation(downstream_pipeline) + log_audit_event(downstream_pipeline) update_bridge_status!(@bridge, downstream_pipeline) rescue StandardError => e @bridge.reset.drop!(:data_integrity_failure) raise e end + def log_audit_event(downstream_pipeline) + # defined in EE + end + private def update_bridge_status!(bridge, pipeline) @@ -172,3 +177,5 @@ def config_checksum(pipeline) end end end + +Ci::CreateDownstreamPipelineService.prepend_mod_with('Ci::CreateDownstreamPipelineService') diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index e08821c3f68d91b9f5387ed09a7bd17dcf572538..02ac911a8add478cd691002dd3146d8e1cf5f167 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -197,6 +197,12 @@ Audit event types belong to the following product categories. | [`container_repository_deletion_marked`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152967) | Triggered when a project's container repository is marked for deletion | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project | | [`container_repository_tags_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156066) | Triggered when a project's container repository tag is deleted | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project | +### Continuous-integration + +| Name | Description | Saved to database | Streamed | Introduced in | Scope | +|:------------|:------------|:------------------|:---------|:--------------|:--------------| +| [`multi_project_downstream_pipeline_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168626) | Triggered when multi project downstream pipeline is created | **{dotted-circle}** No | **{check-circle}** Yes | GitLab [17.6](https://gitlab.com/gitlab-org/gitlab/-/issues/481325) | Project | + ### Continuous delivery | Name | Description | Saved to database | Streamed | Introduced in | Scope | diff --git a/ee/app/services/ee/ci/create_downstream_pipeline_service.rb b/ee/app/services/ee/ci/create_downstream_pipeline_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..6022b4ed3afd0f32cd77d3fe664ab1f444cee122 --- /dev/null +++ b/ee/app/services/ee/ci/create_downstream_pipeline_service.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module EE + module Ci + module CreateDownstreamPipelineService + extend ::Gitlab::Utils::Override + + override :log_audit_event + def log_audit_event(downstream_pipeline) + return unless downstream_pipeline&.persisted? + return if downstream_pipeline.parent_pipeline? + + root_pipeline = downstream_pipeline.upstream_root + + audit_context = { + name: "multi_project_downstream_pipeline_created", + author: current_user, + scope: downstream_pipeline.project, + target: downstream_pipeline, + target_details: downstream_pipeline.id.to_s, + message: "Multi-project downstream pipeline created.", + additional_details: { + upstream_root_pipeline_id: root_pipeline.id, + upstream_root_project_path: root_pipeline.project&.full_path + } + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + end + end +end diff --git a/ee/config/audit_events/types/multi_project_downstream_pipeline_created.yml b/ee/config/audit_events/types/multi_project_downstream_pipeline_created.yml new file mode 100644 index 0000000000000000000000000000000000000000..99520701504ac7e1dc27dba4632017232471f1b8 --- /dev/null +++ b/ee/config/audit_events/types/multi_project_downstream_pipeline_created.yml @@ -0,0 +1,10 @@ +--- +name: multi_project_downstream_pipeline_created +description: Triggered when multi project downstream pipeline is created +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/481325 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168626 +feature_category: continuous-integration +milestone: '17.6' +saved_to_database: false +streamed: true +scope: [Project] diff --git a/ee/spec/services/ci/create_downstream_pipeline_service_spec.rb b/ee/spec/services/ci/create_downstream_pipeline_service_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..1886aadc42a7fb0cbfb0be8941a22ad2b90a4cf7 --- /dev/null +++ b/ee/spec/services/ci/create_downstream_pipeline_service_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::CreateDownstreamPipelineService, feature_category: :continuous_integration do + let_it_be(:user) { create(:user) } + let_it_be(:upstream_project) { create(:project, :repository) } + let_it_be(:upstream_pipeline) { create(:ci_pipeline, :created, project: upstream_project) } + + let(:trigger) do + { + trigger: { + project: downstream_project.full_path, + branch: 'feature' + } + } + end + + let(:bridge) do + create( + :ci_bridge, + status: :pending, + user: user, + options: trigger, + pipeline: upstream_pipeline + ) + end + + let(:service) { described_class.new(upstream_project, user) } + + before do + stub_ci_pipeline_yaml_file(YAML.dump(rspec: { script: 'rspec' })) + allow(::Gitlab::Audit::Auditor).to receive(:audit) + end + + subject(:execute) { service.execute(bridge) } + + context 'when multi project downstream pipeline is created' do + let_it_be(:downstream_project) { create(:project, :repository) } + + before_all do + upstream_project.add_developer(user) + downstream_project.add_developer(user) + end + + it 'calls auditor with correct args' do + pipeline = execute.payload + + expect(::Gitlab::Audit::Auditor).to have_received(:audit).with( + name: "multi_project_downstream_pipeline_created", + author: user, + scope: pipeline.project, + target: pipeline, + target_details: pipeline.id.to_s, + message: "Multi-project downstream pipeline created.", + additional_details: { + upstream_root_pipeline_id: upstream_pipeline.id, + upstream_root_project_path: upstream_pipeline.project.full_path + } + ) + end + end + + context 'when parent child project downstream pipeline is created' do + let_it_be(:downstream_project) { upstream_project } + + before_all do + upstream_project.add_developer(user) + downstream_project.add_developer(user) + end + + it 'does not calls auditor' do + execute.payload + + expect(::Gitlab::Audit::Auditor).not_to have_received(:audit) + end + end +end