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 @@ - + - +