dependabot-nuget 0.282.0 → 0.284.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/Commands/CloneCommand.cs +40 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +144 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/IGitCommandHandler.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +37 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotFound.cs +5 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +9 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobRepoNotFound.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobSource.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MarkAsProcessed.cs +6 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs +5 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UnknownError.cs +5 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdateNotPossible.cs +5 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs +8 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +5 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +30 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +183 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/TestGitCommandHandler.cs +16 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +4 -15
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +225 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +106 -0
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0604d43cad05ef88f7471259b903ec56c1cf7d1bcf127b253bf6c0c2af8c66f0
|
4
|
+
data.tar.gz: 9e4b41b0d72f5989abb57bc18f39116a1a2f5c00f935c7a0c2858e61da6bcb75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f4b7300174349f5a5c5a5ebdc461a18ea2c08a06b0229043216e2f3b19bc5a5c2523f43735f0aeafd95f0bffea693791f307165dbb22a1d58ab81f19e89496e
|
7
|
+
data.tar.gz: '0761288866aa1af50029cbd2f61d2423e06f51d090ed8ca4afb3b5afb9a4aa4b5389fa57a1fdad03b0de95895d3b43eb612cbb992660b44ca854bcc8303f1733'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
using System.CommandLine;
|
2
|
+
|
3
|
+
using NuGetUpdater.Core;
|
4
|
+
using NuGetUpdater.Core.Clone;
|
5
|
+
using NuGetUpdater.Core.Run;
|
6
|
+
|
7
|
+
namespace NuGetUpdater.Cli.Commands;
|
8
|
+
|
9
|
+
internal static class CloneCommand
|
10
|
+
{
|
11
|
+
internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
|
12
|
+
internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { IsRequired = true };
|
13
|
+
internal static readonly Option<Uri> ApiUrlOption = new("--api-url") { IsRequired = true };
|
14
|
+
internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
|
15
|
+
|
16
|
+
internal static Command GetCommand(Action<int> setExitCode)
|
17
|
+
{
|
18
|
+
var command = new Command("clone", "Clones a repository in preparation for a dependabot job.")
|
19
|
+
{
|
20
|
+
JobPathOption,
|
21
|
+
RepoContentsPathOption,
|
22
|
+
ApiUrlOption,
|
23
|
+
JobIdOption,
|
24
|
+
};
|
25
|
+
|
26
|
+
command.TreatUnmatchedTokensAsErrors = true;
|
27
|
+
|
28
|
+
command.SetHandler(async (jobPath, repoContentsPath, apiUrl, jobId) =>
|
29
|
+
{
|
30
|
+
var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
|
31
|
+
var logger = new ConsoleLogger();
|
32
|
+
var gitCommandHandler = new ShellGitCommandHandler(logger);
|
33
|
+
var worker = new CloneWorker(apiHandler, gitCommandHandler, logger);
|
34
|
+
var exitCode = await worker.RunAsync(jobPath, repoContentsPath);
|
35
|
+
setExitCode(exitCode);
|
36
|
+
}, JobPathOption, RepoContentsPathOption, ApiUrlOption, JobIdOption);
|
37
|
+
|
38
|
+
return command;
|
39
|
+
}
|
40
|
+
}
|
@@ -0,0 +1,144 @@
|
|
1
|
+
using System.Net;
|
2
|
+
|
3
|
+
using NuGetUpdater.Core.Run;
|
4
|
+
using NuGetUpdater.Core.Run.ApiModel;
|
5
|
+
|
6
|
+
using CommandArguments = (string[] Args, string? WorkingDirectory);
|
7
|
+
|
8
|
+
namespace NuGetUpdater.Core.Clone;
|
9
|
+
|
10
|
+
public class CloneWorker
|
11
|
+
{
|
12
|
+
private readonly IApiHandler _apiHandler;
|
13
|
+
private readonly IGitCommandHandler _gitCommandHandler;
|
14
|
+
private readonly ILogger _logger;
|
15
|
+
|
16
|
+
public CloneWorker(IApiHandler apiHandler, IGitCommandHandler gitCommandHandler, ILogger logger)
|
17
|
+
{
|
18
|
+
_apiHandler = apiHandler;
|
19
|
+
_gitCommandHandler = gitCommandHandler;
|
20
|
+
_logger = logger;
|
21
|
+
}
|
22
|
+
|
23
|
+
// entrypoint for cli
|
24
|
+
public async Task<int> RunAsync(FileInfo jobFilePath, DirectoryInfo repoContentsPath)
|
25
|
+
{
|
26
|
+
var jobFileContent = await File.ReadAllTextAsync(jobFilePath.FullName);
|
27
|
+
var jobWrapper = RunWorker.Deserialize(jobFileContent);
|
28
|
+
var result = await RunAsync(jobWrapper.Job, repoContentsPath.FullName);
|
29
|
+
return result;
|
30
|
+
}
|
31
|
+
|
32
|
+
// object model entry point
|
33
|
+
public async Task<int> RunAsync(Job job, string repoContentsPath)
|
34
|
+
{
|
35
|
+
JobErrorBase? error = null;
|
36
|
+
try
|
37
|
+
{
|
38
|
+
var commandArgs = GetAllCommandArgs(job, repoContentsPath);
|
39
|
+
foreach (var (args, workingDirectory) in commandArgs)
|
40
|
+
{
|
41
|
+
await _gitCommandHandler.RunGitCommandAsync(args, workingDirectory);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
catch (HttpRequestException ex)
|
45
|
+
when (ex.StatusCode == HttpStatusCode.Unauthorized || ex.StatusCode == HttpStatusCode.Forbidden)
|
46
|
+
{
|
47
|
+
error = new JobRepoNotFound(ex.Message);
|
48
|
+
}
|
49
|
+
catch (Exception ex)
|
50
|
+
{
|
51
|
+
error = new UnknownError(ex.ToString());
|
52
|
+
}
|
53
|
+
|
54
|
+
if (error is not null)
|
55
|
+
{
|
56
|
+
await _apiHandler.RecordUpdateJobError(error);
|
57
|
+
await _apiHandler.MarkAsProcessed(new("unknown"));
|
58
|
+
return 1;
|
59
|
+
}
|
60
|
+
|
61
|
+
return 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
internal static CommandArguments[] GetAllCommandArgs(Job job, string repoContentsPath)
|
65
|
+
{
|
66
|
+
var commandArgs = new List<CommandArguments>()
|
67
|
+
{
|
68
|
+
GetCloneArgs(job, repoContentsPath)
|
69
|
+
};
|
70
|
+
|
71
|
+
if (job.Source.Commit is { } commit)
|
72
|
+
{
|
73
|
+
commandArgs.Add(GetFetchArgs(commit, repoContentsPath));
|
74
|
+
commandArgs.Add(GetResetArgs(commit, repoContentsPath));
|
75
|
+
}
|
76
|
+
|
77
|
+
return commandArgs.ToArray();
|
78
|
+
}
|
79
|
+
|
80
|
+
internal static CommandArguments GetCloneArgs(Job job, string repoContentsPath)
|
81
|
+
{
|
82
|
+
var url = GetRepoUrl(job);
|
83
|
+
var args = new List<string>()
|
84
|
+
{
|
85
|
+
"clone",
|
86
|
+
"--no-tags",
|
87
|
+
"--depth",
|
88
|
+
"1",
|
89
|
+
"--recurse-submodules",
|
90
|
+
"--shallow-submodules",
|
91
|
+
};
|
92
|
+
|
93
|
+
if (job.Source.Branch is { } branch)
|
94
|
+
{
|
95
|
+
args.Add("--branch");
|
96
|
+
args.Add(branch);
|
97
|
+
args.Add("--single-branch");
|
98
|
+
}
|
99
|
+
|
100
|
+
args.Add(url);
|
101
|
+
args.Add(repoContentsPath);
|
102
|
+
return (args.ToArray(), null);
|
103
|
+
}
|
104
|
+
|
105
|
+
internal static CommandArguments GetFetchArgs(string commit, string repoContentsPath)
|
106
|
+
{
|
107
|
+
return
|
108
|
+
(
|
109
|
+
[
|
110
|
+
"fetch",
|
111
|
+
"--depth",
|
112
|
+
"1",
|
113
|
+
"--recurse-submodules=on-demand",
|
114
|
+
"origin",
|
115
|
+
commit
|
116
|
+
],
|
117
|
+
repoContentsPath
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
internal static CommandArguments GetResetArgs(string commit, string repoContentsPath)
|
122
|
+
{
|
123
|
+
return
|
124
|
+
(
|
125
|
+
[
|
126
|
+
"reset",
|
127
|
+
"--hard",
|
128
|
+
"--recurse-submodules",
|
129
|
+
commit
|
130
|
+
],
|
131
|
+
repoContentsPath
|
132
|
+
);
|
133
|
+
}
|
134
|
+
|
135
|
+
private static string GetRepoUrl(Job job)
|
136
|
+
{
|
137
|
+
return job.Source.Provider switch
|
138
|
+
{
|
139
|
+
"azure" => $"https://dev.azure.com/{job.Source.Repo}",
|
140
|
+
"github" => $"https://github.com/{job.Source.Repo}",
|
141
|
+
_ => throw new ArgumentException($"Unknown provider: {job.Source.Provider}")
|
142
|
+
};
|
143
|
+
}
|
144
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
using System.Net;
|
2
|
+
|
3
|
+
namespace NuGetUpdater.Core.Clone;
|
4
|
+
|
5
|
+
public class ShellGitCommandHandler : IGitCommandHandler
|
6
|
+
{
|
7
|
+
private readonly ILogger _logger;
|
8
|
+
|
9
|
+
public ShellGitCommandHandler(ILogger logger)
|
10
|
+
{
|
11
|
+
_logger = logger;
|
12
|
+
}
|
13
|
+
|
14
|
+
public async Task RunGitCommandAsync(IReadOnlyCollection<string> args, string? workingDirectory = null)
|
15
|
+
{
|
16
|
+
_logger.Log($"Running command: git {string.Join(" ", args)}{(workingDirectory is null ? "" : $" in directory {workingDirectory}")}");
|
17
|
+
var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("git", args, workingDirectory);
|
18
|
+
HandleErrorsFromOutput(stdout, stderr);
|
19
|
+
}
|
20
|
+
|
21
|
+
internal static void HandleErrorsFromOutput(string stdout, string stderr)
|
22
|
+
{
|
23
|
+
foreach (var output in new[] { stdout, stderr })
|
24
|
+
{
|
25
|
+
ThrowOnUnauthenticated(output);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
private static void ThrowOnUnauthenticated(string output)
|
30
|
+
{
|
31
|
+
if (output.Contains("Authentication failed for") ||
|
32
|
+
output.Contains("could not read Username for"))
|
33
|
+
{
|
34
|
+
throw new HttpRequestException(output, inner: null, statusCode: HttpStatusCode.Unauthorized);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
@@ -2,5 +2,9 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
2
2
|
|
3
3
|
public record DependencyFileNotFound : JobErrorBase
|
4
4
|
{
|
5
|
-
public
|
5
|
+
public DependencyFileNotFound(string filePath)
|
6
|
+
: base("dependency_file_not_found")
|
7
|
+
{
|
8
|
+
Details = filePath;
|
9
|
+
}
|
6
10
|
}
|
@@ -2,7 +2,7 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
2
2
|
|
3
3
|
public sealed record Job
|
4
4
|
{
|
5
|
-
public
|
5
|
+
public string PackageManager { get; init; } = "nuget";
|
6
6
|
public AllowedUpdate[]? AllowedUpdates { get; init; } = null;
|
7
7
|
public bool Debug { get; init; } = false;
|
8
8
|
public object[]? DependencyGroups { get; init; } = null;
|
@@ -4,8 +4,15 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
4
4
|
|
5
5
|
public abstract record JobErrorBase
|
6
6
|
{
|
7
|
+
public JobErrorBase(string type)
|
8
|
+
{
|
9
|
+
Type = type;
|
10
|
+
}
|
11
|
+
|
7
12
|
[JsonPropertyName("error-type")]
|
8
|
-
public
|
13
|
+
public string Type { get; }
|
14
|
+
|
9
15
|
[JsonPropertyName("error-details")]
|
10
|
-
|
16
|
+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
17
|
+
public object? Details { get; init; } = null;
|
11
18
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
2
|
+
|
3
|
+
public record JobRepoNotFound : JobErrorBase
|
4
|
+
{
|
5
|
+
public JobRepoNotFound(string message)
|
6
|
+
: base("job_repo_not_found")
|
7
|
+
{
|
8
|
+
Details = new Dictionary<string, string>()
|
9
|
+
{
|
10
|
+
["message"] = message
|
11
|
+
};
|
12
|
+
}
|
13
|
+
}
|
@@ -4,6 +4,8 @@ public sealed class JobSource
|
|
4
4
|
{
|
5
5
|
public required string Provider { get; init; }
|
6
6
|
public required string Repo { get; init; }
|
7
|
+
public string? Branch { get; init; } = null;
|
8
|
+
public string? Commit { get; init; } = null;
|
7
9
|
public string? Directory { get; init; } = null;
|
8
10
|
public string[]? Directories { get; init; } = null;
|
9
11
|
public string? Hostname { get; init; } = null;
|
@@ -4,6 +4,11 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
4
4
|
|
5
5
|
public sealed record MarkAsProcessed
|
6
6
|
{
|
7
|
+
public MarkAsProcessed(string baseCommitSha)
|
8
|
+
{
|
9
|
+
BaseCommitSha = baseCommitSha;
|
10
|
+
}
|
11
|
+
|
7
12
|
[JsonPropertyName("base-commit-sha")]
|
8
|
-
public
|
13
|
+
public string BaseCommitSha { get; }
|
9
14
|
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs
CHANGED
@@ -2,5 +2,9 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
2
2
|
|
3
3
|
public record PrivateSourceAuthenticationFailure : JobErrorBase
|
4
4
|
{
|
5
|
-
public
|
5
|
+
public PrivateSourceAuthenticationFailure(string[] urls)
|
6
|
+
: base("private_source_authentication_failure")
|
7
|
+
{
|
8
|
+
Details = $"({string.Join("|", urls)})";
|
9
|
+
}
|
6
10
|
}
|
@@ -2,5 +2,9 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
2
2
|
|
3
3
|
public record UpdateNotPossible : JobErrorBase
|
4
4
|
{
|
5
|
-
public
|
5
|
+
public UpdateNotPossible(string[] dependencies)
|
6
|
+
: base("update_not_possible")
|
7
|
+
{
|
8
|
+
Details = dependencies;
|
9
|
+
}
|
6
10
|
}
|
@@ -50,13 +50,19 @@ public class HttpApiHandler : IApiHandler
|
|
50
50
|
await PostAsJson("mark_as_processed", markAsProcessed);
|
51
51
|
}
|
52
52
|
|
53
|
-
|
53
|
+
internal static string Serialize(object body)
|
54
54
|
{
|
55
55
|
var wrappedBody = new
|
56
56
|
{
|
57
|
-
Data = body
|
57
|
+
Data = body
|
58
58
|
};
|
59
59
|
var payload = JsonSerializer.Serialize(wrappedBody, SerializerOptions);
|
60
|
+
return payload;
|
61
|
+
}
|
62
|
+
|
63
|
+
private async Task PostAsJson(string endpoint, object body)
|
64
|
+
{
|
65
|
+
var payload = Serialize(body);
|
60
66
|
var content = new StringContent(payload, Encoding.UTF8, "application/json");
|
61
67
|
var response = await HttpClient.PostAsync($"{_apiUrl}/update_jobs/{_jobId}/{endpoint}", content);
|
62
68
|
var _ = response.EnsureSuccessStatusCode();
|
@@ -76,31 +76,19 @@ public class RunWorker
|
|
76
76
|
catch (HttpRequestException ex)
|
77
77
|
when (ex.StatusCode == HttpStatusCode.Unauthorized || ex.StatusCode == HttpStatusCode.Forbidden)
|
78
78
|
{
|
79
|
-
error = new PrivateSourceAuthenticationFailure()
|
80
|
-
{
|
81
|
-
Details = $"({string.Join("|", lastUsedPackageSourceUrls)})",
|
82
|
-
};
|
79
|
+
error = new PrivateSourceAuthenticationFailure(lastUsedPackageSourceUrls);
|
83
80
|
}
|
84
81
|
catch (MissingFileException ex)
|
85
82
|
{
|
86
|
-
error = new DependencyFileNotFound()
|
87
|
-
{
|
88
|
-
Details = ex.FilePath,
|
89
|
-
};
|
83
|
+
error = new DependencyFileNotFound(ex.FilePath);
|
90
84
|
}
|
91
85
|
catch (UpdateNotPossibleException ex)
|
92
86
|
{
|
93
|
-
error = new UpdateNotPossible()
|
94
|
-
{
|
95
|
-
Details = ex.Dependencies,
|
96
|
-
};
|
87
|
+
error = new UpdateNotPossible(ex.Dependencies);
|
97
88
|
}
|
98
89
|
catch (Exception ex)
|
99
90
|
{
|
100
|
-
error = new UnknownError()
|
101
|
-
{
|
102
|
-
Details = ex.ToString(),
|
103
|
-
};
|
91
|
+
error = new UnknownError(ex.ToString());
|
104
92
|
}
|
105
93
|
|
106
94
|
if (error is not null)
|
@@ -108,7 +96,7 @@ public class RunWorker
|
|
108
96
|
await _apiHandler.RecordUpdateJobError(error);
|
109
97
|
}
|
110
98
|
|
111
|
-
await _apiHandler.MarkAsProcessed(new(
|
99
|
+
await _apiHandler.MarkAsProcessed(new(baseCommitSha));
|
112
100
|
|
113
101
|
return runResult;
|
114
102
|
}
|
@@ -28,7 +28,9 @@ internal static class BindingRedirectManager
|
|
28
28
|
/// https://learn.microsoft.com/en-us/nuget/resources/check-project-format
|
29
29
|
/// </remarks>
|
30
30
|
/// <param name="projectBuildFile">The project build file (*.xproj) to be updated</param>
|
31
|
-
|
31
|
+
/// <param name="updatedPackageName"/>The name of the package that was updated</param>
|
32
|
+
/// <param name="updatedPackageVersion">The version of the package that was updated</param>
|
33
|
+
public static async ValueTask UpdateBindingRedirectsAsync(ProjectBuildFile projectBuildFile, string updatedPackageName, string updatedPackageVersion)
|
32
34
|
{
|
33
35
|
var configFile = await TryGetRuntimeConfigurationFile(projectBuildFile);
|
34
36
|
if (configFile is null)
|
@@ -47,7 +49,20 @@ internal static class BindingRedirectManager
|
|
47
49
|
return;
|
48
50
|
}
|
49
51
|
|
50
|
-
|
52
|
+
// we need to detect what assembly references come from the newly updated package; the `HintPath` will look like
|
53
|
+
// ..\packages\Some.Package.1.2.3\lib\net45\Some.Package.dll
|
54
|
+
// so we first pull out the packages sub-path, e.g., `..\packages`
|
55
|
+
// then we add the updated package name, version, and a trailing directory separator and ensure it's a unix-style path
|
56
|
+
// e.g., ../packages/Some.Package/1.2.3/
|
57
|
+
// at this point any assembly in that directory is from the updated package and will need a binding redirect
|
58
|
+
// finally we pull out the assembly `HintPath` values for _all_ references relative to the project file in a unix-style value
|
59
|
+
// e.g., ../packages/Some.Other.Package/4.5.6/lib/net45/Some.Other.Package.dll
|
60
|
+
// all of that is passed to `AddBindingRedirects()` so we can ensure binding redirects for the relevant assemblies
|
61
|
+
var packagesDirectory = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, updatedPackageName, updatedPackageVersion, packagesConfigPath: null)!;
|
62
|
+
var assemblyPathPrefix = Path.Combine(packagesDirectory, $"{updatedPackageName}.{updatedPackageVersion}").NormalizePathToUnix().EnsureSuffix("/");
|
63
|
+
var assemblyPaths = references.Select(static x => x.HintPath).Select(x => Path.GetRelativePath(Path.GetDirectoryName(projectBuildFile.Path)!, x).NormalizePathToUnix()).ToList();
|
64
|
+
var bindingsAndAssemblyPaths = bindings.Zip(assemblyPaths);
|
65
|
+
var fileContent = AddBindingRedirects(configFile, bindingsAndAssemblyPaths, assemblyPathPrefix);
|
51
66
|
configFile = configFile with { Content = fileContent };
|
52
67
|
|
53
68
|
await File.WriteAllTextAsync(configFile.Path, configFile.Content);
|
@@ -161,10 +176,10 @@ internal static class BindingRedirectManager
|
|
161
176
|
}
|
162
177
|
}
|
163
178
|
|
164
|
-
private static string AddBindingRedirects(ConfigurationFile configFile, IEnumerable<Runtime_AssemblyBinding>
|
179
|
+
private static string AddBindingRedirects(ConfigurationFile configFile, IEnumerable<(Runtime_AssemblyBinding Binding, string AssemblyPath)> bindingRedirectsAndAssemblyPaths, string assemblyPathPrefix)
|
165
180
|
{
|
166
181
|
// Do nothing if there are no binding redirects to add, bail out
|
167
|
-
if (!
|
182
|
+
if (!bindingRedirectsAndAssemblyPaths.Any())
|
168
183
|
{
|
169
184
|
return configFile.Content;
|
170
185
|
}
|
@@ -185,7 +200,7 @@ internal static class BindingRedirectManager
|
|
185
200
|
// Get all of the current bindings in config
|
186
201
|
var currentBindings = GetAssemblyBindings(runtime);
|
187
202
|
|
188
|
-
foreach (var bindingRedirect in
|
203
|
+
foreach (var (bindingRedirect, assemblyPath) in bindingRedirectsAndAssemblyPaths)
|
189
204
|
{
|
190
205
|
// If the binding redirect already exists in config, update it. Otherwise, add it.
|
191
206
|
var bindingAssemblyIdentity = new AssemblyIdentity(bindingRedirect.Name, bindingRedirect.PublicKeyToken);
|
@@ -208,11 +223,17 @@ internal static class BindingRedirectManager
|
|
208
223
|
}
|
209
224
|
else
|
210
225
|
{
|
211
|
-
//
|
212
|
-
|
226
|
+
// only add a previously missing binding redirect if it's related to the package that caused the whole update
|
227
|
+
// this isn't strictly necessary, but can be helpful to the end user and it's easy for them to revert if they
|
228
|
+
// don't like this particular change
|
229
|
+
if (assemblyPath.StartsWith(assemblyPathPrefix, StringComparison.OrdinalIgnoreCase))
|
230
|
+
{
|
231
|
+
// Get an assembly binding element to use
|
232
|
+
var assemblyBindingElement = GetAssemblyBindingElement(runtime);
|
213
233
|
|
214
|
-
|
215
|
-
|
234
|
+
// Add the binding to that element
|
235
|
+
assemblyBindingElement.AddIndented(bindingRedirect.ToXElement());
|
236
|
+
}
|
216
237
|
}
|
217
238
|
}
|
218
239
|
|
@@ -93,7 +93,7 @@ internal static class PackagesConfigUpdater
|
|
93
93
|
projectBuildFile.NormalizeDirectorySeparatorsInProject();
|
94
94
|
|
95
95
|
// Update binding redirects
|
96
|
-
await BindingRedirectManager.UpdateBindingRedirectsAsync(projectBuildFile);
|
96
|
+
await BindingRedirectManager.UpdateBindingRedirectsAsync(projectBuildFile, dependencyName, newDependencyVersion);
|
97
97
|
|
98
98
|
logger.Log(" Writing project file back to disk");
|
99
99
|
await projectBuildFile.SaveAsync();
|
@@ -196,7 +196,7 @@ internal static class PackagesConfigUpdater
|
|
196
196
|
return processes;
|
197
197
|
}
|
198
198
|
|
199
|
-
internal static string? GetPathToPackagesDirectory(ProjectBuildFile projectBuildFile, string dependencyName, string dependencyVersion, string packagesConfigPath)
|
199
|
+
internal static string? GetPathToPackagesDirectory(ProjectBuildFile projectBuildFile, string dependencyName, string dependencyVersion, string? packagesConfigPath)
|
200
200
|
{
|
201
201
|
// the packages directory can be found from the hint path of the matching dependency, e.g., when given "Newtonsoft.Json", "7.0.1", and a project like this:
|
202
202
|
// <Project>
|
@@ -242,7 +242,7 @@ internal static class PackagesConfigUpdater
|
|
242
242
|
}
|
243
243
|
}
|
244
244
|
|
245
|
-
if (partialPathMatch is null)
|
245
|
+
if (partialPathMatch is null && packagesConfigPath is not null)
|
246
246
|
{
|
247
247
|
// if we got this far, we couldn't find the packages directory for the specified dependency and there are 2 possibilities:
|
248
248
|
// 1. the dependency doesn't actually exist in this project
|
@@ -27,6 +27,8 @@ internal static class PathHelper
|
|
27
27
|
|
28
28
|
public static string EnsurePrefix(this string s, string prefix) => s.StartsWith(prefix) ? s : prefix + s;
|
29
29
|
|
30
|
+
public static string EnsureSuffix(this string s, string suffix) => s.EndsWith(suffix) ? s : s + suffix;
|
31
|
+
|
30
32
|
public static string NormalizePathToUnix(this string path) => path.Replace("\\", "/");
|
31
33
|
|
32
34
|
public static string NormalizeUnixPathParts(this string path)
|
@@ -0,0 +1,183 @@
|
|
1
|
+
using NuGetUpdater.Core.Clone;
|
2
|
+
using NuGetUpdater.Core.Run.ApiModel;
|
3
|
+
using NuGetUpdater.Core.Test.Run;
|
4
|
+
|
5
|
+
using Xunit;
|
6
|
+
|
7
|
+
namespace NuGetUpdater.Core.Test.Clone;
|
8
|
+
|
9
|
+
public class CloneWorkerTests
|
10
|
+
{
|
11
|
+
private const string TestRepoPath = "TEST/REPO/PATH";
|
12
|
+
|
13
|
+
[Fact]
|
14
|
+
public void CloneCommandsAreGenerated()
|
15
|
+
{
|
16
|
+
TestCommands(
|
17
|
+
provider: "github",
|
18
|
+
repoMoniker: "test/repo",
|
19
|
+
expectedCommands:
|
20
|
+
[
|
21
|
+
(["clone", "--no-tags", "--depth", "1", "--recurse-submodules", "--shallow-submodules", "https://github.com/test/repo", TestRepoPath], null)
|
22
|
+
]
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
[Fact]
|
27
|
+
public void CloneCommandsAreGeneratedWhenBranchIsSpecified()
|
28
|
+
{
|
29
|
+
TestCommands(
|
30
|
+
provider: "github",
|
31
|
+
repoMoniker: "test/repo",
|
32
|
+
branch: "some-branch",
|
33
|
+
expectedCommands:
|
34
|
+
[
|
35
|
+
(["clone", "--no-tags", "--depth", "1", "--recurse-submodules", "--shallow-submodules", "--branch", "some-branch", "--single-branch", "https://github.com/test/repo", TestRepoPath], null)
|
36
|
+
]
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
[Fact]
|
41
|
+
public void CloneCommandsAreGeneratedWhenCommitIsSpecified()
|
42
|
+
{
|
43
|
+
TestCommands(
|
44
|
+
provider: "github",
|
45
|
+
repoMoniker: "test/repo",
|
46
|
+
commit: "abc123",
|
47
|
+
expectedCommands:
|
48
|
+
[
|
49
|
+
(["clone", "--no-tags", "--depth", "1", "--recurse-submodules", "--shallow-submodules", "https://github.com/test/repo", TestRepoPath], null),
|
50
|
+
(["fetch", "--depth", "1", "--recurse-submodules=on-demand", "origin", "abc123"], TestRepoPath),
|
51
|
+
(["reset", "--hard", "--recurse-submodules", "abc123"], TestRepoPath)
|
52
|
+
]
|
53
|
+
);
|
54
|
+
}
|
55
|
+
|
56
|
+
[Fact]
|
57
|
+
public async Task SuccessfulCloneGeneratesNoApiMessages()
|
58
|
+
{
|
59
|
+
await TestCloneAsync(
|
60
|
+
provider: "github",
|
61
|
+
repoMoniker: "test/repo",
|
62
|
+
expectedApiMessages: []
|
63
|
+
);
|
64
|
+
}
|
65
|
+
|
66
|
+
[Fact]
|
67
|
+
public async Task UnauthorizedCloneGeneratesTheExpectedApiMessagesFromGenericOutput()
|
68
|
+
{
|
69
|
+
await TestCloneAsync(
|
70
|
+
provider: "github",
|
71
|
+
repoMoniker: "test/repo",
|
72
|
+
testGitCommandHandler: new TestGitCommandHandlerWithOutputs("Authentication failed for repo", ""),
|
73
|
+
expectedApiMessages:
|
74
|
+
[
|
75
|
+
new JobRepoNotFound("Authentication failed for repo"),
|
76
|
+
new MarkAsProcessed("unknown"),
|
77
|
+
],
|
78
|
+
expectedExitCode: 1
|
79
|
+
);
|
80
|
+
}
|
81
|
+
|
82
|
+
[Fact]
|
83
|
+
public async Task UnauthorizedCloneGeneratesTheExpectedApiMessagesFromGitCommandOutput()
|
84
|
+
{
|
85
|
+
await TestCloneAsync(
|
86
|
+
provider: "github",
|
87
|
+
repoMoniker: "test/repo",
|
88
|
+
testGitCommandHandler: new TestGitCommandHandlerWithOutputs("", "fatal: could not read Username for 'https://github.com': No such device or address"),
|
89
|
+
expectedApiMessages:
|
90
|
+
[
|
91
|
+
new JobRepoNotFound("fatal: could not read Username for 'https://github.com': No such device or address"),
|
92
|
+
new MarkAsProcessed("unknown"),
|
93
|
+
],
|
94
|
+
expectedExitCode: 1
|
95
|
+
);
|
96
|
+
}
|
97
|
+
|
98
|
+
private class TestGitCommandHandlerWithOutputs : TestGitCommandHandler
|
99
|
+
{
|
100
|
+
private readonly string _stdout;
|
101
|
+
private readonly string _stderr;
|
102
|
+
|
103
|
+
public TestGitCommandHandlerWithOutputs(string stdout, string stderr)
|
104
|
+
{
|
105
|
+
_stdout = stdout;
|
106
|
+
_stderr = stderr;
|
107
|
+
}
|
108
|
+
|
109
|
+
public override async Task RunGitCommandAsync(IReadOnlyCollection<string> args, string? workingDirectory = null)
|
110
|
+
{
|
111
|
+
await base.RunGitCommandAsync(args, workingDirectory);
|
112
|
+
ShellGitCommandHandler.HandleErrorsFromOutput(_stdout, _stderr);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
private static void TestCommands(string provider, string repoMoniker, (string[] Args, string? WorkingDirectory)[] expectedCommands, string? branch = null, string? commit = null)
|
117
|
+
{
|
118
|
+
var job = new Job()
|
119
|
+
{
|
120
|
+
Source = new()
|
121
|
+
{
|
122
|
+
Provider = provider,
|
123
|
+
Repo = repoMoniker,
|
124
|
+
Branch = branch,
|
125
|
+
Commit = commit,
|
126
|
+
}
|
127
|
+
};
|
128
|
+
var actualCommands = CloneWorker.GetAllCommandArgs(job, TestRepoPath);
|
129
|
+
VerifyCommands(expectedCommands, actualCommands);
|
130
|
+
}
|
131
|
+
|
132
|
+
private static async Task TestCloneAsync(string provider, string repoMoniker, object[] expectedApiMessages, string? branch = null, string? commit = null, TestGitCommandHandler? testGitCommandHandler = null, int expectedExitCode = 0)
|
133
|
+
{
|
134
|
+
// arrange
|
135
|
+
var testApiHandler = new TestApiHandler();
|
136
|
+
testGitCommandHandler ??= new TestGitCommandHandler();
|
137
|
+
var testLogger = new TestLogger();
|
138
|
+
var worker = new CloneWorker(testApiHandler, testGitCommandHandler, testLogger);
|
139
|
+
|
140
|
+
// act
|
141
|
+
var job = new Job()
|
142
|
+
{
|
143
|
+
Source = new()
|
144
|
+
{
|
145
|
+
Provider = provider,
|
146
|
+
Repo = repoMoniker,
|
147
|
+
Branch = branch,
|
148
|
+
Commit = commit,
|
149
|
+
}
|
150
|
+
};
|
151
|
+
var exitCode = await worker.RunAsync(job, TestRepoPath);
|
152
|
+
|
153
|
+
// assert
|
154
|
+
Assert.Equal(expectedExitCode, exitCode);
|
155
|
+
|
156
|
+
var actualApiMessages = testApiHandler.ReceivedMessages.ToArray();
|
157
|
+
if (actualApiMessages.Length > expectedApiMessages.Length)
|
158
|
+
{
|
159
|
+
var extraApiMessages = actualApiMessages.Skip(expectedApiMessages.Length).Select(m => RunWorkerTests.SerializeObjectAndType(m.Object)).ToArray();
|
160
|
+
Assert.Fail($"Expected {expectedApiMessages.Length} API messages, but got {extraApiMessages.Length} extra:\n\t{string.Join("\n\t", extraApiMessages)}");
|
161
|
+
}
|
162
|
+
if (expectedApiMessages.Length > actualApiMessages.Length)
|
163
|
+
{
|
164
|
+
var missingApiMessages = expectedApiMessages.Skip(actualApiMessages.Length).Select(m => RunWorkerTests.SerializeObjectAndType(m)).ToArray();
|
165
|
+
Assert.Fail($"Expected {expectedApiMessages.Length} API messages, but only got {actualApiMessages.Length}; missing:\n\t{string.Join("\n\t", missingApiMessages)}");
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
private static void VerifyCommands((string[] Args, string? WorkingDirectory)[] expected, (string[] Args, string? WorkingDirectory)[] actual)
|
170
|
+
{
|
171
|
+
var expectedCommands = StringifyCommands(expected);
|
172
|
+
var actualCommands = StringifyCommands(actual);
|
173
|
+
Assert.True(expectedCommands.Length == actualCommands.Length, $"Expected {expectedCommands.Length} messages:\n\t{string.Join("\n\t", expectedCommands)}\ngot {actualCommands.Length}:\n\t{string.Join("\n\t", actualCommands)}");
|
174
|
+
foreach (var (expectedCommand, actualCommand) in expectedCommands.Zip(actualCommands))
|
175
|
+
{
|
176
|
+
Assert.Equal(expectedCommand, actualCommand);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
private static string[] StringifyCommands((string[] Args, string? WorkingDirectory)[] commandArgs) => commandArgs.Select(a => StringifyCommand(a.Args, a.WorkingDirectory)).ToArray();
|
181
|
+
private static string StringifyCommand(string[] args, string? workingDirectory) => $"args=[{string.Join(", ", args)}], workingDirectory={ReplaceWorkingDirectory(workingDirectory)}";
|
182
|
+
private static string ReplaceWorkingDirectory(string? arg) => arg ?? "NULL";
|
183
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
using NuGetUpdater.Core.Clone;
|
2
|
+
|
3
|
+
namespace NuGetUpdater.Core.Test.Clone;
|
4
|
+
|
5
|
+
internal class TestGitCommandHandler : IGitCommandHandler
|
6
|
+
{
|
7
|
+
private readonly List<(string[] Args, string? WorkingDirectory)> _seenCommands = new();
|
8
|
+
|
9
|
+
public IReadOnlyCollection<(string[] Args, string? WorkingDirectory)> SeenCommands => _seenCommands;
|
10
|
+
|
11
|
+
public virtual Task RunGitCommandAsync(IReadOnlyCollection<string> args, string? workingDirectory = null)
|
12
|
+
{
|
13
|
+
_seenCommands.Add((args.ToArray(), workingDirectory));
|
14
|
+
return Task.CompletedTask;
|
15
|
+
}
|
16
|
+
}
|
@@ -26,7 +26,6 @@ public class RunWorkerTests
|
|
26
26
|
],
|
27
27
|
job: new Job()
|
28
28
|
{
|
29
|
-
PackageManager = "nuget",
|
30
29
|
Source = new()
|
31
30
|
{
|
32
31
|
Provider = "github",
|
@@ -161,10 +160,7 @@ public class RunWorkerTests
|
|
161
160
|
PrTitle = "TODO: title",
|
162
161
|
PrBody = "TODO: body",
|
163
162
|
},
|
164
|
-
new MarkAsProcessed()
|
165
|
-
{
|
166
|
-
BaseCommitSha = "TEST-COMMIT-SHA",
|
167
|
-
}
|
163
|
+
new MarkAsProcessed("TEST-COMMIT-SHA")
|
168
164
|
]
|
169
165
|
);
|
170
166
|
}
|
@@ -209,7 +205,6 @@ public class RunWorkerTests
|
|
209
205
|
],
|
210
206
|
job: new Job()
|
211
207
|
{
|
212
|
-
PackageManager = "nuget",
|
213
208
|
Source = new()
|
214
209
|
{
|
215
210
|
Provider = "github",
|
@@ -249,14 +244,8 @@ public class RunWorkerTests
|
|
249
244
|
},
|
250
245
|
expectedApiMessages:
|
251
246
|
[
|
252
|
-
new PrivateSourceAuthenticationFailure()
|
253
|
-
|
254
|
-
Details = $"({http.BaseUrl.TrimEnd('/')}/index.json)"
|
255
|
-
},
|
256
|
-
new MarkAsProcessed()
|
257
|
-
{
|
258
|
-
BaseCommitSha = "TEST-COMMIT-SHA",
|
259
|
-
}
|
247
|
+
new PrivateSourceAuthenticationFailure([$"{http.BaseUrl.TrimEnd('/')}/index.json"]),
|
248
|
+
new MarkAsProcessed("TEST-COMMIT-SHA")
|
260
249
|
]
|
261
250
|
);
|
262
251
|
}
|
@@ -308,7 +297,7 @@ public class RunWorkerTests
|
|
308
297
|
}
|
309
298
|
}
|
310
299
|
|
311
|
-
|
300
|
+
internal static string SerializeObjectAndType(object obj)
|
312
301
|
{
|
313
302
|
return $"{obj.GetType().Name}:{JsonSerializer.Serialize(obj)}";
|
314
303
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using NuGetUpdater.Core.Run;
|
2
|
+
using NuGetUpdater.Core.Run.ApiModel;
|
2
3
|
|
3
4
|
using Xunit;
|
4
5
|
|
@@ -57,4 +58,13 @@ public class SerializationTests
|
|
57
58
|
Assert.Equal("some-org/some-repo", jobWrapper.Job.Source.Repo);
|
58
59
|
Assert.Equal("specific-sdk", jobWrapper.Job.Source.Directory);
|
59
60
|
}
|
61
|
+
|
62
|
+
[Fact]
|
63
|
+
public void SerializeError()
|
64
|
+
{
|
65
|
+
var error = new JobRepoNotFound("some message");
|
66
|
+
var actual = HttpApiHandler.Serialize(error);
|
67
|
+
var expected = """{"data":{"error-type":"job_repo_not_found","error-details":{"message":"some message"}}}""";
|
68
|
+
Assert.Equal(expected, actual);
|
69
|
+
}
|
60
70
|
}
|
@@ -0,0 +1,225 @@
|
|
1
|
+
using Xunit;
|
2
|
+
|
3
|
+
namespace NuGetUpdater.Core.Test.Update;
|
4
|
+
|
5
|
+
public class BindingRedirectsTests
|
6
|
+
{
|
7
|
+
[Fact]
|
8
|
+
public async Task SimpleBindingRedirectIsPerformed()
|
9
|
+
{
|
10
|
+
await VerifyBindingRedirectsAsync(
|
11
|
+
projectContents: """
|
12
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
13
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
14
|
+
<PropertyGroup>
|
15
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
16
|
+
</PropertyGroup>
|
17
|
+
<ItemGroup>
|
18
|
+
<None Include="app.config" />
|
19
|
+
</ItemGroup>
|
20
|
+
<ItemGroup>
|
21
|
+
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
|
22
|
+
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
|
23
|
+
<Private>True</Private>
|
24
|
+
</Reference>
|
25
|
+
</ItemGroup>
|
26
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
27
|
+
</Project>
|
28
|
+
""",
|
29
|
+
configContents: """
|
30
|
+
<configuration>
|
31
|
+
<runtime>
|
32
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
33
|
+
<dependentAssembly>
|
34
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
35
|
+
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
|
36
|
+
</dependentAssembly>
|
37
|
+
</assemblyBinding>
|
38
|
+
</runtime>
|
39
|
+
</configuration>
|
40
|
+
""",
|
41
|
+
updatedPackageName: "Some.Package",
|
42
|
+
updatedPackageVersion: "2.0.0",
|
43
|
+
expectedConfigContents: """
|
44
|
+
<configuration>
|
45
|
+
<runtime>
|
46
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
47
|
+
<dependentAssembly>
|
48
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
49
|
+
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
50
|
+
</dependentAssembly>
|
51
|
+
</assemblyBinding>
|
52
|
+
</runtime>
|
53
|
+
</configuration>
|
54
|
+
"""
|
55
|
+
);
|
56
|
+
}
|
57
|
+
|
58
|
+
[Fact]
|
59
|
+
public async Task ConfigFileIndentationIsPreserved()
|
60
|
+
{
|
61
|
+
await VerifyBindingRedirectsAsync(
|
62
|
+
projectContents: """
|
63
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
64
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
65
|
+
<PropertyGroup>
|
66
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
67
|
+
</PropertyGroup>
|
68
|
+
<ItemGroup>
|
69
|
+
<None Include="app.config" />
|
70
|
+
</ItemGroup>
|
71
|
+
<ItemGroup>
|
72
|
+
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
|
73
|
+
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
|
74
|
+
<Private>True</Private>
|
75
|
+
</Reference>
|
76
|
+
</ItemGroup>
|
77
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
78
|
+
</Project>
|
79
|
+
""",
|
80
|
+
configContents: """
|
81
|
+
<configuration>
|
82
|
+
<runtime>
|
83
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
84
|
+
<dependentAssembly>
|
85
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
86
|
+
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
|
87
|
+
</dependentAssembly>
|
88
|
+
</assemblyBinding>
|
89
|
+
</runtime>
|
90
|
+
</configuration>
|
91
|
+
""",
|
92
|
+
updatedPackageName: "Some.Package",
|
93
|
+
updatedPackageVersion: "2.0.0",
|
94
|
+
expectedConfigContents: """
|
95
|
+
<configuration>
|
96
|
+
<runtime>
|
97
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
98
|
+
<dependentAssembly>
|
99
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
100
|
+
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
101
|
+
</dependentAssembly>
|
102
|
+
</assemblyBinding>
|
103
|
+
</runtime>
|
104
|
+
</configuration>
|
105
|
+
"""
|
106
|
+
);
|
107
|
+
}
|
108
|
+
|
109
|
+
[Fact]
|
110
|
+
public async Task NoExtraBindingsAreAdded()
|
111
|
+
{
|
112
|
+
await VerifyBindingRedirectsAsync(
|
113
|
+
projectContents: """
|
114
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
115
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
116
|
+
<PropertyGroup>
|
117
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
118
|
+
</PropertyGroup>
|
119
|
+
<ItemGroup>
|
120
|
+
<None Include="app.config" />
|
121
|
+
</ItemGroup>
|
122
|
+
<ItemGroup>
|
123
|
+
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
|
124
|
+
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
|
125
|
+
<Private>True</Private>
|
126
|
+
</Reference>
|
127
|
+
<Reference Include="Some.Unrelated.Package, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null">
|
128
|
+
<HintPath>packages\Some.Unrelated.Package.3.0.0\lib\net45\Some.Package.dll</HintPath>
|
129
|
+
<Private>True</Private>
|
130
|
+
</Reference>
|
131
|
+
</ItemGroup>
|
132
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
133
|
+
</Project>
|
134
|
+
""",
|
135
|
+
configContents: """
|
136
|
+
<configuration>
|
137
|
+
<runtime>
|
138
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
139
|
+
<dependentAssembly>
|
140
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
141
|
+
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
|
142
|
+
</dependentAssembly>
|
143
|
+
</assemblyBinding>
|
144
|
+
</runtime>
|
145
|
+
</configuration>
|
146
|
+
""",
|
147
|
+
updatedPackageName: "Some.Package",
|
148
|
+
updatedPackageVersion: "2.0.0",
|
149
|
+
expectedConfigContents: """
|
150
|
+
<configuration>
|
151
|
+
<runtime>
|
152
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
153
|
+
<dependentAssembly>
|
154
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
155
|
+
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
156
|
+
</dependentAssembly>
|
157
|
+
</assemblyBinding>
|
158
|
+
</runtime>
|
159
|
+
</configuration>
|
160
|
+
"""
|
161
|
+
);
|
162
|
+
}
|
163
|
+
|
164
|
+
[Fact]
|
165
|
+
public async Task NewBindingIsAdded()
|
166
|
+
{
|
167
|
+
await VerifyBindingRedirectsAsync(
|
168
|
+
projectContents: """
|
169
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
170
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
171
|
+
<PropertyGroup>
|
172
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
173
|
+
</PropertyGroup>
|
174
|
+
<ItemGroup>
|
175
|
+
<None Include="app.config" />
|
176
|
+
</ItemGroup>
|
177
|
+
<ItemGroup>
|
178
|
+
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
|
179
|
+
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
|
180
|
+
<Private>True</Private>
|
181
|
+
</Reference>
|
182
|
+
</ItemGroup>
|
183
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
184
|
+
</Project>
|
185
|
+
""",
|
186
|
+
configContents: """
|
187
|
+
<configuration>
|
188
|
+
<runtime />
|
189
|
+
</configuration>
|
190
|
+
""",
|
191
|
+
updatedPackageName: "Some.Package",
|
192
|
+
updatedPackageVersion: "2.0.0",
|
193
|
+
expectedConfigContents: """
|
194
|
+
<configuration>
|
195
|
+
<runtime>
|
196
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
197
|
+
<dependentAssembly>
|
198
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
199
|
+
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
200
|
+
</dependentAssembly>
|
201
|
+
</assemblyBinding>
|
202
|
+
</runtime>
|
203
|
+
</configuration>
|
204
|
+
"""
|
205
|
+
);
|
206
|
+
}
|
207
|
+
|
208
|
+
private static async Task VerifyBindingRedirectsAsync(string projectContents, string configContents, string expectedConfigContents, string updatedPackageName, string updatedPackageVersion, string configFileName = "app.config")
|
209
|
+
{
|
210
|
+
using var tempDir = new TemporaryDirectory();
|
211
|
+
var projectFileName = "project.csproj";
|
212
|
+
var projectFilePath = Path.Combine(tempDir.DirectoryPath, projectFileName);
|
213
|
+
var configFilePath = Path.Combine(tempDir.DirectoryPath, configFileName);
|
214
|
+
|
215
|
+
await File.WriteAllTextAsync(projectFilePath, projectContents);
|
216
|
+
await File.WriteAllTextAsync(configFilePath, configContents);
|
217
|
+
|
218
|
+
var projectBuildFile = ProjectBuildFile.Open(tempDir.DirectoryPath, projectFilePath);
|
219
|
+
await BindingRedirectManager.UpdateBindingRedirectsAsync(projectBuildFile, updatedPackageName, updatedPackageVersion);
|
220
|
+
|
221
|
+
var actualConfigContents = (await File.ReadAllTextAsync(configFilePath)).Replace("\r", "");
|
222
|
+
expectedConfigContents = expectedConfigContents.Replace("\r", "");
|
223
|
+
Assert.Equal(expectedConfigContents, actualConfigContents);
|
224
|
+
}
|
225
|
+
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs
CHANGED
@@ -594,6 +594,7 @@ public partial class UpdateWorkerTests
|
|
594
594
|
[
|
595
595
|
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
|
596
596
|
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
|
597
|
+
MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
|
597
598
|
],
|
598
599
|
projectContents: """
|
599
600
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
@@ -612,6 +613,10 @@ public partial class UpdateWorkerTests
|
|
612
613
|
<HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
|
613
614
|
<Private>True</Private>
|
614
615
|
</Reference>
|
616
|
+
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
|
617
|
+
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
|
618
|
+
<Private>True</Private>
|
619
|
+
</Reference>
|
615
620
|
</ItemGroup>
|
616
621
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
617
622
|
</Project>
|
@@ -653,6 +658,107 @@ public partial class UpdateWorkerTests
|
|
653
658
|
<HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
|
654
659
|
<Private>True</Private>
|
655
660
|
</Reference>
|
661
|
+
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
|
662
|
+
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
|
663
|
+
<Private>True</Private>
|
664
|
+
</Reference>
|
665
|
+
</ItemGroup>
|
666
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
667
|
+
</Project>
|
668
|
+
""",
|
669
|
+
expectedPackagesConfigContents: """
|
670
|
+
<?xml version="1.0" encoding="utf-8"?>
|
671
|
+
<packages>
|
672
|
+
<package id="Some.Package" version="13.0.1" targetFramework="net45" />
|
673
|
+
</packages>
|
674
|
+
""",
|
675
|
+
additionalFilesExpected:
|
676
|
+
[
|
677
|
+
("app.config", """
|
678
|
+
<configuration>
|
679
|
+
<runtime>
|
680
|
+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
681
|
+
<dependentAssembly>
|
682
|
+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
|
683
|
+
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
684
|
+
</dependentAssembly>
|
685
|
+
</assemblyBinding>
|
686
|
+
</runtime>
|
687
|
+
</configuration>
|
688
|
+
""")
|
689
|
+
]
|
690
|
+
);
|
691
|
+
}
|
692
|
+
|
693
|
+
[Fact]
|
694
|
+
public async Task BindingRedirectIsAddedForUpdatedPackage()
|
695
|
+
{
|
696
|
+
await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
|
697
|
+
packages:
|
698
|
+
[
|
699
|
+
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "7.0.1", "net45", "7.0.0.0"),
|
700
|
+
MockNuGetPackage.CreatePackageWithAssembly("Some.Package", "13.0.1", "net45", "13.0.0.0"),
|
701
|
+
MockNuGetPackage.CreatePackageWithAssembly("Unrelated.Package", "1.2.3", "net45","1.2.0.0"),
|
702
|
+
],
|
703
|
+
projectContents: """
|
704
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
705
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
706
|
+
<PropertyGroup>
|
707
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
708
|
+
</PropertyGroup>
|
709
|
+
<ItemGroup>
|
710
|
+
<None Include="packages.config" />
|
711
|
+
</ItemGroup>
|
712
|
+
<ItemGroup>
|
713
|
+
<None Include="app.config" />
|
714
|
+
</ItemGroup>
|
715
|
+
<ItemGroup>
|
716
|
+
<Reference Include="Some.Package, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null">
|
717
|
+
<HintPath>packages\Some.Package.7.0.1\lib\net45\Some.Package.dll</HintPath>
|
718
|
+
<Private>True</Private>
|
719
|
+
</Reference>
|
720
|
+
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
|
721
|
+
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
|
722
|
+
<Private>True</Private>
|
723
|
+
</Reference>
|
724
|
+
</ItemGroup>
|
725
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
726
|
+
</Project>
|
727
|
+
""",
|
728
|
+
packagesConfigContents: """
|
729
|
+
<packages>
|
730
|
+
<package id="Some.Package" version="7.0.1" targetFramework="net45" />
|
731
|
+
</packages>
|
732
|
+
""",
|
733
|
+
additionalFiles:
|
734
|
+
[
|
735
|
+
("app.config", """
|
736
|
+
<configuration>
|
737
|
+
<runtime />
|
738
|
+
</configuration>
|
739
|
+
""")
|
740
|
+
],
|
741
|
+
expectedProjectContents: """
|
742
|
+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
743
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
744
|
+
<PropertyGroup>
|
745
|
+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
746
|
+
</PropertyGroup>
|
747
|
+
<ItemGroup>
|
748
|
+
<None Include="packages.config" />
|
749
|
+
</ItemGroup>
|
750
|
+
<ItemGroup>
|
751
|
+
<None Include="app.config" />
|
752
|
+
</ItemGroup>
|
753
|
+
<ItemGroup>
|
754
|
+
<Reference Include="Some.Package, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null">
|
755
|
+
<HintPath>packages\Some.Package.13.0.1\lib\net45\Some.Package.dll</HintPath>
|
756
|
+
<Private>True</Private>
|
757
|
+
</Reference>
|
758
|
+
<Reference Include="Unrelated.Package, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null">
|
759
|
+
<HintPath>packages\Unrelated.Package.1.2.3\lib\net45\Unrelated.Package.dll</HintPath>
|
760
|
+
<Private>True</Private>
|
761
|
+
</Reference>
|
656
762
|
</ItemGroup>
|
657
763
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
658
764
|
</Project>
|
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.
|
4
|
+
version: 0.284.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-05 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.
|
19
|
+
version: 0.284.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.
|
26
|
+
version: 0.284.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -297,6 +297,7 @@ files:
|
|
297
297
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs
|
298
298
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/NuGetUpdater.Cli.Test.csproj
|
299
299
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs
|
300
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs
|
300
301
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs
|
301
302
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs
|
302
303
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs
|
@@ -310,6 +311,8 @@ files:
|
|
310
311
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/RequirementTests.cs
|
311
312
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/SecurityVulnerabilityExtensionsTests.cs
|
312
313
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs
|
314
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs
|
315
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/TestGitCommandHandler.cs
|
313
316
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolverEnvironment.cs
|
314
317
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs
|
315
318
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs
|
@@ -338,6 +341,7 @@ files:
|
|
338
341
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestExtensions.cs
|
339
342
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs
|
340
343
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs
|
344
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs
|
341
345
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/ExpectedUpdateOperationResult.cs
|
342
346
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs
|
343
347
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs
|
@@ -366,6 +370,9 @@ files:
|
|
366
370
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/SecurityVulnerabilityExtensions.cs
|
367
371
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs
|
368
372
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionResult.cs
|
373
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs
|
374
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/IGitCommandHandler.cs
|
375
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs
|
369
376
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Dependency.cs
|
370
377
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyType.cs
|
371
378
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs
|
@@ -406,6 +413,7 @@ files:
|
|
406
413
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs
|
407
414
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs
|
408
415
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobFile.cs
|
416
|
+
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobRepoNotFound.cs
|
409
417
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobSource.cs
|
410
418
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/MarkAsProcessed.cs
|
411
419
|
- helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs
|
@@ -497,7 +505,7 @@ licenses:
|
|
497
505
|
- MIT
|
498
506
|
metadata:
|
499
507
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
500
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
508
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.284.0
|
501
509
|
post_install_message:
|
502
510
|
rdoc_options: []
|
503
511
|
require_paths:
|