This commit is contained in:
parent
75a9320b58
commit
33e264a9d5
14 changed files with 270 additions and 0 deletions
|
|
@ -46,6 +46,9 @@ jobs:
|
||||||
*.nupkg
|
*.nupkg
|
||||||
*.snupkg
|
*.snupkg
|
||||||
|
|
||||||
|
- name: test SDK packages
|
||||||
|
run: dotnet test src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj --no-build --no-restore
|
||||||
|
|
||||||
- name: publish to nuget
|
- name: publish to nuget
|
||||||
if: startsWith(forgejo.ref, 'refs/tags/')
|
if: startsWith(forgejo.ref, 'refs/tags/')
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
artifacts/
|
artifacts/
|
||||||
|
TestResults/
|
||||||
node_modules/
|
node_modules/
|
||||||
*.DotSettings.user
|
*.DotSettings.user
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageVersion Include="TUnit" Version="1.75.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
23
src/sdk.tests/DirectoryExtensions.cs
Normal file
23
src/sdk.tests/DirectoryExtensions.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) The Geekeey Authors
|
||||||
|
// SPDX-License-Identifier: EUPL-1.2
|
||||||
|
|
||||||
|
namespace Geekeey.Arcade.NET.Tests;
|
||||||
|
|
||||||
|
public static class DirectoryExtensions
|
||||||
|
{
|
||||||
|
extension(Directory)
|
||||||
|
{
|
||||||
|
public static void Copy(string sourceDirectory, string destinationDirectory)
|
||||||
|
{
|
||||||
|
foreach (var directory in Directory.EnumerateDirectories(sourceDirectory, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.Combine(destinationDirectory, Path.GetRelativePath(sourceDirectory, directory)));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
File.Copy(file, Path.Combine(destinationDirectory, Path.GetRelativePath(sourceDirectory, file)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj
Normal file
15
src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="TUnit" />
|
||||||
|
<Compile Remove="fixtures/**/*.cs" />
|
||||||
|
<None Remove="fixtures/**/*" />
|
||||||
|
<Content Include="fixtures/**/*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
171
src/sdk.tests/SdkPackageIntegrationTests.cs
Normal file
171
src/sdk.tests/SdkPackageIntegrationTests.cs
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
// Copyright (c) The Geekeey Authors
|
||||||
|
// SPDX-License-Identifier: EUPL-1.2
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Geekeey.Arcade.NET.Tests;
|
||||||
|
|
||||||
|
public sealed class SdkPackageIntegrationTests
|
||||||
|
{
|
||||||
|
|
||||||
|
private static string RepositoryPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
for (var directory = new DirectoryInfo(AppContext.BaseDirectory); directory is not null; directory = directory.Parent)
|
||||||
|
{
|
||||||
|
if (File.Exists(Path.Combine(directory.FullName, "global.json")))
|
||||||
|
{
|
||||||
|
return directory.FullName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Could not locate the repository root containing global.json.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NuGetFeedPath { get; } = Path.Combine(RepositoryPath, "artifacts", "package", "release");
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Arguments("Geekeey.Arcade.NET.Sdk", "base")]
|
||||||
|
[Arguments("Geekeey.Arcade.NET.Sdk.Razor", "razor")]
|
||||||
|
[Arguments("Geekeey.Arcade.NET.Sdk.Web", "web")]
|
||||||
|
public async Task SdkPackageCanBeConsumedFromAFeed(string packageId, string name)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var version = FindPackageVersion(packageId);
|
||||||
|
using var sut = await SdkTestProject.CreateAsync(name, version);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await sut.RunDotnetAsync($"restore --configfile \"{sut.NuGetConfigPath}\" --packages \"{sut.PackagesPath}\" --nologo");
|
||||||
|
await sut.RunDotnetAsync("build --no-restore --nologo");
|
||||||
|
await sut.RunDotnetAsync($"pack --no-restore --configuration Debug --output \"{sut.PackedPath}\" --nologo");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await Assert.That(File.Exists(Path.Combine(sut.ProjectPath, "bin", "Debug", "net10.0", $"{sut.ProjectName}.dll"))).IsTrue();
|
||||||
|
await Assert.That(Directory.Exists(sut.PackedPath)).IsTrue();
|
||||||
|
await Assert.That(Directory.EnumerateFiles(sut.PackedPath, $"{sut.ProjectName}.*.nupkg").Any()).IsTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestSdkPackageStoresTestOutputInArtifacts()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var version = FindPackageVersion("Geekeey.Arcade.NET.Sdk.Test");
|
||||||
|
using var sut = await SdkTestProject.CreateAsync("test", version);
|
||||||
|
await sut.RunDotnetAsync($"restore --configfile \"{sut.NuGetConfigPath}\" --packages \"{sut.PackagesPath}\" --nologo");
|
||||||
|
await sut.RunDotnetAsync("build --no-restore --nologo");
|
||||||
|
|
||||||
|
var outputDirectory = Path.Combine(sut.ProjectPath, "artifacts", "bin", sut.ProjectName, "debug");
|
||||||
|
await Assert.That(File.Exists(Path.Combine(outputDirectory, $"{sut.ProjectName}.dll"))).IsTrue();
|
||||||
|
var testConfig = await File.ReadAllTextAsync(Path.Combine(outputDirectory, $"{sut.ProjectName}.testconfig.json"));
|
||||||
|
await Assert.That(testConfig.Contains("results-directory", StringComparison.Ordinal)).IsTrue();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var stdout = await sut.RunDotnetAsync("run --no-build --no-restore");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await Assert.That(stdout.Contains("succeeded: 1", StringComparison.Ordinal)).IsTrue();
|
||||||
|
await Assert.That(Directory.EnumerateFiles(Path.Combine(sut.ProjectPath, "artifacts", "testresults"), $"{sut.ProjectName}-*").Any()).IsTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FindPackageVersion(string packageId)
|
||||||
|
{
|
||||||
|
var pattern = $"""^{Regex.Escape(packageId)}\.(?<version>\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\.nupkg$""";
|
||||||
|
foreach (var package in Directory.EnumerateFiles(NuGetFeedPath, "*.nupkg"))
|
||||||
|
{
|
||||||
|
var match = Regex.Match(Path.GetFileName(package), pattern, RegexOptions.CultureInvariant);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
return match.Groups["version"].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException($"No current package found for {packageId}. Run dotnet pack first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class SdkTestProject : IDisposable
|
||||||
|
{
|
||||||
|
private SdkTestProject(string root)
|
||||||
|
{
|
||||||
|
RootPath = root;
|
||||||
|
ProjectPath = Path.Combine(RootPath, "Project");
|
||||||
|
PackagesPath = Path.Combine(RootPath, "packages");
|
||||||
|
PackedPath = Path.Combine(RootPath, "packed");
|
||||||
|
NuGetConfigPath = Path.Combine(RootPath, "NuGet.config");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<SdkTestProject> CreateAsync(string name, string version)
|
||||||
|
{
|
||||||
|
var sut = new SdkTestProject(Path.Combine(Path.GetTempPath(), $"arcade-sdk-test-{Guid.NewGuid():N}"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(sut.ProjectPath);
|
||||||
|
Directory.Copy(Path.Combine(AppContext.BaseDirectory, "fixtures", name), sut.ProjectPath);
|
||||||
|
sut.ProjectFilePath = Directory.EnumerateFiles(sut.ProjectPath, "*.csproj").Single();
|
||||||
|
sut.ProjectName = Path.GetFileNameWithoutExtension(sut.ProjectFilePath);
|
||||||
|
var project = await File.ReadAllTextAsync(sut.ProjectFilePath);
|
||||||
|
await File.WriteAllTextAsync(sut.ProjectFilePath, project.Replace("{0}", version, StringComparison.Ordinal));
|
||||||
|
var contents = $"""
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<clear />
|
||||||
|
<add key="local" value="{Path.Combine(RepositoryPath, "artifacts", "package", "release")}" />
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
||||||
|
""";
|
||||||
|
await File.WriteAllTextAsync(sut.NuGetConfigPath, contents);
|
||||||
|
return sut;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
sut.Dispose();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string RootPath { get; }
|
||||||
|
|
||||||
|
public string ProjectPath { get; }
|
||||||
|
|
||||||
|
public string ProjectFilePath { get; private set; } = "";
|
||||||
|
|
||||||
|
public string ProjectName { get; private set; } = "";
|
||||||
|
|
||||||
|
public string PackagesPath { get; }
|
||||||
|
|
||||||
|
public string PackedPath { get; }
|
||||||
|
|
||||||
|
public string NuGetConfigPath { get; }
|
||||||
|
|
||||||
|
public async Task<string> RunDotnetAsync(string arguments)
|
||||||
|
{
|
||||||
|
var startInfo = new ProcessStartInfo("dotnet", arguments)
|
||||||
|
{
|
||||||
|
WorkingDirectory = ProjectPath,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
Environment = { ["NUGET_PACKAGES"] = PackagesPath, ["DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER"] = "1" }
|
||||||
|
};
|
||||||
|
var process = Process.Start(startInfo) ?? throw new InvalidOperationException("Could not start dotnet.");
|
||||||
|
var output = await process.StandardOutput.ReadToEndAsync();
|
||||||
|
var error = await process.StandardError.ReadToEndAsync();
|
||||||
|
await process.WaitForExitAsync();
|
||||||
|
if (process.ExitCode is not 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"dotnet {arguments} failed with exit code {process.ExitCode}.\n{output}\n{error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Directory.Delete(RootPath, recursive: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/sdk.tests/fixtures/base/BaseConsumer.csproj
Normal file
9
src/sdk.tests/fixtures/base/BaseConsumer.csproj
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<Project Sdk="Geekeey.Arcade.NET.Sdk/{0}">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
|
<NoBuild>false</NoBuild>
|
||||||
|
<PackageId>BaseConsumer</PackageId>
|
||||||
|
<NoWarn>IDE0055</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
4
src/sdk.tests/fixtures/base/Program.cs
Normal file
4
src/sdk.tests/fixtures/base/Program.cs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
public static class EntryPoint
|
||||||
|
{
|
||||||
|
public static string Value => "ok";
|
||||||
|
}
|
||||||
4
src/sdk.tests/fixtures/razor/Program.cs
Normal file
4
src/sdk.tests/fixtures/razor/Program.cs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
public sealed class ComponentModel
|
||||||
|
{
|
||||||
|
public string Value => "ok";
|
||||||
|
}
|
||||||
5
src/sdk.tests/fixtures/test/Directory.Build.props
Normal file
5
src/sdk.tests/fixtures/test/Directory.Build.props
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ArtifactsPath>$(MSBuildProjectDirectory)/artifacts/</ArtifactsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
7
src/sdk.tests/fixtures/test/Program.cs
Normal file
7
src/sdk.tests/fixtures/test/Program.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
using TUnit.Core;
|
||||||
|
|
||||||
|
public class ConsumerTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestPasses() { }
|
||||||
|
}
|
||||||
14
src/sdk.tests/fixtures/test/TestConsumer.csproj
Normal file
14
src/sdk.tests/fixtures/test/TestConsumer.csproj
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Geekeey.Arcade.NET.Sdk.Test/{0}">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
|
<NoBuild>false</NoBuild>
|
||||||
|
<PackageId>TestConsumer</PackageId>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<NoWarn>IDE0055</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="TUnit" Version="1.75.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
3
src/sdk.tests/fixtures/web/Program.cs
Normal file
3
src/sdk.tests/fixtures/web/Program.cs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
var app = builder.Build();
|
||||||
|
app.MapGet("/", () => "ok");
|
||||||
10
src/sdk.tests/fixtures/web/WebConsumer.csproj
Normal file
10
src/sdk.tests/fixtures/web/WebConsumer.csproj
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<Project Sdk="Geekeey.Arcade.NET.Sdk.Web/{0}">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
|
<NoBuild>false</NoBuild>
|
||||||
|
<PackageId>WebConsumer</PackageId>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<NoWarn>IDE0055</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
Loading…
Reference in a new issue