dependabot-nuget 0.396.0 → 0.398.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c8d2c369fea3791d04cedce39111d000bc6d0052f48a6df16116b9c811b1f4c
4
- data.tar.gz: '08c4cec0fef16173ca1d28eb497127064b4ecc5daeb2a2d84f3ab8ee72cc6852'
3
+ metadata.gz: 3df370cfa9828e959bf529b8a391e336d368cc0c87aab8393665a554fa5e4b48
4
+ data.tar.gz: d3e16c0df803153b916f442af358e42573b89cefff989e5da52524dad83affe4
5
5
  SHA512:
6
- metadata.gz: 220207aba4f007a902a08030847f865afad86e57de5dfcbfe81d9a6ef5bdaa5284ace3c4259f122778a69ad6401e42645858dd09516edf75055b14c48f3c4f59
7
- data.tar.gz: c309c50fd55d24516bca819ff47c5b3981b867fe7d15a5990505c2ad0e527e999d0aa988fcb81c359e98291eb8da983edae2a7d803e7677530bf0dfef8fc85da
6
+ metadata.gz: 0464c48c69bf48bbc512a314c8600b50822defbe997f387ab8f29f54bd9308b8598e0c31d84995c98c266740bb90be3b2e612f0ed69a5d52132f7b57c4c481fd
7
+ data.tar.gz: c7efa1a36e6b822254fa4caf97e4c9b891042df0c866c7e34c9e566be1a64e0f4b3635cf6169d0b0d0b7b3e66ad9331fd0076d8c8296bea347cd57c3569a27f1
@@ -16,9 +16,9 @@
16
16
  <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MSBuildPackageVersion)" />
17
17
  <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.9.0" />
18
18
  <PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
19
- <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.11" />
19
+ <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.12" />
20
20
  <PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="10.0.11" />
21
- <PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.11" />
21
+ <PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.12" />
22
22
  <PackageVersion Include="Microsoft.NET.StringTools" Version="$(MSBuildPackageVersion)" />
23
23
  <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
24
24
  <PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.14.2075" />
@@ -285,7 +285,12 @@ public partial class DiscoveryWorker : IDiscoveryWorker
285
285
  {
286
286
  HashSet<string> expandedProjects = new(PathComparer.Instance);
287
287
  HashSet<string> seenProjects = new(PathComparer.Instance);
288
- Stack<string> filesToExpand = new(entryPoints);
288
+ Stack<string> filesToExpand = new();
289
+ foreach (string entryPoint in entryPoints)
290
+ {
291
+ PushExistingPaths(filesToExpand, entryPoint, repoRootPath);
292
+ }
293
+
289
294
  while (filesToExpand.Count > 0)
290
295
  {
291
296
  string candidateEntryPoint = filesToExpand.Pop();
@@ -299,7 +304,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
299
304
  foreach (ProjectInSolution project in solution.ProjectsInOrder)
300
305
  {
301
306
  logger.Info($" Expanded project: {project.AbsolutePath}");
302
- filesToExpand.Push(project.AbsolutePath);
307
+ PushExistingPaths(filesToExpand, project.AbsolutePath, repoRootPath);
303
308
  }
304
309
  }
305
310
  else if (extension == ".slnx")
@@ -321,7 +326,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
321
326
  {
322
327
  string projectPath = Path.Combine(solutionPath, project.FilePath);
323
328
  logger.Info($" Expanded project: {projectPath}");
324
- filesToExpand.Push(projectPath);
329
+ PushExistingPaths(filesToExpand, projectPath, repoRootPath);
325
330
  }
326
331
  }
327
332
  else if (extension == ".proj")
@@ -331,7 +336,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
331
336
  foreach (var foundProject in foundProjects)
332
337
  {
333
338
  logger.Info($" Expanded project: {foundProject}");
334
- filesToExpand.Push(foundProject);
339
+ PushExistingPaths(filesToExpand, foundProject, repoRootPath);
335
340
  }
336
341
  }
337
342
 
@@ -372,6 +377,18 @@ public partial class DiscoveryWorker : IDiscoveryWorker
372
377
  return result;
373
378
  }
374
379
 
380
+ private static void PushExistingPaths(Stack<string> filesToExpand, string candidatePath, string repoRootPath)
381
+ {
382
+ var resolvedPaths = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(candidatePath, repoRootPath);
383
+ foreach (string resolvedPath in resolvedPaths ?? [])
384
+ {
385
+ if (File.Exists(resolvedPath))
386
+ {
387
+ filesToExpand.Push(resolvedPath);
388
+ }
389
+ }
390
+ }
391
+
375
392
  private static IEnumerable<string> ExpandItemGroupFilesFromProject(string projectPath, params string[] itemTypes)
376
393
  {
377
394
  if (!File.Exists(projectPath))
@@ -41,6 +41,8 @@ public abstract record JobErrorBase : MessageBase
41
41
  return new PrivateSourceBadResponse([badResponse.Uri], badResponse.Message);
42
42
  case DependencyNotFoundException dependencyNotFound:
43
43
  return new DependencyNotFound(string.Join(", ", dependencyNotFound.Dependencies));
44
+ case HttpApiException:
45
+ return new UnknownError(ex, jobId);
44
46
  case HttpRequestException httpRequest:
45
47
  if (httpRequest.StatusCode is null)
46
48
  {
@@ -0,0 +1,24 @@
1
+ using System.Net;
2
+
3
+ namespace NuGetUpdater.Core.Run;
4
+
5
+ public sealed class HttpApiException : HttpRequestException
6
+ {
7
+ public string Method { get; }
8
+ public string Endpoint { get; }
9
+ public string? ResponseContent { get; }
10
+
11
+ public HttpApiException(string method, string endpoint, HttpStatusCode statusCode, string? responseContent)
12
+ : base(BuildMessage(method, endpoint, statusCode, responseContent), inner: null, statusCode: statusCode)
13
+ {
14
+ Method = method;
15
+ Endpoint = endpoint;
16
+ ResponseContent = string.IsNullOrEmpty(responseContent) ? null : responseContent;
17
+ }
18
+
19
+ private static string BuildMessage(string method, string endpoint, HttpStatusCode statusCode, string? responseContent)
20
+ {
21
+ var message = $"{method} {endpoint} failed with {(int)statusCode} ({statusCode})";
22
+ return string.IsNullOrEmpty(responseContent) ? message : $"{message}: {responseContent}";
23
+ }
24
+ }
@@ -46,12 +46,7 @@ public class HttpApiHandler : IApiHandler, IApiRetryDelayProvider
46
46
  if (!response.IsSuccessStatusCode)
47
47
  {
48
48
  var responseContent = await response.Content.ReadAsStringAsync();
49
- if (!string.IsNullOrEmpty(responseContent))
50
- {
51
- responseContent = string.Concat(": ", responseContent);
52
- }
53
-
54
- throw new HttpRequestException(message: $"{(int)response.StatusCode} ({response.StatusCode}){responseContent}", inner: null, statusCode: response.StatusCode);
49
+ throw new HttpApiException(method, endpoint, response.StatusCode, responseContent);
55
50
  }
56
51
  }
57
52
 
@@ -1736,6 +1736,45 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
1736
1736
  AssertEx.Equal(expectedEntryPoints, actualEntryPoints);
1737
1737
  }
1738
1738
 
1739
+ [Fact]
1740
+ public async Task ExpandEntryPoints_IgnoresSolutionFolders()
1741
+ {
1742
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
1743
+ ("solution.sln", """
1744
+ Microsoft Visual Studio Solution File, Format Version 12.00
1745
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Project", "src\project.csproj", "{00000000-0000-0000-0000-000000000001}"
1746
+ EndProject
1747
+ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".sln", ".sln", "{2730C57A-D6A7-4A4F-913A-AF211E54B717}"
1748
+ ProjectSection(SolutionItems) = preProject
1749
+ .editorconfig = .editorconfig
1750
+ EndProjectSection
1751
+ EndProject
1752
+ """),
1753
+ ("src/project.csproj", """
1754
+ <Project Sdk="Microsoft.NET.Sdk">
1755
+ <PropertyGroup>
1756
+ <TargetFramework>net9.0</TargetFramework>
1757
+ </PropertyGroup>
1758
+ </Project>
1759
+ """)
1760
+ );
1761
+ Directory.CreateDirectory(Path.Combine(tempDir.DirectoryPath, ".sln"));
1762
+
1763
+ var actualEntryPoints = (await DiscoveryWorker.ExpandEntryPointsIntoProjectsAsync(
1764
+ [Path.Combine(tempDir.DirectoryPath, "solution.sln")],
1765
+ new ExperimentsManager(),
1766
+ new TestLogger(),
1767
+ repoRootPath: tempDir.DirectoryPath))
1768
+ .Select(p => p.NormalizePathToUnix())
1769
+ .ToArray();
1770
+ var expectedEntryPoints = new[]
1771
+ {
1772
+ Path.Combine(tempDir.DirectoryPath, "src/project.csproj").NormalizePathToUnix(),
1773
+ };
1774
+
1775
+ AssertEx.Equal(expectedEntryPoints, actualEntryPoints);
1776
+ }
1777
+
1739
1778
  [Fact]
1740
1779
  public async Task ExpandEntryPoints_FiltersProjectsInSubmodules()
1741
1780
  {
@@ -2385,4 +2424,3 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
2385
2424
  );
2386
2425
  }
2387
2426
  }
2388
-
@@ -1,3 +1,5 @@
1
+ using System.Net;
2
+
1
3
  using NuGetUpdater.Core.Run;
2
4
  using NuGetUpdater.Core.Run.ApiModel;
3
5
  using NuGetUpdater.Core.Test.Utilities;
@@ -21,15 +23,19 @@ public class HttpApiHandlerTests
21
23
  var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
22
24
 
23
25
  // act
24
- var exception = await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new()
26
+ var exception = await Assert.ThrowsAsync<HttpApiException>(() => handler.IncrementMetric(new()
25
27
  {
26
28
  // body is irrelevant for this test
27
29
  Metric = "TEST",
28
30
  }));
29
31
 
30
32
  // assert
31
- var expectedMessage = $"400 (BadRequest): {errorContent}";
33
+ var expectedMessage = $"POST increment_metric failed with 400 (BadRequest): {errorContent}";
32
34
  Assert.Equal(expectedMessage, exception.Message);
35
+ Assert.Equal("POST", exception.Method);
36
+ Assert.Equal("increment_metric", exception.Endpoint);
37
+ Assert.Equal(errorContent, exception.ResponseContent);
38
+ Assert.Equal(HttpStatusCode.BadRequest, exception.StatusCode);
33
39
  }
34
40
 
35
41
  [Fact]
@@ -44,15 +50,50 @@ public class HttpApiHandlerTests
44
50
  var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
45
51
 
46
52
  // act
47
- var exception = await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new()
53
+ var exception = await Assert.ThrowsAsync<HttpApiException>(() => handler.IncrementMetric(new()
48
54
  {
49
55
  // body is irrelevant for this test
50
56
  Metric = "TEST",
51
57
  }));
52
58
 
53
59
  // assert
54
- var expectedMessage = $"400 (BadRequest)";
60
+ var expectedMessage = $"POST increment_metric failed with 400 (BadRequest)";
55
61
  Assert.Equal(expectedMessage, exception.Message);
62
+ Assert.Null(exception.ResponseContent);
63
+ }
64
+
65
+ [Fact]
66
+ public async Task ForbiddenResponseFromCreatePullRequestIsReportedAsAnApiFailure()
67
+ {
68
+ // arrange
69
+ var requestCount = 0;
70
+ using var http = TestHttpServer.CreateTestStringServer((method, url) =>
71
+ {
72
+ requestCount++;
73
+ return (403, "forbidden");
74
+ });
75
+ var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
76
+
77
+ // act
78
+ var exception = await Assert.ThrowsAsync<HttpApiException>(() =>
79
+ handler.CreatePullRequest(new()
80
+ {
81
+ Dependencies = [],
82
+ UpdatedDependencyFiles = [],
83
+ BaseCommitSha = "base-commit-sha",
84
+ CommitMessage = "commit message",
85
+ PrTitle = "PR title",
86
+ PrBody = "PR body",
87
+ DependencyGroup = null,
88
+ }));
89
+
90
+ // assert
91
+ Assert.Equal("POST create_pull_request failed with 403 (Forbidden): forbidden", exception.Message);
92
+ Assert.Equal("POST", exception.Method);
93
+ Assert.Equal("create_pull_request", exception.Endpoint);
94
+ Assert.Equal("forbidden", exception.ResponseContent);
95
+ Assert.Equal(HttpStatusCode.Forbidden, exception.StatusCode);
96
+ Assert.Equal(1, requestCount);
56
97
  }
57
98
 
58
99
  [Fact]
@@ -95,7 +136,7 @@ public class HttpApiHandlerTests
95
136
  var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
96
137
 
97
138
  // act
98
- await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new() { Metric = "test" }));
139
+ await Assert.ThrowsAsync<HttpApiException>(() => handler.IncrementMetric(new() { Metric = "test" }));
99
140
 
100
141
  // assert
101
142
  Assert.Equal(1, requestCount);
@@ -114,10 +155,10 @@ public class HttpApiHandlerTests
114
155
  var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID", static _ => Task.CompletedTask);
115
156
 
116
157
  // act
117
- var exception = await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new() { Metric = "test" }));
158
+ var exception = await Assert.ThrowsAsync<HttpApiException>(() => handler.IncrementMetric(new() { Metric = "test" }));
118
159
 
119
160
  // assert
120
- Assert.Equal("500 (InternalServerError): attempt-4", exception.Message);
161
+ Assert.Equal("POST increment_metric failed with 500 (InternalServerError): attempt-4", exception.Message);
121
162
  Assert.Equal(4, requestCount);
122
163
  }
123
164
 
@@ -89,6 +89,23 @@ public class JobErrorBaseTests : TestBase
89
89
  new PrivateSourceAuthenticationFailure(["http://nuget.example.com/v3/index.json"]),
90
90
  ];
91
91
 
92
+ // a forbidden response from a package feed turns into private_source_authentication_failure
93
+ yield return
94
+ [
95
+ new HttpRequestException("nope", null, HttpStatusCode.Forbidden),
96
+ new PrivateSourceAuthenticationFailure(["http://nuget.example.com/v3/index.json"]),
97
+ ];
98
+
99
+ // a forbidden response from the Dependabot API is an unknown updater error
100
+ yield return
101
+ [
102
+ new HttpApiException("POST", "create_pull_request", HttpStatusCode.Forbidden, "forbidden"),
103
+ new UnknownError(
104
+ new HttpApiException("POST", "create_pull_request", HttpStatusCode.Forbidden, "forbidden"),
105
+ "TEST-JOB-ID"
106
+ ),
107
+ ];
108
+
92
109
  // inner exception turns into private_source_authentication_failure
93
110
  yield return
94
111
  [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-nuget
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.396.0
4
+ version: 0.398.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.396.0
18
+ version: 0.398.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.396.0
25
+ version: 0.398.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -511,6 +511,7 @@ files:
511
511
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatedDependencyList.cs
512
512
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/CommitOptions_IncludeScopeConverter.cs
513
513
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/GitEOLMetadataProvider.cs
514
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiException.cs
514
515
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs
515
516
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs
516
517
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IEOLMetadataProvider.cs
@@ -587,7 +588,7 @@ licenses:
587
588
  - MIT
588
589
  metadata:
589
590
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
590
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.396.0
591
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.398.0
591
592
  rdoc_options: []
592
593
  require_paths:
593
594
  - lib