Add MergeRequestsProcessor module for security and incident MR detection
What does this MR do and why?
This MR introduces the MergeRequestsProcessor class that identifies security patches and incident fixes during rollback checks. This is the second component in enhancing rollback safety by detecting critical fixes that would be removed during a rollback.
Note: This MR builds upon the foundation established in !4204 (merged), which provides the core data retrieval classes that this tracker depends on.
Dependencies:
- Builds upon: !4204 (merged) - Provides the core data retrieval classes.
- Requires: !4330 (merged) - This MR must be merged first as it provides the configurable pagination limits needed for the MergeRequestsProcessor to handle large commit ranges.
- Foundation: !4319 (merged) - Provides the underlying configurable pagination functionality.
Content
Key Features:
-
Security Detection: Identifies security fixes through URL patterns
- Checks if URL pattern contains
/gitlab-org/security/
- Checks if URL pattern contains
-
Incident Detection: Identifies incident fixes through MR labels:
-
severity::1,severity::2
-
Core Methods:
-
Constructor:
initialize(deployments_data)- Accepts pre-built deployment data for processing
-
Main Method:
execute- Returns categorized merge requests as{ security_mrs: [], incident_mrs: [] } -
Private Methods:
-
deployments_data- Retrieves both security and canonical deployment data with configurable pagination -
security_merge_request?(mr)- Identifies security MRs by URL pattern -
incident_merge_request?(mr)- Identifies incident MRs by labels -
label?(mr, labels)- Generic label matching with case-insensitive support and nil safety
-
Usage Pattern:
# Build deployment data
deployments_data = {
security: DeploymentsInformation.security_deployments(environment: 'gstg', from_sha: from_sha, to_sha: to_sha),
canonical: DeploymentsInformation.canonical_deployments(environment: 'gstg', from_sha: from_sha, to_sha: to_sha, commit_count: commit_count)
}
# Initialize processor with commit count for proper pagination
processor = MergeRequestsProcessor.new(deployments_data)
result = processor.execute
# Returns: { security_mrs: [mr1, mr2], incident_mrs: [mr3, mr4] }
Testing
The implementation has been successfully tested using real deployment data with large commit ranges, demonstrating both security and incident MR detection capabilities:
Test Scenario: Security and incident detection
-
Current version:
18.3.202507210821-18dd5529921.279410844ce -
Target version:
18.2.202507070007-2f81e6f6496.a9fe83c5dc4 - Commit count: 2,752 commits between versions
- Processing time: ~8.7 minutes (17:50:15 - 17:59:00)
- Deployments processed: 54 total deployments
-
Results:
- Security MRs detected: 6 (including XSS fixes, CI token vulnerabilities, permission enforcement)
- Incident MRs detected: 25 (mix of severity::1 and severity::2 including database issues, performance fixes, and critical reverts)
Test Setup
# 1. Set up version comparison for rollback scenario
current_version = ReleaseTools::ProductVersion.from_package_version('18.3.202507210821-18dd5529921.279410844ce')
target_version = ReleaseTools::ProductVersion.from_package_version('18.2.202507070007-2f81e6f6496.a9fe83c5dc4')
comparison = ReleaseTools::Rollback::Comparison.new(current: current_version, target: target_version, environment: 'gstg')
# 2. Execute comparison to populate commit data
comparison.execute
# 3. Extract commit count and SHAs for processor
commit_count = comparison.instance_variable_get(:@compare).commits.size
to_sha = comparison.current_rails_sha
from_sha = comparison.target_rails_sha
# 4. Build deployment data
deployments_data = {
security: DeploymentsInformation.security_deployments(
environment: 'gstg',
from_sha: from_sha,
to_sha: to_sha
),
canonical: DeploymentsInformation.canonical_deployments(
environment: 'gstg',
from_sha: from_sha,
to_sha: to_sha,
commit_count: commit_count
)
}
# 5. Initialize processor with commit count for proper pagination
processor = ReleaseTools::Rollback::MergeRequestsProcessor.new(deployments_data)
result = processor.execute
Key Validation Points:
-
Security Detection: Successfully identified 6 security MRs through URL pattern matching (
/gitlab-org/security/) -
Incident Detection: Successfully identified 25 incident MRs through severity labels (
severity::1,severity::2) - Overlap Handling: Some MRs appear in both categories (e.g., security MRs with severity labels)
- Large-scale Processing: Handled 2,752 commits across 54 deployments without pagination failures
- Performance: Processed complex rollback scenarios in approximately 9 minutes (normally we won't have to go through such huge commits)
Detection Accuracy:
- Security MRs included critical fixes: XSS vulnerabilities, CI token security issues, permission enforcement
- Incident MRs included high-priority fixes: database issues, performance problems, master branch reverts
- All detected MRs contained appropriate labels and URL patterns as expected
Detection Method: Security MRs are identified by URL patterns rather than labels for improved reliability. Regular MRs follow the pattern gitlab.com/gitlab-org/gitlab/-/merge_requests/X while security MRs follow gitlab.com/gitlab-org/security/gitlab/-/merge_requests/X.
Implementation Note:
This MR implements the simplified MergeRequestsProcessor that accepts pre-built deployments_data, improving testability and following single responsibility principle.
Current implementation:
# Caller builds deployment data with proper pagination
deployments_data = { security: ..., canonical: ... }
processor = MergeRequestsProcessor.new(deployments_data)
result = processor.execute
Related Issue: gitlab-com/gl-infra/delivery#20923 (closed)
Author Check-list
-
Has documentation been updated?