From 54c8c63fd028901503233ceff46ef306d86ed7a7 Mon Sep 17 00:00:00 2001 From: mc_rocha Date: Wed, 30 Jul 2025 16:50:14 -0400 Subject: [PATCH 1/2] Send a audit event for pep errors during pipeline creation Changelog: added EE: true --- ee/app/models/ee/ci/pipeline.rb | 7 ++++++- ee/spec/models/ci/pipeline_spec.rb | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ee/app/models/ee/ci/pipeline.rb b/ee/app/models/ee/ci/pipeline.rb index 48acf7741e4bac..1b79a5293ba10d 100644 --- a/ee/app/models/ee/ci/pipeline.rb +++ b/ee/app/models/ee/ci/pipeline.rb @@ -375,7 +375,7 @@ def sbom_report_ingestion_errors_redis_key def should_audit_security_policy_pipeline_failure?(pipeline) return false if ::Feature.disabled?(:collect_security_policy_failed_pipelines_audit_events, pipeline.project) - pipeline_created_by_security_policies?(pipeline.source) || pipeline_with_security_policy_jobs? + pipeline_created_by_security_policies?(pipeline.source) || pipeline_with_security_policy_jobs? || pipeline_with_security_policy_errors?(pipeline) end def pipeline_created_by_security_policies?(source) @@ -385,6 +385,11 @@ def pipeline_created_by_security_policies?(source) def pipeline_with_security_policy_jobs? builds.joins(:build_source).where(p_ci_build_sources: { source: PIPELINE_EXECUTION_POLICIES_BUILD_SOURCES }).exists? end + + def pipeline_with_security_policy_errors?(pipeline) + ::Ci::PipelineMessage.where(pipeline: pipeline, severity: :error) + .where("content LIKE ?", "Pipeline execution policy error:%").exists? + end end end end diff --git a/ee/spec/models/ci/pipeline_spec.rb b/ee/spec/models/ci/pipeline_spec.rb index 43844931e05c62..e43a01075e88cc 100644 --- a/ee/spec/models/ci/pipeline_spec.rb +++ b/ee/spec/models/ci/pipeline_spec.rb @@ -778,10 +778,21 @@ context 'when the pipeline was created by a security policy' do let(:source) { :security_orchestration_policy } - it 'enqueues FailedPipelinesAuditWorker' do - expect(Security::Policies::FailedPipelinesAuditWorker).to receive(:perform_async).with(pipeline.id) + it_behaves_like 'enqueues FailedPipelinesAuditWorker' + end - transition_pipeline + context 'when the pipeline has errors messages' do + context 'when the errors are not related to security policies' do + let!(:error_message) { create(:ci_pipeline_message, pipeline: pipeline, content: 'error', severity: :error) } + + it_behaves_like 'does not enqueue FailedPipelinesAuditWorker' + end + + context 'when the errors are related to security policies' do + let(:security_policies_error_message) { 'Pipeline execution policy error: Cyclic dependencies detected when enforcing policies. Ensure stages across the project and policies are aligned.' } + let!(:error_message) { create(:ci_pipeline_message, pipeline: pipeline, content: security_policies_error_message, severity: :error) } + + it_behaves_like 'enqueues FailedPipelinesAuditWorker' end end end -- GitLab From 9a1eed073b610bba5a195ed219d22043444527ed Mon Sep 17 00:00:00 2001 From: mc_rocha Date: Fri, 1 Aug 2025 13:47:08 -0400 Subject: [PATCH 2/2] Address reviewers comment --- app/models/ci/pipeline_message.rb | 2 + ee/app/models/ee/ci/pipeline.rb | 3 +- ee/app/models/ee/ci/pipeline_message.rb | 17 +++++++ ee/spec/models/ee/ci/pipeline_message_spec.rb | 45 +++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 ee/app/models/ee/ci/pipeline_message.rb create mode 100644 ee/spec/models/ee/ci/pipeline_message_spec.rb diff --git a/app/models/ci/pipeline_message.rb b/app/models/ci/pipeline_message.rb index 21f05258040be3..273aa17a6ce6e0 100644 --- a/app/models/ci/pipeline_message.rb +++ b/app/models/ci/pipeline_message.rb @@ -26,3 +26,5 @@ def truncate_long_content end end end + +Ci::PipelineMessage.prepend_mod_with('Ci::PipelineMessage') diff --git a/ee/app/models/ee/ci/pipeline.rb b/ee/app/models/ee/ci/pipeline.rb index 1b79a5293ba10d..05e01c859dd1b5 100644 --- a/ee/app/models/ee/ci/pipeline.rb +++ b/ee/app/models/ee/ci/pipeline.rb @@ -387,8 +387,7 @@ def pipeline_with_security_policy_jobs? end def pipeline_with_security_policy_errors?(pipeline) - ::Ci::PipelineMessage.where(pipeline: pipeline, severity: :error) - .where("content LIKE ?", "Pipeline execution policy error:%").exists? + pipeline.messages.pipeline_execution_policy_failure.exists? end end end diff --git a/ee/app/models/ee/ci/pipeline_message.rb b/ee/app/models/ee/ci/pipeline_message.rb new file mode 100644 index 00000000000000..f2fab5584d15cc --- /dev/null +++ b/ee/app/models/ee/ci/pipeline_message.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module EE + module Ci + module PipelineMessage + extend ActiveSupport::Concern + + PIPELINE_EXECUTION_POLICY_ERROR = 'Pipeline execution policy error:' + + prepended do + scope :pipeline_execution_policy_failure, -> { + where("content LIKE ?", "#{sanitize_sql_like(PIPELINE_EXECUTION_POLICY_ERROR)}%").where(severity: :error) + } + end + end + end +end diff --git a/ee/spec/models/ee/ci/pipeline_message_spec.rb b/ee/spec/models/ee/ci/pipeline_message_spec.rb new file mode 100644 index 00000000000000..dbf3ec099bf052 --- /dev/null +++ b/ee/spec/models/ee/ci/pipeline_message_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::PipelineMessage, feature_category: :continuous_integration do + let_it_be(:pipeline, refind: true) do + create(:ci_empty_pipeline) + end + + describe 'scopes' do + describe '.pipeline_execution_policy_failure' do + subject(:pipeline_execution_policy_failure) { described_class.pipeline_execution_policy_failure } + + let!(:warning_message) do + create(:ci_pipeline_message, pipeline: pipeline, content: 'Warning message', severity: :warning) + end + + let!(:non_pipeline_execution_policy_error_message) do + create(:ci_pipeline_message, pipeline: pipeline, content: 'Non Pipeline execution policy error', + severity: :error) + end + + context 'when content does not contains pipeline execution policy error' do + specify do + expect(pipeline_execution_policy_failure).to be_empty + end + end + + context 'when content contains pipeline execution policy error' do + let(:security_policies_error_message) do + 'Pipeline execution policy error: Cyclic dependencies detected when enforcing policies.' \ + 'Ensure stages across the project and policies are aligned.' + end + + let!(:pipeline_execution_policy_error_message) do + create(:ci_pipeline_message, pipeline: pipeline, content: security_policies_error_message, severity: :error) + end + + it 'returns the pipeline_execution_policy_error_message' do + expect(pipeline_execution_policy_failure).to contain_exactly(pipeline_execution_policy_error_message) + end + end + end + end +end -- GitLab