dependabot-nuget 0.300.0 → 0.301.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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +1 -0
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +2 -0
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ClosePullRequest.cs +1 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +5 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CreatePullRequest.cs +1 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +1 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +36 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +1 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MessageBase.cs +5 -0
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +2 -5
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestDependency.cs +11 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatePullRequest.cs +1 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/CommitOptions_IncludeScopeConverter.cs +29 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs +5 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs +1 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestConverter.cs +35 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +44 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +205 -49
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +76 -1
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +1 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +252 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +136 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +145 -22
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +15 -10
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/TestApiHandler.cs +6 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/{UpdateAllowedTests.cs → UpdatePermittedAndMessageTests.cs} +110 -6
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +105 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +75 -0
  30. metadata +13 -6
@@ -33,6 +33,12 @@ internal class TestApiHandler : IApiHandler
33
33
  return Task.CompletedTask;
34
34
  }
35
35
 
36
+ public Task ClosePullRequest(ClosePullRequest closePullRequest)
37
+ {
38
+ _receivedMessages.Add((closePullRequest.GetType(), closePullRequest));
39
+ return Task.CompletedTask;
40
+ }
41
+
36
42
  public Task UpdatePullRequest(UpdatePullRequest updatePullRequest)
37
43
  {
38
44
  _receivedMessages.Add((updatePullRequest.GetType(), updatePullRequest));
@@ -1,5 +1,7 @@
1
1
  using System.Collections.Immutable;
2
2
 
3
+ using NuGet.Versioning;
4
+
3
5
  using NuGetUpdater.Core.Analyze;
4
6
  using NuGetUpdater.Core.Run;
5
7
  using NuGetUpdater.Core.Run.ApiModel;
@@ -10,17 +12,30 @@ using DepType = NuGetUpdater.Core.Run.ApiModel.DependencyType;
10
12
 
11
13
  namespace NuGetUpdater.Core.Test.Run;
12
14
 
13
- public class UpdateAllowedTests
15
+ public class UpdatePermittedAndMessageTests
14
16
  {
15
17
  [Theory]
16
- [MemberData(nameof(IsUpdateAllowedTestData))]
17
- public void IsUpdateAllowed(Job job, Dependency dependency, bool expectedResult)
18
+ [MemberData(nameof(UpdatePermittedAndMessageTestData))]
19
+ public void UpdatePermittedAndMessage(Job job, Dependency dependency, bool expectedResult, MessageBase? expectedMessage)
18
20
  {
19
- var actualResult = RunWorker.IsUpdateAllowed(job, dependency);
21
+ var (actualResult, actualMessage) = RunWorker.UpdatePermittedAndMessage(job, dependency);
20
22
  Assert.Equal(expectedResult, actualResult);
23
+
24
+ if (expectedMessage is null)
25
+ {
26
+ Assert.Null(actualMessage);
27
+ }
28
+ else
29
+ {
30
+ Assert.True(actualMessage is not null, $"Expected message of type {expectedMessage.GetType().Name} but got null");
31
+ Assert.Equal(expectedMessage.GetType(), actualMessage.GetType());
32
+ var actualMessageJson = HttpApiHandler.Serialize(actualMessage);
33
+ var expectedMessageJson = HttpApiHandler.Serialize(expectedMessage);
34
+ Assert.Equal(expectedMessageJson, actualMessageJson);
35
+ }
21
36
  }
22
37
 
23
- public static IEnumerable<object[]> IsUpdateAllowedTestData()
38
+ public static IEnumerable<object?[]> UpdatePermittedAndMessageTestData()
24
39
  {
25
40
  // with default allowed updates on a transitive dependency
26
41
  yield return
@@ -29,6 +44,7 @@ public class UpdateAllowedTests
29
44
  allowedUpdates: [
30
45
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All }
31
46
  ],
47
+ existingPrs: [],
32
48
  securityAdvisories: [
33
49
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
34
50
  ],
@@ -36,6 +52,8 @@ public class UpdateAllowedTests
36
52
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
37
53
  // expectedResult
38
54
  false,
55
+ // expectedMessage
56
+ null,
39
57
  ];
40
58
 
41
59
  // when dealing with a security update
@@ -45,6 +63,7 @@ public class UpdateAllowedTests
45
63
  allowedUpdates: [
46
64
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All }
47
65
  ],
66
+ existingPrs: [],
48
67
  securityAdvisories: [
49
68
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
50
69
  ],
@@ -52,6 +71,8 @@ public class UpdateAllowedTests
52
71
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
53
72
  // expectedResult
54
73
  true,
74
+ // expectedMessage
75
+ null,
55
76
  ];
56
77
 
57
78
  // with a top-level dependency
@@ -62,11 +83,14 @@ public class UpdateAllowedTests
62
83
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
63
84
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
64
85
  ],
86
+ existingPrs: [],
65
87
  securityAdvisories: [],
66
88
  securityUpdatesOnly: false),
67
89
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
68
90
  // expectedResult
69
91
  true,
92
+ // expectedMessage
93
+ null,
70
94
  ];
71
95
 
72
96
  // with a sub-dependency
@@ -77,11 +101,14 @@ public class UpdateAllowedTests
77
101
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
78
102
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
79
103
  ],
104
+ existingPrs: [],
80
105
  securityAdvisories: [],
81
106
  securityUpdatesOnly: false),
82
107
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
83
108
  // expectedResult
84
109
  false,
110
+ // expectedMessage
111
+ null,
85
112
  ];
86
113
 
87
114
  // when insecure
@@ -92,6 +119,7 @@ public class UpdateAllowedTests
92
119
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
93
120
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
94
121
  ],
122
+ existingPrs: [],
95
123
  securityAdvisories: [
96
124
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
97
125
  ],
@@ -99,6 +127,8 @@ public class UpdateAllowedTests
99
127
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: true),
100
128
  // expectedResult
101
129
  true,
130
+ // expectedMessage
131
+ null,
102
132
  ];
103
133
 
104
134
  // when only security fixes are allowed
@@ -109,11 +139,14 @@ public class UpdateAllowedTests
109
139
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
110
140
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
111
141
  ],
142
+ existingPrs: [],
112
143
  securityAdvisories: [],
113
144
  securityUpdatesOnly: true),
114
145
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
115
146
  // expectedResult
116
147
  false,
148
+ // expectedMessage
149
+ null,
117
150
  ];
118
151
 
119
152
  // when dealing with a security fix
@@ -124,6 +157,7 @@ public class UpdateAllowedTests
124
157
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
125
158
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
126
159
  ],
160
+ existingPrs: [],
127
161
  securityAdvisories: [
128
162
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
129
163
  ],
@@ -131,6 +165,8 @@ public class UpdateAllowedTests
131
165
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
132
166
  // expectedResult
133
167
  true,
168
+ // expectedMessage
169
+ null,
134
170
  ];
135
171
 
136
172
  // when dealing with a security fix that doesn't apply
@@ -141,6 +177,7 @@ public class UpdateAllowedTests
141
177
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
142
178
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
143
179
  ],
180
+ existingPrs: [],
144
181
  securityAdvisories: [
145
182
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("> 1.8.0")], PatchedVersions = [], UnaffectedVersions = [] }
146
183
  ],
@@ -148,6 +185,8 @@ public class UpdateAllowedTests
148
185
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
149
186
  // expectedResult
150
187
  false,
188
+ // expectedMessage
189
+ new SecurityUpdateNotNeeded("Some.Package"),
151
190
  ];
152
191
 
153
192
  // when dealing with a security fix that doesn't apply to some versions
@@ -158,6 +197,7 @@ public class UpdateAllowedTests
158
197
  new AllowedUpdate() { DependencyType = DepType.Direct, UpdateType = UpdateType.All },
159
198
  new AllowedUpdate() { DependencyType = DepType.Indirect, UpdateType = UpdateType.Security }
160
199
  ],
200
+ existingPrs: [],
161
201
  securityAdvisories: [
162
202
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("< 1.8.0"), Requirement.Parse("> 1.8.0")], PatchedVersions = [], UnaffectedVersions = [] }
163
203
  ],
@@ -165,6 +205,8 @@ public class UpdateAllowedTests
165
205
  new Dependency("Some.Package", "1.8.1", DependencyType.PackageReference, IsTransitive: false),
166
206
  // expectedResult
167
207
  true,
208
+ // expectedMessage
209
+ null,
168
210
  ];
169
211
 
170
212
  // when a dependency allow list that includes the dependency
@@ -174,11 +216,14 @@ public class UpdateAllowedTests
174
216
  allowedUpdates: [
175
217
  new AllowedUpdate() { DependencyName = "Some.Package" }
176
218
  ],
219
+ existingPrs: [],
177
220
  securityAdvisories: [],
178
221
  securityUpdatesOnly: false),
179
222
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
180
223
  // expectedResult
181
224
  true,
225
+ // expectedMessage
226
+ null,
182
227
  ];
183
228
 
184
229
  // with a dependency allow list that uses a wildcard
@@ -188,11 +233,14 @@ public class UpdateAllowedTests
188
233
  allowedUpdates: [
189
234
  new AllowedUpdate() { DependencyName = "Some.*" }
190
235
  ],
236
+ existingPrs: [],
191
237
  securityAdvisories: [],
192
238
  securityUpdatesOnly: false),
193
239
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
194
240
  // expectedResult
195
241
  true,
242
+ // expectedMessage
243
+ null,
196
244
  ];
197
245
 
198
246
  // when dependency allow list that excludes the dependency
@@ -202,11 +250,14 @@ public class UpdateAllowedTests
202
250
  allowedUpdates: [
203
251
  new AllowedUpdate() { DependencyName = "Unrelated.Package" }
204
252
  ],
253
+ existingPrs: [],
205
254
  securityAdvisories: [],
206
255
  securityUpdatesOnly: false),
207
256
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
208
257
  // expectedResult
209
258
  false,
259
+ // expectedMessage
260
+ null,
210
261
  ];
211
262
 
212
263
  // when matching with an incomplete dependency name
@@ -216,11 +267,14 @@ public class UpdateAllowedTests
216
267
  allowedUpdates: [
217
268
  new AllowedUpdate() { DependencyName = "Some" }
218
269
  ],
270
+ existingPrs: [],
219
271
  securityAdvisories: [],
220
272
  securityUpdatesOnly: false),
221
273
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
222
274
  // expectedResult
223
275
  false,
276
+ // expectedMessage
277
+ null,
224
278
  ];
225
279
 
226
280
  // with a dependency allow list that uses a wildcard
@@ -230,11 +284,14 @@ public class UpdateAllowedTests
230
284
  allowedUpdates: [
231
285
  new AllowedUpdate() { DependencyName = "Unrelated.*" }
232
286
  ],
287
+ existingPrs: [],
233
288
  securityAdvisories: [],
234
289
  securityUpdatesOnly: false),
235
290
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
236
291
  // expectedResult
237
292
  false,
293
+ // expectedMessage
294
+ null,
238
295
  ];
239
296
 
240
297
  // when security fixes are also allowed
@@ -245,11 +302,14 @@ public class UpdateAllowedTests
245
302
  new AllowedUpdate() { DependencyName = "Unrelated.Package" },
246
303
  new AllowedUpdate() { UpdateType = UpdateType.Security }
247
304
  ],
305
+ existingPrs: [],
248
306
  securityAdvisories: [],
249
307
  securityUpdatesOnly: false),
250
308
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
251
309
  // expectedResult
252
310
  false,
311
+ // expectedMessage
312
+ null,
253
313
  ];
254
314
 
255
315
  // when dealing with a security fix
@@ -259,6 +319,7 @@ public class UpdateAllowedTests
259
319
  allowedUpdates: [
260
320
  new AllowedUpdate() { DependencyName = "Unrelated.Package"}, new AllowedUpdate(){ UpdateType = UpdateType.Security }
261
321
  ],
322
+ existingPrs: [],
262
323
  securityAdvisories: [
263
324
  new Advisory() { DependencyName = "Some.Package", AffectedVersions = [], PatchedVersions = [Requirement.Parse(">= 1.11.0")], UnaffectedVersions = [] }
264
325
  ],
@@ -266,14 +327,57 @@ public class UpdateAllowedTests
266
327
  new Dependency("Some.Package", "1.8.0", DependencyType.PackageReference, IsTransitive: false),
267
328
  // expectedResult
268
329
  true,
330
+ // expectedMessage
331
+ null,
332
+ ];
333
+
334
+ // security job, not vulnerable => security update not needed
335
+ yield return
336
+ [
337
+ CreateJob(
338
+ allowedUpdates: [
339
+ new AllowedUpdate() { UpdateType = UpdateType.Security }
340
+ ],
341
+ existingPrs: [],
342
+ securityAdvisories: [
343
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("1.0.0")], PatchedVersions = [Requirement.Parse("1.1.0")] }
344
+ ],
345
+ securityUpdatesOnly: true),
346
+ new Dependency("Some.Package", "1.1.0", DependencyType.PackageReference),
347
+ // expectedResult
348
+ false,
349
+ // expectedMessage
350
+ new SecurityUpdateNotNeeded("Some.Package")
351
+ ];
352
+
353
+ // security job, not updating existing => pr already exists
354
+ yield return
355
+ [
356
+ CreateJob(
357
+ allowedUpdates: [
358
+ new AllowedUpdate() { UpdateType = UpdateType.Security }
359
+ ],
360
+ existingPrs: [
361
+ new PullRequest() { Dependencies = [new PullRequestDependency() { DependencyName = "Some.Package", DependencyVersion = NuGetVersion.Parse("1.2.0") }] }
362
+ ],
363
+ securityAdvisories: [
364
+ new Advisory() { DependencyName = "Some.Package", AffectedVersions = [Requirement.Parse("1.1.0")] }
365
+ ],
366
+ securityUpdatesOnly: true),
367
+ new Dependency("Some.Package", "1.1.0", DependencyType.PackageReference),
368
+ // expectedResult
369
+ false,
370
+ // expectedMessage
371
+ new PullRequestExistsForLatestVersion("Some.Package", "1.2.0")
269
372
  ];
270
373
  }
271
374
 
272
- private static Job CreateJob(AllowedUpdate[] allowedUpdates, Advisory[] securityAdvisories, bool securityUpdatesOnly)
375
+ private static Job CreateJob(AllowedUpdate[] allowedUpdates, PullRequest[] existingPrs, Advisory[] securityAdvisories, bool securityUpdatesOnly)
273
376
  {
274
377
  return new Job()
275
378
  {
276
379
  AllowedUpdates = allowedUpdates.ToImmutableArray(),
380
+ ExistingPullRequests = existingPrs.ToImmutableArray(),
277
381
  SecurityAdvisories = securityAdvisories.ToImmutableArray(),
278
382
  SecurityUpdatesOnly = securityUpdatesOnly,
279
383
  Source = new()
@@ -2,6 +2,10 @@ using System.Net;
2
2
  using System.Net.Sockets;
3
3
  using System.Text;
4
4
 
5
+ using NuGet.Versioning;
6
+ using NuGet;
7
+ using NuGetUpdater.Core.Utilities;
8
+
5
9
  namespace NuGetUpdater.Core.Test
6
10
  {
7
11
  public class TestHttpServer : IDisposable
@@ -32,6 +36,8 @@ namespace NuGetUpdater.Core.Test
32
36
  _listener.Stop();
33
37
  }
34
38
 
39
+ public string GetPackageFeedIndex() => BaseUrl.TrimEnd('/') + "/index.json";
40
+
35
41
  private async Task HandleResponses()
36
42
  {
37
43
  while (_runServer)
@@ -69,6 +75,105 @@ namespace NuGetUpdater.Core.Test
69
75
  return CreateTestServer(bytesRequestHandler);
70
76
  }
71
77
 
78
+ public static TestHttpServer CreateTestNuGetFeed(params MockNuGetPackage[] packages)
79
+ {
80
+ var packageVersions = new Dictionary<string, HashSet<NuGetVersion>>(StringComparer.OrdinalIgnoreCase);
81
+ foreach (var package in packages)
82
+ {
83
+ var versions = packageVersions.GetOrAdd(package.Id, () => new HashSet<NuGetVersion>());
84
+ var version = NuGetVersion.Parse(package.Version);
85
+ versions.Add(version);
86
+ }
87
+
88
+ var responses = new Dictionary<string, byte[]>();
89
+ foreach (var kvp in packageVersions)
90
+ {
91
+ var packageId = kvp.Key;
92
+ var versions = kvp.Value.OrderBy(v => v).ToArray();
93
+
94
+ // registration
95
+ var registrationUrl = $"/registrations/{packageId.ToLowerInvariant()}/index.json";
96
+ var registrationContent = $$"""
97
+ {
98
+ "count": {{versions.Length}},
99
+ "items": [
100
+ {
101
+ "lower": "{{versions.First()}}",
102
+ "upper": "{{versions.Last()}}",
103
+ "items": [
104
+ {{string.Join(",\n", versions.Select(v => $$"""
105
+ {
106
+ "catalogEntry": {
107
+ "version": "{{v}}"
108
+ }
109
+ }
110
+ """))}}
111
+ ]
112
+ }
113
+ ]
114
+ }
115
+ """;
116
+ responses[registrationUrl] = Encoding.UTF8.GetBytes(registrationContent);
117
+
118
+ // download
119
+ var downloadUrl = $"/download/{packageId.ToLowerInvariant()}/index.json";
120
+ var downloadContent = $$"""
121
+ {
122
+ "versions": [{{string.Join(", ", versions.Select(v => $"\"{v}\""))}}]
123
+ }
124
+ """;
125
+ responses[downloadUrl] = Encoding.UTF8.GetBytes(downloadContent);
126
+
127
+ // nupkg
128
+ foreach (var package in packages.Where(p => p.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase)))
129
+ {
130
+ var id = packageId.ToLowerInvariant();
131
+ var v = package.Version.ToLowerInvariant();
132
+ var nupkgUrl = $"/download/{id}/{v}/{id}.{v}.nupkg";
133
+ var nupkgContent = package.GetZipStream().ReadAllBytes();
134
+ responses[nupkgUrl] = nupkgContent;
135
+ }
136
+ }
137
+
138
+ (int, byte[]) HttpHandler(string uriString)
139
+ {
140
+ var uri = new Uri(uriString, UriKind.Absolute);
141
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
142
+ if (uri.PathAndQuery == "/index.json")
143
+ {
144
+ return (200, Encoding.UTF8.GetBytes($$"""
145
+ {
146
+ "version": "3.0.0",
147
+ "resources": [
148
+ {
149
+ "@id": "{{baseUrl}}/download",
150
+ "@type": "PackageBaseAddress/3.0.0"
151
+ },
152
+ {
153
+ "@id": "{{baseUrl}}/query",
154
+ "@type": "SearchQueryService"
155
+ },
156
+ {
157
+ "@id": "{{baseUrl}}/registrations",
158
+ "@type": "RegistrationsBaseUrl"
159
+ }
160
+ ]
161
+ }
162
+ """));
163
+ }
164
+
165
+ if (responses.TryGetValue(uri.PathAndQuery, out var response))
166
+ {
167
+ return (200, response);
168
+ }
169
+
170
+ return (404, Encoding.UTF8.GetBytes("{}"));
171
+ }
172
+
173
+ var server = TestHttpServer.CreateTestServer(HttpHandler);
174
+ return server;
175
+ }
176
+
72
177
  private static int FindFreePort()
73
178
  {
74
179
  var tcpListener = new TcpListener(IPAddress.Loopback, 0);
@@ -3632,5 +3632,80 @@ public partial class UpdateWorkerTests
3632
3632
  """
3633
3633
  );
3634
3634
  }
3635
+
3636
+ [Fact]
3637
+ public async Task CentralPackageManagementStillWorksWithMultipleFeedsListedInConfig()
3638
+ {
3639
+ using var http1 = TestHttpServer.CreateTestNuGetFeed(
3640
+ MockNuGetPackage.CreateSimplePackage("Package1", "1.0.0", "net9.0"),
3641
+ MockNuGetPackage.CreateSimplePackage("Package1", "1.0.1", "net9.0"));
3642
+ using var http2 = TestHttpServer.CreateTestNuGetFeed(MockNuGetPackage.CreateSimplePackage("Package2", "2.0.0", "net9.0"));
3643
+ await TestUpdate("Package1", "1.0.0", "1.0.1",
3644
+ useSolution: false,
3645
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
3646
+ packages: [],
3647
+ projectContents: """
3648
+ <Project Sdk="Microsoft.NET.Sdk">
3649
+ <PropertyGroup>
3650
+ <TargetFramework>net9.0</TargetFramework>
3651
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
3652
+ <MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
3653
+ </PropertyGroup>
3654
+ <ItemGroup>
3655
+ <PackageReference Include="Package1" />
3656
+ <PackageReference Include="Package2" />
3657
+ </ItemGroup>
3658
+ </Project>
3659
+ """,
3660
+ additionalFiles: [
3661
+ ("Directory.Packages.props", """
3662
+ <Project>
3663
+ <PropertyGroup>
3664
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
3665
+ </PropertyGroup>
3666
+ <ItemGroup>
3667
+ <PackageVersion Include="Package1" Version="1.0.0" />
3668
+ <PackageVersion Include="Package2" Version="2.0.0" />
3669
+ </ItemGroup>
3670
+ </Project>
3671
+ """),
3672
+ ("NuGet.Config", $"""
3673
+ <configuration>
3674
+ <packageSources>
3675
+ <!-- explicitly _not_ calling "clear" because we also want the upstream sources in addition to these two remote sources -->
3676
+ <add key="source_1" value="{http1.GetPackageFeedIndex()}" allowInsecureConnections="true" />
3677
+ <add key="source_2" value="{http2.GetPackageFeedIndex()}" allowInsecureConnections="true" />
3678
+ </packageSources>
3679
+ </configuration>
3680
+ """)
3681
+ ],
3682
+ expectedProjectContents: """
3683
+ <Project Sdk="Microsoft.NET.Sdk">
3684
+ <PropertyGroup>
3685
+ <TargetFramework>net9.0</TargetFramework>
3686
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
3687
+ <MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
3688
+ </PropertyGroup>
3689
+ <ItemGroup>
3690
+ <PackageReference Include="Package1" />
3691
+ <PackageReference Include="Package2" />
3692
+ </ItemGroup>
3693
+ </Project>
3694
+ """,
3695
+ additionalFilesExpected: [
3696
+ ("Directory.Packages.props", """
3697
+ <Project>
3698
+ <PropertyGroup>
3699
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
3700
+ </PropertyGroup>
3701
+ <ItemGroup>
3702
+ <PackageVersion Include="Package1" Version="1.0.1" />
3703
+ <PackageVersion Include="Package2" Version="2.0.0" />
3704
+ </ItemGroup>
3705
+ </Project>
3706
+ """)
3707
+ ]
3708
+ );
3709
+ }
3635
3710
  }
3636
3711
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-nuget
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.300.0
4
+ version: 0.301.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-06 00:00:00.000000000 Z
11
+ date: 2025-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.300.0
19
+ version: 0.301.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.300.0
26
+ version: 0.301.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubyzip
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -348,10 +348,12 @@ files:
348
348
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs
349
349
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj
350
350
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs
351
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs
352
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs
351
353
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs
352
354
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs
353
355
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/TestApiHandler.cs
354
- - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateAllowedTests.cs
356
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatePermittedAndMessageTests.cs
355
357
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs
356
358
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs
357
359
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryEnvironment.cs
@@ -457,8 +459,10 @@ files:
457
459
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobRepoNotFound.cs
458
460
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobSource.cs
459
461
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MarkAsProcessed.cs
462
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MessageBase.cs
460
463
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs
461
464
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs
465
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestDependency.cs
462
466
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestExistsForLatestVersion.cs
463
467
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ReportedDependency.cs
464
468
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ReportedRequirement.cs
@@ -469,8 +473,11 @@ files:
469
473
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdateNotPossible.cs
470
474
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatePullRequest.cs
471
475
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatedDependencyList.cs
476
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/CommitOptions_IncludeScopeConverter.cs
472
477
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs
473
478
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs
479
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestConverter.cs
480
+ - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs
474
481
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunResult.cs
475
482
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs
476
483
  - helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs
@@ -537,7 +544,7 @@ licenses:
537
544
  - MIT
538
545
  metadata:
539
546
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
540
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.300.0
547
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.301.0
541
548
  post_install_message:
542
549
  rdoc_options: []
543
550
  require_paths: