Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ed2f211
wip
hojmark Dec 13, 2025
04235ee
windows ping tool implementation
hojmark Dec 13, 2025
42452ef
ci: windows workflow
hojmark Dec 13, 2025
9c2915b
linux only tests
hojmark Dec 13, 2025
2de69a1
windows multiline command backticks
hojmark Dec 13, 2025
c770f75
oops
hojmark Dec 13, 2025
3f5f8e6
temp skip e2e on windows
hojmark Dec 13, 2025
e70cb9c
f
hojmark Dec 13, 2025
7a9e35a
platform
hojmark Dec 13, 2025
c26eca9
f
hojmark Dec 13, 2025
54c614f
fix test
hojmark Dec 13, 2025
5016aef
fix tests
hojmark Dec 13, 2025
41d3d79
fix test
hojmark Dec 13, 2025
1639084
enable test on windows
hojmark Dec 13, 2025
5e9958a
temp disable test on Windows
hojmark Dec 13, 2025
e467f42
test on windows
hojmark Dec 13, 2025
542f905
test on windows
hojmark Dec 13, 2025
484cd35
fix test
hojmark Dec 13, 2025
d78f608
refactor arp tables
hojmark Dec 13, 2025
b882a35
blind windows arp table implementation
hojmark Dec 13, 2025
27e5bfb
blind windows ping subnet scanner implementation
hojmark Dec 13, 2025
995cc36
disable test on windows
hojmark Dec 14, 2025
4a65f75
more specific disable
hojmark Dec 14, 2025
34d5d84
enable e2e
hojmark Dec 14, 2025
bc96a89
build binaries on the right platforms
hojmark Dec 14, 2025
2336943
default platform when localbuild
hojmark Dec 14, 2025
6324afe
fix RID
hojmark Dec 14, 2025
85b6d4b
platform dependant binary name
hojmark Dec 14, 2025
6cafa7e
f
hojmark Dec 14, 2025
7d318a7
bump windows timeout to 10 minutes
hojmark Dec 14, 2025
dbfd4e7
f
hojmark Dec 14, 2025
2e22dff
f
hojmark Dec 14, 2025
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
3 changes: 2 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ 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
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/ci_windows.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: 🔁 🪟 CI
permissions:
contents: read

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
inputs:
verbosity:
description: 'MSBuild verbosity level'
required: false
default: 'normal'
type: choice
options:
- 'quiet'
- 'minimal'
- 'normal'
- 'detailed'
- 'diagnostic'

jobs:
test:
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

# TODO fix publish warnings and re-enable check
- 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 @@ -148,6 +148,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
1 change: 1 addition & 0 deletions Drift.sln
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflows", "Workflows", "{
.github\workflows\ci.yaml = .github\workflows\ci.yaml
.github\workflows\release.yaml = .github\workflows\release.yaml
.github\workflows\prerelease.yaml = .github\workflows\prerelease.yaml
.github\workflows\ci_windows.yaml = .github\workflows\ci_windows.yaml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cli.E2ETests.Abstractions", "src\Cli.E2ETests.Abstractions\Cli.E2ETests.Abstractions.csproj", "{A2CE629F-8D56-4539-9642-C31B550F7C30}"
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 @@ -4,6 +4,7 @@
using HLabs.Containers;
using Nuke.Common;
using Nuke.Common.Tools.Docker;
using Nuke.Common.Tools.DotNet;
using Serilog;

// ReSharper disable VariableHidesOuterVariable
Expand All @@ -25,6 +26,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
68 changes: 36 additions & 32 deletions build/NukeBuild.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,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,38 +78,37 @@ sealed partial class NukeBuild {

var version = await Versioning.Value.GetVersionAsync();

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 },
// TODO use this!
// { "DRIFT_CONTAINER_IMAGE_REF", ImageReference.Localhost( "drift", version ).ToString() }
{ "DRIFT_CONTAINER_IMAGE_REF", ImageReference.Localhost( "drift", version ).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 },
// TODO use this!
// { "DRIFT_CONTAINER_IMAGE_REF", ImageReference.Localhost( "drift", version ).ToString() }
{ "DRIFT_CONTAINER_IMAGE_REF", ImageReference.Localhost( "drift", version ).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
2 changes: 2 additions & 0 deletions src/Cli.E2ETests/DriftImageFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace Drift.Cli.E2ETests;

// TODO can run on linux too, as long as the image is available from the Windows CI runner
[Platform("Linux")]
internal abstract class DriftImageFixture {
protected static ImageReference DriftImage {
get;
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
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
@@ -0,0 +1,2 @@
Validating {SolutionDirectory}src\Spec.Tests\resources\network_single_subnet.yaml
✔ Valid
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[<time> INF] Validating network spec: {SolutionDirectory}src\Spec.Tests\resources\network_single_subnet.yaml
[<time> INF] Spec is valid
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Validating {SolutionDirectory}src\Spec.Tests\resources\network_single_subnet.yaml
✔ Valid
21 changes: 21 additions & 0 deletions src/Cli.Tests/Commands/LintCommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.InteropServices;
using Drift.Cli.Abstractions;
using Drift.Cli.Tests.Utils;
using Drift.TestUtilities;
Expand All @@ -7,9 +8,13 @@ namespace Drift.Cli.Tests.Commands;
internal sealed class LintCommandTests {
[Test]
public async Task LintValidSpec(
[Values( Platform.Linux, Platform.Windows )]
Platform platform,
[Values( "network_single_subnet" )] string specName,
[Values( "", "normal", "log" )] string outputFormat
) {
SkipIfNot( platform );

// Arrange
var outputOption = string.IsNullOrWhiteSpace( outputFormat ) ? string.Empty : $" -o {outputFormat}";

Expand All @@ -28,10 +33,14 @@ await Verify( output.ToString() + error )

[Test]
public async Task LintInvalidSpec(
[Values( Platform.Linux, Platform.Windows )]
Platform platform,
[Values( "network_single_device_host" )]
string specName,
[Values( "", "normal", "log" )] string outputFormat
) {
SkipIfNot( platform );

// Arrange
var outputOption = string.IsNullOrWhiteSpace( outputFormat ) ? string.Empty : $" -o {outputFormat}";

Expand All @@ -48,6 +57,18 @@ await Verify( output.ToString() + error )
}
}

private static void SkipIfNot( Platform platform ) {
var expectedOs = platform switch {
Platform.Linux => OSPlatform.Linux,
Platform.Windows => OSPlatform.Windows,
_ => throw new PlatformNotSupportedException()
};

if ( !RuntimeInformation.IsOSPlatform( expectedOs ) ) {
Assert.Inconclusive( $"Can only be run on {platform}" );
}
}

[Test]
public async Task LintMissingSpec() {
// Arrange / Act
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
✗ This exception was thrown from ExceptionCommandHandler
at Drift.Cli.Tests.ExitCodeTests.ExceptionCommandHandler.Invoke(DefaultParameters parameters, CancellationToken cancellationToken) in {ProjectDirectory}ExitCodeTests.cs:line 104
at Drift.Cli.Commands.Common.CommandBase`2.<>c__DisplayClass0_0.<.ctor>b__0(ParseResult parseResult, CancellationToken cancellationToken) in {SolutionDirectory}src/Cli/Commands/Common/CommandBase.cs:line 25
at System.CommandLine.Invocation.AnonymousAsynchronousCommandLineAction.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at Drift.Cli.DriftCli.InvokeAsync(String[] args, Boolean toConsole, Boolean plainConsole, Action`1 configureServices, CommandRegistration[] customCommands, Action`1 configureInvocation, CancellationToken cancellationToken) in {SolutionDirectory}src/Cli/DriftCli.cs:line 41
at Drift.Cli.Tests.ExitCodeTests.ExceptionCommandHandler.Invoke(DefaultParameters parameters, CancellationToken cancellationToken) in {ProjectDirectory}ExitCodeTests.cs:line 111
Loading
Loading