Skip to content

Commit 9673ef1

Browse files
authored
ci:.NET Innovation Days Q3FY25: Update Dotty to update test library versions automatically via PR (#2810)
1 parent 5059eae commit 9673ef1

9 files changed

+292
-42
lines changed

.github/workflows/nuget_slack_notifications.yml

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969
NEW_RELIC_HOST: staging-collector.newrelic.com
7070
NEW_RELIC_LICENSE_KEY: ${{ secrets.STAGING_LICENSE_KEY }}
7171
DOTTY_LAST_RUN_TIMESTAMP: ${{ env.LAST_RUN_TIMESTAMP }}
72+
DOTTY_SEARCH_ROOT_PATH: ${{ github.workspace }}
7273

7374
run: |
7475
if [ ${{ inputs.daysToSearch }} != "" ]; then
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text.RegularExpressions;
6+
using System.Threading.Tasks;
7+
using System.Xml.Serialization;
8+
using Serilog;
9+
10+
namespace nugetSlackNotifications
11+
{
12+
public class CsprojHandler
13+
{
14+
public static async Task<List<string>> UpdatePackageReferences(string csprojPath, List<NugetVersionData> versionDatas)
15+
{
16+
var updateLog = new List<string>();
17+
var csprojLines = await File.ReadAllLinesAsync(csprojPath);
18+
19+
var packages = Parse(csprojLines);
20+
if (packages.Count == 0)
21+
{
22+
Log.Warning("No packages found in csproj file " + csprojPath);
23+
return updateLog;
24+
}
25+
26+
foreach (var versionData in versionDatas)
27+
{
28+
var matchingPackages = packages.Where(p => p.Include == versionData.PackageName).ToList();
29+
if (matchingPackages.Count == 0)
30+
{
31+
Log.Warning($"No matching packages found in csproj file for {versionData.PackageName}");
32+
continue;
33+
}
34+
35+
foreach (var package in matchingPackages)
36+
{
37+
if(package.VersionAsVersion < versionData.NewVersionAsVersion && package.Pin)
38+
{
39+
Log.Warning($"Not updating {package.Include} for {package.TargetFramework}, it is pinned to {package.Version}. Manual verification recommended.");
40+
continue;
41+
}
42+
43+
if (package.VersionAsVersion < versionData.NewVersionAsVersion)
44+
{
45+
Log.Information($"Updating {package.Include} from {package.Version} to {versionData.NewVersion}");
46+
var pattern = @"\d+(\.\d+){2,3}";
47+
var result = Regex.Replace(csprojLines[package.LineNumber], pattern, versionData.NewVersion);
48+
csprojLines[package.LineNumber] = result;
49+
50+
updateLog.Add($"- Package [{versionData.PackageName}]({versionData.Url}) " +
51+
$"for {package.TargetFramework} " +
52+
$"was updated from {versionData.OldVersion} to {versionData.NewVersion} " +
53+
$"on {versionData.PublishDate.ToShortDateString()}.");
54+
}
55+
}
56+
}
57+
58+
await File.WriteAllLinesAsync(csprojPath, csprojLines);
59+
updateLog.Add("");
60+
return updateLog;
61+
}
62+
63+
private static List<PackageReference> Parse(string[] csprojLines)
64+
{
65+
var packages = new List<PackageReference>();
66+
try
67+
{
68+
for (int i = 0; i < csprojLines.Length; i++)
69+
{
70+
var line = csprojLines[i];
71+
if (!line.Contains("PackageReference"))
72+
{
73+
continue;
74+
}
75+
76+
var serializer = new XmlSerializer(typeof(PackageReference));
77+
using (var reader = new StringReader(line))
78+
{
79+
var packageReference = (PackageReference)serializer.Deserialize(reader);
80+
packageReference.LineNumber = i;
81+
packages.Add(packageReference);
82+
}
83+
}
84+
85+
return packages;
86+
}
87+
catch (Exception e)
88+
{
89+
Log.Error(e, "XML issue");
90+
return packages;
91+
}
92+
}
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace nugetSlackNotifications
4+
{
5+
public class NugetVersionData
6+
{
7+
public string PackageName { get; set; }
8+
public string OldVersion { get; set; }
9+
public string NewVersion { get; set; }
10+
public Version NewVersionAsVersion { get; set; }
11+
public string Url { get; set; }
12+
public DateTime PublishDate { get; set; }
13+
14+
public NugetVersionData(string packageName, string oldVersion, string newVersion, string url, DateTime publishDate)
15+
{
16+
PackageName = packageName;
17+
OldVersion = oldVersion;
18+
NewVersion = newVersion;
19+
NewVersionAsVersion = new Version(newVersion);
20+
Url = url;
21+
PublishDate = publishDate;
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace nugetSlackNotifications
4+
{
5+
public class PackageInfo
6+
{
7+
[JsonPropertyName("packageName")]
8+
public string PackageName { get; set; }
9+
[JsonPropertyName("ignorePatch")]
10+
public bool IgnorePatch { get; set; }
11+
[JsonPropertyName("ignoreMinor")]
12+
public bool IgnoreMinor { get; set; }
13+
[JsonPropertyName("ignoreReason")]
14+
public string IgnoreReason {get; set;}
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Text.RegularExpressions;
3+
using System.Xml.Serialization;
4+
5+
namespace nugetSlackNotifications
6+
{
7+
public class PackageReference
8+
{
9+
[XmlAttribute]
10+
public string Include { get; set; }
11+
12+
[XmlAttribute]
13+
public string Version { get; set; }
14+
15+
[XmlIgnore]
16+
public Version VersionAsVersion => new Version(Version);
17+
18+
[XmlIgnore]
19+
public int LineNumber { get; set; }
20+
21+
[XmlAttribute]
22+
public string Condition { get; set; }
23+
24+
public string TargetFramework
25+
{
26+
get
27+
{
28+
if (Condition == null)
29+
{
30+
return null;
31+
}
32+
var match = Regex.Match(Condition, @"net\d+\.*\d+");
33+
return match.Success ? match.Value : null;
34+
}
35+
}
36+
37+
[XmlAttribute]
38+
public bool Pin { get; set; }
39+
}
40+
}

0 commit comments

Comments
 (0)