dependabot-nuget 0.315.0 → 0.316.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/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ClosePullRequest.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CreatePullRequest.cs +47 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +60 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +151 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -18
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestExistsForSecurityUpdate.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateDependencyNotFound.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateIgnored.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateNotFound.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateNotPossible.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatePullRequest.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +151 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +78 -32
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +99 -111
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +169 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +271 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/IUpdateHandler.cs +22 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +192 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +187 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +175 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +43 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +17 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +15 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MarkdownListBuilder.cs +65 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/JobTests.cs +405 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +92 -82
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +5 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +67 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +445 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +260 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +30 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +69 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +766 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +636 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandlerTests.cs +513 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandlerTests.cs +806 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandlerTests.cs +589 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlerSelectionTests.cs +183 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlersTestsBase.cs +43 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateOperationBaseTests.cs +121 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +51 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MarkdownListBuilderTests.cs +42 -0
- metadata +26 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b42ebbf0a6556e3766516b2b59eec508929837779a8f9ca2042a4d4f7d629626
|
4
|
+
data.tar.gz: abb2a60e86d368d9d4a0f09c6311fd7b73f2ac708c1ec73c05d92d1b9409b27d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b266cf823214164397b8e9ed67e5f238364ab95074f33f5cacec47adac5a6cecf147a39ccdb11701e29d0de0ca675b3dabd4a330d75d8ff81dbf7b660c26807
|
7
|
+
data.tar.gz: fa309cdd55f81b5507329def15d7a7e6c50b7668e8f1f886cc7c0e1498ac8209aab577d6ba617dbe7ecffda79f93be8d696908b692a07415b78c677905bb9fdb
|
@@ -50,8 +50,8 @@ public partial class EntryPointTests
|
|
50
50
|
},
|
51
51
|
expectedUrls:
|
52
52
|
[
|
53
|
-
"POST /update_jobs/TEST-ID/update_dependency_list",
|
54
53
|
"POST /update_jobs/TEST-ID/increment_metric",
|
54
|
+
"POST /update_jobs/TEST-ID/update_dependency_list",
|
55
55
|
"POST /update_jobs/TEST-ID/create_pull_request",
|
56
56
|
"PATCH /update_jobs/TEST-ID/mark_as_processed",
|
57
57
|
]
|
@@ -9,4 +9,10 @@ public sealed record WorkspaceDiscoveryResult : NativeResult
|
|
9
9
|
public ImmutableArray<ProjectDiscoveryResult> Projects { get; init; }
|
10
10
|
public GlobalJsonDiscoveryResult? GlobalJson { get; init; }
|
11
11
|
public DotNetToolsJsonDiscoveryResult? DotNetToolsJson { get; init; }
|
12
|
+
|
13
|
+
public ProjectDiscoveryResult? GetProjectDiscoveryFromPath(string repoPath)
|
14
|
+
{
|
15
|
+
var projectDiscovery = Projects.FirstOrDefault(p => System.IO.Path.Join(Path, p.FilePath).FullyNormalizedRootedPath().Equals(repoPath, StringComparison.OrdinalIgnoreCase));
|
16
|
+
return projectDiscovery;
|
17
|
+
}
|
12
18
|
}
|
@@ -10,6 +10,7 @@ public record ExperimentsManager
|
|
10
10
|
public bool InstallDotnetSdks { get; init; } = false;
|
11
11
|
public bool NativeUpdater { get; init; } = false;
|
12
12
|
public bool UseLegacyDependencySolver { get; init; } = false;
|
13
|
+
public bool UseLegacyUpdateHandler { get; init; } = false;
|
13
14
|
public bool UseDirectDiscovery { get; init; } = false;
|
14
15
|
|
15
16
|
public Dictionary<string, object> ToDictionary()
|
@@ -19,6 +20,7 @@ public record ExperimentsManager
|
|
19
20
|
["nuget_install_dotnet_sdks"] = InstallDotnetSdks,
|
20
21
|
["nuget_native_updater"] = NativeUpdater,
|
21
22
|
["nuget_legacy_dependency_solver"] = UseLegacyDependencySolver,
|
23
|
+
["nuget_use_legacy_update_handler"] = UseLegacyUpdateHandler,
|
22
24
|
["nuget_use_direct_discovery"] = UseDirectDiscovery,
|
23
25
|
};
|
24
26
|
}
|
@@ -30,6 +32,7 @@ public record ExperimentsManager
|
|
30
32
|
InstallDotnetSdks = IsEnabled(experiments, "nuget_install_dotnet_sdks"),
|
31
33
|
NativeUpdater = IsEnabled(experiments, "nuget_native_updater"),
|
32
34
|
UseLegacyDependencySolver = IsEnabled(experiments, "nuget_legacy_dependency_solver"),
|
35
|
+
UseLegacyUpdateHandler = IsEnabled(experiments, "nuget_use_legacy_update_handler"),
|
33
36
|
UseDirectDiscovery = IsEnabled(experiments, "nuget_use_direct_discovery"),
|
34
37
|
};
|
35
38
|
}
|
@@ -22,4 +22,19 @@ public sealed record ClosePullRequest : MessageBase
|
|
22
22
|
|
23
23
|
return report.ToString().Trim();
|
24
24
|
}
|
25
|
+
|
26
|
+
public static ClosePullRequest WithDependenciesChanged(Job job) => CloseWithReason(job, "dependencies_changed");
|
27
|
+
public static ClosePullRequest WithDependenciesRemoved(Job job) => CloseWithReason(job, "dependencies_removed");
|
28
|
+
public static ClosePullRequest WithDependencyRemoved(Job job) => CloseWithReason(job, "dependency_removed");
|
29
|
+
public static ClosePullRequest WithUpdateNoLongerPossible(Job job) => CloseWithReason(job, "update_no_longer_possible");
|
30
|
+
public static ClosePullRequest WithUpToDate(Job job) => CloseWithReason(job, "up_to_date");
|
31
|
+
|
32
|
+
private static ClosePullRequest CloseWithReason(Job job, string reason)
|
33
|
+
{
|
34
|
+
return new ClosePullRequest()
|
35
|
+
{
|
36
|
+
DependencyNames = [.. job.Dependencies.Distinct().OrderBy(n => n, StringComparer.OrdinalIgnoreCase)],
|
37
|
+
Reason = reason,
|
38
|
+
};
|
39
|
+
}
|
25
40
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using System.Text;
|
2
|
+
using System.Text.Json;
|
2
3
|
using System.Text.Json.Serialization;
|
3
4
|
|
4
5
|
using NuGet.Versioning;
|
@@ -8,17 +9,29 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
8
9
|
public sealed record CreatePullRequest : MessageBase
|
9
10
|
{
|
10
11
|
public required ReportedDependency[] Dependencies { get; init; }
|
12
|
+
|
11
13
|
[JsonPropertyName("updated-dependency-files")]
|
12
14
|
public required DependencyFile[] UpdatedDependencyFiles { get; init; }
|
15
|
+
|
13
16
|
[JsonPropertyName("base-commit-sha")]
|
14
17
|
public required string BaseCommitSha { get; init; }
|
18
|
+
|
15
19
|
[JsonPropertyName("commit-message")]
|
16
20
|
public required string CommitMessage { get; init; }
|
21
|
+
|
17
22
|
[JsonPropertyName("pr-title")]
|
18
23
|
public required string PrTitle { get; init; }
|
24
|
+
|
19
25
|
[JsonPropertyName("pr-body")]
|
20
26
|
public required string PrBody { get; init; }
|
21
27
|
|
28
|
+
/// <summary>
|
29
|
+
/// This is serialized as either `null` or `{"name": "group-name"}`.
|
30
|
+
/// </summary>
|
31
|
+
[JsonPropertyName("dependency-group")]
|
32
|
+
[JsonConverter(typeof(DependencyGroupConverter))]
|
33
|
+
public required string? DependencyGroup { get; init; }
|
34
|
+
|
22
35
|
public override string GetReport()
|
23
36
|
{
|
24
37
|
var dependencyNames = Dependencies
|
@@ -35,4 +48,38 @@ public sealed record CreatePullRequest : MessageBase
|
|
35
48
|
|
36
49
|
return report.ToString().Trim();
|
37
50
|
}
|
51
|
+
|
52
|
+
public class DependencyGroupConverter : JsonConverter<string?>
|
53
|
+
{
|
54
|
+
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
55
|
+
{
|
56
|
+
if (reader.TokenType == JsonTokenType.Null)
|
57
|
+
{
|
58
|
+
return null;
|
59
|
+
}
|
60
|
+
|
61
|
+
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(ref reader, options);
|
62
|
+
if (dict is not null &&
|
63
|
+
dict.TryGetValue("name", out var name))
|
64
|
+
{
|
65
|
+
return name;
|
66
|
+
}
|
67
|
+
|
68
|
+
throw new NotSupportedException("Expected an object with a `name` property.");
|
69
|
+
}
|
70
|
+
|
71
|
+
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
|
72
|
+
{
|
73
|
+
if (value is null)
|
74
|
+
{
|
75
|
+
writer.WriteNullValue();
|
76
|
+
}
|
77
|
+
else
|
78
|
+
{
|
79
|
+
writer.WriteStartObject();
|
80
|
+
writer.WriteString("name", value);
|
81
|
+
writer.WriteEndObject();
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
38
85
|
}
|
@@ -1,8 +1,68 @@
|
|
1
|
+
using System.Collections.Immutable;
|
2
|
+
using System.IO.Enumeration;
|
3
|
+
|
1
4
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
5
|
|
3
6
|
public record DependencyGroup
|
4
7
|
{
|
5
8
|
public required string Name { get; init; }
|
6
9
|
public string? AppliesTo { get; init; }
|
10
|
+
|
11
|
+
// TODO: make more strongly typed, but currently this seems to be:
|
12
|
+
// "patterns" => string[] where each element is a wildcard name pattern
|
13
|
+
// "exclude-patterns"=> string[] where each element is a wildcard name pattern
|
14
|
+
// "dependency-type" => production|development // not used for nuget?
|
7
15
|
public Dictionary<string, object> Rules { get; init; } = new();
|
16
|
+
|
17
|
+
public GroupMatcher GetGroupMatcher() => GroupMatcher.FromRules(Rules);
|
18
|
+
}
|
19
|
+
|
20
|
+
public class GroupMatcher
|
21
|
+
{
|
22
|
+
public ImmutableArray<string> Patterns { get; init; } = ImmutableArray<string>.Empty;
|
23
|
+
public ImmutableArray<string> ExcludePatterns { get; init; } = ImmutableArray<string>.Empty;
|
24
|
+
|
25
|
+
public bool IsMatch(string dependencyName)
|
26
|
+
{
|
27
|
+
var isIncluded = Patterns.Any(p => FileSystemName.MatchesSimpleExpression(p, dependencyName));
|
28
|
+
var isExcluded = ExcludePatterns.Any(p => FileSystemName.MatchesSimpleExpression(p, dependencyName));
|
29
|
+
var isMatch = isIncluded && !isExcluded;
|
30
|
+
return isMatch;
|
31
|
+
}
|
32
|
+
|
33
|
+
public static GroupMatcher FromRules(Dictionary<string, object> rules)
|
34
|
+
{
|
35
|
+
string[] patterns;
|
36
|
+
if (rules.TryGetValue("patterns", out var patternsObject) &&
|
37
|
+
patternsObject is string[] patternsArray)
|
38
|
+
{
|
39
|
+
patterns = patternsArray;
|
40
|
+
}
|
41
|
+
else
|
42
|
+
{
|
43
|
+
patterns = ["*"]; // default to matching everything unless excluded below
|
44
|
+
}
|
45
|
+
|
46
|
+
string[] excludePatterns;
|
47
|
+
if (rules.TryGetValue("exclude-patterns", out var excludePatternsObject) &&
|
48
|
+
excludePatternsObject is string[] excludePatternsArray)
|
49
|
+
{
|
50
|
+
excludePatterns = excludePatternsArray;
|
51
|
+
}
|
52
|
+
else
|
53
|
+
{
|
54
|
+
excludePatterns = [];
|
55
|
+
}
|
56
|
+
|
57
|
+
return new GroupMatcher()
|
58
|
+
{
|
59
|
+
Patterns = [.. patterns],
|
60
|
+
ExcludePatterns = [.. excludePatterns],
|
61
|
+
};
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
public static class DependencyGroupExtensions
|
66
|
+
{
|
67
|
+
public static bool IsSecurity(this DependencyGroup group) => group.AppliesTo == "security-updates";
|
8
68
|
}
|
@@ -1,9 +1,14 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
|
+
using System.IO.Enumeration;
|
2
3
|
using System.Text.Json;
|
3
4
|
using System.Text.Json.Serialization;
|
4
5
|
|
6
|
+
using Microsoft.Extensions.FileSystemGlobbing;
|
7
|
+
|
5
8
|
using NuGet.Versioning;
|
6
9
|
|
10
|
+
using NuGetUpdater.Core.Analyze;
|
11
|
+
|
7
12
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
8
13
|
|
9
14
|
public sealed record Job
|
@@ -14,7 +19,9 @@ public sealed record Job
|
|
14
19
|
[JsonConverter(typeof(NullAsBoolConverter))]
|
15
20
|
public bool Debug { get; init; } = false;
|
16
21
|
public ImmutableArray<DependencyGroup> DependencyGroups { get; init; } = [];
|
17
|
-
|
22
|
+
|
23
|
+
[JsonConverter(typeof(NullAsEmptyStringArrayConverter))]
|
24
|
+
public ImmutableArray<string> Dependencies { get; init; } = [];
|
18
25
|
public string? DependencyGroupToRefresh { get; init; } = null;
|
19
26
|
public ImmutableArray<PullRequest> ExistingPullRequests { get; init; } = [];
|
20
27
|
public ImmutableArray<GroupPullRequest> ExistingGroupPullRequests { get; init; } = [];
|
@@ -34,25 +41,29 @@ public sealed record Job
|
|
34
41
|
public ImmutableArray<Dictionary<string, object>>? CredentialsMetadata { get; init; } = null;
|
35
42
|
public int MaxUpdaterRunTime { get; init; } = 0;
|
36
43
|
|
37
|
-
public
|
44
|
+
public ImmutableArray<string> GetAllDirectories()
|
38
45
|
{
|
39
|
-
var
|
46
|
+
var builder = ImmutableArray.CreateBuilder<string>();
|
40
47
|
if (Source.Directory is not null)
|
41
48
|
{
|
42
|
-
|
43
|
-
yield return Source.Directory;
|
49
|
+
builder.Add(Source.Directory);
|
44
50
|
}
|
45
51
|
|
46
|
-
|
52
|
+
builder.AddRange(Source.Directories ?? []);
|
53
|
+
if (builder.Count == 0)
|
47
54
|
{
|
48
|
-
|
49
|
-
yield return directory;
|
55
|
+
builder.Add("/");
|
50
56
|
}
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
return builder.ToImmutable();
|
59
|
+
}
|
60
|
+
|
61
|
+
public ImmutableArray<DependencyGroup> GetRelevantDependencyGroups()
|
62
|
+
{
|
63
|
+
var appliesToKey = SecurityUpdatesOnly ? "security-updates" : "version-updates";
|
64
|
+
var groups = DependencyGroups.Where(g => g.AppliesTo == appliesToKey)
|
65
|
+
.ToImmutableArray();
|
66
|
+
return groups;
|
56
67
|
}
|
57
68
|
|
58
69
|
public ImmutableArray<Tuple<string?, ImmutableArray<PullRequestDependency>>> GetAllExistingPullRequests()
|
@@ -66,27 +77,125 @@ public sealed record Job
|
|
66
77
|
return existingPullRequests;
|
67
78
|
}
|
68
79
|
|
69
|
-
public Tuple<string?, ImmutableArray<PullRequestDependency>>?
|
80
|
+
public Tuple<string?, ImmutableArray<PullRequestDependency>>? GetExistingPullRequestForDependencies(IEnumerable<Dependency> dependencies, bool considerVersions)
|
70
81
|
{
|
71
|
-
if (
|
82
|
+
if (dependencies.Any(d => d.Version is null))
|
72
83
|
{
|
73
84
|
return null;
|
74
85
|
}
|
75
86
|
|
76
|
-
|
87
|
+
string CreateIdentifier(string dependencyName, string dependencyVersion)
|
88
|
+
{
|
89
|
+
return $"{dependencyName}/{(considerVersions ? dependencyVersion : null)}";
|
90
|
+
}
|
91
|
+
|
92
|
+
var desiredDependencySet = dependencies.Select(d => CreateIdentifier(d.Name, d.Version!)).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
77
93
|
var existingPullRequests = GetAllExistingPullRequests();
|
78
|
-
var existingPullRequest = existingPullRequests
|
94
|
+
var existingPullRequest = existingPullRequests
|
95
|
+
.FirstOrDefault(pr =>
|
96
|
+
{
|
97
|
+
var prDependencySet = pr.Item2.Select(d => CreateIdentifier(d.DependencyName, d.DependencyVersion.ToString())).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
98
|
+
return prDependencySet.SetEquals(desiredDependencySet);
|
99
|
+
});
|
100
|
+
return existingPullRequest;
|
101
|
+
}
|
102
|
+
|
103
|
+
public bool IsDependencyIgnored(string dependencyName, string dependencyVersion)
|
104
|
+
{
|
105
|
+
var versionsToIgnore = IgnoreConditions
|
106
|
+
.Where(c => FileSystemName.MatchesSimpleExpression(c.DependencyName, dependencyName))
|
107
|
+
.Select(c => c.VersionRequirement ?? Requirement.Parse(">= 0.0.0")) // no range means ignore everything
|
108
|
+
.ToArray();
|
109
|
+
var parsedDependencyVersion = NuGetVersion.Parse(dependencyVersion);
|
110
|
+
var isIgnored = versionsToIgnore
|
111
|
+
.Any(r => r.IsSatisfiedBy(parsedDependencyVersion));
|
112
|
+
return isIgnored;
|
113
|
+
}
|
114
|
+
|
115
|
+
public bool IsUpdatePermitted(Dependency dependency)
|
116
|
+
{
|
117
|
+
if (dependency.Version is null)
|
79
118
|
{
|
80
|
-
if
|
81
|
-
|
82
|
-
|
119
|
+
// if we don't know the version, there's nothing we can do
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
|
123
|
+
var version = NuGetVersion.Parse(dependency.Version);
|
124
|
+
var dependencyInfo = RunWorker.GetDependencyInfo(this, dependency);
|
125
|
+
var isVulnerable = dependencyInfo.Vulnerabilities.Any(v => v.IsVulnerable(version));
|
126
|
+
|
127
|
+
bool IsAllowed(AllowedUpdate allowedUpdate)
|
128
|
+
{
|
129
|
+
// check name restriction, if any
|
130
|
+
if (allowedUpdate.DependencyName is not null)
|
83
131
|
{
|
84
|
-
|
132
|
+
var matcher = new Matcher(StringComparison.OrdinalIgnoreCase)
|
133
|
+
.AddInclude(allowedUpdate.DependencyName);
|
134
|
+
var result = matcher.Match(dependency.Name);
|
135
|
+
if (!result.HasMatches)
|
136
|
+
{
|
137
|
+
return false;
|
138
|
+
}
|
85
139
|
}
|
86
140
|
|
87
|
-
|
88
|
-
|
89
|
-
|
141
|
+
var isSecurityUpdate = allowedUpdate.UpdateType == UpdateType.Security || SecurityUpdatesOnly;
|
142
|
+
if (isSecurityUpdate)
|
143
|
+
{
|
144
|
+
if (isVulnerable)
|
145
|
+
{
|
146
|
+
// try to match to existing PR
|
147
|
+
var dependencyVersion = NuGetVersion.Parse(dependency.Version);
|
148
|
+
var existingPullRequests = GetAllExistingPullRequests()
|
149
|
+
.Where(pr => pr.Item2.Any(d => d.DependencyName.Equals(dependency.Name, StringComparison.OrdinalIgnoreCase) && d.DependencyVersion >= dependencyVersion))
|
150
|
+
.ToArray();
|
151
|
+
if (existingPullRequests.Length > 0)
|
152
|
+
{
|
153
|
+
// found a matching pr...
|
154
|
+
if (UpdatingAPullRequest)
|
155
|
+
{
|
156
|
+
// ...and we've been asked to update it
|
157
|
+
return true;
|
158
|
+
}
|
159
|
+
else
|
160
|
+
{
|
161
|
+
// ...but no update requested => don't perform any update
|
162
|
+
return false;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
else
|
166
|
+
{
|
167
|
+
// no matching pr...
|
168
|
+
if (UpdatingAPullRequest)
|
169
|
+
{
|
170
|
+
// ...but we've been asked to perform an update => no update possible
|
171
|
+
return false;
|
172
|
+
}
|
173
|
+
else
|
174
|
+
{
|
175
|
+
// ...and no update specifically requested => create new
|
176
|
+
return true;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
return false;
|
182
|
+
}
|
183
|
+
else
|
184
|
+
{
|
185
|
+
// not a security update, so only update if...
|
186
|
+
// ...we've been explicitly asked to update this
|
187
|
+
if (Dependencies.Any(d => d.Equals(dependency.Name, StringComparison.OrdinalIgnoreCase)))
|
188
|
+
{
|
189
|
+
return true;
|
190
|
+
}
|
191
|
+
|
192
|
+
// ...no specific update being performed, do it if it's not transitive
|
193
|
+
return !dependency.IsTransitive;
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
var allowed = AllowedUpdates.Any(IsAllowed);
|
198
|
+
return allowed;
|
90
199
|
}
|
91
200
|
}
|
92
201
|
|
@@ -107,3 +216,22 @@ public class NullAsBoolConverter : JsonConverter<bool>
|
|
107
216
|
writer.WriteBooleanValue(value);
|
108
217
|
}
|
109
218
|
}
|
219
|
+
|
220
|
+
public class NullAsEmptyStringArrayConverter : JsonConverter<ImmutableArray<string>>
|
221
|
+
{
|
222
|
+
public override ImmutableArray<string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
223
|
+
{
|
224
|
+
if (reader.TokenType == JsonTokenType.Null)
|
225
|
+
{
|
226
|
+
return [];
|
227
|
+
}
|
228
|
+
|
229
|
+
return JsonSerializer.Deserialize<ImmutableArray<string>>(ref reader, options);
|
230
|
+
}
|
231
|
+
|
232
|
+
public override void Write(Utf8JsonWriter writer, ImmutableArray<string> value, JsonSerializerOptions options)
|
233
|
+
{
|
234
|
+
writer.WriteStartArray();
|
235
|
+
writer.WriteEndArray();
|
236
|
+
}
|
237
|
+
}
|
@@ -5,6 +5,7 @@ using System.Text.Json.Serialization;
|
|
5
5
|
using Microsoft.Build.Exceptions;
|
6
6
|
|
7
7
|
using NuGetUpdater.Core.Analyze;
|
8
|
+
using NuGetUpdater.Core.Utilities;
|
8
9
|
|
9
10
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
10
11
|
|
@@ -25,24 +26,9 @@ public abstract record JobErrorBase : MessageBase
|
|
25
26
|
{
|
26
27
|
var report = new StringBuilder();
|
27
28
|
report.AppendLine($"Error type: {Type}");
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
{
|
32
|
-
// there's nothing meaningful in this field
|
33
|
-
continue;
|
34
|
-
}
|
35
|
-
|
36
|
-
var valueString = value.ToString();
|
37
|
-
if (value is IEnumerable<string> strings)
|
38
|
-
{
|
39
|
-
valueString = string.Join(", ", strings);
|
40
|
-
}
|
41
|
-
|
42
|
-
report.AppendLine($"- {key}: {valueString}");
|
43
|
-
}
|
44
|
-
|
45
|
-
return report.ToString().Trim();
|
29
|
+
report.Append(MarkdownListBuilder.FromObject(Details));
|
30
|
+
var fullReport = report.ToString().TrimEnd();
|
31
|
+
return fullReport;
|
46
32
|
}
|
47
33
|
|
48
34
|
public static JobErrorBase ErrorFromException(Exception ex, string jobId, string currentDirectory)
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestExistsForSecurityUpdate.cs
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
|
+
|
3
|
+
public record PullRequestExistsForSecurityUpdate : JobErrorBase
|
4
|
+
{
|
5
|
+
public PullRequestExistsForSecurityUpdate(Dependency[] dependencies)
|
6
|
+
: base("pull_request_exists_for_security_update")
|
7
|
+
{
|
8
|
+
Details["updated-dependencies"] = dependencies.Select(d => new Dictionary<string, object>()
|
9
|
+
{
|
10
|
+
["dependency-name"] = d.Name,
|
11
|
+
["dependency-version"] = d.Version!,
|
12
|
+
["dependency-removed"] = false,
|
13
|
+
}).ToArray();
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
|
+
|
3
|
+
public record SecurityUpdateNotFound : JobErrorBase
|
4
|
+
{
|
5
|
+
public SecurityUpdateNotFound(string dependencyName, string dependencyVersion)
|
6
|
+
: base("security_update_not_found")
|
7
|
+
{
|
8
|
+
Details["dependency-name"] = dependencyName;
|
9
|
+
Details["dependency-version"] = dependencyVersion;
|
10
|
+
}
|
11
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
|
+
|
3
|
+
public record SecurityUpdateNotPossible : JobErrorBase
|
4
|
+
{
|
5
|
+
public SecurityUpdateNotPossible(string dependencyName, string latestResolvableVersion, string lowestNonVulnerableVersion, string[] conflictingDependencies)
|
6
|
+
: base("security_update_not_possible")
|
7
|
+
{
|
8
|
+
Details["dependency-name"] = dependencyName;
|
9
|
+
Details["latest-resolvable-version"] = latestResolvableVersion;
|
10
|
+
Details["lowest-non-vulnerable-version"] = lowestNonVulnerableVersion;
|
11
|
+
Details["conflicting-dependencies"] = conflictingDependencies;
|
12
|
+
}
|
13
|
+
}
|
@@ -2,6 +2,8 @@ using System.Collections.Immutable;
|
|
2
2
|
using System.Text;
|
3
3
|
using System.Text.Json.Serialization;
|
4
4
|
|
5
|
+
using static NuGetUpdater.Core.Run.ApiModel.CreatePullRequest;
|
6
|
+
|
5
7
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
6
8
|
|
7
9
|
public sealed record UpdatePullRequest : MessageBase
|
@@ -24,7 +26,11 @@ public sealed record UpdatePullRequest : MessageBase
|
|
24
26
|
[JsonPropertyName("commit-message")]
|
25
27
|
public required string CommitMessage { get; init; }
|
26
28
|
|
29
|
+
/// <summary>
|
30
|
+
/// This is serialized as either `null` or `{"name": "group-name"}`.
|
31
|
+
/// </summary>
|
27
32
|
[JsonPropertyName("dependency-group")]
|
33
|
+
[JsonConverter(typeof(DependencyGroupConverter))]
|
28
34
|
public required string? DependencyGroup { get; init; }
|
29
35
|
|
30
36
|
public override string GetReport()
|