Skip to content

Commit

Permalink
Show ignore conditions in a request body (dependabot#7654)
Browse files Browse the repository at this point in the history
* Added ignore condition to message builder class to show the ignore conditions of the dependencies in the PR body.
  • Loading branch information
honeyankit committed Jul 31, 2023
1 parent 1294daf commit 45c1132
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 9 deletions.
65 changes: 62 additions & 3 deletions common/lib/dependabot/pull_request_creator/message_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ class MessageBuilder
:pr_message_header, :pr_message_footer,
:commit_message_options, :vulnerabilities_fixed,
:github_redirection_service, :dependency_group, :pr_message_max_length,
:pr_message_encoding
:pr_message_encoding, :ignore_conditions

TRUNCATED_MSG = "...\n\n_Description has been truncated_"

def initialize(source:, dependencies:, files:, credentials:,
pr_message_header: nil, pr_message_footer: nil,
commit_message_options: {}, vulnerabilities_fixed: {},
github_redirection_service: DEFAULT_GITHUB_REDIRECTION_SERVICE,
dependency_group: nil, pr_message_max_length: nil, pr_message_encoding: nil)
dependency_group: nil, pr_message_max_length: nil, pr_message_encoding: nil, ignore_conditions: [])
@dependencies = dependencies
@files = files
@source = source
Expand All @@ -44,6 +44,7 @@ def initialize(source:, dependencies:, files:, credentials:,
@dependency_group = dependency_group
@pr_message_max_length = pr_message_max_length
@pr_message_encoding = pr_message_encoding
@ignore_conditions = ignore_conditions
end

attr_writer :pr_message_max_length
Expand All @@ -57,13 +58,31 @@ def pr_name
end

def pr_message
msg = "#{suffixed_pr_message_header}#{commit_message_intro}#{metadata_cascades}#{prefixed_pr_message_footer}"
# TODO: Remove unignore_commands? feature flag once we are confident
# that it is working as expected
msg = if unignore_commands?
"#{suffixed_pr_message_header}" \
"#{commit_message_intro}" \
"#{metadata_cascades}" \
"#{ignore_conditions_table}" \
"#{prefixed_pr_message_footer}"
else
"#{suffixed_pr_message_header}" \
"#{commit_message_intro}" \
"#{metadata_cascades}" \
"#{prefixed_pr_message_footer}"
end

truncate_pr_message(msg)
rescue StandardError => e
Dependabot.logger.error("Error while generating PR message: #{e.message}")
suffixed_pr_message_header + prefixed_pr_message_footer
end

def unignore_commands?
Experiments.enabled?(:unignore_commands)
end

# Truncate PR message as determined by the pr_message_max_length and pr_message_encoding instance variables
# The encoding is used when calculating length, all messages are returned as ruby UTF_8 encoded string
def truncate_pr_message(msg)
Expand Down Expand Up @@ -504,6 +523,46 @@ def metadata_cascades_for_dep(dependency)
).to_s
end

def ignore_conditions_table
# Return an empty string if ignore_conditions is empty
return "" if @ignore_conditions.empty?

# Filter out the conditions where from_config_file is false and dependency is in @dependencies
valid_ignore_conditions = @ignore_conditions.select do |ic|
!ic[:from_config_file] && dependencies.any? { |dep| dep.name == ic[:dependency_name] }
end

# Return an empty string if no valid ignore conditions after filtering
return "" if valid_ignore_conditions.empty?

# Sort them by updated_at (or created_at if updated_at is nil), taking the latest 20
sorted_ignore_conditions = valid_ignore_conditions.sort_by { |ic| ic[:updated_at] || ic[:created_at] }.last(20)

# Map each condition to a row string
table_rows = sorted_ignore_conditions.map do |ic|
"| #{ic[:dependency_name]} | [#{ic[:version_requirement]}] |"
end

summary = "Most Recent Ignore Conditions Applied to This Pull Request"
build_table(summary, table_rows)
end

def build_table(summary, rows)
table_header = "| Dependency Name | Ignore Conditions |"
table_divider = "| --- | --- |"
table_body = rows.join("\n")
body = "\n#{[table_header, table_divider, table_body].join("\n")}\n"

if %w(azure bitbucket codecommit).include?(source.provider)
"\n##{summary}\n\n#{body}"
else
# Build the collapsible section
msg = "<details>\n<summary>#{summary}</summary>\n\n" \
"#{[table_header, table_divider, table_body].join("\n")}\n</details>"
"\n#{msg}\n"
end
end

def changelog_url(dependency)
metadata_finder(dependency).changelog_url
end
Expand Down
Loading

0 comments on commit 45c1132

Please sign in to comment.