diff --git a/.gitignore b/.gitignore
index cd10746c..c2f26590 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
*.dylib
/cmd/dagger/dagger
/cmd/dagger/dagger-debug
+**/obj/*
# Test binary, build with `go test -c`
*.test
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/container.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/container.cue
new file mode 100644
index 00000000..468c89cd
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/container.cue
@@ -0,0 +1,31 @@
+// .NET operation
+package dotnet
+
+import (
+ "dagger.io/dagger"
+ "universe.dagger.io/docker"
+)
+
+// A standalone dotnet environment to run dotnet command
+#Container: {
+ // Container app name
+ name: *"dotnet_publisher" | string
+
+ // Source code
+ source: dagger.#FS
+
+ // Use dotnet image
+ _image: #Image
+
+ _sourcePath: "/src"
+
+ docker.#Run & {
+ input: *_image.output | docker.#Image
+ workdir: "/src"
+ command: name: "dotnet"
+ mounts: "source": {
+ dest: _sourcePath
+ contents: source
+ }
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/image.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/image.cue
new file mode 100644
index 00000000..488cce1d
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/image.cue
@@ -0,0 +1,20 @@
+package dotnet
+
+import (
+ "universe.dagger.io/docker"
+)
+
+// .NET image default version
+_#DefaultVersion: "6.0"
+
+// Pull a dotnet base image
+#Image: {
+ version: *_#DefaultVersion | string
+ docker.#Build & {
+ steps: [
+ docker.#Pull & {
+ source: "mcr.microsoft.com/dotnet/sdk:\(version)-alpine"
+ },
+ ]
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/publish.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/publish.cue
new file mode 100644
index 00000000..a4cdbf7c
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/publish.cue
@@ -0,0 +1,34 @@
+package dotnet
+
+import (
+ "dagger.io/dagger"
+)
+
+// Publish a dotnet binary
+#Publish: {
+ // Source code
+ source: dagger.#FS
+
+ // Target package to publish
+ package: *"." | string
+
+ env: [string]: string
+
+ container: #Container & {
+ "source": source
+ "env": {
+ env
+ }
+ command: {
+ args: [package]
+ flags: {
+ publish: true
+ "-o": "/output/"
+ }
+ }
+ export: directories: "/output": _
+ }
+
+ // Directory containing the output of the publish
+ output: container.export.directories."/output"
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test.cue
new file mode 100644
index 00000000..2611f2dd
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test.cue
@@ -0,0 +1,14 @@
+package dotnet
+
+// Test a dotnet package
+#Test: {
+ // Package to test
+ package: *"." | string
+
+ #Container & {
+ command: {
+ args: [package]
+ flags: test: true
+ }
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting.Tests.csproj b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting.Tests.csproj
new file mode 100755
index 00000000..14148ae1
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting.Tests.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net6.0
+ enable
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting_Should.cs b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting_Should.cs
new file mode 100755
index 00000000..ab60dc9c
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting.Tests/Greeting_Should.cs
@@ -0,0 +1,14 @@
+using System;
+using Xunit;
+
+public class Greeting_Should
+{
+ [Fact]
+ public void Greeting_PrintName()
+ {
+ var name = "Dagger Test";
+ var expect = "Hi Dagger Test!";
+ var value = Greeting.GetMessage(name);
+ Assert.Equal(expect, value);
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.cs b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.cs
new file mode 100755
index 00000000..55f18fbe
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.cs
@@ -0,0 +1,6 @@
+public class Greeting
+{
+ public static string GetMessage(string name) {
+ return String.Format("Hi {0}!", name);
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.csproj b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.csproj
new file mode 100755
index 00000000..132c02c5
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/Greeting/Greeting.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/Program.cs b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/Program.cs
new file mode 100755
index 00000000..357f27c0
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/Program.cs
@@ -0,0 +1,13 @@
+using System;
+
+public class Program
+{
+ public static void Main()
+ {
+ var name = Environment.GetEnvironmentVariable("NAME");
+ if (String.IsNullOrEmpty(name)) {
+ name = "John Doe";
+ }
+ Console.Write(Greeting.GetMessage(name));
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/hello.csproj b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/hello.csproj
new file mode 100755
index 00000000..554b892a
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/data/hello/hello.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ true
+ linux-musl-x64
+
+
+
+
+
+
+
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/image.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/image.cue
new file mode 100644
index 00000000..2a85dda1
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/image.cue
@@ -0,0 +1,39 @@
+package dotnet
+
+import (
+ "dagger.io/dagger"
+ "universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet"
+ "universe.dagger.io/docker"
+)
+
+dagger.#Plan & {
+ actions: test: {
+ _source: dagger.#Scratch & {}
+
+ simple: {
+ _image: dotnet.#Image & {}
+
+ verify: docker.#Run & {
+ input: _image.output
+ command: {
+ name: "/bin/sh"
+ args: ["-c", "dotnet --list-sdks | grep '6.0'"]
+ }
+ }
+ }
+
+ custom: {
+ _image: dotnet.#Image & {
+ version: "5.0"
+ }
+
+ verify: docker.#Run & {
+ input: _image.output
+ command: {
+ name: "/bin/sh"
+ args: ["-c", "dotnet --list-sdks | grep '5.0'"]
+ }
+ }
+ }
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/publish.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/publish.cue
new file mode 100644
index 00000000..cd9a0ef2
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/publish.cue
@@ -0,0 +1,58 @@
+package dotnet
+
+import (
+ "dagger.io/dagger"
+ "dagger.io/dagger/core"
+ "universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet"
+ "universe.dagger.io/docker"
+ "universe.dagger.io/alpine"
+)
+
+dagger.#Plan & {
+ client: filesystem: "./data": read: contents: dagger.#FS
+
+ actions: test: {
+ _baseImage: {
+ build: alpine.#Build & {
+ packages: {
+ "ca-certificates": {}
+ "krb5-libs": {}
+ libgcc: {}
+ libintl: {}
+ "libssl1.1": {}
+ "libstdc++": {}
+ zlib: {}
+ }
+ }
+ output: build.output
+ }
+
+ simple: {
+ publish: dotnet.#Publish & {
+ source: client.filesystem."./data".read.contents
+ package: "hello"
+ }
+
+ exec: docker.#Run & {
+ input: _baseImage.output
+ command: {
+ name: "/bin/sh"
+ args: ["-c", "/app/hello >> /output.txt"]
+ }
+ env: NAME: "dagger"
+ mounts: binary: {
+ dest: "/app"
+ contents: publish.output
+ source: "/"
+ }
+ }
+
+ verify: core.#ReadFile & {
+ input: exec.output.rootfs
+ path: "/output.txt"
+ } & {
+ contents: "Hi dagger!"
+ }
+ }
+ }
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.bats b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.bats
new file mode 100644
index 00000000..1f1458c4
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.bats
@@ -0,0 +1,11 @@
+setup() {
+ load '../../../../bats_helpers'
+
+ common_setup
+}
+
+@test "dotnet" {
+ dagger "do" -p ./publish.cue test
+ dagger "do" -p ./image.cue test
+ dagger "do" -p ./test.cue test
+}
diff --git a/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.cue b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.cue
new file mode 100644
index 00000000..2d642192
--- /dev/null
+++ b/pkg/universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet/test/test.cue
@@ -0,0 +1,15 @@
+package dotnet
+
+import (
+ "dagger.io/dagger"
+ "universe.dagger.io/x/olli.janatuinen@gmail.com/dotnet"
+)
+
+dagger.#Plan & {
+ client: filesystem: "./data": read: contents: dagger.#FS
+
+ actions: test: dotnet.#Test & {
+ source: client.filesystem."./data".read.contents
+ package: "./Greeting.Tests"
+ }
+}