Skip to content

Generate Unicode 17 Indic extend ranges #29

Generate Unicode 17 Indic extend ranges

Generate Unicode 17 Indic extend ranges #29

Workflow file for this run

name: Release
on:
push:
tags: ['v*']
permissions:
contents: read
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
DOTNET_VERSION: '10.0.x'
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
jobs:
# ─────────────────────────────────────────────
# Native builds for each platform
# ─────────────────────────────────────────────
native-macos:
name: Native (macOS ${{ matrix.arch }})
# Pin macOS 15 for reproducible SDK compatibility with the native artifacts.
runs-on: macos-15
strategy:
matrix:
arch: [arm64, x64]
steps:
- name: Checkout
uses: actions/checkout@v7
with:
submodules: recursive
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- name: Build libghostty-vt
working-directory: external/ghostty
run: |
if [ "${{ matrix.arch }}" = "arm64" ]; then
zig build -Doptimize=ReleaseFast -Dapp-runtime=none -Demit-lib-vt=true -Demit-xcframework=false -Demit-macos-app=false
else
zig build -Doptimize=ReleaseFast -Dapp-runtime=none -Demit-lib-vt=true -Demit-xcframework=false -Demit-macos-app=false -Dtarget=x86_64-macos
fi
- name: Build ghostty-renderer-capi
working-directory: native/ghostty-renderer-capi
run: |
if [ "${{ matrix.arch }}" = "arm64" ]; then
zig build -Doptimize=ReleaseFast
else
zig build -Doptimize=ReleaseFast -Dtarget=x86_64-macos
fi
- name: Collect artifacts
run: |
mkdir -p artifacts
find external/ghostty/zig-out -name "libghostty-vt*.dylib" -exec cp -L {} artifacts/ \;
if [ -f native/ghostty-renderer-capi/zig-out/lib/libghostty-renderer-capi.dylib ]; then
cp -L native/ghostty-renderer-capi/zig-out/lib/libghostty-renderer-capi.dylib artifacts/
fi
ls -la artifacts/
- name: Verify required native artifacts (macOS)
run: |
set -euo pipefail
required=(
"libghostty-vt.dylib"
"libghostty-renderer-capi.dylib"
)
for file in "${required[@]}"; do
if [ ! -f "artifacts/${file}" ]; then
echo "::error::Missing required macOS native artifact: ${file}"
exit 1
fi
done
- name: Upload
uses: actions/upload-artifact@v7
with:
name: native-osx-${{ matrix.arch }}
path: artifacts/
native-linux:
name: Native (Linux ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
- arch: x64
runner: ubuntu-latest
zig-target: x86_64-linux-gnu
- arch: arm64
runner: ubuntu-24.04-arm
zig-target: aarch64-linux-gnu
steps:
- name: Checkout
uses: actions/checkout@v7
with:
submodules: recursive
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
pkg-config \
libbz2-dev \
libfreetype6-dev \
libharfbuzz-dev \
libfontconfig1-dev \
libpng-dev \
zlib1g-dev \
libonig-dev \
glslang-dev \
libspirv-cross-c-shared-dev
multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
if [ -f "/usr/lib/${multiarch}/libbz2.so" ] && [ ! -e "/usr/lib/${multiarch}/libbzip2.so" ]; then
sudo ln -s "/usr/lib/${multiarch}/libbz2.so" "/usr/lib/${multiarch}/libbzip2.so"
fi
if [ -f "/usr/lib/${multiarch}/libbz2.a" ] && [ ! -e "/usr/lib/${multiarch}/libbzip2.a" ]; then
sudo ln -s "/usr/lib/${multiarch}/libbz2.a" "/usr/lib/${multiarch}/libbzip2.a"
fi
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- name: Build libghostty-vt
working-directory: external/ghostty
run: |
# Keep Linux native packages on a portable CPU baseline. A runner-native
# Ghostty build can SIGILL during terminal/PageList startup on another
# machine with the same RID. Do not force -fsys dependencies here:
# explicit targets make Zig use cross-target system-library discovery.
build_args=(
build
-Doptimize=ReleaseFast
-Dapp-runtime=none
-Demit-lib-vt=true
-Dtarget=${{ matrix.zig-target }}
-Dsimd=false
)
zig "${build_args[@]}"
- name: Build ghostty-renderer-capi
working-directory: native/ghostty-renderer-capi
run: |
build_args=(build -Doptimize=ReleaseFast -Dtarget=${{ matrix.zig-target }})
zig "${build_args[@]}"
- name: Collect artifacts
run: |
mkdir -p artifacts
find external/ghostty/zig-out -name "libghostty-vt.so*" -exec cp -L {} artifacts/ \;
find native/ghostty-renderer-capi/zig-out -name "libghostty-renderer-capi.so*" -exec cp -L {} artifacts/ \; || true
for base in libghostty-vt libghostty-renderer-capi; do
if [ ! -f "artifacts/${base}.so" ]; then
candidate="$(find artifacts -maxdepth 1 -type f -name "${base}.so*" | head -n1 || true)"
if [ -n "${candidate}" ]; then
cp -f "${candidate}" "artifacts/${base}.so"
fi
fi
done
ls -la artifacts/
- name: Verify required native artifacts (Linux)
run: |
set -euo pipefail
required=(
"libghostty-vt.so"
"libghostty-renderer-capi.so"
)
for file in "${required[@]}"; do
if [ ! -f "artifacts/${file}" ]; then
echo "::error::Missing required Linux native artifact: ${file}"
exit 1
fi
done
- name: Upload
uses: actions/upload-artifact@v7
with:
name: native-linux-${{ matrix.arch }}
path: artifacts/
native-windows:
name: Native (Windows ${{ matrix.arch }})
runs-on: windows-latest
strategy:
matrix:
arch: [x64, arm64]
steps:
- name: Checkout
uses: actions/checkout@v7
with:
submodules: recursive
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- name: Build libghostty-vt
working-directory: external/ghostty
shell: bash
run: |
cpu=""
simd=""
if [ "${{ matrix.arch }}" = "arm64" ]; then
target="-Dtarget=aarch64-windows-gnu"
# Zig 0.16.0's Windows ARM64 stdlib stack-trace code fails to
# compile when Ghostty's vendored SIMD archive is enabled.
simd="-Dsimd=false"
else
# Keep win-x64 release artifacts on a true baseline x64 CPU model.
# x86_64-windows-msvc alone still allows LLVM/third-party SIMD code
# to leave VEX/AVX instructions in startup paths. Disable Zig's
# vzeroupper feature and Ghostty's SIMD bundle for the compatibility
# DLL; CI verifies the resulting DLL with disassembly below.
target="-Dtarget=x86_64-windows-msvc"
cpu="-Dcpu=x86_64-vzeroupper"
simd="-Dsimd=false"
fi
zig build -Doptimize=ReleaseFast -Dapp-runtime=none -Demit-lib-vt=true ${target} ${cpu} ${simd}
- name: Build ghostty-renderer-capi
working-directory: native/ghostty-renderer-capi
shell: bash
run: |
cpu=""
if [ "${{ matrix.arch }}" = "arm64" ]; then
target="-Dtarget=aarch64-windows-gnu"
else
target="-Dtarget=x86_64-windows-msvc"
cpu="-Dcpu=x86_64-vzeroupper"
fi
zig build -Doptimize=ReleaseFast ${target} ${cpu}
- name: Collect artifacts
shell: bash
run: |
mkdir -p artifacts/win-${{ matrix.arch }}
find external/ghostty/zig-out \( -name "ghostty-vt.dll" -o -name "libghostty-vt.dll" \) -exec cp -L {} artifacts/win-${{ matrix.arch }}/ \;
find native/ghostty-renderer-capi/zig-out \( -name "ghostty-renderer-capi.dll" -o -name "libghostty-renderer-capi.dll" \) -exec cp -L {} artifacts/win-${{ matrix.arch }}/ \; || true
for base in ghostty-vt ghostty-renderer-capi; do
if [ ! -f "artifacts/win-${{ matrix.arch }}/${base}.dll" ] && [ -f "artifacts/win-${{ matrix.arch }}/lib${base}.dll" ]; then
cp -f "artifacts/win-${{ matrix.arch }}/lib${base}.dll" "artifacts/win-${{ matrix.arch }}/${base}.dll"
fi
done
ls -la artifacts/win-${{ matrix.arch }}/
- name: Verify required native artifacts (Windows)
shell: bash
run: |
set -euo pipefail
required=(
"ghostty-vt.dll"
"ghostty-renderer-capi.dll"
)
for file in "${required[@]}"; do
if [ ! -f "artifacts/win-${{ matrix.arch }}/${file}" ]; then
echo "::error::Missing required Windows native artifact: ${file}"
exit 1
fi
done
- name: Verify Windows x64 native artifacts avoid AVX
if: matrix.arch == 'x64'
shell: pwsh
run: |
./scripts/verify-windows-x64-no-avx.ps1 `
-Path "artifacts/win-x64/ghostty-vt.dll", "artifacts/win-x64/ghostty-renderer-capi.dll"
- name: Upload
uses: actions/upload-artifact@v7
with:
name: native-win-${{ matrix.arch }}
path: artifacts/win-${{ matrix.arch }}/
# ─────────────────────────────────────────────
# Build, test, pack, and publish
# ─────────────────────────────────────────────
test:
name: Test
runs-on: macos-latest
needs: [native-macos]
steps:
- name: Checkout
uses: actions/checkout@v7
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Download native (macOS arm64)
uses: actions/download-artifact@v8
with:
name: native-osx-arm64
path: src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-arm64/native/
- name: Download native (macOS x64)
uses: actions/download-artifact@v8
with:
name: native-osx-x64
path: src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-x64/native/
- name: Stage native artifacts for managed interop (macOS)
shell: bash
run: |
set -euo pipefail
for rid in osx-arm64 osx-x64; do
src="src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/${rid}/native"
dst_interop="src/RoyalTerminal.Rendering.Interop.Ghostty/runtimes/${rid}/native"
dst_fixture="native/${rid}"
mkdir -p "${dst_interop}" "${dst_fixture}"
cp -f "${src}"/* "${dst_interop}/"
cp -f "${src}"/* "${dst_fixture}/"
done
ls -la src/RoyalTerminal.Rendering.Interop.Ghostty/runtimes/osx-arm64/native/
- name: Restore & Build
run: dotnet build -c Release
- name: Unit Tests
shell: bash
env:
ROYALTERMINAL_VALIDATE_TEST_BATCH_COVERAGE: true
ROYALTERMINAL_TEST_BLAME_CRASH: true
ROYALTERMINAL_TEST_BLAME_HANG: true
ROYALTERMINAL_TEST_BLAME_HANG_TIMEOUT: 5m
ROYALTERMINAL_TEST_BLAME_HANG_DUMP_TYPE: mini
run: bash scripts/run-unit-test-batches.sh
- name: Unit Smoke Tests
run: dotnet test tests/RoyalTerminal.Tests/RoyalTerminal.Tests.csproj -c Release --no-build --filter "(FullyQualifiedName~TerminalModeResolverTests)|(FullyQualifiedName~Headless_FallbackParity_AutoAndManaged_PreserveKeyboardMousePasteAndResize_WhenHostedInScrollViewer)" --logger "trx;LogFileName=mode-startup-smoke-results.trx" --results-directory ./test-results
- name: Integration Tests
run: dotnet test tests/RoyalTerminal.IntegrationTests/RoyalTerminal.IntegrationTests.csproj -c Release
- name: Upload test results
uses: actions/upload-artifact@v7
if: always()
with:
name: release-test-results
path: test-results/
retention-days: 7
pack-and-publish:
name: Pack & Publish
runs-on: ubuntu-latest
needs: [test, native-macos, native-linux, native-windows]
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Validate release tag
id: version
shell: bash
run: |
set -euo pipefail
version="${GITHUB_REF_NAME#v}"
if [[ ! "${version}" =~ ^[0-9]+(\.[0-9]+){2}(-[0-9A-Za-z][0-9A-Za-z.-]*)?$ ]]; then
echo "::error::Release tags must use vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-prerelease, got ${GITHUB_REF_NAME}"
exit 1
fi
echo "VERSION=${version}" >> "$GITHUB_OUTPUT"
# Download native artifacts into package runtime directories
- name: Download macOS arm64
uses: actions/download-artifact@v8
with:
name: native-osx-arm64
path: src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-arm64/native/
- name: Download macOS x64
uses: actions/download-artifact@v8
with:
name: native-osx-x64
path: src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-x64/native/
- name: Download Linux x64
uses: actions/download-artifact@v8
with:
name: native-linux-x64
path: src/RoyalTerminal.GhosttySharp.Native.Linux64/runtimes/linux-x64/native/
- name: Download Linux arm64
uses: actions/download-artifact@v8
with:
name: native-linux-arm64
path: src/RoyalTerminal.GhosttySharp.Native.Linux64/runtimes/linux-arm64/native/
- name: Download Windows x64
uses: actions/download-artifact@v8
with:
name: native-win-x64
path: src/RoyalTerminal.GhosttySharp.Native.Win64/runtimes/win-x64/native/
- name: Download Windows arm64
uses: actions/download-artifact@v8
with:
name: native-win-arm64
path: src/RoyalTerminal.GhosttySharp.Native.Win64/runtimes/win-arm64/native/
- name: Verify downloaded native artifacts
shell: bash
run: |
set -euo pipefail
check_files() {
local dir="$1"
shift
for file in "$@"; do
if [ ! -f "${dir}/${file}" ]; then
echo "::error::Missing required native artifact ${file} in ${dir}"
exit 1
fi
done
}
check_files "src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-arm64/native" \
"libghostty-vt.dylib" "libghostty-renderer-capi.dylib"
check_files "src/RoyalTerminal.GhosttySharp.Native.OSX/runtimes/osx-x64/native" \
"libghostty-vt.dylib" "libghostty-renderer-capi.dylib"
check_files "src/RoyalTerminal.GhosttySharp.Native.Linux64/runtimes/linux-x64/native" \
"libghostty-vt.so" "libghostty-renderer-capi.so"
check_files "src/RoyalTerminal.GhosttySharp.Native.Linux64/runtimes/linux-arm64/native" \
"libghostty-vt.so" "libghostty-renderer-capi.so"
check_files "src/RoyalTerminal.GhosttySharp.Native.Win64/runtimes/win-x64/native" \
"ghostty-vt.dll" "ghostty-renderer-capi.dll"
check_files "src/RoyalTerminal.GhosttySharp.Native.Win64/runtimes/win-arm64/native" \
"ghostty-vt.dll" "ghostty-renderer-capi.dll"
- name: Pack all packable projects
shell: bash
run: bash scripts/pack-nuget.sh --configuration Release --output artifacts --version "${{ steps.version.outputs.VERSION }}"
- name: List packages
shell: bash
run: |
set -euo pipefail
find artifacts -maxdepth 1 -type f -name '*.nupkg' -print | sort
# Publish to NuGet
- name: Push to NuGet.org
shell: bash
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
NUGET_SOURCE: https://api.nuget.org/v3/index.json
run: bash scripts/push-nuget.sh --directory artifacts
- name: Create GitHub Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
release_args=()
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
release_args+=(--prerelease)
fi
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
gh release edit "${GITHUB_REF_NAME}" \
--title "${GITHUB_REF_NAME}" \
--draft=false \
"${release_args[@]}"
else
gh release create "${GITHUB_REF_NAME}" \
--title "${GITHUB_REF_NAME}" \
--generate-notes \
--verify-tag \
"${release_args[@]}"
fi
gh release upload "${GITHUB_REF_NAME}" artifacts/*.nupkg --clobber