diff --git a/sdk/dotnet/.editorconfig b/sdk/dotnet/.editorconfig
new file mode 100644
index 00000000000..14c1d8c1953
--- /dev/null
+++ b/sdk/dotnet/.editorconfig
@@ -0,0 +1,6 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
diff --git a/sdk/dotnet/.gitignore b/sdk/dotnet/.gitignore
index 8a30d258ed9..a437a653013 100644
--- a/sdk/dotnet/.gitignore
+++ b/sdk/dotnet/.gitignore
@@ -1,21 +1,22 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+*.swp
+*.*~
+project.lock.json
+.DS_Store
+*.pyc
+nupkg/
+
+# Visual Studio Code
+.vscode
+
+# Rider
+.idea
# User-specific files
-*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Mono auto generated files
-mono_crash.*
-
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -23,376 +24,14 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
-[Ww][Ii][Nn]32/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
+build/
bld/
[Bb]in/
[Oo]bj/
-[Ll]og/
-[Ll]ogs/
+[Oo]ut/
+msbuild.log
+msbuild.err
+msbuild.wrn
-# Visual Studio 2015/2017 cache/options directory
+# Visual Studio 2015
.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# Visual Studio 2017 auto generated files
-Generated\ Files/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUnit
-*.VisualState.xml
-TestResult.xml
-nunit-*.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# Benchmark Results
-BenchmarkDotNet.Artifacts/
-
-# .NET Core
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-# ASP.NET Scaffolding
-ScaffoldingReadMe.txt
-
-# StyleCop
-StyleCopReport.xml
-
-# Files built by Visual Studio
-*_i.c
-*_p.c
-*_h.h
-*.ilk
-*.meta
-*.obj
-*.iobj
-*.pch
-*.pdb
-*.ipdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*_wpftmp.csproj
-*.log
-*.tlog
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# Visual Studio Trace Files
-*.e2e
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# AxoCover is a Code Coverage Tool
-.axoCover/*
-!.axoCover/settings.json
-
-# Coverlet is a free, cross platform Code Coverage Tool
-coverage*.json
-coverage*.xml
-coverage*.info
-
-# Visual Studio code coverage results
-*.coverage
-*.coveragexml
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# Note: Comment the next line if you want to checkin your web deploy settings,
-# but database connection strings (with potential passwords) will be unencrypted
-*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# NuGet Symbol Packages
-*.snupkg
-# The packages folder can be ignored because of Package Restore
-**/[Pp]ackages/*
-# except build/, which is used as an MSBuild target.
-!**/[Pp]ackages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/[Pp]ackages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-*.appx
-*.appxbundle
-*.appxupload
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!?*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-orleans.codegen.cs
-
-# Including strong name files can present a security risk
-# (https://github.com/github/gitignore/pull/2483#issue-259490424)
-#*.snk
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-ServiceFabricBackup/
-*.rptproj.bak
-
-# SQL Server files
-*.mdf
-*.ldf
-*.ndf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-*.rptproj.rsuser
-*- [Bb]ackup.rdl
-*- [Bb]ackup ([0-9]).rdl
-*- [Bb]ackup ([0-9][0-9]).rdl
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-node_modules/
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
-*.vbw
-
-# Visual Studio 6 auto-generated project file (contains which files were open etc.)
-*.vbp
-
-# Visual Studio 6 workspace and project file (working project files containing files to include in project)
-*.dsw
-*.dsp
-
-# Visual Studio 6 technical files
-*.ncb
-*.aps
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# CodeRush personal settings
-.cr/personal
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
-
-# Tabs Studio
-*.tss
-
-# Telerik's JustMock configuration file
-*.jmconfig
-
-# BizTalk build output
-*.btp.cs
-*.btm.cs
-*.odx.cs
-*.xsd.cs
-
-# OpenCover UI analysis results
-OpenCover/
-
-# Azure Stream Analytics local run output
-ASALocalRun/
-
-# MSBuild Binary and Structured Log
-*.binlog
-
-# NVidia Nsight GPU debugger configuration file
-*.nvuser
-
-# MFractors (Xamarin productivity tool) working folder
-.mfractor/
-
-# Local History for Visual Studio
-.localhistory/
-
-# Visual Studio History (VSHistory) files
-.vshistory/
-
-# BeatPulse healthcheck temp database
-healthchecksdb
-
-# Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
-
-# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
-
-# Fody - auto-generated XML schema
-FodyWeavers.xsd
-
-# VS Code files for those working on multiple tools
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
-*.code-workspace
-
-# Local History for Visual Studio Code
-.history/
-
-# Windows Installer files from build outputs
-*.cab
-*.msi
-*.msix
-*.msm
-*.msp
-
-# JetBrains Rider
-*.sln.iml
diff --git a/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj b/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj
new file mode 100644
index 00000000000..2180b388b94
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs
new file mode 100644
index 00000000000..2489777b42d
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs
@@ -0,0 +1,33 @@
+using System.Net;
+using System.Net.Http.Json;
+using Dagger.SDK.GraphQL;
+
+namespace Dagger.SDK.Tests.GraphQL;
+
+public class GraphQLClientTest
+{
+ [Fact]
+ public async void TestRequest()
+ {
+ var query = """
+ query {
+ container {
+ from(address: "alpine:3.16") {
+ withExec(args: ["echo", "hello"]) {
+ stdout
+ }
+ }
+ }
+ }
+ """;
+
+ var gqlCLient = new GraphQLClient();
+ var response = await gqlCLient.RequestAsync(query);
+
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+
+ var gqlResponse = await response.Content.ReadFromJsonAsync();
+ Assert.Null(gqlResponse!.Errors);
+ Assert.Equal("hello\n", gqlResponse!.Data.GetProperty("container").GetProperty("from").GetProperty("withExec").GetProperty("stdout").GetString());
+ }
+}
diff --git a/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs
new file mode 100644
index 00000000000..b7b005389cc
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs
@@ -0,0 +1,83 @@
+using Dagger.SDK.GraphQL;
+
+namespace Dagger.SDK.Tests.GraphQL;
+
+public class QueryBuilderTest
+{
+ [Fact]
+ public void TestSelect()
+ {
+ var query = QueryBuilder
+ .Builder()
+ .Select("container")
+ .Build();
+
+ Assert.Equal("query{container}", query);
+ }
+
+ [Fact]
+ public void TestSelect_WithArgument()
+ {
+ var query = QueryBuilder
+ .Builder()
+ .Select("container")
+ .Select("from", [new Argument("address", new StringValue("nginx"))])
+ .Build();
+
+ Assert.Equal("query{container{from(address:\"nginx\")}}", query);
+
+ query = QueryBuilder
+ .Builder()
+ .Select("container")
+ .Select("withExec", [new Argument("args", new ListValue([new StringValue("echo"), new StringValue("hello")]))])
+ .Build();
+
+ Assert.Equal("query{container{withExec(args:[\"echo\",\"hello\"])}}", query);
+
+ query = QueryBuilder
+ .Builder()
+ .Select(
+ "buildDocker",
+ [
+ new Argument(
+ "buildArgs",
+ new ObjectValue(
+ [
+ KeyValuePair.Create("key", new StringValue("value") as Value)
+ ]
+ )
+ )
+ ]
+ )
+ .Build();
+
+ Assert.Equal("query{buildDocker(buildArgs:{key:\"value\"})}", query);
+
+ query = QueryBuilder
+ .Builder()
+ .Select("withEnvVariable", [new Argument("expand", new BooleanValue(true))])
+ .Build();
+
+ Assert.Equal("query{withEnvVariable(expand:true)}", query);
+ }
+
+ [Fact]
+ public void TestSelect_ImmutableQuery()
+ {
+ var query1 = QueryBuilder
+ .Builder()
+ .Select("envVariables");
+
+ var query2 = query1
+ .Select("name")
+ .Build();
+
+ Assert.Equal("query{envVariables{name}}", query2);
+
+ var query3 = query1
+ .Select("value")
+ .Build();
+
+ Assert.Equal("query{envVariables{value}}", query3);
+ }
+}
diff --git a/sdk/dotnet/DaggerSDK/DaggerSDK.csproj b/sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj
similarity index 74%
rename from sdk/dotnet/DaggerSDK/DaggerSDK.csproj
rename to sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj
index a1ed5b3f0a7..bb23fb7d66b 100644
--- a/sdk/dotnet/DaggerSDK/DaggerSDK.csproj
+++ b/sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj
@@ -1,9 +1,9 @@
-
-
-
- net7.0
- enable
- enable
-
-
-
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/sdk/dotnet/Dagger.SDK/Dagger.cs b/sdk/dotnet/Dagger.SDK/Dagger.cs
new file mode 100644
index 00000000000..dea72f7839d
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/Dagger.cs
@@ -0,0 +1,5 @@
+namespace Dagger.SDK;
+
+public class Dagger
+{
+}
diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs b/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs
new file mode 100644
index 00000000000..9f20625aef9
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs
@@ -0,0 +1,21 @@
+using System.Collections.Immutable;
+
+namespace Dagger.SDK.GraphQL;
+
+public class Argument(string key, Value value)
+{
+ public string Key { get; } = key;
+ public Value Value { get; } = value;
+
+ public string FormatValue()
+ {
+ return Value.Format();
+ }
+}
+
+public class Field(string name, ImmutableList args)
+{
+ public string Name { get; } = name;
+
+ public ImmutableList Args { get; } = args;
+}
diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs
new file mode 100644
index 00000000000..37e0024bc40
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs
@@ -0,0 +1,42 @@
+
+using System.Net.Http.Headers;
+using System.Net.Http.Json;
+using System.Text;
+
+namespace Dagger.SDK.GraphQL;
+
+///
+/// GraphQL client for Dagger.
+///
+public class GraphQLClient
+{
+ private readonly HttpClient _httpClient;
+
+ public GraphQLClient() : this(Environment.GetEnvironmentVariable("DAGGER_SESSION_PORT")!, Environment.GetEnvironmentVariable("DAGGER_SESSION_TOKEN")!)
+ {
+ }
+
+ public GraphQLClient(string port, string token, string scheme = "http", string host = "localhost")
+ {
+ _httpClient = new HttpClient();
+ _httpClient.DefaultRequestHeaders.Add("Authorization", BasicAuth(token));
+ _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
+ _httpClient.BaseAddress = new Uri($"{scheme}://{host}:{port}");
+ }
+
+ private static string BasicAuth(string token)
+ {
+ var usernamePassword = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{token}:"));
+ return $"Basic {usernamePassword}";
+ }
+
+ ///
+ /// Perform GraphQL request.
+ ///
+ /// GraphQL query.
+ /// Raw HTTP response.
+ public async Task RequestAsync(string query)
+ {
+ return await _httpClient.PostAsJsonAsync("/query", new { query });
+ }
+}
diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs
new file mode 100644
index 00000000000..5bc33967ba7
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs
@@ -0,0 +1,22 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Dagger.SDK.GraphQL;
+
+public class GraphQLError
+{
+ [JsonPropertyName("message")]
+ public required string Message { get; set; }
+
+ [JsonPropertyName("path")]
+ public required List Path { get; set; }
+}
+
+public class GraphQLResponse
+{
+ [JsonPropertyName("errors")]
+ public List? Errors { get; set; }
+
+ [JsonPropertyName("data")]
+ public required JsonElement Data { get; set; }
+}
diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs b/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs
new file mode 100644
index 00000000000..8e28eeac27f
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs
@@ -0,0 +1,60 @@
+using System.Collections.Immutable;
+using System.Net;
+using System.Text;
+
+namespace Dagger.SDK.GraphQL;
+
+public class QueryBuilder
+{
+ public readonly ImmutableList Path = [];
+
+ public QueryBuilder() { }
+
+ public QueryBuilder(ImmutableList children)
+ {
+ this.Path = children;
+ }
+
+ public QueryBuilder Select(string name)
+ {
+ return Select(name, []);
+ }
+
+ public QueryBuilder Select(string name, ImmutableList args)
+ {
+ return Select(new Field(name, args));
+ }
+
+ public QueryBuilder Select(Field field)
+ {
+ return new QueryBuilder(Path.Add(field));
+ }
+
+ ///
+ /// Build GraphQL query.
+ ///
+ /// GraphQL query string
+ public string Build()
+ {
+ var builder = new StringBuilder();
+ builder.Append("query");
+ foreach (var selection in Path)
+ {
+ builder.Append('{');
+ builder.Append(selection.Name);
+ if (selection.Args.Count > 0)
+ {
+ builder.Append('(');
+ builder.Append(string.Join(",", selection.Args.Select(arg => $"{arg.Key}:{arg.FormatValue()}")));
+ builder.Append(')');
+ }
+ }
+ builder.Append(new string('}', Path.Count));
+ return builder.ToString();
+ }
+
+ public static QueryBuilder Builder()
+ {
+ return new QueryBuilder();
+ }
+}
diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs b/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs
new file mode 100644
index 00000000000..d0ee4a19850
--- /dev/null
+++ b/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs
@@ -0,0 +1,83 @@
+using System.Text;
+
+namespace Dagger.SDK.GraphQL;
+
+public abstract class Value
+{
+ public abstract string Format();
+}
+
+public class StringValue(string s) : Value
+{
+ private readonly string value = s;
+
+ public override string Format()
+ {
+ return $"\"{value}\"";
+ }
+}
+
+public class IntValue(int n) : Value
+{
+ private readonly int value = n;
+
+ public override string Format()
+ {
+ return value.ToString();
+ }
+}
+
+public class FloatValue(float f) : Value
+{
+ private readonly float value = f;
+
+ public override string Format()
+ {
+ return value.ToString();
+ }
+}
+
+public class BooleanValue(bool f) : Value
+{
+ private readonly bool value = f;
+
+ public override string Format()
+ {
+ if (value == true)
+ {
+ return "true";
+ }
+ else
+ {
+ return "false";
+ }
+ }
+}
+
+public class ListValue(List list) : Value
+{
+ private readonly List value = list;
+
+ public override string Format()
+ {
+ var builder = new StringBuilder();
+ builder.Append('[');
+ builder.Append(string.Join(",", value.Select(element => element.Format())));
+ builder.Append(']');
+ return builder.ToString();
+ }
+}
+
+public class ObjectValue(List> obj) : Value
+{
+ private readonly List> value = obj;
+
+ public override string Format()
+ {
+ var builder = new StringBuilder();
+ builder.Append('{');
+ builder.Append(string.Join(",", value.Select(kv => $"{kv.Key}:{kv.Value.Format()}")));
+ builder.Append('}');
+ return builder.ToString();
+ }
+}
diff --git a/sdk/dotnet/Dagger.sln b/sdk/dotnet/Dagger.sln
new file mode 100644
index 00000000000..21ff50592cd
--- /dev/null
+++ b/sdk/dotnet/Dagger.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dagger.SDK", "Dagger.SDK\Dagger.SDK.csproj", "{2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dagger.SDK.Tests", "Dagger.SDK.Tests\Dagger.SDK.Tests.csproj", "{9B811549-D265-4E16-AC82-48C364A827E3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9B811549-D265-4E16-AC82-48C364A827E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9B811549-D265-4E16-AC82-48C364A827E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9B811549-D265-4E16-AC82-48C364A827E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9B811549-D265-4E16-AC82-48C364A827E3}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/sdk/dotnet/DaggerSDK.sln b/sdk/dotnet/DaggerSDK.sln
deleted file mode 100644
index a97f5ea1d2b..00000000000
--- a/sdk/dotnet/DaggerSDK.sln
+++ /dev/null
@@ -1,42 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.4.33213.308
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DaggerSDK", "DaggerSDK\DaggerSDK.csproj", "{68892045-452C-4AA8-BA1A-978846A7803C}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{134BD5AA-8DD2-4EEF-BBB4-393C4B631E8A}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "Tests\IntegrationTests\IntegrationTests.csproj", "{A0C7B3A6-61C0-441C-8BD1-66517F08C14D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DaggerSDKCodeGen", "DaggerSDKCodeGen\DaggerSDKCodeGen.csproj", "{E05F4484-2F33-472E-B9D3-1D8AC5C4E414}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {68892045-452C-4AA8-BA1A-978846A7803C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {68892045-452C-4AA8-BA1A-978846A7803C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {68892045-452C-4AA8-BA1A-978846A7803C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {68892045-452C-4AA8-BA1A-978846A7803C}.Release|Any CPU.Build.0 = Release|Any CPU
- {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Release|Any CPU.Build.0 = Release|Any CPU
- {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {A0C7B3A6-61C0-441C-8BD1-66517F08C14D} = {134BD5AA-8DD2-4EEF-BBB4-393C4B631E8A}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {578F7FE8-F7C2-4C2A-9AC1-7EAC171BA6A2}
- EndGlobalSection
-EndGlobal
diff --git a/sdk/dotnet/DaggerSDK/ContainerBuilder.cs b/sdk/dotnet/DaggerSDK/ContainerBuilder.cs
deleted file mode 100644
index b9605bb6072..00000000000
--- a/sdk/dotnet/DaggerSDK/ContainerBuilder.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using DaggerSDK.GraphQL;
-using DaggerSDK.GraphQL.QueryElements;
-
-namespace DaggerSDK;
-
-public class ContainerBuilder
-{
- public string Platform { get; set; } = "";
- public string BaseImage { get; set; } = "";
- public List Commands { get; set; } = new();
-
- public GraphQLElement GetQuery()
- {
- var result = new Container(platform: Platform, new[]
- {
- new From(BaseImage)
- });
-
- var curr = result.Body[0];
- foreach (var c in Commands)
- {
- var sub = new WithExec(c);
- curr.Body.Add(sub);
- curr = sub;
- }
-
- curr.Body.Add(new("stdout"));
- curr.Body.Add(new("stderr"));
- return result;
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs b/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs
deleted file mode 100644
index 8d5e27f6728..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Net.Http.Json;
-using System.Text;
-
-namespace DaggerSDK.GraphQL;
-
-public class GraphQLClient
-{
- private readonly HttpClient _http;
-
- public GraphQLClient()
- {
- var port = Environment.GetEnvironmentVariable("DAGGER_SESSION_PORT");
- var token = Environment.GetEnvironmentVariable("DAGGER_SESSION_TOKEN");
- token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token + ":"));
- var url = $"http://localhost:{port}/query";
-
- _http = new HttpClient();
- _http.DefaultRequestHeaders.Add("Authorization", $"Basic {token}");
- _http.DefaultRequestHeaders.Add("Accept", "application/json");
- _http.BaseAddress= new Uri(url);
- }
-
- public async Task RequestAsync(string body)
- {
- var content = JsonContent.Create(new { query = body });
- return await _http.PostAsync("", content);
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs b/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs
deleted file mode 100644
index 108a2ea0cc3..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace DaggerSDK.GraphQL;
-
-public class GraphQLQuery
-{
- public string Generate()
- {
- return "";
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs
deleted file mode 100644
index 47b48610b92..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace DaggerSDK.GraphQL.QueryElements;
-
-public class Container : GraphQLElement
-{
- public Container(string? platform = null, IEnumerable? sub = null)
- {
- Name = "container";
- if (!string.IsNullOrEmpty(platform))
- {
- Params.Add("platform", platform);
- }
-
- foreach (var element in sub ?? Enumerable.Empty())
- {
- Body.Add(element);
- }
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs
deleted file mode 100644
index 4b47bf2121c..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace DaggerSDK.GraphQL.QueryElements;
-
-public class From : GraphQLElement
-{
- public From(string? address, IEnumerable? sub = null)
- {
- Name = "from";
- if (!string.IsNullOrEmpty(address))
- {
- Params.Add("address", address);
- }
-
- foreach (var element in sub ?? Enumerable.Empty())
- {
- Body.Add(element);
- }
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs
deleted file mode 100644
index 3d4558b35d0..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace DaggerSDK.GraphQL.QueryElements;
-
-public class GraphQLElement
-{
- public GraphQLElement()
- {
-
- }
-
- public GraphQLElement(string name)
- {
- Name = name;
- }
-
- public string Label { get; set; } = "";
- public string Name { get; set; } = "";
- public Dictionary Params { get; set; } = new();
- public List Body { get; set; } = new();
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs
deleted file mode 100644
index 9db4fe8ee2f..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace DaggerSDK.GraphQL.QueryElements;
-
-public class WithExec : GraphQLElement
-{
- public WithExec(string[] args, IEnumerable? sub = null)
- {
- Name = "withExec";
- if (args != null)
- {
- Params.Add("args", args);
- }
-
- foreach (var element in sub ?? Enumerable.Empty())
- {
- Body.Add(element);
- }
- }
-}
diff --git a/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs b/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs
deleted file mode 100644
index 4d37dab353d..00000000000
--- a/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System.Text;
-using System.Text.Encodings.Web;
-using System.Text.Json;
-using System.Text.Unicode;
-using DaggerSDK.GraphQL.QueryElements;
-
-namespace DaggerSDK.GraphQL;
-
-public class Serializer
-{
- public static string Serialize(params GraphQLElement[] elements)
- {
- var result = new StringBuilder();
- result.Append("query {");
- PrintIndented(result, elements);
- result.Append("\n}");
- return result.ToString();
- }
-
- private static void PrintIndented(StringBuilder result, GraphQLElement[] elements, int indent = 1)
- {
- if (elements.Length == 0)
- {
- return;
- }
-
- var prefix = "\n";
- foreach (var e in elements)
- {
- result.Append(prefix);
- prefix = ",\n";
- PrintIndented(result, e, indent);
- }
- }
- private static void PrintIndented(StringBuilder result, GraphQLElement element, int indent)
- {
- AddIndent(result, indent);
- if (!string.IsNullOrEmpty(element.Label))
- {
- result.Append(element.Label).Append(": ");
- }
-
- result.Append(element.Name);
- AddArgs(result, element.Params);
-
- if (!element.Body.Any())
- {
- return;
- }
-
- result.Append(" {");
-
- PrintIndented(result, element.Body.ToArray(), indent + 1);
-
- result.Append("\n");
- AddIndent(result, indent);
- result.Append("}");
- }
-
- private static void AddArgs(StringBuilder result, Dictionary args)
- {
- if (args.Count < 1)
- {
- return;
- }
-
- result.Append("(");
- var prefix = "";
- foreach (var (k, v) in args)
- {
- result.Append(prefix);
- prefix = ", ";
- result.Append($"{k}: {JsonSerializer.Serialize(v)}");
- }
- result.Append(")");
-
- }
-
- private static void AddIndent(StringBuilder result, int indent)
- {
- for (int i = 0; i < indent; i++)
- {
- result.Append(" ");
- }
- }
-}
diff --git a/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj b/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj
index 4de2f4593d0..e27611057c9 100644
--- a/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj
+++ b/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net8.0
enable
enable
diff --git a/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs b/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs
index c954a711f8a..7a3defb7048 100644
--- a/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs
+++ b/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs
@@ -4,7 +4,7 @@ public class QueryField
{
public QueryArg[]? Args { get; set; }
public string? DeprecationReason { get; set; }
- public string? Description { get; set; }
+ public string? Description { get; set; }
public bool IsDeprecated { get; set; }
public string? Name { get; set; }
public ArgType? Type { get; set; }
diff --git a/sdk/dotnet/DaggerSDKCodeGen/Program.cs b/sdk/dotnet/DaggerSDKCodeGen/Program.cs
index d074f4537fa..5ca71cf0a58 100644
--- a/sdk/dotnet/DaggerSDKCodeGen/Program.cs
+++ b/sdk/dotnet/DaggerSDKCodeGen/Program.cs
@@ -19,10 +19,11 @@
var directives = JsonSerializer.Deserialize>(schema.GetProperty("directives"), opt)
?? throw new Exception("Failed to deserialize directives");
var types = JsonSerializer.Deserialize>(schema.GetProperty("types"), opt)
- ?? throw new Exception("Failed to deserialize types");;
+ ?? throw new Exception("Failed to deserialize types"); ;
Console.WriteLine("Writing introspect-api.json");
-File.WriteAllText("introspect-api.json", JsonSerializer.Serialize(new {
+File.WriteAllText("introspect-api.json", JsonSerializer.Serialize(new
+{
directives = schema.GetProperty("directives"),
types = schema.GetProperty("types"),
}, opt));
diff --git a/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs b/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs
deleted file mode 100644
index 31a43a022e8..00000000000
--- a/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using DaggerSDK.GraphQL;
-using IntegrationTests.TestData;
-using Newtonsoft.Json;
-
-namespace IntegrationTests;
-
-public class BasicTests
-{
- [Test]
- public async Task BasicConnectAsync()
- {
- var query = LaravelExample.RuntimeQuery;
- var client = new GraphQLClient();
- var response = await client.RequestAsync(query);
- var body = await response.Content.ReadAsStringAsync();
- var json = JsonConvert.DeserializeObject(body);
- Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented));
- Assert.That((int)response.StatusCode, Is.EqualTo(200));
- }
-
- [Test]
- public void CreateQuery()
- {
- var e = LaravelExample.RuntimeQueryElement;
- var q = Serializer.Serialize(e).Replace("\\u0027", "'");
- Console.WriteLine(q);
- Assert.That(q, Is.EqualTo(LaravelExample.RuntimeQuery.Replace("\r\n", "\n").Replace(" ", " ")));
- }
-
- [Test]
- public void ContainerBuilder()
- {
- var builder = LaravelExample.ContainerBuilder;
- var builderQuery = Serializer.Serialize(builder.GetQuery());
-
- var compare = LaravelExample.RuntimeQueryElement;
- var expectedResult = Serializer.Serialize(compare);
-
- Assert.That(builderQuery, Is.EqualTo(expectedResult));
- }
-}
diff --git a/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj b/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj
deleted file mode 100644
index de30691665a..00000000000
--- a/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- net7.0
- enable
- enable
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs b/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs
deleted file mode 100644
index 782a5ce1996..00000000000
--- a/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using DaggerSDK;
-using DaggerSDK.GraphQL.QueryElements;
-
-namespace IntegrationTests.TestData;
-
-// taken from:
-public class LaravelExample
-{
- public static string RuntimeQuery = """
- query {
- container(platform: "linux/amd64") {
- from(address: "php:8.2-apache-buster") {
- withExec(args: ["apt-get","update"]) {
- withExec(args: ["apt-get","install","--yes","git-core"]) {
- withExec(args: ["apt-get","install","--yes","zip"]) {
- withExec(args: ["apt-get","install","--yes","curl"]) {
- withExec(args: ["docker-php-ext-install","pdo","pdo_mysql","mysqli"]) {
- withExec(args: ["sh","-c","sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf"]) {
- withExec(args: ["sh","-c","sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf"]) {
- withExec(args: ["a2enmod","rewrite"]) {
- stdout,
- stderr
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- """;
-
- public static GraphQLElement RuntimeQueryElement = new Container("linux/amd64", new[] {
- new From("php:8.2-apache-buster", new[]
- {
- new WithExec(new []{"apt-get", "update" }, new []
- {
- new WithExec(new []{"apt-get", "install", "--yes", "git-core" }, new []
- {
- new WithExec(new []{"apt-get", "install", "--yes", "zip" }, new[]
- {
- new WithExec(new []{"apt-get", "install", "--yes", "curl" }, new[]
- {
- new WithExec(new []{"docker-php-ext-install", "pdo", "pdo_mysql", "mysqli" }, new[]
- {
- new WithExec(new []{"sh", "-c", "sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf" }, new[]
- {
- new WithExec(new []{"sh", "-c", "sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf" }, new[]
- {
- new WithExec(new []{"a2enmod", "rewrite" }, new GraphQLElement[]{new("stdout"), new("stderr") })
- })
- })
- })
- })
- })
- })
- })
- })
- });
-
- public static ContainerBuilder ContainerBuilder = new ContainerBuilder
- {
- Platform = "linux/amd64",
- BaseImage = "php:8.2-apache-buster",
- Commands = new()
- {
- new[]{"apt-get", "update"},
- new[]{"apt-get", "install", "--yes", "git-core"},
- new[]{"apt-get", "install", "--yes", "zip"},
- new[]{"apt-get", "install", "--yes", "curl"},
- new[]{"docker-php-ext-install", "pdo", "pdo_mysql", "mysqli"},
- new[]{"sh", "-c", "sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf"},
- new[]{"sh", "-c", "sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf"},
- new[]{"a2enmod", "rewrite" },
- }
- };
-}
diff --git a/sdk/dotnet/Tests/IntegrationTests/Usings.cs b/sdk/dotnet/Tests/IntegrationTests/Usings.cs
deleted file mode 100644
index cefced49698..00000000000
--- a/sdk/dotnet/Tests/IntegrationTests/Usings.cs
+++ /dev/null
@@ -1 +0,0 @@
-global using NUnit.Framework;
\ No newline at end of file