Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f8bb790
wip
hojmark Dec 13, 2025
3268400
windows ping tool implementation
hojmark Dec 13, 2025
66d761a
ci: windows workflow
hojmark Dec 13, 2025
fcfddfc
linux only tests
hojmark Dec 13, 2025
83dba0a
windows multiline command backticks
hojmark Dec 13, 2025
29535bf
oops
hojmark Dec 13, 2025
032fa69
temp skip e2e on windows
hojmark Dec 13, 2025
3f0e053
f
hojmark Dec 13, 2025
f72d8d4
platform
hojmark Dec 13, 2025
d3d2d75
f
hojmark Dec 13, 2025
15b418d
fix test
hojmark Dec 13, 2025
f127d1a
fix tests
hojmark Dec 13, 2025
e7d2fe9
fix test
hojmark Dec 13, 2025
8a76888
enable test on windows
hojmark Dec 13, 2025
128de02
temp disable test on Windows
hojmark Dec 13, 2025
4e467cb
test on windows
hojmark Dec 13, 2025
acfb234
test on windows
hojmark Dec 13, 2025
45da251
fix test
hojmark Dec 13, 2025
fbf3e5f
refactor arp tables
hojmark Dec 13, 2025
12eaa58
blind windows arp table implementation
hojmark Dec 13, 2025
cc7d8e1
blind windows ping subnet scanner implementation
hojmark Dec 13, 2025
1ee3e76
disable test on windows
hojmark Dec 14, 2025
f841387
more specific disable
hojmark Dec 14, 2025
2eb7745
enable e2e
hojmark Dec 14, 2025
cbbc4d0
build binaries on the right platforms
hojmark Dec 14, 2025
2df6850
default platform when localbuild
hojmark Dec 14, 2025
b642780
fix RID
hojmark Dec 14, 2025
bd24405
platform dependant binary name
hojmark Dec 14, 2025
5a1f877
f
hojmark Dec 14, 2025
6fdf81e
bump windows timeout to 10 minutes
hojmark Dec 14, 2025
3398b54
f
hojmark Dec 14, 2025
20e58da
f
hojmark Dec 14, 2025
3d4b925
pinguin
hojmark Feb 6, 2026
eb98cf7
can't run containers on gha win runners
hojmark Feb 6, 2026
fea9693
normalize content
hojmark Feb 6, 2026
c088bf4
normalize whitespace
hojmark Feb 6, 2026
d56b23e
another checkmark char
hojmark Feb 6, 2026
768aeb4
update windows snapshots
hojmark Feb 6, 2026
7278ed1
refactor
hojmark Feb 6, 2026
6b09159
use unicode for checkmark and cross
hojmark Feb 6, 2026
791fe91
fix warning
hojmark Feb 6, 2026
126d317
update windows snapshots
hojmark Feb 6, 2026
6320982
Fix merge conflict resolution in TestE2E
hojmark Feb 18, 2026
e407807
merge ci workflow files
hojmark Feb 18, 2026
18ccd2d
remove outdated todo
hojmark Feb 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ on:
- 'diagnostic'

jobs:
test:
name: Test
test-linux:
name: 🐧 Test
runs-on: ubuntu-latest
timeout-minutes: 5
env:
Expand All @@ -42,16 +42,47 @@ jobs:
--project ./build/_build.csproj \
--target Test \
--commit ${{ github.sha }} \
--msbuildverbosity ${{ github.event.inputs.verbosity }}
--msbuildverbosity ${{ github.event.inputs.verbosity }} \
--platform linux_x64

- name: Display test results
continue-on-error: true
if: always()
run: dotnet trx --verbosity normal

# TODO fix publish warnings and re-enable check
- name: Check for warnings
run: |
dotnet run \
--project ./build/_build.csproj \
--target CheckBuildWarnings

test-windows:
name: 🪟 Test
runs-on: windows-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up runner
uses: ./.github/actions/setup-runner

- name: Run tests
run: |
dotnet run `
--project ./build/_build.csproj `
--target Test `
--commit ${{ github.sha }} `
--msbuildverbosity ${{ github.event.inputs.verbosity }} `
--platform win_x64

- name: Display test results
continue-on-error: true
if: always()
run: dotnet trx --verbosity normal

- name: Check for warnings
run: |
dotnet run `
--project ./build/_build.csproj `
--target CheckBuildWarnings
39 changes: 39 additions & 0 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,45 @@
"type": "string",
"description": "MsBuildVerbosity - Console output verbosity - Default is 'normal'"
},
"Platform": {
"type": "string",
"description": "Platform - A .NET RID but with underscores instead of dashes e.g. linux_x64 or win_x64",
"enum": [
"linux_arm",
"linux_arm64",
"linux_musl_x64",
"linux_x64",
"osx_10_10_x64",
"osx_10_11_x64",
"osx_10_12_x64",
"osx_10_13_x64",
"osx_10_14_x64",
"osx_10_15_x64",
"osx_11_0_arm64",
"osx_11_0_x64",
"osx_12_arm64",
"osx_12_x64",
"osx_x64",
"rhel_6_x64",
"rhel_x64",
"tizen",
"tizen_4_0_0",
"tizen_5_0_0",
"win_arm",
"win_arm64",
"win_x64",
"win_x86",
"win10_arm",
"win10_arm64",
"win10_x64",
"win10_x86",
"win7_x64",
"win7_x86",
"win81_arm",
"win81_x64",
"win81_x86"
]
},
"Solution": {
"type": "string",
"description": "Path to a solution file that is automatically loaded"
Expand Down
37 changes: 18 additions & 19 deletions build/NukeBuild.Binaries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,28 @@ sealed partial class NukeBuild {

Target PublishBinaries => _ => _
.DependsOn( Build, CleanArtifacts )
.Requires( () => Platform )
.Requires( () => SupportedRuntimes.Contains( Platform ) )
.Executes( async () => {
using var _ = new OperationTimer( nameof(PublishBinaries) );

// TODO https://nuke.build/docs/common/cli-tools/#combinatorial-modifications
foreach ( var runtime in SupportedRuntimes ) {
var publishDir = Paths.PublishDirectoryForRuntime( runtime );
var version = await Versioning.Value.GetVersionAsync();
var publishDir = Paths.PublishDirectoryForRuntime( Platform );
var version = await Versioning.Value.GetVersionAsync();

Log.Information( "Publishing {Runtime} build to {PublishDir}", runtime, publishDir );
DotNetPublish( s => s
.SetProject( Solution.Cli )
.SetConfiguration( Configuration )
.SetOutput( publishDir )
.SetSelfContained( true )
.SetVersionProperties( version )
// TODO if not specifying a RID, apparently only x64 gets built on x64 host
.SetRuntime( runtime )
.SetProcessAdditionalArguments( $"-bl:{BinaryPublishLogName}" )
.EnableNoLogo()
.EnableNoRestore()
.EnableNoBuild()
);
}
Log.Information( "Publishing {Runtime} build to {PublishDir}", Platform, publishDir );
Log.Debug( "Supported runtimes are {SupportedRuntimes}", string.Join( ", ", SupportedRuntimes ) );
DotNetPublish( s => s
.SetProject( Solution.Cli )
.SetConfiguration( Configuration )
.SetOutput( publishDir )
.SetSelfContained( true )
.SetVersionProperties( version )
.SetRuntime( Platform )
.SetProcessAdditionalArguments( $"-bl:{BinaryPublishLogName}" )
.EnableNoLogo()
.EnableNoRestore()
.EnableNoBuild()
);
}
);

Expand Down
2 changes: 2 additions & 0 deletions build/NukeBuild.Container.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using JetBrains.Annotations;
using Nuke.Common;
using Nuke.Common.Tools.Docker;
using Nuke.Common.Tools.DotNet;
using Serilog;
using Versioning;

Expand Down Expand Up @@ -33,6 +34,7 @@ partial class NukeBuild {

Target PublishContainer => _ => _
.DependsOn( PublishBinaries, CleanArtifacts )
.OnlyWhenDynamic( () => Platform != DotNetRuntimeIdentifier.win_x64 )
.Requires( () => Commit )
.Executes( async () => {
using var _ = new OperationTimer( nameof(PublishContainer) );
Expand Down
64 changes: 34 additions & 30 deletions build/NukeBuild.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
// ReSharper disable UnusedMember.Local

sealed partial class NukeBuild {
private string DriftBinaryName =>
Platform == DotNetRuntimeIdentifier.linux_x64 ? "drift" :
Platform == DotNetRuntimeIdentifier.win_x64 ? "drift.exe" :
throw new PlatformNotSupportedException();

Target Test => _ => _
.DependsOn( TestSelf, TestUnit, TestE2E );

Expand Down Expand Up @@ -73,36 +78,35 @@ sealed partial class NukeBuild {
var imageRef = _driftImageRef ?? throw new ArgumentNullException( nameof(_driftImageRef) );
Log.Information( "Using image {ImageRef}", imageRef );

foreach ( var runtime in SupportedRuntimes ) {
var driftBinary = Paths.PublishDirectoryForRuntime( runtime ) / "drift";

var envVars = new Dictionary<string, string> {
// { nameof(EnvVar.DRIFT_BINARY_PATH), driftBinary },
{ "DRIFT_BINARY_PATH", driftBinary }, //
{ "DRIFT_CONTAINER_IMAGE_REF", imageRef.ToString() }
};

var alternateDockerHost = await FindAlternateDockerHostAsync();

DotNetTest( settings => {
if ( alternateDockerHost != null ) {
Log.Information( "Using alternate Docker host: {Host}", alternateDockerHost );
settings.SetProcessEnvironmentVariable( "DOCKER_HOST", alternateDockerHost );
}

return settings
.SetProjectFile( Solution.Cli_E2ETests )
.SetConfiguration( Configuration )
.ConfigureLoggers( MsBuildVerbosityParsed )
.SetBlameHangTimeout( "60s" )
.EnableNoLogo()
.EnableNoRestore()
.EnableNoBuild()
.AddProcessEnvironmentVariables( envVars );
} );

Log.Information( "Running E2E test on {Runtime} using binary {Binary}", runtime, driftBinary );
}
var driftBinary = Paths.PublishDirectoryForRuntime( Platform ) / DriftBinaryName;

Log.Information( "Running E2E test on {Runtime} using binary {Binary}", Platform, driftBinary );
Log.Debug( "Supported runtimes are {SupportedRuntimes}", string.Join( ", ", SupportedRuntimes ) );

var envVars = new Dictionary<string, string> {
// { nameof(EnvVar.DRIFT_BINARY_PATH), driftBinary },
{ "DRIFT_BINARY_PATH", driftBinary },
{ "DRIFT_CONTAINER_IMAGE_REF", imageRef.ToString() }
};

var alternateDockerHost = await FindAlternateDockerHostAsync();

DotNetTest( settings => {
if ( alternateDockerHost != null ) {
Log.Information( "Using alternate Docker host: {Host}", alternateDockerHost );
settings.SetProcessEnvironmentVariable( "DOCKER_HOST", alternateDockerHost );
}

return settings
.SetProjectFile( Solution.Cli_E2ETests )
.SetConfiguration( Configuration )
.ConfigureLoggers( MsBuildVerbosityParsed )
.SetBlameHangTimeout( "60s" )
.EnableNoLogo()
.EnableNoRestore()
.EnableNoBuild()
.AddProcessEnvironmentVariables( envVars );
} );
}
);

Expand Down
11 changes: 11 additions & 0 deletions build/NukeBuild.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Drift.Build.Utilities;
Expand Down Expand Up @@ -64,8 +65,18 @@ public NukeBuild() {
[Secret, Parameter( $"{nameof(GitHubToken)} - GitHub token used to create releases" )]
public string GitHubToken;

[Parameter( $"{nameof(Platform)} - A .NET RID but with underscores instead of dashes e.g. linux_x64 or win_x64" )]
public DotNetRuntimeIdentifier Platform = IsLocalBuild
? RuntimeInformation.IsOSPlatform( OSPlatform.Linux )
? DotNetRuntimeIdentifier.linux_x64
: RuntimeInformation.IsOSPlatform( OSPlatform.Windows )
? DotNetRuntimeIdentifier.win_x64
: throw new PlatformNotSupportedException()
: null;

private static readonly DotNetRuntimeIdentifier[] SupportedRuntimes = [
DotNetRuntimeIdentifier.linux_x64,
DotNetRuntimeIdentifier.win_x64
// TODO support more architectures
/*
, DotNetRuntimeIdentifier.linux_musl_x64
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Validating {CurrentDirectory}unittest.spec.yaml
Valid
Valid
2 changes: 1 addition & 1 deletion src/Cli.E2ETests/Commands/LintTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public async Task InitThenLintTest() {

using ( Assert.EnterMultipleScope() ) {
Assert.That( initResult.ExitCode, Is.EqualTo( ExitCodes.Success ) );
Assert.That( initResult.StdOut, Contains.Substring( " Spec created" ) );
Assert.That( initResult.StdOut, Contains.Substring( " Spec created" ) );
Assert.That( initResult.ErrOut, Is.Empty );
}

Expand Down
2 changes: 1 addition & 1 deletion src/Cli.E2ETests/Commands/ReadmeWorkflowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task InitThenScanTest() {

using ( Assert.EnterMultipleScope() ) {
Assert.That( initResult.ExitCode, Is.EqualTo( ExitCodes.Success ) );
Assert.That( initResult.StdOut, Contains.Substring( " Spec created /" ) );
Assert.That( initResult.StdOut, Contains.Substring( " Spec created /" ) );
}

await Verify( initResult.StdOut )
Expand Down
1 change: 1 addition & 0 deletions src/Cli.E2ETests/Container/CommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace Drift.Cli.E2ETests.Container;

[Platform( "Linux" )]
internal sealed class CommandTests : DriftImageFixture {
[Test]
public async Task ValidCommand_ReturnsSuccessExitCode() {
Expand Down
1 change: 1 addition & 0 deletions src/Cli.E2ETests/Container/LabelsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Drift.Cli.E2ETests.Container;

[Platform( "Linux" )]
internal sealed class LabelsTest : DriftImageFixture {
private readonly List<string> _ociAnnotationsV1_1_1 = [
"org.opencontainers.image.created",
Expand Down
1 change: 1 addition & 0 deletions src/Cli.E2ETests/Container/PortTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace Drift.Cli.E2ETests.Container;

[Platform( "Linux" )]
internal sealed class PortTest : DriftImageFixture {
[Explicit( "Not implemented yet" )]
[Test]
Expand Down
1 change: 1 addition & 0 deletions src/Cli.E2ETests/Installation/InstallTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Drift.Cli.E2ETests.Installation;
"S2325:Methods and properties that don\'t access instance data should be static",
Justification = "Unimplemented test methods should not be static"
)]
[Platform("Linux")]
internal sealed class InstallTests {
// TODO split test into at least two parts
[Test]
Expand Down
8 changes: 7 additions & 1 deletion src/Cli.E2ETests/Schemas/SchemasAvailabilityTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.RegularExpressions;

namespace Drift.Cli.E2ETests.Schemas;

internal sealed class SchemasAvailabilityTests {
Expand Down Expand Up @@ -44,6 +46,10 @@ public async Task SchemaIsAvailableAtDocumentedUrl( string documentedUrl, string
// Assert
Assert.DoesNotThrow( () => response.EnsureSuccessStatusCode() );
var content = await response.Content.ReadAsStringAsync();
Assert.That( content, Contains.Substring( expectedPartialContent ) );

var normalizedContent = Regex.Replace( content, @"\s", string.Empty );
var normalizedExpected = Regex.Replace( expectedPartialContent, @"\s", string.Empty );

Assert.That( normalizedContent, Contains.Substring( normalizedExpected ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Found interfaces: [lo, up, 127.0.0.0/8], [enp0xxxxx, down, -], [enp8xxxxx, up, 192.168.0.0/24], [wlp, up, 192.168.0.0/24], [tun0, up, 100.100.1.9/32]
Discovered subnet(s): 192.168.0.0/24 (RFC1918 addresses only)
Found subnets: 192.168.0.0/24 (254 addresses, 00:00:05.0800000 estimated scan time)
Spec created {CurrentDirectory}myNetworkWithDiscovery.spec.yaml
Spec created {CurrentDirectory}myNetworkWithDiscovery.spec.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
 Spec created {CurrentDirectory}myNetworkWithDiscovery.spec.yaml
 Spec created {CurrentDirectory}myNetworkWithDiscovery.spec.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
 Spec created {CurrentDirectory}myNetworkWithoutDiscovery.spec.yaml
 Spec created {CurrentDirectory}myNetworkWithoutDiscovery.spec.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
 Name is required
 Name is required
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Validating {SolutionDirectory}src/Spec.Tests/resources/network_single_device_host.yaml
Validation failed
Validation failed
• /: Required properties ["version"] are not present
• /network/subnets/0: Required properties ["address"] are not present
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Validating {SolutionDirectory}src/Spec.Tests/resources/network_single_device_host.yaml
Validation failed
Validation failed
• /: Required properties ["version"] are not present
• /network/subnets/0: Required properties ["address"] are not present
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Validating {SolutionDirectory}src\Spec.Tests\resources\network_single_device_host.yaml
✕ Validation failed
• /: Required properties ["version"] are not present
• /network/subnets/0: Required properties ["address"] are not present
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[<time> INF] Validating network spec: {SolutionDirectory}src\Spec.Tests\resources\network_single_device_host.yaml
[<time> WRN] Spec is invalid
[<time> ERR] /: Required properties ["version"] are not present
[<time> ERR] /network/subnets/0: Required properties ["address"] are not present
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Validating {SolutionDirectory}src\Spec.Tests\resources\network_single_device_host.yaml
✕ Validation failed
• /: Required properties ["version"] are not present
• /network/subnets/0: Required properties ["address"] are not present
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Validating {SolutionDirectory}src/Spec.Tests/resources/network_single_subnet.yaml
Valid
Valid
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Validating {SolutionDirectory}src/Spec.Tests/resources/network_single_subnet.yaml
Valid
Valid
Loading
Loading