dependabot-nuget 0.352.0 → 0.354.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +15 -41
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +102 -46
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +0 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +19 -0
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +23 -2
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -2
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/OutOfDisk.cs +9 -0
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs +11 -1
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +25 -4
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +2 -2
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +4 -4
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +3 -3
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +2 -2
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +2 -2
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +20 -23
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +41 -1
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +93 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +2 -5
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +21 -9
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +23 -104
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -66
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/JobTests.cs +39 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +142 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +76 -7
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +8 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +30 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +25 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +250 -0
  33. metadata +5 -4
@@ -4,6 +4,7 @@ using NuGet.Versioning;
4
4
 
5
5
  using NuGetUpdater.Core.Analyze;
6
6
  using NuGetUpdater.Core.Run.ApiModel;
7
+ using NuGetUpdater.Core.Test.Utilities;
7
8
 
8
9
  using Xunit;
9
10
 
@@ -379,6 +380,44 @@ public class JobTests
379
380
  ];
380
381
  }
381
382
 
383
+ [Fact]
384
+ public async Task ExpandJobDirectories()
385
+ {
386
+ // arrange
387
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
388
+ // file names are irrelevant, but make this function easy to use
389
+ ("src/client/android/ui/file.txt", "contents irrelevant"),
390
+ ("src/client/ios/ui/file.txt", "contents irrelevant"),
391
+ ("src/legacy/winphone/ui/file.txt", "contents irrelevant"),
392
+ ("src/server/linux/cloud/file.txt", "contents irrelevant"),
393
+ ("src/server/windows/file.txt", "contents irrelevant")
394
+ );
395
+ var job = new Job()
396
+ {
397
+ Source = new()
398
+ {
399
+ Provider = "github",
400
+ Repo = "test/repo",
401
+ Directories = [
402
+ "src/server/linux", // single value
403
+ "src/client/*/ui", // wildcard
404
+ ]
405
+ }
406
+ };
407
+
408
+ // act
409
+ var actualDirectories = job.GetAllDirectories(tempDir.DirectoryPath);
410
+
411
+ // assert - directories were expanded and original order maintained
412
+ var expectedDirectories = new[]
413
+ {
414
+ "/src/server/linux",
415
+ "/src/client/android/ui",
416
+ "/src/client/ios/ui"
417
+ }.ToImmutableArray();
418
+ AssertEx.Equal(expectedDirectories, actualDirectories);
419
+ }
420
+
382
421
  private static Job CreateJob(
383
422
  ImmutableArray<AllowedUpdate> allowedUpdates,
384
423
  ImmutableArray<string> dependencies,
@@ -995,6 +995,148 @@ public class EndToEndTests
995
995
  );
996
996
  }
997
997
 
998
+ [Fact]
999
+ public async Task WildcardDirectory_OneOfWhichIsEmpty()
1000
+ {
1001
+ // job is run with a wildcard which will expand to
1002
+ // /src
1003
+ // /src/other
1004
+ // /src/project
1005
+ // but only `/src/project` contains a project file that can be operated on
1006
+ await RunAsync(
1007
+ packages: [
1008
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net9.0"),
1009
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net9.0"),
1010
+ ],
1011
+ job: new()
1012
+ {
1013
+ Source = new()
1014
+ {
1015
+ Provider = "github",
1016
+ Repo = "test/repo",
1017
+ Directory = "src/**/*",
1018
+ }
1019
+ },
1020
+ files: [
1021
+ ("src/Directory.Build.props", "<Project />"),
1022
+ ("src/Directory.Build.targets", "<Project />"),
1023
+ ("src/Directory.Packages.props", """
1024
+ <Project>
1025
+ <PropertyGroup>
1026
+ <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
1027
+ </PropertyGroup>
1028
+ </Project>
1029
+ """),
1030
+ ("src/other/not-a-nuget-file.txt", "contents irrelevant"),
1031
+ ("src/project/project.csproj", """
1032
+ <Project Sdk="Microsoft.NET.Sdk">
1033
+ <PropertyGroup>
1034
+ <TargetFramework>net9.0</TargetFramework>
1035
+ </PropertyGroup>
1036
+ <ItemGroup>
1037
+ <PackageReference Include="Some.Package" Version="1.0.0" />
1038
+ </ItemGroup>
1039
+ </Project>
1040
+ """)
1041
+ ],
1042
+ discoveryWorker: null, // use real worker
1043
+ analyzeWorker: null, // use real worker
1044
+ updaterWorker: null, // use real worker
1045
+ expectedApiMessages: [
1046
+ new IncrementMetric()
1047
+ {
1048
+ Metric = "updater.started",
1049
+ Tags = new()
1050
+ {
1051
+ ["operation"] = "group_update_all_versions"
1052
+ }
1053
+ },
1054
+ // no dependencies reported for `/src`
1055
+ // no dependencies reported for `/src/other`
1056
+ // but dependencies _are_ reported for `/src/project`
1057
+ new UpdatedDependencyList()
1058
+ {
1059
+ Dependencies = [
1060
+ new()
1061
+ {
1062
+ Name = "Some.Package",
1063
+ Version = "1.0.0",
1064
+ Requirements = [
1065
+ new()
1066
+ {
1067
+ Requirement = "1.0.0",
1068
+ File = "/src/project/project.csproj",
1069
+ Groups = ["dependencies"],
1070
+ }
1071
+ ]
1072
+ },
1073
+ ],
1074
+ DependencyFiles = [
1075
+ "/src/Directory.Build.props",
1076
+ "/src/Directory.Build.targets",
1077
+ "/src/Directory.Packages.props",
1078
+ "/src/project/project.csproj",
1079
+ ],
1080
+ },
1081
+ new CreatePullRequest()
1082
+ {
1083
+ Dependencies = [
1084
+ new()
1085
+ {
1086
+ Name = "Some.Package",
1087
+ Version = "2.0.0",
1088
+ Requirements = [
1089
+ new()
1090
+ {
1091
+ Requirement = "2.0.0",
1092
+ File = "/src/project/project.csproj",
1093
+ Groups = ["dependencies"],
1094
+ Source = new()
1095
+ {
1096
+ SourceUrl = null,
1097
+ Type = "nuget_repo",
1098
+ }
1099
+ }
1100
+ ],
1101
+ PreviousVersion = "1.0.0",
1102
+ PreviousRequirements = [
1103
+ new()
1104
+ {
1105
+ Requirement = "1.0.0",
1106
+ File = "/src/project/project.csproj",
1107
+ Groups = ["dependencies"],
1108
+ }
1109
+ ],
1110
+ },
1111
+ ],
1112
+ UpdatedDependencyFiles = [
1113
+ new()
1114
+ {
1115
+ Directory = "/src/project",
1116
+ Name = "project.csproj",
1117
+ Content = """
1118
+ <Project Sdk="Microsoft.NET.Sdk">
1119
+ <PropertyGroup>
1120
+ <TargetFramework>net9.0</TargetFramework>
1121
+ </PropertyGroup>
1122
+ <ItemGroup>
1123
+ <PackageReference Include="Some.Package" Version="2.0.0" />
1124
+ </ItemGroup>
1125
+ </Project>
1126
+ """
1127
+ },
1128
+ ],
1129
+ BaseCommitSha = "TEST-COMMIT-SHA",
1130
+ CommitMessage = TestPullRequestCommitMessage,
1131
+ PrTitle = TestPullRequestTitle,
1132
+ PrBody = TestPullRequestBody,
1133
+ DependencyGroup = null,
1134
+ },
1135
+ new MarkAsProcessed("TEST-COMMIT-SHA")
1136
+ ]
1137
+ );
1138
+ }
1139
+
998
1140
  public const string TestPullRequestCommitMessage = "test-pull-request-commit-message";
999
1141
  public const string TestPullRequestTitle = "test-pull-request-title";
1000
1142
  public const string TestPullRequestBody = "test-pull-request-body";
@@ -147,6 +147,7 @@ public class HttpApiHandlerTests
147
147
  yield return [new DependencyFileNotParseable("unused"), "record_update_job_error"];
148
148
  yield return [new DependencyNotFound("unused"), "record_update_job_error"];
149
149
  yield return [new JobRepoNotFound("unused"), "record_update_job_error"];
150
+ yield return [new OutOfDisk(), "record_update_job_error"];
150
151
  yield return [new PrivateSourceAuthenticationFailure(["unused"]), "record_update_job_error"];
151
152
  yield return [new PrivateSourceBadResponse(["unused"], "unused"), "record_update_job_error"];
152
153
  yield return [new PrivateSourceTimedOut("unused"), "record_update_job_error"];
@@ -40,6 +40,13 @@ public class JobErrorBaseTests : TestBase
40
40
 
41
41
  public static IEnumerable<object[]> GenerateErrorFromExceptionTestData()
42
42
  {
43
+ // disk full
44
+ yield return
45
+ [
46
+ new IOException("No space left on device : '/path/to/directory'"),
47
+ new OutOfDisk(),
48
+ ];
49
+
43
50
  // something elevated to a bad response
44
51
  yield return
45
52
  [
@@ -138,6 +138,17 @@ public class MessageReportTests
138
138
  """
139
139
  ];
140
140
 
141
+ yield return
142
+ [
143
+ // message
144
+ new OutOfDisk(),
145
+ // expected
146
+ """
147
+ Error type: out_of_disk
148
+ """
149
+
150
+ ];
151
+
141
152
  yield return
142
153
  [
143
154
  // message
@@ -129,14 +129,15 @@ public class MiscellaneousTests
129
129
  }
130
130
 
131
131
  [Fact]
132
- public void DeserializeDependencyGroup()
132
+ public void DeserializeDependencyGroup_SpecificValues()
133
133
  {
134
134
  var json = """
135
135
  {
136
136
  "name": "test-group",
137
137
  "rules": {
138
138
  "patterns": ["Test.*"],
139
- "exclude-patterns": ["Dependency.*"]
139
+ "exclude-patterns": ["Dependency.*"],
140
+ "update-types": ["minor", "patch"]
140
141
  }
141
142
  }
142
143
  """;
@@ -146,6 +147,24 @@ public class MiscellaneousTests
146
147
  var matcher = group.GetGroupMatcher();
147
148
  Assert.Equal(["Test.*"], matcher.Patterns);
148
149
  Assert.Equal(["Dependency.*"], matcher.ExcludePatterns);
150
+ Assert.Equal([GroupUpdateType.Minor, GroupUpdateType.Patch], matcher.UpdateTypes);
151
+ }
152
+
153
+ [Fact]
154
+ public void DeserializeDependencyGroup_DefaultValues()
155
+ {
156
+ var json = """
157
+ {
158
+ "name": "test-group"
159
+ }
160
+ """;
161
+ var group = JsonSerializer.Deserialize<DependencyGroup>(json, RunWorker.SerializerOptions);
162
+ Assert.NotNull(group);
163
+ Assert.Equal("test-group", group.Name);
164
+ var matcher = group.GetGroupMatcher();
165
+ Assert.Equal(["*"], matcher.Patterns);
166
+ Assert.Equal([], matcher.ExcludePatterns);
167
+ Assert.Equal([GroupUpdateType.Major, GroupUpdateType.Minor, GroupUpdateType.Patch], matcher.UpdateTypes);
149
168
  }
150
169
 
151
170
  [Fact]
@@ -156,7 +175,8 @@ public class MiscellaneousTests
156
175
  "name": "test-group",
157
176
  "rules": {
158
177
  "patterns": { "unexpected": 1 },
159
- "exclude-patterns": { "unexpected": 2 }
178
+ "exclude-patterns": { "unexpected": 2 },
179
+ "update-types": { "unexpected": 3 }
160
180
  }
161
181
  }
162
182
  """;
@@ -166,6 +186,7 @@ public class MiscellaneousTests
166
186
  var matcher = group.GetGroupMatcher();
167
187
  Assert.Equal([], matcher.Patterns);
168
188
  Assert.Equal([], matcher.ExcludePatterns);
189
+ Assert.Equal([], matcher.UpdateTypes);
169
190
  }
170
191
 
171
192
  [Theory]
@@ -515,9 +536,9 @@ public class MiscellaneousTests
515
536
 
516
537
  [Theory]
517
538
  [MemberData(nameof(DependencyInfoFromJobData))]
518
- public void DependencyInfoFromJob(Job job, Dependency dependency, DependencyInfo expectedDependencyInfo)
539
+ public void DependencyInfoFromJob(Job job, Dependency dependency, GroupMatcher? groupMatcher, DependencyInfo expectedDependencyInfo)
519
540
  {
520
- var actualDependencyInfo = RunWorker.GetDependencyInfo(job, dependency, allowCooldown: true);
541
+ var actualDependencyInfo = RunWorker.GetDependencyInfo(job, dependency, groupMatcher is null ? [] : [groupMatcher], allowCooldown: true);
521
542
  var expectedString = JsonSerializer.Serialize(expectedDependencyInfo, AnalyzeWorker.SerializerOptions);
522
543
  var actualString = JsonSerializer.Serialize(actualDependencyInfo, AnalyzeWorker.SerializerOptions);
523
544
  Assert.Equal(expectedString, actualString);
@@ -604,7 +625,7 @@ public class MiscellaneousTests
604
625
  ];
605
626
  }
606
627
 
607
- public static IEnumerable<object[]> DependencyInfoFromJobData()
628
+ public static IEnumerable<object?[]> DependencyInfoFromJobData()
608
629
  {
609
630
  // with security advisory
610
631
  yield return
@@ -634,6 +655,8 @@ public class MiscellaneousTests
634
655
  },
635
656
  // dependency
636
657
  new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
658
+ // groupMatcher
659
+ null,
637
660
  // expectedDependencyInfo
638
661
  new DependencyInfo()
639
662
  {
@@ -679,6 +702,8 @@ public class MiscellaneousTests
679
702
  },
680
703
  // dependency
681
704
  new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
705
+ // groupMatcher
706
+ null,
682
707
  // expectedDependencyInfo
683
708
  new DependencyInfo()
684
709
  {
@@ -712,6 +737,8 @@ public class MiscellaneousTests
712
737
  },
713
738
  // dependency
714
739
  new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
740
+ // groupMatcher
741
+ null,
715
742
  // expectedDependencyInfo
716
743
  new DependencyInfo()
717
744
  {
@@ -753,6 +780,8 @@ public class MiscellaneousTests
753
780
  },
754
781
  // dependency
755
782
  new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
783
+ // groupMatcher
784
+ null,
756
785
  // expectedDependencyInfo
757
786
  new DependencyInfo()
758
787
  {
@@ -795,6 +824,8 @@ public class MiscellaneousTests
795
824
  },
796
825
  // dependency
797
826
  new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
827
+ // groupMatcher
828
+ null,
798
829
  // expectedDependencyInfo
799
830
  new DependencyInfo()
800
831
  {
@@ -808,6 +839,44 @@ public class MiscellaneousTests
808
839
  },
809
840
  ];
810
841
 
811
-
842
+ // with limited group update types; major is explicitly ignored, only patch is explicitly allowed => major and minor are ignored
843
+ yield return
844
+ [
845
+ // job
846
+ new Job()
847
+ {
848
+ Source = new()
849
+ {
850
+ Provider = "github",
851
+ Repo = "some/repo"
852
+ },
853
+ IgnoreConditions = [
854
+ new Condition()
855
+ {
856
+ DependencyName = "Some.*",
857
+ UpdateTypes = [ConditionUpdateType.SemVerMajor],
858
+ },
859
+ ],
860
+ },
861
+ // dependency
862
+ new Dependency("Some.Dependency", "1.0.0", DependencyType.PackageReference),
863
+ // groupMatcher
864
+ new GroupMatcher()
865
+ {
866
+ Patterns = ["Some.*"],
867
+ ExcludePatterns = [],
868
+ UpdateTypes = [GroupUpdateType.Patch],
869
+ },
870
+ // expectedDependencyInfo
871
+ new DependencyInfo()
872
+ {
873
+ Name = "Some.Dependency",
874
+ Version = "1.0.0",
875
+ IsVulnerable = false,
876
+ IgnoredVersions = [],
877
+ Vulnerabilities = [],
878
+ IgnoredUpdateTypes = [ConditionUpdateType.SemVerMajor, ConditionUpdateType.SemVerMinor],
879
+ },
880
+ ];
812
881
  }
813
882
  }
@@ -791,6 +791,14 @@ public class SerializationTests : TestBase
791
791
  """
792
792
  ];
793
793
 
794
+ yield return
795
+ [
796
+ new OutOfDisk(),
797
+ """
798
+ {"data":{"error-type":"out_of_disk","error-details":{}}}
799
+ """
800
+ ];
801
+
794
802
  yield return
795
803
  [
796
804
  new PrivateSourceAuthenticationFailure(["url1", "url2"]),
@@ -11,6 +11,36 @@ namespace NuGetUpdater.Core.Test.Update;
11
11
 
12
12
  public class PackageReferenceUpdaterTests
13
13
  {
14
+ [Theory]
15
+ [InlineData("net9.0", "net9.0")]
16
+ [InlineData("net9.0-android", "net9.0")]
17
+ [InlineData("net9.0-android", "net9.0-android")]
18
+ public async Task GetPackageGraphForDependencies_DifferentTargetFrameworks(string projectTfm, string packageTfm)
19
+ {
20
+ // arrange
21
+ using var repoRoot = await TemporaryDirectory.CreateWithContentsAsync(("project.csproj", "<Project Sdk=\"Microsoft.NET.Sdk\" />"));
22
+ var projectPath = Path.Combine(repoRoot.DirectoryPath, "project.csproj");
23
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory([
24
+ MockNuGetPackage.CreateSimplePackage("Parent.Package", "1.0.0", packageTfm, [(null, [("Transitive.Package", "2.0.0")])]),
25
+ MockNuGetPackage.CreateSimplePackage("Transitive.Package", "2.0.0", packageTfm, [(null, [("Super.Transitive.Package", "3.0.0")])]),
26
+ MockNuGetPackage.CreateSimplePackage("Super.Transitive.Package", "3.0.0", "net8.0"), // explicitly a different but compatible tfm
27
+ ], repoRoot.DirectoryPath);
28
+ var topLevelDependencies = new[]
29
+ {
30
+ new Dependency("Parent.Package", "1.0.0", DependencyType.PackageReference),
31
+ };
32
+
33
+ // act
34
+ var packageGraph = await PackageReferenceUpdater.GetPackageGraphForDependencies(repoRoot.DirectoryPath, projectPath, projectTfm, [.. topLevelDependencies], new TestLogger());
35
+
36
+ // assert
37
+ Assert.Equal("1.0.0", packageGraph.PackageVersions["Parent.Package"].ToString());
38
+ Assert.Equal("2.0.0", packageGraph.PackageVersions["Transitive.Package"].ToString());
39
+ Assert.Equal("3.0.0", packageGraph.PackageVersions["Super.Transitive.Package"].ToString());
40
+ Assert.Equal("Parent.Package", packageGraph.PackageParents["Transitive.Package"].Single());
41
+ Assert.Equal("Transitive.Package", packageGraph.PackageParents["Super.Transitive.Package"].Single());
42
+ }
43
+
14
44
  [Theory]
15
45
  [MemberData(nameof(ComputeUpdateOperationsTestData))]
16
46
  public async Task ComputeUpdateOperations
@@ -414,6 +414,19 @@ public class MSBuildHelperTests : TestBase
414
414
  // normalize default message for the test
415
415
  actualError = new DependencyFileNotFound(notFound.Details["file-path"].ToString()!, "test message");
416
416
  }
417
+ if (actualError is DependencyFileNotParseable notParseable)
418
+ {
419
+ // normalize the path for the test
420
+ actualError = new DependencyFileNotParseable("/" + notParseable.Details["file-path"].ToString()!.TrimStart('.', '/'), notParseable.Details["message"]?.ToString());
421
+ }
422
+ if (actualError is UnknownError unknownError)
423
+ {
424
+ // remove callstack from unknown error to make testing easier
425
+ var originalMessage = unknownError.Exception.Message;
426
+ var newlineIndex = originalMessage.IndexOf('\n');
427
+ var trimmedMessage = newlineIndex >= 0 ? originalMessage[..newlineIndex] : originalMessage;
428
+ actualError = new UnknownError(new Exception(trimmedMessage.Trim()), "TEST-JOB-ID");
429
+ }
417
430
 
418
431
  var actualErrorJson = JsonSerializer.Serialize(actualError, RunWorker.SerializerOptions);
419
432
  var expectedErrorJson = JsonSerializer.Serialize(expectedError, RunWorker.SerializerOptions);
@@ -609,5 +622,17 @@ public class MSBuildHelperTests : TestBase
609
622
  // expectedError
610
623
  new DependencyFileNotParseable("/path/to/NuGet.Config", "Some error message."),
611
624
  ];
625
+
626
+ yield return
627
+ [
628
+ // output
629
+ """
630
+ Output:
631
+ Using Msbuild from '/usr/local/dotnet/current/sdk/9.0.307'.
632
+ Found multiple project files for '/home/dependabot/dependabot-updater/repo/path/to/packages.config'.
633
+ """,
634
+ // expectedError
635
+ new UnknownError(new Exception("Multiple project files found for single packages.config"), "TEST-JOB-ID"),
636
+ ];
612
637
  }
613
638
  }