Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show ignore conditions in a request body #7654

Merged
merged 9 commits into from
Jul 31, 2023
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] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jurre: We also need to modify this function. My earlier assumption was wrong about the attributes of ignore_conditions, We have to replace from_config_file with source

Copy link
Contributor Author

@honeyankit honeyankit Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source will contain string with info whether it was invoked via config file or via @dependabot ignore command. It will have to match the ignore command here.

Copy link
Contributor Author

@honeyankit honeyankit Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have implemented @dependbot show <dep -name> ignore conditions which is something similar to this. You can get context from that and modify the ignore_conditions_table method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the field created_at and updated_at in update job on this PR: https://github.com/github/dependabot-api/pull/4319

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
Loading