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

Sync updater files to version 0.275.0 #1343

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions update-files.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ $files = @(
"updater/lib/dependabot/environment.rb"
"updater/lib/dependabot/file_fetcher_command.rb"
"updater/lib/dependabot/job.rb"
"updater/lib/dependabot/notices_helpers.rb"
"updater/lib/dependabot/opentelemetry.rb"
"updater/lib/dependabot/pull_request.rb"
"updater/lib/dependabot/sentry.rb"
"updater/lib/dependabot/service.rb"
"updater/lib/dependabot/setup.rb"
Expand Down
42 changes: 40 additions & 2 deletions updater/lib/dependabot/api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,11 @@ def close_pull_request(dependency_names, reason)
sig { params(error_type: T.any(String, Symbol), error_details: T.nilable(T::Hash[T.untyped, T.untyped])).void }
def record_update_job_error(error_type:, error_details:)
::Dependabot::OpenTelemetry.tracer.in_span("record_update_job_error", kind: :internal) do |_span|
::Dependabot::OpenTelemetry.record_update_job_error(job_id: job_id, error_type: error_type,
error_details: error_details)
::Dependabot::OpenTelemetry.record_update_job_error(
job_id: job_id,
error_type: error_type,
error_details: error_details
)
api_url = "#{base_url}/update_jobs/#{job_id}/record_update_job_error"
body = {
data: {
Expand All @@ -123,6 +126,41 @@ def record_update_job_error(error_type:, error_details:)
end
end

sig do
params(
warn_type: T.any(String, Symbol),
warn_title: String,
warn_description: String
).void
end
def record_update_job_warning(warn_type:, warn_title:, warn_description:)
::Dependabot::OpenTelemetry.tracer.in_span("record_update_job_message", kind: :internal) do |_span|
::Dependabot::OpenTelemetry.record_update_job_warning(
job_id: job_id,
warn_type: warn_type,
warn_title: warn_title,
warn_description: warn_description
)
api_url = "#{base_url}/update_jobs/#{job_id}/record_update_job_warning"
body = {
data: {
"warn-type": warn_type,
"warn-title": warn_title,
"warn-description": warn_description
}
}
response = http_client.post(api_url, json: body)
raise ApiError, response.body if response.code >= 400
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
retry_count ||= 0
retry_count += 1
raise if retry_count > 3

sleep(rand(3.0..10.0))
retry
end
end

sig { params(error_type: T.any(Symbol, String), error_details: T.nilable(T::Hash[T.untyped, T.untyped])).void }
def record_update_job_unknown_error(error_type:, error_details:)
error_type = "unknown_error" if error_type.nil?
Expand Down
26 changes: 18 additions & 8 deletions updater/lib/dependabot/dependency_change.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,27 @@ def initialize(deps_no_previous_version:, deps_no_change:)
sig { returns(T.nilable(Dependabot::DependencyGroup)) }
attr_reader :dependency_group

sig { returns(T::Array[Dependabot::Notice]) }
attr_reader :notices

sig do
params(
job: Dependabot::Job,
updated_dependencies: T::Array[Dependabot::Dependency],
updated_dependency_files: T::Array[Dependabot::DependencyFile],
dependency_group: T.nilable(Dependabot::DependencyGroup)
dependency_group: T.nilable(Dependabot::DependencyGroup),
notices: T::Array[Dependabot::Notice]
).void
end
def initialize(job:, updated_dependencies:, updated_dependency_files:, dependency_group: nil)
def initialize(job:, updated_dependencies:, updated_dependency_files:, dependency_group: nil, notices: [])
@job = job
@updated_dependencies = updated_dependencies
@updated_dependency_files = updated_dependency_files
@dependency_group = dependency_group

@pr_message = T.let(nil, T.nilable(Dependabot::PullRequestCreator::Message))
ensure_dependencies_have_directories
@notices = notices
end

sig { returns(Dependabot::PullRequestCreator::Message) }
Expand Down Expand Up @@ -90,7 +95,8 @@ def pr_message
dependency_group: dependency_group,
pr_message_max_length: pr_message_max_length,
pr_message_encoding: pr_message_encoding,
ignore_conditions: job.ignore_conditions
ignore_conditions: job.ignore_conditions,
notices: notices
).message

@pr_message = message
Expand Down Expand Up @@ -135,9 +141,11 @@ def merge_changes!(dependency_changes)
dependency_changes.each do |dependency_change|
updated_dependencies.concat(dependency_change.updated_dependencies)
updated_dependency_files.concat(dependency_change.updated_dependency_files)
notices.concat(dependency_change.notices)
end
updated_dependencies.compact!
updated_dependency_files.compact!
notices.compact!
end

sig { returns(T::Boolean) }
Expand Down Expand Up @@ -171,11 +179,7 @@ def matches_existing_pr?
Set.new(pr["dependencies"]) == updated_dependencies_set(should_consider_directory: directories_in_use)
end
else
job.existing_pull_requests.any? do |pr|
directories_in_use = pr.all? { |dep| dep["directory"] }

Set.new(pr) == updated_dependencies_set(should_consider_directory: directories_in_use)
end
job.existing_pull_requests.any?(new_pr)
end
end

Expand All @@ -197,6 +201,12 @@ def updated_dependencies_set(should_consider_directory:)
)
end

sig { returns(PullRequest) }
def new_pr
@new_pr ||= T.let(PullRequest.create_from_updated_dependencies(updated_dependencies),
T.nilable(Dependabot::PullRequest))
end

sig { returns(T::Array[Dependabot::Dependency]) }
def ensure_dependencies_have_directories
updated_dependencies.each do |dep|
Expand Down
20 changes: 14 additions & 6 deletions updater/lib/dependabot/dependency_change_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ class DependencyChangeBuilder
job: Dependabot::Job,
dependency_files: T::Array[Dependabot::DependencyFile],
updated_dependencies: T::Array[Dependabot::Dependency],
change_source: T.any(Dependabot::Dependency, Dependabot::DependencyGroup)
change_source: T.any(Dependabot::Dependency, Dependabot::DependencyGroup),
notices: T::Array[Dependabot::Notice]
).returns(Dependabot::DependencyChange)
end
def self.create_from(job:, dependency_files:, updated_dependencies:, change_source:)
def self.create_from(job:, dependency_files:, updated_dependencies:, change_source:, notices: [])
new(
job: job,
dependency_files: dependency_files,
updated_dependencies: updated_dependencies,
change_source: change_source
change_source: change_source,
notices: notices
).run
end

Expand All @@ -47,10 +49,11 @@ def self.create_from(job:, dependency_files:, updated_dependencies:, change_sour
job: Dependabot::Job,
dependency_files: T::Array[Dependabot::DependencyFile],
updated_dependencies: T::Array[Dependabot::Dependency],
change_source: T.any(Dependabot::Dependency, Dependabot::DependencyGroup)
change_source: T.any(Dependabot::Dependency, Dependabot::DependencyGroup),
notices: T::Array[Dependabot::Notice]
).void
end
def initialize(job:, dependency_files:, updated_dependencies:, change_source:)
def initialize(job:, dependency_files:, updated_dependencies:, change_source:, notices: [])
@job = job

dir = Pathname.new(job.source.directory).cleanpath
Expand All @@ -61,6 +64,7 @@ def initialize(job:, dependency_files:, updated_dependencies:, change_source:)

@updated_dependencies = updated_dependencies
@change_source = change_source
@notices = notices
end

sig { returns(Dependabot::DependencyChange) }
Expand All @@ -84,7 +88,8 @@ def run
job: job,
updated_dependencies: updated_deps,
updated_dependency_files: updated_files,
dependency_group: source_dependency_group
dependency_group: source_dependency_group,
notices: notices
)
end

Expand All @@ -102,6 +107,9 @@ def run
sig { returns(T.any(Dependabot::Dependency, Dependabot::DependencyGroup)) }
attr_reader :change_source

sig { returns(T::Array[Dependabot::Notice]) }
attr_reader :notices

sig { returns(T.nilable(String)) }
def source_dependency_name
return nil unless change_source.is_a? Dependabot::Dependency
Expand Down
35 changes: 34 additions & 1 deletion updater/lib/dependabot/dependency_snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "sorbet-runtime"

require "dependabot/file_parsers"
require "dependabot/notices_helpers"

# This class describes the dependencies obtained from a project at a specific commit SHA
# including both the Dependabot::DependencyFile objects at that reference as well as
Expand All @@ -15,6 +16,7 @@
module Dependabot
class DependencySnapshot
extend T::Sig
include NoticesHelpers

sig do
params(job: Dependabot::Job, job_definition: T::Hash[String, T.untyped]).returns(Dependabot::DependencySnapshot)
Expand Down Expand Up @@ -65,6 +67,18 @@ def dependencies
T.must(@dependencies[@current_directory])
end

sig { returns(T.nilable(Dependabot::PackageManagerBase)) }
def package_manager
@package_manager[@current_directory]
end

sig { returns(T::Array[Dependabot::Notice]) }
def notices
# The notices array in dependency snapshot stay immutable,
# so we can return a copy
@notices[@current_directory]&.dup || []
end

# Returns the subset of all project dependencies which are permitted
# by the project configuration.
sig { returns(T::Array[Dependabot::Dependency]) }
Expand Down Expand Up @@ -167,6 +181,9 @@ def initialize(job:, base_commit_sha:, dependency_files:) # rubocop:disable Metr
@current_directory = T.let("", String)

@dependencies = T.let({}, T::Hash[String, T::Array[Dependabot::Dependency]])
@package_manager = T.let({}, T::Hash[String, T.nilable(Dependabot::PackageManagerBase)])
@notices = T.let({}, T::Hash[String, T::Array[Dependabot::Notice]])

directories.each do |dir|
@current_directory = dir
@dependencies[dir] = parse_files!
Expand Down Expand Up @@ -216,14 +233,30 @@ def parse_files!
def dependency_file_parser
assert_current_directory_set!
job.source.directory = @current_directory
Dependabot::FileParsers.for_package_manager(job.package_manager).new(
parser = Dependabot::FileParsers.for_package_manager(job.package_manager).new(
dependency_files: dependency_files,
repo_contents_path: job.repo_contents_path,
source: job.source,
credentials: job.credentials,
reject_external_code: job.reject_external_code?,
options: job.experiments
)
# Add 'package_manager' to the depedency_snapshopt to use it in operations'
package_manager_for_current_directory = parser.package_manager
@package_manager[@current_directory] = package_manager_for_current_directory

# Log deprecation notices if the package manager is deprecated
# and add them to the notices array
notices_for_current_directory = []

# add deprecation notices for the package manager
add_deprecation_notice(
notices: notices_for_current_directory,
package_manager: package_manager_for_current_directory
)
@notices[@current_directory] = notices_for_current_directory

parser
end

sig { params(group: Dependabot::DependencyGroup).returns(T::Array[T::Hash[String, String]]) }
Expand Down
6 changes: 3 additions & 3 deletions updater/lib/dependabot/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require "dependabot/experiments"
require "dependabot/requirements_update_strategy"
require "dependabot/source"
require "dependabot/pull_request"

# Describes a single Dependabot workload within the GitHub-integrated Service
#
Expand Down Expand Up @@ -60,7 +61,7 @@ class Job
sig { returns(T.nilable(T::Array[String])) }
attr_reader :dependencies

sig { returns(T::Array[T::Array[T::Hash[String, String]]]) }
sig { returns(T::Array[PullRequest]) }
attr_reader :existing_pull_requests

sig { returns(T::Array[T::Hash[String, T.untyped]]) }
Expand Down Expand Up @@ -139,8 +140,7 @@ def initialize(attributes) # rubocop:disable Metrics/AbcSize
end,
T::Array[Dependabot::Credential])
@dependencies = T.let(attributes.fetch(:dependencies), T.nilable(T::Array[T.untyped]))
@existing_pull_requests = T.let(attributes.fetch(:existing_pull_requests),
T::Array[T::Array[T::Hash[String, String]]])
@existing_pull_requests = T.let(PullRequest.create_from_job_definition(attributes), T::Array[PullRequest])
# TODO: Make this hash required
#
# We will need to do a pass updating the CLI and smoke tests before this is possible,
Expand Down
75 changes: 75 additions & 0 deletions updater/lib/dependabot/notices_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# typed: strong
# frozen_string_literal: true

require "sorbet-runtime"
require "dependabot/notices"
require "dependabot/package_manager"

# This module extracts helpers for notice generations that can be used
# for showing notices in logs, pr messages and alert ui page.
module Dependabot
module NoticesHelpers
extend T::Sig
extend T::Helpers

abstract!

# Add a deprecation notice to the notice list if the package manager is deprecated
# if the package manager is deprecated.
# notices << deprecation_notices if deprecation_notices
sig do
params(
notices: T::Array[Dependabot::Notice],
package_manager: T.nilable(PackageManagerBase)
)
.void
end
def add_deprecation_notice(notices:, package_manager:)
# Create a deprecation notice if the package manager is deprecated
deprecation_notice = create_deprecation_notice(package_manager)

return unless deprecation_notice

log_notice(deprecation_notice)

notices << deprecation_notice
end

sig { params(notice: Dependabot::Notice).void }
def log_notice(notice)
logger = Dependabot.logger
# Log each non-empty line of the deprecation notice description
notice.description.each_line do |line|
line = line.strip
next if line.empty?

case notice.mode
when Dependabot::Notice::NoticeMode::INFO
logger.info(line)
when Dependabot::Notice::NoticeMode::WARN
logger.warn(line)
when Dependabot::Notice::NoticeMode::ERROR
logger.error(line)
else
logger.info(line)
end
end
end

private

sig { params(package_manager: T.nilable(PackageManagerBase)).returns(T.nilable(Dependabot::Notice)) }
def create_deprecation_notice(package_manager)
# Feature flag check if deprecation notice should be added to notices.
return unless Dependabot::Experiments.enabled?(:add_deprecation_warn_to_pr_message)

return unless package_manager

return unless package_manager.is_a?(PackageManagerBase)

Notice.generate_pm_deprecation_notice(
package_manager
)
end
end
end
Loading