Skip to content

Commit b630833

Browse files
committed
Migrated to .Net10.
1 parent 770f1cd commit b630833

28 files changed

+194
-212
lines changed

.github/workflows/build-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Install .NET Core
2323
uses: actions/setup-dotnet@v5
2424
with:
25-
dotnet-version: 9.0.x
25+
dotnet-version: 10.0.x
2626

2727
- name: Setup Node.js
2828
uses: actions/setup-node@v5

.pipelines/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ extends:
3232
steps:
3333
- checkout: self
3434
- task: UseDotNet@2
35-
displayName: Setup .NET 9
35+
displayName: Setup .NET 10
3636
inputs:
37-
version: 9.0.x
37+
version: 10.0.x
3838
- task: UseNode@1
3939
displayName: Setup Node.js 24
4040
inputs:

.pipelines/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ extends:
4646
steps:
4747
- checkout: self
4848
- task: UseDotNet@2
49-
displayName: Setup .NET 9
49+
displayName: Setup .NET 10
5050
inputs:
51-
version: 9.0.x
51+
version: 10.0.x
5252
- ${{ if eq(parameters.DoEsrp, 'true') }}:
5353
- task: UseDotNet@2
5454
displayName: Setup .NET 6.0 (For ESRP Task)

global.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"test": {
3+
"runner": "Microsoft.Testing.Platform"
4+
}
5+
}

scripts/build-cli.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ try
8181
# Step 2: Run tests (unless skipped)
8282
if (-not $SkipTests) {
8383
Write-Host "[TEST] Running tests..." -ForegroundColor Blue
84-
dotnet test $CliSolutionPath -c Release --no-build --results-directory .\TestResults -- --report-trx
84+
dotnet test --solution $CliSolutionPath -c Release --no-build --results-directory .\TestResults --report-trx
8585
$TestExitCode = $LASTEXITCODE
8686

8787
# Copy test results to artifacts BEFORE checking for failure - find all TRX files

src/winapp-CLI/.editorconfig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ dotnet_analyzer_diagnostic.category-reliability.severity = warning
3838
dotnet_analyzer_diagnostic.category-security.severity = warning
3939
dotnet_analyzer_diagnostic.category-usage.severity = warning
4040

41+
# CA1068: CancellationToken parameters must come last
42+
dotnet_diagnostic.CA1068.severity = warning
43+
4144
# CancellationToken rules (Built-in .NET analyzers) - MOST IMPORTANT
4245
# CA2016: Forward the CancellationToken parameter to methods that take one
4346
dotnet_diagnostic.CA2016.severity = warning
@@ -58,9 +61,6 @@ dotnet_diagnostic.CA1031.severity = none
5861
# CA2201: Exception type System.Exception is not sufficiently specific
5962
dotnet_diagnostic.CA2201.severity = suggestion
6063

61-
# CA1822: Mark members as static (can be noisy)
62-
dotnet_diagnostic.CA1822.severity = none
63-
6464
# CA1852: Type can be sealed (not critical)
6565
dotnet_diagnostic.CA1852.severity = none
6666

@@ -76,6 +76,9 @@ dotnet_diagnostic.CA1031.severity = suggestion
7676
# CA1848: Use the LoggerMessage delegates
7777
dotnet_diagnostic.CA1848.severity = none
7878

79+
# CA1873:
80+
dotnet_diagnostic.CA1873.severity = none
81+
7982
# CA2249: Consider using String.Contains instead of String.IndexOf
8083
dotnet_diagnostic.CA2249.severity = suggestion
8184

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<Project>
22
<ItemGroup>
3-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
4-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
3+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0-rc.2.25502.107" />
4+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.0-rc.2.25502.107" />
55
<PackageVersion Include="System.CommandLine" Version="2.0.0-rc.2.25502.107" />
6-
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.10" />
6+
<PackageVersion Include="System.Diagnostics.EventLog" Version="10.0.0-rc.2.25502.107" />
77
<PackageVersion Include="Microsoft.Telemetry.Inbox.Managed" Version="10.0.25148.1001-220626-1600.rs-fun-deploy-dev5" />
88
</ItemGroup>
9-
</Project>
9+
</Project>

src/winapp-CLI/WinApp.Cli.Tests/BaseCommandTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public abstract class BaseCommandTests(bool configPaths = true)
1919
protected StringWriter ConsoleStdOut { private set; get; } = null!;
2020
protected StringWriter ConsoleStdErr { private set; get; } = null!;
2121

22+
public TestContext TestContext { get; set; } = null!;
23+
2224
[TestInitialize]
2325
public void SetupBase()
2426
{

src/winapp-CLI/WinApp.Cli.Tests/BuildToolsServiceTests.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public async Task RunBuildToolAsync_WithValidTool_ReturnsOutput()
157157
File.WriteAllText(fakeToolPath, "@echo Hello from fake tool");
158158

159159
// Act
160-
var (stdout, stderr) = await _buildToolsService.RunBuildToolAsync("echo.cmd", "");
160+
var (stdout, stderr) = await _buildToolsService.RunBuildToolAsync("echo.cmd", "", TestContext.CancellationToken);
161161

162162
// Assert
163163
Assert.Contains("Hello from fake tool", stdout);
@@ -173,7 +173,7 @@ public async Task RunBuildToolAsync_WithNonExistentTool_ThrowsFileNotFoundExcept
173173
// Act & Assert
174174
await Assert.ThrowsExactlyAsync<FileNotFoundException>(async () =>
175175
{
176-
await _buildToolsService.RunBuildToolAsync("nonexistent.exe", "");
176+
await _buildToolsService.RunBuildToolAsync("nonexistent.exe", "", TestContext.CancellationToken);
177177
});
178178
}
179179

@@ -184,7 +184,7 @@ public async Task EnsureBuildToolsAsync_WithNoExistingPackage_ShouldAttemptInsta
184184
// since we can't easily mock the package installation service in this test setup
185185

186186
// Act
187-
var result = await _buildToolsService.EnsureBuildToolsAsync();
187+
var result = await _buildToolsService.EnsureBuildToolsAsync(cancellationToken: TestContext.CancellationToken);
188188

189189
// Assert - Result can be either null (if installation fails) or a path (if successful)
190190
// The important part is that the method completes without throwing
@@ -202,7 +202,7 @@ public async Task EnsureBuildToolsAsync_WithExistingPackage_ReturnsExistingPath(
202202
Directory.CreateDirectory(binDir);
203203

204204
// Act
205-
var result = await _buildToolsService.EnsureBuildToolsAsync();
205+
var result = await _buildToolsService.EnsureBuildToolsAsync(cancellationToken: TestContext.CancellationToken);
206206

207207
// Assert - Should find and return the existing bin path
208208
Assert.AreEqual(binDir, result!.FullName);
@@ -218,7 +218,7 @@ public async Task EnsureBuildToolsAsync_WithForceLatest_ShouldAttemptReinstallat
218218
Directory.CreateDirectory(binDir);
219219

220220
// Act - Force latest should attempt reinstallation even with existing package
221-
var result = await _buildToolsService.EnsureBuildToolsAsync(forceLatest: true);
221+
var result = await _buildToolsService.EnsureBuildToolsAsync(forceLatest: true, TestContext.CancellationToken);
222222

223223
// Assert - Result can be either null (if installation fails) or a path (if successful)
224224
// The important part is that the method completes and attempts reinstallation
@@ -238,7 +238,7 @@ public async Task EnsureBuildToolAvailableAsync_WithExistingTool_ReturnsToolPath
238238
File.WriteAllText(toolPath, "fake mt.exe");
239239

240240
// Act
241-
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt.exe");
241+
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt.exe", TestContext.CancellationToken);
242242

243243
// Assert
244244
Assert.AreEqual(toolPath, result!.FullName);
@@ -257,7 +257,7 @@ public async Task EnsureBuildToolAvailableAsync_WithToolNameWithoutExtension_Add
257257
File.WriteAllText(toolPath, "fake mt.exe");
258258

259259
// Act - Request tool without .exe extension
260-
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt");
260+
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt", TestContext.CancellationToken);
261261

262262
// Assert
263263
Assert.AreEqual(toolPath, result.FullName);
@@ -272,7 +272,7 @@ public async Task EnsureBuildToolAvailableAsync_WithNoExistingPackageAndInstallS
272272
// Act
273273
try
274274
{
275-
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt.exe");
275+
var result = await _buildToolsService.EnsureBuildToolAvailableAsync("mt.exe", TestContext.CancellationToken);
276276

277277
// Assert - If we get here, installation was successful and we got a path
278278
Assert.IsNotNull(result);
@@ -306,7 +306,7 @@ public async Task EnsureBuildToolAvailableAsync_WithNonExistentTool_ThrowsFileNo
306306
// Act & Assert
307307
await Assert.ThrowsExactlyAsync<FileNotFoundException>(async () =>
308308
{
309-
await _buildToolsService.EnsureBuildToolAvailableAsync("nonexistent.exe");
309+
await _buildToolsService.EnsureBuildToolAvailableAsync("nonexistent.exe", TestContext.CancellationToken);
310310
});
311311
}
312312

@@ -320,7 +320,7 @@ public async Task RunBuildToolAsync_WithNoExistingPackage_AutoInstallsAndRuns()
320320
{
321321
// Create a simple batch command that outputs something
322322
// This will either succeed (if BuildTools installs successfully) or throw an exception
323-
await _buildToolsService.RunBuildToolAsync("echo.cmd", "test");
323+
await _buildToolsService.RunBuildToolAsync("echo.cmd", "test", TestContext.CancellationToken);
324324

325325
// If we reach here, the auto-installation worked - test passes
326326
}
@@ -347,7 +347,7 @@ public async Task RunBuildToolAsync_WithExistingTool_RunsDirectly()
347347
File.WriteAllText(batchFile, "@echo Hello from test tool");
348348

349349
// Act
350-
var (stdout, stderr) = await _buildToolsService.RunBuildToolAsync("test.cmd", "");
350+
var (stdout, stderr) = await _buildToolsService.RunBuildToolAsync("test.cmd", "", TestContext.CancellationToken);
351351

352352
// Assert
353353
Assert.Contains("Hello from test tool", stdout);

src/winapp-CLI/WinApp.Cli.Tests/EndToEndTests.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public async Task E2E_WinFormsApp_CreateBuildManifestAndPackage_ShouldSucceed()
6868
};
6969

7070
var manifestParseResult = manifestGenerateCommand.Parse(manifestArgs);
71-
var manifestExitCode = await manifestParseResult.InvokeAsync();
71+
var manifestExitCode = await manifestParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
7272
Assert.AreEqual(0, manifestExitCode, "Manifest generate command should complete successfully");
7373

7474
// Verify manifest generated the necessary files
@@ -90,7 +90,7 @@ public async Task E2E_WinFormsApp_CreateBuildManifestAndPackage_ShouldSucceed()
9090
};
9191

9292
var packageParseResult = packageCommand.Parse(packageArgs);
93-
var packageExitCode = await packageParseResult.InvokeAsync();
93+
var packageExitCode = await packageParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
9494
Assert.AreEqual(0, packageExitCode, "Package command should complete successfully");
9595

9696
// Step 6: Verify the MSIX package was created
@@ -100,7 +100,7 @@ public async Task E2E_WinFormsApp_CreateBuildManifestAndPackage_ShouldSucceed()
100100
Assert.IsGreaterThan(0, fileInfo.Length, "MSIX package should not be empty");
101101

102102
// Verify the MSIX contains expected files
103-
using var archive = ZipFile.OpenRead(packageOutputPath);
103+
using var archive = await ZipFile.OpenReadAsync(packageOutputPath, TestContext.CancellationToken);
104104
var entries = archive.Entries.Select(e => e.FullName).ToList();
105105

106106
Assert.IsTrue(entries.Any(e => e.EndsWith("AppxManifest.xml", StringComparison.OrdinalIgnoreCase)),
@@ -149,14 +149,14 @@ public async Task E2E_WinFormsApp_WithCustomManifestOptions_ShouldPackageSuccess
149149
};
150150

151151
var manifestParseResult = manifestGenerateCommand.Parse(manifestArgs);
152-
var manifestExitCode = await manifestParseResult.InvokeAsync();
152+
var manifestExitCode = await manifestParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
153153
Assert.AreEqual(0, manifestExitCode, "Manifest generate command should complete successfully");
154154

155155
// Verify custom options were applied
156156
var manifestPath = Path.Combine(projectDir.FullName, "appxmanifest.xml");
157157
Assert.IsTrue(File.Exists(manifestPath), "Manifest should be created");
158158

159-
var manifestContent = await File.ReadAllTextAsync(manifestPath);
159+
var manifestContent = await File.ReadAllTextAsync(manifestPath, TestContext.CancellationToken);
160160
Assert.IsTrue(manifestContent.Contains("CustomPackageName", StringComparison.OrdinalIgnoreCase),
161161
"Manifest should contain custom package name");
162162
Assert.IsTrue(manifestContent.Contains("CN=TestPublisher", StringComparison.Ordinal),
@@ -176,7 +176,7 @@ public async Task E2E_WinFormsApp_WithCustomManifestOptions_ShouldPackageSuccess
176176
};
177177

178178
var packageParseResult = packageCommand.Parse(packageArgs);
179-
var packageExitCode = await packageParseResult.InvokeAsync();
179+
var packageExitCode = await packageParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
180180
Assert.AreEqual(0, packageExitCode, "Package command should complete successfully");
181181

182182
Assert.IsTrue(File.Exists(packageOutputPath), "MSIX package should be created");
@@ -208,7 +208,7 @@ def main():
208208
if __name__ == ""__main__"":
209209
sys.exit(main())
210210
";
211-
await File.WriteAllTextAsync(scriptPath, pythonScript);
211+
await File.WriteAllTextAsync(scriptPath, pythonScript, TestContext.CancellationToken);
212212
Assert.IsTrue(File.Exists(scriptPath), "Python script should be created");
213213

214214
// Step 2: Run 'winapp manifest generate --template hostedapp --entrypoint main.py'
@@ -222,14 +222,14 @@ def main():
222222
};
223223

224224
var manifestParseResult = manifestGenerateCommand.Parse(manifestArgs);
225-
var manifestExitCode = await manifestParseResult.InvokeAsync();
225+
var manifestExitCode = await manifestParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
226226
Assert.AreEqual(0, manifestExitCode, "Manifest generate command should complete successfully");
227227

228228
// Verify manifest was created with hosted app configuration
229229
var manifestPath = Path.Combine(projectDir.FullName, "appxmanifest.xml");
230230
Assert.IsTrue(File.Exists(manifestPath), "Manifest should be created");
231231

232-
var manifestContent = await File.ReadAllTextAsync(manifestPath);
232+
var manifestContent = await File.ReadAllTextAsync(manifestPath, TestContext.CancellationToken);
233233
Assert.IsTrue(manifestContent.Contains("Python314", StringComparison.OrdinalIgnoreCase) ||
234234
manifestContent.Contains("Python", StringComparison.OrdinalIgnoreCase),
235235
"Manifest should contain Python runtime dependency");
@@ -247,7 +247,7 @@ def main():
247247
};
248248

249249
var debugIdentityParseResult = createDebugIdentityCommand.Parse(debugIdentityArgs);
250-
var debugIdentityExitCode = await debugIdentityParseResult.InvokeAsync();
250+
var debugIdentityExitCode = await debugIdentityParseResult.InvokeAsync(cancellationToken: TestContext.CancellationToken);
251251
Assert.AreEqual(0, debugIdentityExitCode, "Create debug identity command should complete successfully");
252252

253253
// Verify the debug identity package was created (sparse package registration)
@@ -258,7 +258,7 @@ def main():
258258
/// <summary>
259259
/// Helper method to run dotnet commands
260260
/// </summary>
261-
private async Task<(int ExitCode, string Output, string Error)> RunDotnetCommandAsync(
261+
private static async Task<(int ExitCode, string Output, string Error)> RunDotnetCommandAsync(
262262
DirectoryInfo workingDirectory,
263263
string arguments)
264264
{

0 commit comments

Comments
 (0)