From 09fcc096e84dfff0a52740eaaed5bca67aa7cf6c Mon Sep 17 00:00:00 2001 From: Rhys Koedijk Date: Wed, 23 Oct 2024 23:15:53 +1300 Subject: [PATCH 1/2] Add `job.update_dependency_list_only`; skips `Dependabot::Updater.run()` when set true --- updater/lib/dependabot/job.rb | 7 ++ .../lib/dependabot/update_files_command.rb | 5 ++ updater/spec/dependabot/job_spec.rb | 14 ++++ .../dependabot/update_files_command_spec.rb | 31 ++++++++ .../list_dependencies_only_output.json | 71 +++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json diff --git a/updater/lib/dependabot/job.rb b/updater/lib/dependabot/job.rb index 75f052e905..8c85cd1e7c 100644 --- a/updater/lib/dependabot/job.rb +++ b/updater/lib/dependabot/job.rb @@ -44,6 +44,7 @@ class Job security_advisories security_updates_only source + update_dependency_list_only update_subdependencies updating_a_pull_request vendor_dependencies @@ -164,6 +165,7 @@ def initialize(attributes) # rubocop:disable Metrics/AbcSize @source = T.let(build_source(attributes.fetch(:source)), Dependabot::Source) @token = T.let(attributes.fetch(:token, nil), T.nilable(String)) @update_subdependencies = T.let(attributes.fetch(:update_subdependencies), T::Boolean) + @update_dependency_list_only = T.let(attributes.fetch(:update_dependency_list_only, false), T::Boolean) @updating_a_pull_request = T.let(attributes.fetch(:updating_a_pull_request), T::Boolean) @vendor_dependencies = T.let(attributes.fetch(:vendor_dependencies, false), T::Boolean) # TODO: Make this hash required @@ -216,6 +218,11 @@ def update_subdependencies? @update_subdependencies end + sig { returns(T::Boolean) } + def update_dependency_list_only? + @update_dependency_list_only + end + sig { returns(T::Boolean) } def security_updates_only? @security_updates_only diff --git a/updater/lib/dependabot/update_files_command.rb b/updater/lib/dependabot/update_files_command.rb index d04b4abc8d..6d887e956d 100644 --- a/updater/lib/dependabot/update_files_command.rb +++ b/updater/lib/dependabot/update_files_command.rb @@ -32,6 +32,11 @@ def perform_job # Update the service's metadata about this project service.update_dependency_list(dependency_snapshot: dependency_snapshot) + if job.update_dependency_list_only? + # If the job is to only discover dependencies, there's nothing more to do, + # skip the updater, mark the job as processed and stop. + return service.mark_job_as_processed(dependency_snapshot.base_commit_sha) + end # TODO: Pull fatal error handling handling up into this class # diff --git a/updater/spec/dependabot/job_spec.rb b/updater/spec/dependabot/job_spec.rb index 6e1277ab79..b3a1797773 100644 --- a/updater/spec/dependabot/job_spec.rb +++ b/updater/spec/dependabot/job_spec.rb @@ -39,6 +39,7 @@ lockfile_only: lockfile_only, requirements_update_strategy: nil, update_subdependencies: false, + update_dependency_list_only: update_dependency_list_only, updating_a_pull_request: false, vendor_dependencies: vendor_dependencies, experiments: experiments, @@ -56,6 +57,7 @@ let(:package_manager) { "bundler" } let(:lockfile_only) { false } let(:security_updates_only) { false } + let(:update_dependency_list_only) { false } let(:allowed_updates) do [ { @@ -411,6 +413,18 @@ end end + describe "#update_dependency_list_only?" do + subject { job.update_dependency_list_only? } + + it { is_expected.to be(false) } + + context "with update dependency list only allowed" do + let(:update_dependency_list_only) { true } + + it { is_expected.to be(true) } + end + end + describe "#experiments" do it "handles nil values" do expect(job.experiments).to eq({}) diff --git a/updater/spec/dependabot/update_files_command_spec.rb b/updater/spec/dependabot/update_files_command_spec.rb index db17767e0f..ac75481d47 100644 --- a/updater/spec/dependabot/update_files_command_spec.rb +++ b/updater/spec/dependabot/update_files_command_spec.rb @@ -92,6 +92,37 @@ perform_job end end + + context "with update_dependency_list_only" do + let(:snapshot) do + instance_double(Dependabot::DependencySnapshot, + base_commit_sha: "1c6331732c41e4557a16dacb82534f1d1c831848") + end + let(:repo_contents_path) { "repo/path" } + + let(:job_definition) do + JSON.parse(fixture("file_fetcher_output/update_dependency_list_only_output.json")) + end + + before do + allow(Dependabot::Environment).to receive(:repo_contents_path).and_return(repo_contents_path) + allow(Dependabot::DependencySnapshot).to receive(:create_from_job_definition).and_return(snapshot) + end + + it "sends dependency metadata to the service" do + expect(service).to receive(:update_dependency_list) + .with(dependency_snapshot: an_instance_of(Dependabot::DependencySnapshot)) + + perform_job + end + + it "does not delegate to Dependabot::Updater" do + expect(Dependabot::Updater) + .not_to receive(:new) + + perform_job + end + end end describe "#perform_job when there is an error parsing the dependency files" do diff --git a/updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json b/updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json new file mode 100644 index 0000000000..dc290f9313 --- /dev/null +++ b/updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json @@ -0,0 +1,71 @@ +{ + "job": { + "allowed-updates": [ + { + "dependency-type": "direct", + "update-type": "all" + }, + { + "dependency-type": "indirect", + "update-type": "security" + } + ], + "credentials": [ + { + "type": "git_source", + "host": "github.com", + "username": "x-access-token", + "password": "v1.exampletokenfromgithubinityesitisforsure" + }, + { + "type": "rubygems_index", + "host": "my.rubygems-host.org", + "token": "secret" + } + ], + "credentials-metadata": [ + { + "type": "git_source", + "host": "github.com" + }, + { + "type": "rubygems_index", + "host": "my.rubygems-host.org" + } + ], + "dependencies": null, + "directory": "/", + "existing-pull-requests": [], + "ignore-conditions": [], + "security-advisories": [], + "package_manager": "bundler", + "repo-name": "dependabot-fixtures/dependabot-test-ruby-package", + "source": { + "provider": "github", + "repo": "dependabot-fixtures/dependabot-test-ruby-package", + "directory": "/", + "branch": null, + "hostname": "github.com", + "api-endpoint": "https://api.github.com/" + }, + "lockfile-only": false, + "requirements-update-strategy": null, + "update-subdependencies": false, + "update_dependency_list_only": true, + "updating-a-pull-request": false, + "vendor-dependencies": true, + "security-updates-only": false + }, + "base64_dependency_files":[ + { + "name":"dependabot-test-ruby-package.gemspec", + "content":"IyBmcm96ZW5fc3RyaW5nX2xpdGVyYWw6IHRydWUKCkdlbTo6U3BlY2lmaWNh\ndGlvbi5uZXcgZG8gfHNwZWN8CiAgc3BlYy5uYW1lICAgICA9ICdkZXBlbmRh\nYm90LXRlc3QtcnVieS1wYWNrYWdlJwogIHNwZWMudmVyc2lvbiAgPSAnMS4w\nLjEnCiAgc3BlYy5zdW1tYXJ5ICA9ICdBIGR1bW15IHBhY2thZ2UgZm9yIHRl\nc3RpbmcgRGVwZW5kYWJvdCcKICBzcGVjLmF1dGhvciAgID0gJ0RlcGVuZGFi\nb3QnCiAgc3BlYy5saWNlbnNlICA9ICdNSVQnCiAgc3BlYy5lbWFpbCAgICA9\nICdub3JlcGx5QGdpdGh1Yi5jb20nCiAgc3BlYy5ob21lcGFnZSA9ICdodHRw\nOi8vZ2l0aHViLmNvbS9kZXBlbmRhYm90LWZpeHR1cmVzL2RlcGVuZGFib3Qt\ndGVzdC1ydWJ5LXBhY2thZ2UnCmVuZAo=\n", + "directory":"/", + "type":"file", + "support_file":false, + "content_encoding":"utf-8", + "deleted":false + } + ], + "base_commit_sha":"1c6331732c41e4557a16dacb82534f1d1c831848" +} From d0f5f5a1cdcf4903334cbb05fa7a311041a6b50f Mon Sep 17 00:00:00 2001 From: Rhys Koedijk Date: Thu, 24 Oct 2024 00:35:13 +1300 Subject: [PATCH 2/2] Fix tests --- .../dependabot/update_files_command_spec.rb | 2 +- ...> update_dependency_list_only_output.json} | 26 +++---------------- 2 files changed, 5 insertions(+), 23 deletions(-) rename updater/spec/fixtures/file_fetcher_output/{list_dependencies_only_output.json => update_dependency_list_only_output.json} (74%) diff --git a/updater/spec/dependabot/update_files_command_spec.rb b/updater/spec/dependabot/update_files_command_spec.rb index ac75481d47..079de15626 100644 --- a/updater/spec/dependabot/update_files_command_spec.rb +++ b/updater/spec/dependabot/update_files_command_spec.rb @@ -111,7 +111,7 @@ it "sends dependency metadata to the service" do expect(service).to receive(:update_dependency_list) - .with(dependency_snapshot: an_instance_of(Dependabot::DependencySnapshot)) + .with(dependency_snapshot: snapshot) perform_job end diff --git a/updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json b/updater/spec/fixtures/file_fetcher_output/update_dependency_list_only_output.json similarity index 74% rename from updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json rename to updater/spec/fixtures/file_fetcher_output/update_dependency_list_only_output.json index dc290f9313..c2cb0f25a4 100644 --- a/updater/spec/fixtures/file_fetcher_output/list_dependencies_only_output.json +++ b/updater/spec/fixtures/file_fetcher_output/update_dependency_list_only_output.json @@ -1,36 +1,18 @@ { "job": { - "allowed-updates": [ - { - "dependency-type": "direct", - "update-type": "all" - }, - { - "dependency-type": "indirect", - "update-type": "security" - } - ], + "allowed-updates": [], "credentials": [ { "type": "git_source", "host": "github.com", "username": "x-access-token", "password": "v1.exampletokenfromgithubinityesitisforsure" - }, - { - "type": "rubygems_index", - "host": "my.rubygems-host.org", - "token": "secret" } ], "credentials-metadata": [ { "type": "git_source", "host": "github.com" - }, - { - "type": "rubygems_index", - "host": "my.rubygems-host.org" } ], "dependencies": null, @@ -39,10 +21,10 @@ "ignore-conditions": [], "security-advisories": [], "package_manager": "bundler", - "repo-name": "dependabot-fixtures/dependabot-test-ruby-package", + "repo-name": "dependabot-fixtures/dependabot-test-discovery", "source": { "provider": "github", - "repo": "dependabot-fixtures/dependabot-test-ruby-package", + "repo": "dependabot-fixtures/dependabot-test-discovery", "directory": "/", "branch": null, "hostname": "github.com", @@ -58,7 +40,7 @@ }, "base64_dependency_files":[ { - "name":"dependabot-test-ruby-package.gemspec", + "name":"dependabot-test-discovery.gemspec", "content":"IyBmcm96ZW5fc3RyaW5nX2xpdGVyYWw6IHRydWUKCkdlbTo6U3BlY2lmaWNh\ndGlvbi5uZXcgZG8gfHNwZWN8CiAgc3BlYy5uYW1lICAgICA9ICdkZXBlbmRh\nYm90LXRlc3QtcnVieS1wYWNrYWdlJwogIHNwZWMudmVyc2lvbiAgPSAnMS4w\nLjEnCiAgc3BlYy5zdW1tYXJ5ICA9ICdBIGR1bW15IHBhY2thZ2UgZm9yIHRl\nc3RpbmcgRGVwZW5kYWJvdCcKICBzcGVjLmF1dGhvciAgID0gJ0RlcGVuZGFi\nb3QnCiAgc3BlYy5saWNlbnNlICA9ICdNSVQnCiAgc3BlYy5lbWFpbCAgICA9\nICdub3JlcGx5QGdpdGh1Yi5jb20nCiAgc3BlYy5ob21lcGFnZSA9ICdodHRw\nOi8vZ2l0aHViLmNvbS9kZXBlbmRhYm90LWZpeHR1cmVzL2RlcGVuZGFib3Qt\ndGVzdC1ydWJ5LXBhY2thZ2UnCmVuZAo=\n", "directory":"/", "type":"file",