lib/release_tools/security/target_issues_processor.rb (93 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module Security
class TargetIssuesProcessor
include ::SemanticLogger::Loggable
TRACKING_ISSUE_PROJECT = 'gitlab-org/gitlab'
def execute
if security_target_issues.empty?
logger.info("No target issues found, skipping.")
return
end
logger.info("#{security_target_issues.count} target issues found. They will be evaluated and considered for linking to the patch release tracking issue: #{security_release_tracking_issue.web_url}.")
security_target_issues.each do |target_issue|
case [target_issue.ready_to_be_processed?, linked_to_security_tracking_issue?(target_issue)]
when [true, true]
logger.info("#{target_issue.web_url} is already linked to the patch release tracking issue and still ready to be processed.")
nil
when [false, false]
logger.info("#{target_issue.web_url} is not ready to be processed or linked to the patch release tracking issue.")
TargetIssueNotifier.notify(:not_ready, target_issue)
remove_security_target_label(target_issue)
when [true, false]
logger.info("#{target_issue.web_url} is ready to be processed and will be linked to the patch release tracking issue.")
link(target_issue)
TargetIssueNotifier.notify(:linked, target_issue)
SecurityReleaseTrackingIssueNotifier.notify(target_issue)
ImplementationIssueProcessor.new(target_issue).execute
when [false, true]
logger.info("#{target_issue.web_url} will be unlinked from the patch release tracking issue as it is no longer ready to be processed.")
unlink(target_issue)
TargetIssueNotifier.notify(:unlinked, target_issue)
remove_security_target_label(target_issue)
end
end
update_security_issue_table
end
private
def link(issue)
return if SharedStatus.dry_run?
Retriable.with_context(:api) do
client.link_issues(security_release_tracking_issue, issue)
end
end
def unlink(issue)
return if SharedStatus.dry_run?
Retriable.with_context(:api) do
client.delete_issue_link(
security_release_tracking_issue,
link_id_for(issue)
)
end
end
def link_id_for(issue)
tracking_issue_links.find { |link| link.id == issue.issue.id }.issue_link_id
end
def linked_to_security_tracking_issue?(issue)
linked_security_issues.any? do |linked_issue|
linked_issue.iid == issue.iid && linked_issue.project_id == issue.project_id
end
end
def tracking_issue_links
@tracking_issue_links ||= Retriable.with_context(:api) do
client.issue_links(TRACKING_ISSUE_PROJECT, security_release_tracking_issue.iid)
end
end
def security_release_tracking_issue
@security_release_tracking_issue ||= ReleaseTools::Issue.new(issue_crawler.security_tracking_issue)
end
def linked_security_issues
@linked_security_issues ||= issue_crawler.related_security_issues
end
def security_target_issues
@security_target_issues ||= issue_crawler.evaluable_security_issues
end
def issue_crawler
@issue_crawler ||= Security::IssueCrawler.new
end
def remove_security_target_label(issue)
return if SharedStatus.dry_run?
issue_data = issue.issue
issue_data.labels.delete('security-target')
Retriable.with_context(:api) do
client.update_issue(issue_data, issue.project)
end
end
def update_security_issue_table
ReleaseTools::Security::IssueTable::Service.new(client).execute
end
def client
ReleaseTools::GitlabClient
end
end
end
end