dependabot-nuget 0.364.0 → 0.366.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 +4 -4
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +5 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +5 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +28 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +41 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +58 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +69 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +93 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +146 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +12 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e0aedc20fa2f1df16323aca062c9c44c6eea43e7765b723de4e95a140684876d
|
|
4
|
+
data.tar.gz: e4b9b5783a76aeb9a28c8af0ade2db202eeb93112a4d49a940860541a433c2fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ac6071c674f86aaf2822d46bb9510d4ae8a9914bea75856864a50087e0aacc4eb36087e3d9403fcba55acc0ad88ae477d289e8134e27958ade18307cd278fe6
|
|
7
|
+
data.tar.gz: 6c0ec49e96823dc4d6dc110ba9aef051031a9adba875242f087eaf8f1484ac49abf59a25e69e72a2f04457398aa32ef3de539c456ced39f677b0b4561ff9185f
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
<PackageVersion Include="System.Formats.Asn1" Version="10.0.3" />
|
|
36
36
|
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.3" />
|
|
37
37
|
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.11" />
|
|
38
|
-
<PackageVersion Include="System.Text.Json" Version="
|
|
38
|
+
<PackageVersion Include="System.Text.Json" Version="10.0.3" />
|
|
39
39
|
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
|
40
40
|
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="10.0.3" />
|
|
41
|
-
<PackageVersion Include="xunit.v3" Version="3.
|
|
41
|
+
<PackageVersion Include="xunit.v3" Version="3.2.2" />
|
|
42
42
|
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
|
|
43
43
|
</ItemGroup>
|
|
44
44
|
</Project>
|
|
@@ -111,6 +111,11 @@ internal record NuGetContext : IDisposable
|
|
|
111
111
|
// if anything goes wrong here, the package source obviously doesn't contain the requested package
|
|
112
112
|
continue;
|
|
113
113
|
}
|
|
114
|
+
catch (InvalidDataException)
|
|
115
|
+
{
|
|
116
|
+
// this usually means the feed returns an unexpected 404 when paging results; nothing we can do about it here
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
114
119
|
|
|
115
120
|
var downloadResource = await sourceRepository.GetResourceAsync<DownloadResource>(cancellationToken);
|
|
116
121
|
using var downloadResult = await downloadResource.GetDownloadResourceResultAsync(packageIdentity, PackageDownloadContext, globalPackagesFolder, Logger, cancellationToken);
|
|
@@ -141,6 +141,11 @@ internal static class VersionFinder
|
|
|
141
141
|
// if anything goes wrong here, the package source obviously doesn't contain the requested package
|
|
142
142
|
continue;
|
|
143
143
|
}
|
|
144
|
+
catch (InvalidDataException)
|
|
145
|
+
{
|
|
146
|
+
// this usually means the feed returns an unexpected 404 when paging results; nothing we can do about it here
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
144
149
|
catch (JsonReaderException ex)
|
|
145
150
|
{
|
|
146
151
|
// unable to parse server response
|
|
@@ -2,6 +2,8 @@ using System.Collections.Immutable;
|
|
|
2
2
|
using System.IO.Enumeration;
|
|
3
3
|
using System.Text.Json;
|
|
4
4
|
|
|
5
|
+
using NuGet.Versioning;
|
|
6
|
+
|
|
5
7
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
6
8
|
|
|
7
9
|
public record DependencyGroup
|
|
@@ -40,6 +42,32 @@ public class GroupMatcher
|
|
|
40
42
|
return isMatch;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
public bool IsAllowedByVersion(NuGetVersion oldVersion, NuGetVersion newVersion)
|
|
46
|
+
{
|
|
47
|
+
var isMajorBump = newVersion.Major > oldVersion.Major;
|
|
48
|
+
var isMinorBump = newVersion.Major == oldVersion.Major && newVersion.Minor > oldVersion.Minor;
|
|
49
|
+
var isPatchBump = newVersion.Major == oldVersion.Major && newVersion.Minor == oldVersion.Minor && newVersion.Patch > oldVersion.Patch;
|
|
50
|
+
|
|
51
|
+
var allowedUpdateTypes = new HashSet<GroupUpdateType>(UpdateTypes);
|
|
52
|
+
|
|
53
|
+
if (isMajorBump && allowedUpdateTypes.Contains(GroupUpdateType.Major))
|
|
54
|
+
{
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (isMinorBump && allowedUpdateTypes.Contains(GroupUpdateType.Minor))
|
|
59
|
+
{
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (isPatchBump && allowedUpdateTypes.Contains(GroupUpdateType.Patch))
|
|
64
|
+
{
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
43
71
|
public static GroupMatcher FromRules(Dictionary<string, object> rules)
|
|
44
72
|
{
|
|
45
73
|
var patterns = GetStringArray(rules, "patterns", ["*"]); // default to matching everything unless explicitly excluded
|
|
@@ -157,7 +157,7 @@ internal class CreateSecurityUpdatePullRequestHandler : IUpdateHandler
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
if (updatedDependencyFiles.Length > 0)
|
|
160
|
+
if (updateOperationsPerformed.Count > 0 && updatedDependencyFiles.Length > 0)
|
|
161
161
|
{
|
|
162
162
|
var commitMessage = PullRequestTextGenerator.GetPullRequestCommitMessage(job, [.. updateOperationsPerformed], null);
|
|
163
163
|
var prTitle = PullRequestTextGenerator.GetPullRequestTitle(job, [.. updateOperationsPerformed], null);
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
using System.Collections.Immutable;
|
|
2
2
|
|
|
3
|
+
using NuGet.Versioning;
|
|
4
|
+
|
|
5
|
+
using NuGetUpdater.Core.Analyze;
|
|
3
6
|
using NuGetUpdater.Core.Discover;
|
|
4
7
|
using NuGetUpdater.Core.Run.ApiModel;
|
|
5
8
|
using NuGetUpdater.Core.Updater;
|
|
@@ -106,6 +109,13 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
|
|
|
106
109
|
continue;
|
|
107
110
|
}
|
|
108
111
|
|
|
112
|
+
var isUpdateAllowed = groupMatcher.IsAllowedByVersion(NuGetVersion.Parse(dependency.Version!), NuGetVersion.Parse(analysisResult.UpdatedVersion));
|
|
113
|
+
if (!isUpdateAllowed)
|
|
114
|
+
{
|
|
115
|
+
logger.Info($"Dependency {dependency.Name} skipped for group {group.Name} because update type was not allowed.");
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
var projectDiscovery = discoveryResult.GetProjectDiscoveryFromPath(projectPath);
|
|
110
120
|
var updaterResult = await updaterWorker.RunAsync(repoContentsPath.FullName, projectPath, dependency.Name, dependency.Version!, analysisResult.UpdatedVersion, dependency.IsTransitive);
|
|
111
121
|
if (updaterResult.Error is not null)
|
|
@@ -204,15 +214,6 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
|
|
|
204
214
|
continue;
|
|
205
215
|
}
|
|
206
216
|
|
|
207
|
-
var matchingGroups = job.DependencyGroups
|
|
208
|
-
.Where(group => group.GetGroupMatcher().IsMatch(dependency.Name))
|
|
209
|
-
.ToImmutableArray();
|
|
210
|
-
if (matchingGroups.Length > 0)
|
|
211
|
-
{
|
|
212
|
-
logger.Info($"Dependency {dependency.Name} skipped for ungrouped updates because it's a member of the following groups: {string.Join(", ", matchingGroups.Select(group => group.Name))}");
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
217
|
var dependencyInfo = RunWorker.GetDependencyInfo(job, dependency, groupMatchers: [], allowCooldown: true);
|
|
217
218
|
var analysisResult = await analyzeWorker.RunAsync(repoContentsPath.FullName, discoveryResult, dependencyInfo);
|
|
218
219
|
if (analysisResult.Error is not null)
|
|
@@ -228,6 +229,12 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
|
|
|
228
229
|
continue;
|
|
229
230
|
}
|
|
230
231
|
|
|
232
|
+
var isSkipped = IsUngroupedDependencySkipped(dependency, analysisResult, job.DependencyGroups, logger);
|
|
233
|
+
if (isSkipped)
|
|
234
|
+
{
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
|
|
231
238
|
var projectDiscovery = discoveryResult.GetProjectDiscoveryFromPath(projectPath);
|
|
232
239
|
var updaterResult = await updaterWorker.RunAsync(repoContentsPath.FullName, projectPath, dependency.Name, dependency.Version!, analysisResult.UpdatedVersion, dependency.IsTransitive);
|
|
233
240
|
if (updaterResult.Error is not null)
|
|
@@ -293,4 +300,29 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
|
|
|
293
300
|
.ToImmutableArray();
|
|
294
301
|
return updateOperationsToPerformByDependency;
|
|
295
302
|
}
|
|
303
|
+
|
|
304
|
+
internal static bool IsUngroupedDependencySkipped(Dependency dependency, AnalysisResult dependencyAnalysis, ImmutableArray<DependencyGroup> dependencyGroups, ILogger logger)
|
|
305
|
+
{
|
|
306
|
+
var matcherGroups = dependencyGroups
|
|
307
|
+
.Select(group => (group.Name, Matcher: group.GetGroupMatcher()))
|
|
308
|
+
.Where(pair => pair.Matcher.IsMatch(dependency.Name))
|
|
309
|
+
.ToImmutableArray();
|
|
310
|
+
if (matcherGroups.Length > 0)
|
|
311
|
+
{
|
|
312
|
+
// update matches a group by name
|
|
313
|
+
// if any group allows the proposed version range, then it's not allowed in an ungrouped update
|
|
314
|
+
var oldVersion = NuGetVersion.Parse(dependency.Version!);
|
|
315
|
+
var newVersion = NuGetVersion.Parse(dependencyAnalysis.UpdatedVersion);
|
|
316
|
+
var matcherGroupsAllowingVersionRange = matcherGroups
|
|
317
|
+
.Where(pair => pair.Matcher.IsAllowedByVersion(oldVersion, newVersion))
|
|
318
|
+
.ToImmutableArray();
|
|
319
|
+
if (matcherGroupsAllowingVersionRange.Length > 0)
|
|
320
|
+
{
|
|
321
|
+
logger.Info($"Dependency {dependency.Name} skipped for ungrouped updates because it's a member of the following groups: {string.Join(", ", matcherGroupsAllowingVersionRange.Select(pair => pair.Name))}");
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
296
328
|
}
|
|
@@ -728,6 +728,7 @@ internal static partial class MSBuildHelper
|
|
|
728
728
|
{
|
|
729
729
|
new Regex(@"\nAn error occurred while reading file '(?<FilePath>[^']+)': (?<Message>[^\n]*)\n"),
|
|
730
730
|
new Regex(@"NuGet\.Config is not valid XML\. Path: '(?<FilePath>[^']+)'\.\n\s*(?<Message>[^\n]*)(\n|$)"),
|
|
731
|
+
new Regex(@"Error parsing packages\.config file at (?<FilePath>[^:]+): (?<Message>[^\n]*)\n"),
|
|
731
732
|
};
|
|
732
733
|
var match = patterns.Select(p => p.Match(output)).Where(m => m.Success).FirstOrDefault();
|
|
733
734
|
if (match is not null)
|
|
@@ -1446,4 +1446,62 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
|
|
|
1446
1446
|
Assert.Equal("< 1.0.1", dependencyInfo.IgnoredVersions.Single().ToString());
|
|
1447
1447
|
Assert.Empty(dependencyInfo.Vulnerabilities);
|
|
1448
1448
|
}
|
|
1449
|
+
|
|
1450
|
+
[Fact]
|
|
1451
|
+
public async Task MisbehavingNuGetFeedDoesNotTakeDownURLDiscovery()
|
|
1452
|
+
{
|
|
1453
|
+
using var http = TestHttpServer.CreateTestStringServer(url =>
|
|
1454
|
+
{
|
|
1455
|
+
var uri = new Uri(url, UriKind.Absolute);
|
|
1456
|
+
var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
|
|
1457
|
+
return uri.PathAndQuery switch
|
|
1458
|
+
{
|
|
1459
|
+
"/index.json" => (200, $$"""
|
|
1460
|
+
{
|
|
1461
|
+
"version": "3.0.0",
|
|
1462
|
+
"resources": [
|
|
1463
|
+
{
|
|
1464
|
+
"@id": "{{baseUrl}}/download",
|
|
1465
|
+
"@type": "PackageBaseAddress/3.0.0"
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
"@id": "{{baseUrl}}/registrations",
|
|
1469
|
+
"@type": "RegistrationsBaseUrl"
|
|
1470
|
+
}
|
|
1471
|
+
]
|
|
1472
|
+
}
|
|
1473
|
+
"""),
|
|
1474
|
+
// registration index returns a range with @id but no inlined items;
|
|
1475
|
+
// this causes the URL specified in @id to be queried but if that isn't present, the NuGet libraries will eventually throw
|
|
1476
|
+
"/registrations/some.package/index.json" => (200, $$"""
|
|
1477
|
+
{
|
|
1478
|
+
"count": 1,
|
|
1479
|
+
"items": [
|
|
1480
|
+
{
|
|
1481
|
+
"@id": "{{baseUrl}}/registrations/some.package/page1.json",
|
|
1482
|
+
"lower": "1.0.0",
|
|
1483
|
+
"upper": "2.0.0"
|
|
1484
|
+
}
|
|
1485
|
+
]
|
|
1486
|
+
}
|
|
1487
|
+
"""),
|
|
1488
|
+
_ => (404, "")
|
|
1489
|
+
};
|
|
1490
|
+
});
|
|
1491
|
+
var feedUrl = $"{http.BaseUrl.TrimEnd('/')}/index.json";
|
|
1492
|
+
using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
|
|
1493
|
+
("NuGet.Config", $"""
|
|
1494
|
+
<configuration>
|
|
1495
|
+
<packageSources>
|
|
1496
|
+
<clear />
|
|
1497
|
+
<add key="private_feed" value="{feedUrl}" allowInsecureConnections="true" />
|
|
1498
|
+
</packageSources>
|
|
1499
|
+
</configuration>
|
|
1500
|
+
""")
|
|
1501
|
+
);
|
|
1502
|
+
|
|
1503
|
+
var context = new NuGetContext(tempDir.DirectoryPath);
|
|
1504
|
+
var infoUrl = await context.GetPackageInfoUrlAsync("some.package", "1.0.0", CancellationToken.None);
|
|
1505
|
+
Assert.Null(infoUrl);
|
|
1506
|
+
}
|
|
1449
1507
|
}
|
|
@@ -458,4 +458,73 @@ public class VersionFinderTests : TestBase
|
|
|
458
458
|
var actual = versions.Select(v => v.ToString()).ToArray();
|
|
459
459
|
AssertEx.Equal(expected, actual);
|
|
460
460
|
}
|
|
461
|
+
|
|
462
|
+
[Fact]
|
|
463
|
+
public async Task MisbehavingNuGetFeedDoesNotPreventFindingVersions()
|
|
464
|
+
{
|
|
465
|
+
using var http = TestHttpServer.CreateTestStringServer(url =>
|
|
466
|
+
{
|
|
467
|
+
var uri = new Uri(url, UriKind.Absolute);
|
|
468
|
+
var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
|
|
469
|
+
return uri.PathAndQuery switch
|
|
470
|
+
{
|
|
471
|
+
"/index.json" => (200, $$"""
|
|
472
|
+
{
|
|
473
|
+
"version": "3.0.0",
|
|
474
|
+
"resources": [
|
|
475
|
+
{
|
|
476
|
+
"@id": "{{baseUrl}}/download",
|
|
477
|
+
"@type": "PackageBaseAddress/3.0.0"
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
"@id": "{{baseUrl}}/registrations",
|
|
481
|
+
"@type": "RegistrationsBaseUrl"
|
|
482
|
+
}
|
|
483
|
+
]
|
|
484
|
+
}
|
|
485
|
+
"""),
|
|
486
|
+
// registration index returns a range with @id but no inlined items;
|
|
487
|
+
// this causes the URL specified in @id to be queried but if that isn't present, the NuGet libraries will eventually throw
|
|
488
|
+
"/registrations/some.package/index.json" => (200, $$"""
|
|
489
|
+
{
|
|
490
|
+
"count": 1,
|
|
491
|
+
"items": [
|
|
492
|
+
{
|
|
493
|
+
"@id": "{{baseUrl}}/registrations/some.package/page1.json",
|
|
494
|
+
"lower": "1.0.0",
|
|
495
|
+
"upper": "2.0.0"
|
|
496
|
+
}
|
|
497
|
+
]
|
|
498
|
+
}
|
|
499
|
+
"""),
|
|
500
|
+
_ => (404, "")
|
|
501
|
+
};
|
|
502
|
+
});
|
|
503
|
+
var feedUrl = $"{http.BaseUrl.TrimEnd('/')}/index.json";
|
|
504
|
+
using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
|
|
505
|
+
("NuGet.Config", $"""
|
|
506
|
+
<configuration>
|
|
507
|
+
<packageSources>
|
|
508
|
+
<clear />
|
|
509
|
+
<add key="private_feed" value="{feedUrl}" allowInsecureConnections="true" />
|
|
510
|
+
</packageSources>
|
|
511
|
+
</configuration>
|
|
512
|
+
""")
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
var context = new NuGetContext(tempDir.DirectoryPath);
|
|
516
|
+
|
|
517
|
+
var projectTfm = NuGetFramework.Parse("net9.0");
|
|
518
|
+
var dependencyInfo = new DependencyInfo()
|
|
519
|
+
{
|
|
520
|
+
Name = "Some.Package",
|
|
521
|
+
Version = "1.0.0",
|
|
522
|
+
IsVulnerable = false,
|
|
523
|
+
};
|
|
524
|
+
var currentVersion = NuGetVersion.Parse(dependencyInfo.Version);
|
|
525
|
+
var versionsResult = await VersionFinder.GetVersionsAsync([projectTfm], dependencyInfo, currentVersion, DateTime.Now, context, new TestLogger(), CancellationToken.None);
|
|
526
|
+
Assert.NotNull(versionsResult);
|
|
527
|
+
var versions = versionsResult.GetVersions();
|
|
528
|
+
Assert.Empty(versions);
|
|
529
|
+
}
|
|
461
530
|
}
|
|
@@ -763,4 +763,97 @@ public class CreateSecurityUpdatePullRequestHandlerTests : UpdateHandlersTestsBa
|
|
|
763
763
|
]
|
|
764
764
|
);
|
|
765
765
|
}
|
|
766
|
+
|
|
767
|
+
[Fact]
|
|
768
|
+
public async Task ErrantFileUpdatesDoNotCauseCallToCreatePullRequest()
|
|
769
|
+
{
|
|
770
|
+
// if an external tool inadvertently updates files on disk without reporting any update operations, don't try
|
|
771
|
+
// to create a PR
|
|
772
|
+
await TestAsync(
|
|
773
|
+
job: new Job()
|
|
774
|
+
{
|
|
775
|
+
Dependencies = ["Some.Dependency"],
|
|
776
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
|
777
|
+
SecurityUpdatesOnly = true,
|
|
778
|
+
Source = CreateJobSource("/src"),
|
|
779
|
+
},
|
|
780
|
+
files: [
|
|
781
|
+
("src/project.csproj", "initial project contents"),
|
|
782
|
+
("src/packages.config", "initial packages contents"),
|
|
783
|
+
],
|
|
784
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
|
785
|
+
("/src", new WorkspaceDiscoveryResult()
|
|
786
|
+
{
|
|
787
|
+
Path = "/src",
|
|
788
|
+
Projects = [
|
|
789
|
+
new()
|
|
790
|
+
{
|
|
791
|
+
FilePath = "project.csproj",
|
|
792
|
+
Dependencies = [
|
|
793
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
|
794
|
+
],
|
|
795
|
+
ImportedFiles = [],
|
|
796
|
+
AdditionalFiles = ["packages.config"],
|
|
797
|
+
}
|
|
798
|
+
],
|
|
799
|
+
})
|
|
800
|
+
),
|
|
801
|
+
analyzeWorker: new TestAnalyzeWorker(async input =>
|
|
802
|
+
{
|
|
803
|
+
var repoRoot = input.Item1;
|
|
804
|
+
var discovery = input.Item2;
|
|
805
|
+
var dependencyInfo = input.Item3;
|
|
806
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
|
807
|
+
{
|
|
808
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// no update possible but a file was touched on disk
|
|
812
|
+
var projectPath = Path.Join(repoRoot, discovery.Path, discovery.Projects.Single().FilePath);
|
|
813
|
+
var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath), "packages.config");
|
|
814
|
+
await File.WriteAllTextAsync(packagesConfigPath, "updated packages contents");
|
|
815
|
+
|
|
816
|
+
return new AnalysisResult()
|
|
817
|
+
{
|
|
818
|
+
CanUpdate = false,
|
|
819
|
+
UpdatedVersion = "1.0.0",
|
|
820
|
+
UpdatedDependencies = [],
|
|
821
|
+
};
|
|
822
|
+
}),
|
|
823
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
|
824
|
+
{
|
|
825
|
+
return new UpdateOperationResult()
|
|
826
|
+
{
|
|
827
|
+
UpdateOperations = [],
|
|
828
|
+
};
|
|
829
|
+
}),
|
|
830
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
|
831
|
+
expectedApiMessages: [
|
|
832
|
+
new UpdatedDependencyList()
|
|
833
|
+
{
|
|
834
|
+
Dependencies = [
|
|
835
|
+
new()
|
|
836
|
+
{
|
|
837
|
+
Name = "Some.Dependency",
|
|
838
|
+
Version = "1.0.0",
|
|
839
|
+
Requirements = [
|
|
840
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
],
|
|
844
|
+
DependencyFiles = ["/src/packages.config", "/src/project.csproj"],
|
|
845
|
+
},
|
|
846
|
+
new IncrementMetric()
|
|
847
|
+
{
|
|
848
|
+
Metric = "updater.started",
|
|
849
|
+
Tags = new()
|
|
850
|
+
{
|
|
851
|
+
["operation"] = "create_security_pr",
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
new SecurityUpdateNotFound("Some.Dependency", "1.0.0"),
|
|
855
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
|
856
|
+
]
|
|
857
|
+
);
|
|
858
|
+
}
|
|
766
859
|
}
|
|
@@ -1370,4 +1370,150 @@ public class GroupUpdateAllVersionsHandlerTests : UpdateHandlersTestsBase
|
|
|
1370
1370
|
]
|
|
1371
1371
|
);
|
|
1372
1372
|
}
|
|
1373
|
+
|
|
1374
|
+
[Fact]
|
|
1375
|
+
public async Task UngroupedPullRequestCanBeCreatedIfGroupAppliesToNonMatchedTypes()
|
|
1376
|
+
{
|
|
1377
|
+
// group only applies to minor and patch updates, but a major update is requested and gets generated separately
|
|
1378
|
+
await TestAsync(
|
|
1379
|
+
job: new Job()
|
|
1380
|
+
{
|
|
1381
|
+
Source = CreateJobSource("/src"),
|
|
1382
|
+
DependencyGroups = [new()
|
|
1383
|
+
{
|
|
1384
|
+
Name = "test-group",
|
|
1385
|
+
Rules = new()
|
|
1386
|
+
{
|
|
1387
|
+
["patterns"] = new[] { "Some.Dependency" },
|
|
1388
|
+
["update-types"] = new[] { "minor", "patch" }
|
|
1389
|
+
},
|
|
1390
|
+
}]
|
|
1391
|
+
},
|
|
1392
|
+
files: [
|
|
1393
|
+
("src/project.csproj", "initial contents"),
|
|
1394
|
+
],
|
|
1395
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
|
1396
|
+
("/src", new WorkspaceDiscoveryResult()
|
|
1397
|
+
{
|
|
1398
|
+
Path = "/src",
|
|
1399
|
+
Projects = [
|
|
1400
|
+
new()
|
|
1401
|
+
{
|
|
1402
|
+
FilePath = "project.csproj",
|
|
1403
|
+
Dependencies = [
|
|
1404
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
|
1405
|
+
],
|
|
1406
|
+
ImportedFiles = [],
|
|
1407
|
+
AdditionalFiles = [],
|
|
1408
|
+
}
|
|
1409
|
+
],
|
|
1410
|
+
})
|
|
1411
|
+
),
|
|
1412
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
|
1413
|
+
{
|
|
1414
|
+
var repoRoot = input.Item1;
|
|
1415
|
+
var discovery = input.Item2;
|
|
1416
|
+
var dependencyInfo = input.Item3;
|
|
1417
|
+
var newVersion = dependencyInfo.Name switch
|
|
1418
|
+
{
|
|
1419
|
+
"Some.Dependency" => "2.0.0",
|
|
1420
|
+
_ => throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}"),
|
|
1421
|
+
};
|
|
1422
|
+
return Task.FromResult(new AnalysisResult()
|
|
1423
|
+
{
|
|
1424
|
+
CanUpdate = true,
|
|
1425
|
+
UpdatedVersion = newVersion,
|
|
1426
|
+
UpdatedDependencies = [],
|
|
1427
|
+
});
|
|
1428
|
+
}),
|
|
1429
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
|
1430
|
+
{
|
|
1431
|
+
var repoRoot = input.Item1;
|
|
1432
|
+
var workspacePath = input.Item2;
|
|
1433
|
+
var dependencyName = input.Item3;
|
|
1434
|
+
var previousVersion = input.Item4;
|
|
1435
|
+
var newVersion = input.Item5;
|
|
1436
|
+
var isTransitive = input.Item6;
|
|
1437
|
+
|
|
1438
|
+
await File.WriteAllTextAsync(Path.Join(repoRoot, workspacePath), "updated contents");
|
|
1439
|
+
|
|
1440
|
+
return new UpdateOperationResult()
|
|
1441
|
+
{
|
|
1442
|
+
UpdateOperations = [new DirectUpdate() { DependencyName = dependencyName, NewVersion = NuGetVersion.Parse(newVersion), UpdatedFiles = [workspacePath] }],
|
|
1443
|
+
};
|
|
1444
|
+
}),
|
|
1445
|
+
expectedUpdateHandler: GroupUpdateAllVersionsHandler.Instance,
|
|
1446
|
+
expectedApiMessages: [
|
|
1447
|
+
new IncrementMetric()
|
|
1448
|
+
{
|
|
1449
|
+
Metric = "updater.started",
|
|
1450
|
+
Tags = new()
|
|
1451
|
+
{
|
|
1452
|
+
["operation"] = "group_update_all_versions",
|
|
1453
|
+
}
|
|
1454
|
+
},
|
|
1455
|
+
// discovery from group updater
|
|
1456
|
+
new UpdatedDependencyList()
|
|
1457
|
+
{
|
|
1458
|
+
Dependencies = [
|
|
1459
|
+
new()
|
|
1460
|
+
{
|
|
1461
|
+
Name = "Some.Dependency",
|
|
1462
|
+
Version = "1.0.0",
|
|
1463
|
+
Requirements = [
|
|
1464
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
|
1465
|
+
],
|
|
1466
|
+
},
|
|
1467
|
+
],
|
|
1468
|
+
DependencyFiles = ["/src/project.csproj"],
|
|
1469
|
+
},
|
|
1470
|
+
// discovery from ungrouped updater
|
|
1471
|
+
new UpdatedDependencyList()
|
|
1472
|
+
{
|
|
1473
|
+
Dependencies = [
|
|
1474
|
+
new()
|
|
1475
|
+
{
|
|
1476
|
+
Name = "Some.Dependency",
|
|
1477
|
+
Version = "1.0.0",
|
|
1478
|
+
Requirements = [
|
|
1479
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
|
1480
|
+
],
|
|
1481
|
+
},
|
|
1482
|
+
],
|
|
1483
|
+
DependencyFiles = ["/src/project.csproj"],
|
|
1484
|
+
},
|
|
1485
|
+
new CreatePullRequest()
|
|
1486
|
+
{
|
|
1487
|
+
Dependencies = [
|
|
1488
|
+
new()
|
|
1489
|
+
{
|
|
1490
|
+
Name = "Some.Dependency",
|
|
1491
|
+
Version = "2.0.0",
|
|
1492
|
+
Requirements = [
|
|
1493
|
+
new() { Requirement = "2.0.0", File = "/src/project.csproj", Groups = ["dependencies"], Source = new() { SourceUrl = null } },
|
|
1494
|
+
],
|
|
1495
|
+
PreviousVersion = "1.0.0",
|
|
1496
|
+
PreviousRequirements = [
|
|
1497
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
|
1498
|
+
],
|
|
1499
|
+
},
|
|
1500
|
+
],
|
|
1501
|
+
UpdatedDependencyFiles = [
|
|
1502
|
+
new()
|
|
1503
|
+
{
|
|
1504
|
+
Directory = "/src",
|
|
1505
|
+
Name = "project.csproj",
|
|
1506
|
+
Content = "updated contents",
|
|
1507
|
+
},
|
|
1508
|
+
],
|
|
1509
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
|
1510
|
+
CommitMessage = EndToEndTests.TestPullRequestCommitMessage,
|
|
1511
|
+
PrTitle = EndToEndTests.TestPullRequestTitle,
|
|
1512
|
+
PrBody = EndToEndTests.TestPullRequestBody,
|
|
1513
|
+
DependencyGroup = null,
|
|
1514
|
+
},
|
|
1515
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
|
1516
|
+
]
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1373
1519
|
}
|
|
@@ -634,5 +634,17 @@ public class MSBuildHelperTests : TestBase
|
|
|
634
634
|
// expectedError
|
|
635
635
|
new UnknownError(new Exception("Multiple project files found for single packages.config"), "TEST-JOB-ID"),
|
|
636
636
|
];
|
|
637
|
+
|
|
638
|
+
yield return
|
|
639
|
+
[
|
|
640
|
+
// output
|
|
641
|
+
"""
|
|
642
|
+
Error parsing packages.config file at /path/to/packages.config: Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it. Line 1, position 5.
|
|
643
|
+
|
|
644
|
+
^^^ this blank line is necessary to force a newline at the end of the output
|
|
645
|
+
""",
|
|
646
|
+
// expectedError
|
|
647
|
+
new DependencyFileNotParseable("/path/to/packages.config", "Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it. Line 1, position 5.")
|
|
648
|
+
];
|
|
637
649
|
}
|
|
638
650
|
}
|
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.
|
|
4
|
+
version: 0.366.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.
|
|
18
|
+
version: 0.366.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.
|
|
25
|
+
version: 0.366.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: debug
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -553,7 +553,7 @@ licenses:
|
|
|
553
553
|
- MIT
|
|
554
554
|
metadata:
|
|
555
555
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
556
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
556
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.366.0
|
|
557
557
|
rdoc_options: []
|
|
558
558
|
require_paths:
|
|
559
559
|
- lib
|