From b23387fab354c1780c5c6d889c762b9322c1233e Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Mon, 6 Oct 2025 11:37:17 +0200 Subject: [PATCH 1/6] Release partial scans Remove the vulnerability_partial_scans feature flag and release the feature globally. Changelog: added EE: true --- .../pipeline_vulnerability_report.vue | 3 --- .../mr_widget_security_reports.vue | 6 ----- .../ee/projects/merge_requests_controller.rb | 1 - .../ee/projects/pipelines_controller.rb | 1 - ee/app/finders/security/findings_finder.rb | 2 +- ...uest_security_report_generation_service.rb | 21 ---------------- .../services/security/store_scan_service.rb | 2 -- .../beta/vulnerability_partial_scans.yml | 10 -------- .../finders/security/findings_finder_spec.rb | 24 ------------------- .../pipeline_vulnerability_report_spec.js | 4 ---- .../mr_widget_security_reports_spec.js | 6 +---- ...security_report_generation_service_spec.rb | 12 ---------- .../security/store_scan_service_spec.rb | 12 ---------- 13 files changed, 2 insertions(+), 102 deletions(-) delete mode 100644 ee/config/feature_flags/beta/vulnerability_partial_scans.yml diff --git a/ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue b/ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue index 4a9f2984e59870..2c084798bd4d00 100644 --- a/ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue +++ b/ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue @@ -63,9 +63,6 @@ export default { message: s__('ciReport|Error while fetching enabled scans. Please try again later.'), }); }, - skip() { - return !this.glFeatures.vulnerabilityPartialScans; - }, }, }, diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports.vue b/ee/app/assets/javascripts/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports.vue index c7cc42dd24dc59..5e3b0a08a3f98a 100644 --- a/ee/app/assets/javascripts/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports.vue +++ b/ee/app/assets/javascripts/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports.vue @@ -6,7 +6,6 @@ import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; import enabledScansQuery from 'ee/vue_merge_request_widget/queries/enabled_scans.query.graphql'; import SummaryHighlights from 'ee/vue_shared/security_reports/components/summary_highlights.vue'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants'; import { convertToCamelCase } from '~/lib/utils/text_utility'; import { helpPagePath } from '~/helpers/help_page_helper'; @@ -31,7 +30,6 @@ export default { SummaryHighlights, SecurityTrainingPromoWidget, }, - mixins: [glFeatureFlagMixin()], i18n, props: { mr: { @@ -253,10 +251,6 @@ export default { ); }, skip() { - if (!this.glFeatures.vulnerabilityPartialScans) { - return true; - } - return ( !this.mr.pipeline?.iid || !this.mr.targetProjectFullPath || diff --git a/ee/app/controllers/ee/projects/merge_requests_controller.rb b/ee/app/controllers/ee/projects/merge_requests_controller.rb index a6c95bc43c5f8f..256e6d19ca9a54 100644 --- a/ee/app/controllers/ee/projects/merge_requests_controller.rb +++ b/ee/app/controllers/ee/projects/merge_requests_controller.rb @@ -11,7 +11,6 @@ module MergeRequestsController before_action only: [:show] do push_frontend_feature_flag(:merge_trains_skip_train, @project) - push_frontend_feature_flag(:vulnerability_partial_scans, @project) push_frontend_feature_flag(:security_policy_approval_warn_mode, @project) push_frontend_ability(ability: :resolve_vulnerability_with_ai, resource: @project, user: current_user) push_frontend_ability(ability: :measure_comment_temperature, resource: merge_request, user: current_user) diff --git a/ee/app/controllers/ee/projects/pipelines_controller.rb b/ee/app/controllers/ee/projects/pipelines_controller.rb index bbb1549434f3ae..263871cb0f983f 100644 --- a/ee/app/controllers/ee/projects/pipelines_controller.rb +++ b/ee/app/controllers/ee/projects/pipelines_controller.rb @@ -11,7 +11,6 @@ module PipelinesController before_action :authorize_read_licenses!, only: [:licenses, :license_count] before_action do - push_frontend_feature_flag(:vulnerability_partial_scans, project) push_frontend_feature_flag(:vulnerability_report_type_scanner_filter) push_frontend_feature_flag(:validity_checks_security_finding_status, project) end diff --git a/ee/app/finders/security/findings_finder.rb b/ee/app/finders/security/findings_finder.rb index 01fb0986415ca9..c77a339101d38e 100644 --- a/ee/app/finders/security/findings_finder.rb +++ b/ee/app/finders/security/findings_finder.rb @@ -143,7 +143,7 @@ def by_report_types(relation) def by_scan_mode(relation) scan_mode = params.fetch(:scan_mode, 'all') - return relation if ::Feature.disabled?(:vulnerability_partial_scans, project) || scan_mode == 'all' + return relation if scan_mode == 'all' exists_clause = <<~SQL EXISTS ( diff --git a/ee/app/services/security/merge_request_security_report_generation_service.rb b/ee/app/services/security/merge_request_security_report_generation_service.rb index 57836b69dfbe60..5167a3f9a45ecd 100644 --- a/ee/app/services/security/merge_request_security_report_generation_service.rb +++ b/ee/app/services/security/merge_request_security_report_generation_service.rb @@ -106,8 +106,6 @@ def fixed_findings strong_memoize_attr def report validate_report_type! - return old_report if Feature.disabled?(:vulnerability_partial_scans, project) - with_reactive_cache(params.stringify_keys) do |data| latest = Vulnerabilities::CompareSecurityReportsService.new(project, nil, params).latest?(base_pipeline, head_pipeline, data) @@ -117,25 +115,6 @@ def fixed_findings end || { status: :parsing } end - def old_report - case report_type - when 'sast' - merge_request.compare_sast_reports(nil) - when 'secret_detection' - merge_request.compare_secret_detection_reports(nil) - when 'container_scanning' - merge_request.compare_container_scanning_reports(nil) - when 'dependency_scanning' - merge_request.compare_dependency_scanning_reports(nil) - when 'dast' - merge_request.compare_dast_reports(nil) - when 'coverage_fuzzing' - merge_request.compare_coverage_fuzzing_reports(nil) - when 'api_fuzzing' - merge_request.compare_api_fuzzing_reports(nil) - end - end - def validate_report_type! raise InvalidReportTypeError unless ALLOWED_REPORT_TYPES.include?(report_type) end diff --git a/ee/app/services/security/store_scan_service.rb b/ee/app/services/security/store_scan_service.rb index 4e53f11374556d..332c4a68ea197d 100644 --- a/ee/app/services/security/store_scan_service.rb +++ b/ee/app/services/security/store_scan_service.rb @@ -77,8 +77,6 @@ def security_scan alias_method :store_security_scan, :security_scan def store_partial_scan - return unless ::Feature.enabled?(:vulnerability_partial_scans, project) - # If we have a dependency scanning report then `scan` will return nil mode = security_report.scan&.partial_scan_mode diff --git a/ee/config/feature_flags/beta/vulnerability_partial_scans.yml b/ee/config/feature_flags/beta/vulnerability_partial_scans.yml deleted file mode 100644 index 4f767d9b43cc89..00000000000000 --- a/ee/config/feature_flags/beta/vulnerability_partial_scans.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: vulnerability_partial_scans -description: Track scans that do not run on the entire codebase and indicate them on the MR -feature_issue_url: https://gitlab.com/groups/gitlab-org/-/epics/17758 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/195373 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/552051 -milestone: '18.2' -group: group::security insights -type: beta -default_enabled: true diff --git a/ee/spec/finders/security/findings_finder_spec.rb b/ee/spec/finders/security/findings_finder_spec.rb index c2f6d82afab478..0793c858313efb 100644 --- a/ee/spec/finders/security/findings_finder_spec.rb +++ b/ee/spec/finders/security/findings_finder_spec.rb @@ -310,18 +310,6 @@ it 'returns only full scan results' do is_expected.to match_array(expected_uuids) end - - context 'when feature is disabled' do - before do - stub_feature_flags(vulnerability_partial_scans: false) - end - - let(:result_uuids) { Security::Finding.pluck(:uuid) } - - it 'returns both full and partial scan results' do - is_expected.to match_array(expected_uuids) - end - end end context 'when scan_mode is partial' do @@ -331,18 +319,6 @@ it 'returns only partial scan results' do is_expected.to match_array(expected_uuids) end - - context 'when feature is disabled' do - before do - stub_feature_flags(vulnerability_partial_scans: false) - end - - let(:result_uuids) { Security::Finding.pluck(:uuid) } - - it 'returns both full and partial scan results' do - is_expected.to match_array(expected_uuids) - end - end end end end diff --git a/ee/spec/frontend/security_dashboard/components/pipeline/pipeline_vulnerability_report_spec.js b/ee/spec/frontend/security_dashboard/components/pipeline/pipeline_vulnerability_report_spec.js index c55dae353ff00f..b55b690e8fbee8 100644 --- a/ee/spec/frontend/security_dashboard/components/pipeline/pipeline_vulnerability_report_spec.js +++ b/ee/spec/frontend/security_dashboard/components/pipeline/pipeline_vulnerability_report_spec.js @@ -27,7 +27,6 @@ describe('Pipeline vulnerability report', () => { const createWrapper = ({ vulnerabilityReportTypeScannerFilter = true, - vulnerabilityPartialScans = false, mockApolloProvider, } = {}) => { wrapper = shallowMountExtended(PipelineVulnerabilityReport, { @@ -41,7 +40,6 @@ describe('Pipeline vulnerability report', () => { projectFullPath: TEST_PROJECT_FULL_PATH, glFeatures: { vulnerabilityReportTypeScannerFilter, - vulnerabilityPartialScans, }, }, }); @@ -203,7 +201,6 @@ describe('Pipeline vulnerability report', () => { it('should create an alert when enabled scans query fails', async () => { createWrapper({ - vulnerabilityPartialScans: true, mockApolloProvider: createMockApollo([ [enabledScansQuery, jest.fn().mockRejectedValue({})], ]), @@ -224,7 +221,6 @@ describe('Pipeline vulnerability report', () => { 'should $text the banner when partial scans are enabled=$hasBanner', async ({ enabledPartialScans, hasBanner }) => { createWrapper({ - vulnerabilityPartialScans: true, mockApolloProvider: createMockApollo([ [ enabledScansQuery, diff --git a/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js b/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js index ec1b4f2a9c4261..2e905d54a50a46 100644 --- a/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js +++ b/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js @@ -213,10 +213,9 @@ describe('MR Widget Security Reports', () => { }); }); - describe('with vulnerabilityPartialScans feature flag turned on', () => { + describe('partial scans', () => { it('should display a loading state until enabled scans are fetched', async () => { createComponent({ - provide: { glFeatures: { vulnerabilityPartialScans: true } }, mountFn: mountExtended, mockApolloProvider: defaultMockApollo, }); @@ -236,7 +235,6 @@ describe('MR Widget Security Reports', () => { 'should fetch full scans=$fullScans, partial scans=$partialScans', async ({ fullScans, partialScans, expectedNumberOfRESTcalls, expectedScanModes }) => { createComponent({ - provide: { glFeatures: { vulnerabilityPartialScans: true } }, mountFn: mountExtended, mockApolloProvider: createMockApollo([ [ @@ -272,7 +270,6 @@ describe('MR Widget Security Reports', () => { mockAxios = new MockAdapter(axios); createComponent({ - provide: { glFeatures: { vulnerabilityPartialScans: true } }, mountFn: mountExtended, apolloProvider: createMockApollo([ [ @@ -317,7 +314,6 @@ describe('MR Widget Security Reports', () => { it('when the query fails', async () => { createComponent({ - provide: { glFeatures: { vulnerabilityPartialScans: true } }, mountFn: mountExtended, apolloProvider: createMockApollo([ [ diff --git a/ee/spec/services/security/merge_request_security_report_generation_service_spec.rb b/ee/spec/services/security/merge_request_security_report_generation_service_spec.rb index bc636f3d4d5982..89019076f7d87f 100644 --- a/ee/spec/services/security/merge_request_security_report_generation_service_spec.rb +++ b/ee/spec/services/security/merge_request_security_report_generation_service_spec.rb @@ -226,18 +226,6 @@ def stub_report(data) } end - context 'when vulnerability_partial_scans is disabled' do - before do - stub_feature_flags(vulnerability_partial_scans: false) - end - - it 'returns the report and does not queue ReactiveCachingWorker' do - expect(ReactiveCachingWorker).not_to receive(:perform_async) - expect(merge_request).to receive(mr_report_method).with(nil).and_return(mock_report) - expect(report).to eq(expected_report) - end - end - context 'when cached results is not latest' do before do allow(ReactiveCachingWorker).to receive(:perform_async).and_call_original diff --git a/ee/spec/services/security/store_scan_service_spec.rb b/ee/spec/services/security/store_scan_service_spec.rb index 167ae425d1e4db..beaecc6001045f 100644 --- a/ee/spec/services/security/store_scan_service_spec.rb +++ b/ee/spec/services/security/store_scan_service_spec.rb @@ -137,18 +137,6 @@ it_behaves_like 'stores partial scan record' - context 'when vulnerability_partial_scans feature flag is disabled' do - before do - stub_feature_flags(vulnerability_partial_scans: false) - end - - it 'does not create partial scan record' do - store_scan - - expect(security_scan.partial_scan).to be_nil - end - end - context 'when there is an existing security scan' do let_it_be(:existing_scan) do create(:security_scan, build: artifact.job, scan_type: artifact.security_report.type) -- GitLab From c6c9228f0716e939eebd22181e161233cb73d693 Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Tue, 21 Oct 2025 09:20:58 +0200 Subject: [PATCH 2/6] Fix failing specs --- .../mr_widget_security_reports_spec.js | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js b/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js index 2e905d54a50a46..14c149307ed043 100644 --- a/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js +++ b/ee/spec/frontend/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports_spec.js @@ -163,6 +163,19 @@ describe('MR Widget Security Reports', () => { propsData: { mr: mrProps, }, + mockApolloProvider: createMockApollo([ + [ + enabledScansQuery, + jest.fn().mockResolvedValue( + enabledScansQueryResult({ + full: { + sast: true, + dast: true, + }, + }), + ), + ], + ]), ...options, }); @@ -334,7 +347,6 @@ describe('MR Widget Security Reports', () => { it('when the pipeline is null, it should not render anything', async () => { createComponent({ - provide: { glFeatures: { vulnerabilityPartialScans: true } }, mountFn: mountExtended, apolloProvider: createMockApollo([ [ @@ -359,7 +371,7 @@ describe('MR Widget Security Reports', () => { describe('with empty MR data', () => { beforeEach(() => { - createComponent(); + createComponent({ mockApolloProvider: defaultMockApollo }); }); it('should mount the widget component', () => { @@ -442,6 +454,19 @@ describe('MR Widget Security Reports', () => { createComponent({ mountFn: mountExtended, + mockApolloProvider: createMockApollo([ + [ + enabledScansQuery, + jest.fn().mockResolvedValue( + enabledScansQueryResult({ + full: { + sast: true, + dast: true, + }, + }), + ), + ], + ]), }); await waitForPromises(); @@ -468,7 +493,7 @@ describe('MR Widget Security Reports', () => { }); it('should display the view all pipeline findings button', async () => { - await createComponent(); + await createComponent({ mockApolloProvider: defaultMockApollo }); expect(findWidget().props('actionButtons')).toEqual([ { -- GitLab From be89d91479adfa8c4c45cf7802151d0ca468b1ae Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Tue, 21 Oct 2025 09:23:11 +0200 Subject: [PATCH 3/6] Add history note on feature flag removal --- doc/user/application_security/sast/gitlab_advanced_sast.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/user/application_security/sast/gitlab_advanced_sast.md b/doc/user/application_security/sast/gitlab_advanced_sast.md index 07b168f6e9ee0b..fe014874836948 100644 --- a/doc/user/application_security/sast/gitlab_advanced_sast.md +++ b/doc/user/application_security/sast/gitlab_advanced_sast.md @@ -147,6 +147,7 @@ When analyzing PHP code, GitLab Advanced SAST has the following limitations: - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/16790) in GitLab 18.5 [with a flag](../../../administration/feature_flags/_index.md) named `vulnerability_partial_scans`. Disabled by default. - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/552051) in GitLab 18.5. +- [Feature flag `vulnerability_partial_scans` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/552051) in GitLab 18.6. {{< /history >}} -- GitLab From 75f0961b88b44b1c9e82b81cfa96ed34c10c4a7c Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Tue, 21 Oct 2025 13:56:22 +0000 Subject: [PATCH 4/6] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Ryan Lehmann --- doc/user/application_security/sast/gitlab_advanced_sast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/application_security/sast/gitlab_advanced_sast.md b/doc/user/application_security/sast/gitlab_advanced_sast.md index fe014874836948..51f3e86fa005fc 100644 --- a/doc/user/application_security/sast/gitlab_advanced_sast.md +++ b/doc/user/application_security/sast/gitlab_advanced_sast.md @@ -147,7 +147,7 @@ When analyzing PHP code, GitLab Advanced SAST has the following limitations: - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/16790) in GitLab 18.5 [with a flag](../../../administration/feature_flags/_index.md) named `vulnerability_partial_scans`. Disabled by default. - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/552051) in GitLab 18.5. -- [Feature flag `vulnerability_partial_scans` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/552051) in GitLab 18.6. +- [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/552051) in GitLab 18.6. Feature flag `vulnerability_partial_scans` removed. {{< /history >}} -- GitLab From 592db36e5ed25c195627c1284ba21952cbef177b Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Tue, 21 Oct 2025 13:56:30 +0000 Subject: [PATCH 5/6] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Ryan Lehmann --- doc/user/application_security/sast/gitlab_advanced_sast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/application_security/sast/gitlab_advanced_sast.md b/doc/user/application_security/sast/gitlab_advanced_sast.md index 51f3e86fa005fc..25994daaa0b26d 100644 --- a/doc/user/application_security/sast/gitlab_advanced_sast.md +++ b/doc/user/application_security/sast/gitlab_advanced_sast.md @@ -164,7 +164,7 @@ To ensure complete coverage, a full scan runs on the default branch after the me When diff-based scanning is enabled: - Only files that were modified or added in the merge request, along with their dependent files, are scanned in merge request pipelines. -- If enabled, you’ll see the job log print: `Running differential scan` +- If enabled, you'll see the job log print: `Running differential scan` If disabled, it prints: `Running full scan` - In the **merge request security widget**, a dedicated **Diff-based** tab shows relevant scan findings. - In the **Pipeline Security** tab, an alert labeled **Partial SAST report** indicates that only partial findings are included. -- GitLab From aafcddd8485383426b063a9383981ab6779d2be7 Mon Sep 17 00:00:00 2001 From: Savas Vedova Date: Tue, 21 Oct 2025 13:56:44 +0000 Subject: [PATCH 6/6] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Ryan Lehmann --- doc/user/application_security/sast/gitlab_advanced_sast.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/user/application_security/sast/gitlab_advanced_sast.md b/doc/user/application_security/sast/gitlab_advanced_sast.md index 25994daaa0b26d..8e222533eaf8a0 100644 --- a/doc/user/application_security/sast/gitlab_advanced_sast.md +++ b/doc/user/application_security/sast/gitlab_advanced_sast.md @@ -151,12 +151,6 @@ When analyzing PHP code, GitLab Advanced SAST has the following limitations: {{< /history >}} -{{< alert type="flag" >}} - -The availability of this feature is controlled by a feature flag. For more information, see the history. - -{{< /alert >}} - Diff-based scanning analyzes only the files modified in a merge request, along with their dependent files. This targeted approach reduces scan times and delivers faster feedback during development. To ensure complete coverage, a full scan runs on the default branch after the merge request is merged. -- GitLab