From 84e9871b3d25361e67c3d2bea59db2c223edce90 Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 19:10:32 +0900
Subject: [PATCH 1/9] chore: static lib for linux
---
.github/workflows/build.yaml | 8 ++++++++
Directory.Build.props | 2 +-
Directory.Build.targets | 4 ++++
buildTransitive/MiniPty.targets | 24 ++++++++++++++++++++++++
scripts/build-native.sh | 22 ++++++++++++++++++++++
scripts/pack-with-native.sh | 2 ++
src/MiniPty/MiniPty.csproj | 7 +++++++
7 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 Directory.Build.targets
create mode 100644 buildTransitive/MiniPty.targets
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index c64ed60..0b5e412 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -55,6 +55,11 @@ jobs:
- name: Test
shell: bash
run: dotnet test -c Release
+ - name: Build libminipty_unix
+ if: ${{ !startsWith(matrix.rid, 'win') }}
+ shell: bash
+ run: bash scripts/build-native.sh "${{ matrix.rid }}"
+
- name: Publish and run samples (NativeAOT)
shell: bash
run: |
@@ -66,6 +71,9 @@ jobs:
exe="$out/${sample}.exe"
fi
test -f "$exe"
+ if [[ "${{ matrix.rid }}" == linux-* ]]; then
+ test ! -f "$out/libminipty_unix.so"
+ fi
"$exe"
done
diff --git a/Directory.Build.props b/Directory.Build.props
index 15462e1..c82857d 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -10,7 +10,7 @@
true
README.md
false
- 1.1.0
+ 1.2.0
guitarrapc
© guitarrapc
pty
diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 0000000..30a5ecd
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,4 @@
+
+
+
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
new file mode 100644
index 0000000..342c501
--- /dev/null
+++ b/buildTransitive/MiniPty.targets
@@ -0,0 +1,24 @@
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/build-native.sh b/scripts/build-native.sh
index 3a8571b..3716fb6 100644
--- a/scripts/build-native.sh
+++ b/scripts/build-native.sh
@@ -12,9 +12,31 @@ out_dir="$root/runtimes/$rid/native"
mkdir -p "$out_dir"
+build_linux_static_archive() {
+ local out="$1"
+ shift
+ local src
+ local work
+ local objs=()
+
+ work="$(mktemp -d)"
+ for src in "$@"; do
+ local base
+ base="$(basename "$src")"
+ cp "$src" "$work/$base"
+ local obj="$work/${base%.c}.o"
+ cc -c -fPIC -O2 -o "$obj" "$work/$base"
+ objs+=("$obj")
+ done
+
+ ar rcs "$out" "${objs[@]}"
+ rm -rf "$work"
+}
+
case "$rid" in
linux-*)
cc -shared -fPIC -O2 -lutil -o "$out_dir/libminipty_unix.so" "${sources[@]}"
+ build_linux_static_archive "$out_dir/libminipty_unix.a" "${sources[@]}"
;;
osx-*)
cc -shared -fPIC -O2 -lutil -o "$out_dir/libminipty_unix.dylib" "${sources[@]}"
diff --git a/scripts/pack-with-native.sh b/scripts/pack-with-native.sh
index 462bfb8..c6e2359 100644
--- a/scripts/pack-with-native.sh
+++ b/scripts/pack-with-native.sh
@@ -8,7 +8,9 @@ root="$(cd "$(dirname "$0")/.." && pwd)"
required=(
"linux-x64/native/libminipty_unix.so"
+ "linux-x64/native/libminipty_unix.a"
"linux-arm64/native/libminipty_unix.so"
+ "linux-arm64/native/libminipty_unix.a"
"osx-x64/native/libminipty_unix.dylib"
"osx-x64/native/minipty_spawn_helper"
"osx-arm64/native/libminipty_unix.dylib"
diff --git a/src/MiniPty/MiniPty.csproj b/src/MiniPty/MiniPty.csproj
index e9a0121..c57940d 100644
--- a/src/MiniPty/MiniPty.csproj
+++ b/src/MiniPty/MiniPty.csproj
@@ -33,6 +33,7 @@
@@ -45,6 +46,12 @@
PackagePath="runtimes/osx-x64/native" />
+
+
+
+
From f0c4aabea9168fdc8a526f2972b5b115825b8267 Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 19:14:17 +0900
Subject: [PATCH 2/9] chore: static lib for macOS
---
.github/workflows/build.yaml | 4 ++++
buildTransitive/MiniPty.targets | 8 ++++----
scripts/build-native.sh | 5 +++--
scripts/pack-with-native.sh | 2 ++
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 0b5e412..b4cb673 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -74,6 +74,10 @@ jobs:
if [[ "${{ matrix.rid }}" == linux-* ]]; then
test ! -f "$out/libminipty_unix.so"
fi
+ if [[ "${{ matrix.rid }}" == osx-* ]]; then
+ test ! -f "$out/libminipty_unix.dylib"
+ test -f "$out/minipty_spawn_helper"
+ fi
"$exe"
done
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index 342c501..11b896a 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -1,5 +1,5 @@
-
+
true
@@ -14,11 +14,11 @@
BeforeTargets="AssignTargetPaths"
Condition="'$(MiniPtyStaticUnixNative)' == 'true'">
-
+
+ Condition="'%(ContentWithTargetPath.TargetPath)' == 'libminipty_unix.so' or '%(ContentWithTargetPath.TargetPath)' == 'libminipty_unix.dylib'" />
+ Condition="'%(ResolvedFileToPublish.RelativePath)' == 'libminipty_unix.so' or '%(ResolvedFileToPublish.RelativePath)' == 'libminipty_unix.dylib'" />
diff --git a/scripts/build-native.sh b/scripts/build-native.sh
index 3716fb6..a5169ec 100644
--- a/scripts/build-native.sh
+++ b/scripts/build-native.sh
@@ -12,7 +12,7 @@ out_dir="$root/runtimes/$rid/native"
mkdir -p "$out_dir"
-build_linux_static_archive() {
+build_static_archive() {
local out="$1"
shift
local src
@@ -36,10 +36,11 @@ build_linux_static_archive() {
case "$rid" in
linux-*)
cc -shared -fPIC -O2 -lutil -o "$out_dir/libminipty_unix.so" "${sources[@]}"
- build_linux_static_archive "$out_dir/libminipty_unix.a" "${sources[@]}"
+ build_static_archive "$out_dir/libminipty_unix.a" "${sources[@]}"
;;
osx-*)
cc -shared -fPIC -O2 -lutil -o "$out_dir/libminipty_unix.dylib" "${sources[@]}"
+ build_static_archive "$out_dir/libminipty_unix.a" "${sources[@]}"
cc -O2 -o "$out_dir/minipty_spawn_helper" "$native_dir/minipty_spawn_helper.c" "$native_dir/minipty_unix_exec.c"
;;
win-*)
diff --git a/scripts/pack-with-native.sh b/scripts/pack-with-native.sh
index c6e2359..b57a0f2 100644
--- a/scripts/pack-with-native.sh
+++ b/scripts/pack-with-native.sh
@@ -12,8 +12,10 @@ required=(
"linux-arm64/native/libminipty_unix.so"
"linux-arm64/native/libminipty_unix.a"
"osx-x64/native/libminipty_unix.dylib"
+ "osx-x64/native/libminipty_unix.a"
"osx-x64/native/minipty_spawn_helper"
"osx-arm64/native/libminipty_unix.dylib"
+ "osx-arm64/native/libminipty_unix.a"
"osx-arm64/native/minipty_spawn_helper"
)
From fe5354c787672ebdb67ff063cd0f41e314cd13cb Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 21:44:28 +0900
Subject: [PATCH 3/9] chore: handle .a
---
buildTransitive/MiniPty.targets | 10 +++++-----
scripts/build-native.sh | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index 11b896a..6b22624 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -9,16 +9,16 @@
-
+
-
+
+ Condition="'%(ContentWithTargetPath.TargetPath)' == 'libminipty_unix.so' or '%(ContentWithTargetPath.TargetPath)' == 'libminipty_unix.dylib' or '%(ContentWithTargetPath.TargetPath)' == 'libminipty_unix.a'" />
+ Condition="'%(ResolvedFileToPublish.RelativePath)' == 'libminipty_unix.so' or '%(ResolvedFileToPublish.RelativePath)' == 'libminipty_unix.dylib' or '%(ResolvedFileToPublish.RelativePath)' == 'libminipty_unix.a'" />
diff --git a/scripts/build-native.sh b/scripts/build-native.sh
index a5169ec..8534bd8 100644
--- a/scripts/build-native.sh
+++ b/scripts/build-native.sh
@@ -25,7 +25,7 @@ build_static_archive() {
base="$(basename "$src")"
cp "$src" "$work/$base"
local obj="$work/${base%.c}.o"
- cc -c -fPIC -O2 -o "$obj" "$work/$base"
+ cc -c -fPIC -O2 -I"$native_dir" -o "$obj" "$work/$base"
objs+=("$obj")
done
From ce24dd7a78388f618fb49aba4e1a1db68e00c4d1 Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 22:34:16 +0900
Subject: [PATCH 4/9] fix: macOS handling
---
.github/workflows/build.yaml | 2 ++
buildTransitive/MiniPty.targets | 15 +++++++++++----
src/MiniPty/MiniPty.csproj | 3 ++-
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index b4cb673..4c7b3d0 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -73,9 +73,11 @@ jobs:
test -f "$exe"
if [[ "${{ matrix.rid }}" == linux-* ]]; then
test ! -f "$out/libminipty_unix.so"
+ test ! -f "$out/libminipty_unix.a"
fi
if [[ "${{ matrix.rid }}" == osx-* ]]; then
test ! -f "$out/libminipty_unix.dylib"
+ test ! -f "$out/libminipty_unix.a"
test -f "$out/minipty_spawn_helper"
fi
"$exe"
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index 6b22624..b9867fe 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -1,6 +1,7 @@
true
+ false
@@ -11,14 +12,20 @@
-
+
+
+ Condition="$([System.String]::Copy('%(TargetPath)').EndsWith('libminipty_unix.so')) or $([System.String]::Copy('%(TargetPath)').EndsWith('libminipty_unix.dylib')) or $([System.String]::Copy('%(TargetPath)').EndsWith('libminipty_unix.a'))" />
+ <_ResolvedCopyLocalPublishAssets Remove="@(_ResolvedCopyLocalPublishAssets)"
+ Condition="$([System.String]::Copy('%(Filename)%(Extension)').Equals('libminipty_unix.so')) or $([System.String]::Copy('%(Filename)%(Extension)').Equals('libminipty_unix.dylib')) or $([System.String]::Copy('%(Filename)%(Extension)').Equals('libminipty_unix.a'))" />
+ Condition="$([System.String]::Copy('%(RelativePath)').EndsWith('libminipty_unix.so')) or $([System.String]::Copy('%(RelativePath)').EndsWith('libminipty_unix.dylib')) or $([System.String]::Copy('%(RelativePath)').EndsWith('libminipty_unix.a'))" />
diff --git a/src/MiniPty/MiniPty.csproj b/src/MiniPty/MiniPty.csproj
index c57940d..a5a0809 100644
--- a/src/MiniPty/MiniPty.csproj
+++ b/src/MiniPty/MiniPty.csproj
@@ -9,6 +9,7 @@
false
<_MiniPtyRuntimesRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\runtimes'))
false
+ false
true
libminipty_unix.dylib
libminipty_unix.so
@@ -63,7 +64,7 @@
$(MiniPtyUnixNativeLibraryName)
PreserveNewest
- PreserveNewest
+ PreserveNewest
From 11e13604124f9c164a32c695383db93176e70ade Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 23:39:06 +0900
Subject: [PATCH 5/9] ci: smoke on release
---
.github/workflows/build.yaml | 8 +++++++-
.github/workflows/release.yaml | 8 +++++++-
scripts/run-nuget-smoke.sh | 27 +++++++++++++++++++++++++--
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 4c7b3d0..9824fec 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -159,11 +159,17 @@ jobs:
matrix:
include:
- os: ubuntu-24.04
+ rid: linux-x64
- os: ubuntu-24.04-arm
+ rid: linux-arm64
- os: windows-2025
+ rid: win-x64
- os: windows-11-arm
+ rid: win-arm64
- os: macos-26
+ rid: osx-arm64
- os: macos-26-intel
+ rid: osx-x64
permissions:
contents: read
runs-on: ${{ matrix.os }}
@@ -186,7 +192,7 @@ jobs:
path: ./publish
- name: Run NuGet smoke sample
shell: bash
- run: bash scripts/run-nuget-smoke.sh "${MINIPTY_CI_PACKAGE_VERSION}" ./publish
+ run: bash scripts/run-nuget-smoke.sh "${MINIPTY_CI_PACKAGE_VERSION}" ./publish "${{ matrix.rid }}"
build-complete:
needs: [build, nuget-smoke]
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 0e28f4d..f17c1a1 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -149,11 +149,17 @@ jobs:
matrix:
include:
- os: ubuntu-24.04
+ rid: linux-x64
- os: ubuntu-24.04-arm
+ rid: linux-arm64
- os: windows-2025
+ rid: win-x64
- os: windows-11-arm
+ rid: win-arm64
- os: macos-26
+ rid: osx-arm64
- os: macos-26-intel
+ rid: osx-x64
permissions:
contents: read
runs-on: ${{ matrix.os }}
@@ -176,7 +182,7 @@ jobs:
path: ./publish
- name: Run NuGet smoke sample
shell: bash
- run: bash scripts/run-nuget-smoke.sh "${{ needs.verify.outputs.version }}" ./publish
+ run: bash scripts/run-nuget-smoke.sh "${{ needs.verify.outputs.version }}" ./publish "${{ matrix.rid }}"
attest:
name: Attest packages
diff --git a/scripts/run-nuget-smoke.sh b/scripts/run-nuget-smoke.sh
index 70d1619..f4d0602 100644
--- a/scripts/run-nuget-smoke.sh
+++ b/scripts/run-nuget-smoke.sh
@@ -1,8 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
-version="${1:?Usage: run-nuget-smoke.sh }"
-feed_dir="${2:?Usage: run-nuget-smoke.sh }"
+version="${1:?Usage: run-nuget-smoke.sh [runtime-identifier]}"
+feed_dir="${2:?Usage: run-nuget-smoke.sh [runtime-identifier]}"
+rid="${3:-}"
version="${version#v}"
to_dotnet_path() {
@@ -63,3 +64,25 @@ cat > "$tmp/NuGetSmoke.csproj" <
Date: Sun, 5 Jul 2026 23:41:20 +0900
Subject: [PATCH 6/9] fix: review
---
buildTransitive/MiniPty.targets | 6 ++++++
scripts/build-native.sh | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index b9867fe..f9d6125 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -10,6 +10,12 @@
+
+
+
+
Date: Sun, 5 Jul 2026 23:48:52 +0900
Subject: [PATCH 7/9] fix: test failure
---
tests/MiniPty.Tests/PtyTests.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/MiniPty.Tests/PtyTests.cs b/tests/MiniPty.Tests/PtyTests.cs
index 73f7870..ed90d79 100644
--- a/tests/MiniPty.Tests/PtyTests.cs
+++ b/tests/MiniPty.Tests/PtyTests.cs
@@ -1041,10 +1041,11 @@ public async Task PtyChildSeesResizedSize()
if (!TryResolveWindowsPowerShell(out var powershell))
return;
+ // Block on stdin until after Resize so a fast runner cannot query size before ConPTY applies it.
await using var session = Pty.Start(
- Spawn(powershell, ["-NoLogo", "-NoProfile", "-Command", "$s = $Host.UI.RawUI.WindowSize; Start-Sleep -Milliseconds 200; Write-Output (\"{0} {1}\" -f $s.Width, $s.Height); exit 0"]));
+ Spawn(powershell, ["-NoLogo", "-NoProfile", "-Command", "[Console]::In.ReadLine() | Out-Null; $s = $Host.UI.RawUI.WindowSize; Write-Output (\"{0} {1}\" -f $s.Width, $s.Height); exit 0"]));
session.Resize(new(100, 30));
- var result = await session.CompleteAsync();
+ var result = await session.CompleteAsync(new PtyCompleteOptions { Input = "go\r\n" });
await Assert.That(result.ExitCode).IsEqualTo(0);
await Assert.That(result.Contains("100 30")).IsTrue();
From 809f45d611c5780dd2150b8d76fd352045bb4e05 Mon Sep 17 00:00:00 2001
From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com>
Date: Sun, 5 Jul 2026 23:51:54 +0900
Subject: [PATCH 8/9] fix: review
---
buildTransitive/MiniPty.targets | 16 +++++++++++++++-
scripts/build-native.sh | 2 +-
src/MiniPty/MiniPty.csproj | 2 +-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index f9d6125..8fa4cfe 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -7,7 +7,15 @@
-
+
+
+
+
+
+
+
+
+
+ PackagePath="buildTransitive/" />
Date: Mon, 6 Jul 2026 00:09:39 +0900
Subject: [PATCH 9/9] fix: review
---
buildTransitive/MiniPty.targets | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/buildTransitive/MiniPty.targets b/buildTransitive/MiniPty.targets
index 8fa4cfe..3e3b374 100644
--- a/buildTransitive/MiniPty.targets
+++ b/buildTransitive/MiniPty.targets
@@ -1,5 +1,10 @@
-
+
+ <_MiniPtyStaticUnixRid>false
+ <_MiniPtyStaticUnixRid Condition="'$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'osx-x64' or '$(RuntimeIdentifier)' == 'osx-arm64'">true
+
+
+
true
false
@@ -21,13 +26,13 @@
-
+
-
+