aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/.github/workflows
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/.github/workflows
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/.github/workflows')
-rw-r--r--vendor/libghostty-vt/.github/workflows/clean-artifacts.yml17
-rw-r--r--vendor/libghostty-vt/.github/workflows/flatpak.yml50
-rw-r--r--vendor/libghostty-vt/.github/workflows/milestone.yml33
-rw-r--r--vendor/libghostty-vt/.github/workflows/nix.yml59
-rw-r--r--vendor/libghostty-vt/.github/workflows/publish-tag.yml74
-rw-r--r--vendor/libghostty-vt/.github/workflows/release-tag.yml410
-rw-r--r--vendor/libghostty-vt/.github/workflows/release-tip.yml911
-rw-r--r--vendor/libghostty-vt/.github/workflows/snap.yml59
-rw-r--r--vendor/libghostty-vt/.github/workflows/test.yml1760
-rw-r--r--vendor/libghostty-vt/.github/workflows/update-colorschemes.yml96
-rw-r--r--vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml22
-rw-r--r--vendor/libghostty-vt/.github/workflows/vouch-check-pr.yml22
-rw-r--r--vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml35
-rw-r--r--vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml36
-rw-r--r--vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml32
15 files changed, 3616 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml b/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml
new file mode 100644
index 00000000..69cb74ae
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/clean-artifacts.yml
@@ -0,0 +1,17 @@
+name: Clean Artifacts
+on:
+ schedule:
+ # Once a day
+ - cron: "0 0 * * *"
+ workflow_dispatch:
+jobs:
+ remove-old-artifacts:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Remove old artifacts
+ uses: c-hive/gha-remove-artifacts@44fc7acaf1b3d0987da0e8d4707a989d80e9554b # v1.4.0
+ with:
+ age: "1 week"
+ skip-tags: true
+ skip-recent: 5
diff --git a/vendor/libghostty-vt/.github/workflows/flatpak.yml b/vendor/libghostty-vt/.github/workflows/flatpak.yml
new file mode 100644
index 00000000..d64ab829
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/flatpak.yml
@@ -0,0 +1,50 @@
+on:
+ workflow_dispatch:
+ inputs:
+ source-run-id:
+ description: run id of the workflow that generated the artifact
+ required: true
+ type: string
+ source-artifact-id:
+ description: source tarball built during build-dist
+ required: true
+ type: string
+
+name: Flatpak
+
+jobs:
+ build:
+ if: github.repository == 'ghostty-org/ghostty'
+ name: "Flatpak"
+ container:
+ image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-47
+ options: --privileged
+ strategy:
+ fail-fast: false
+ matrix:
+ variant:
+ - arch: x86_64
+ runner: namespace-profile-ghostty-md
+ - arch: aarch64
+ runner: namespace-profile-ghostty-md-arm64
+ runs-on: ${{ matrix.variant.runner }}
+ steps:
+ - name: Download Source Tarball Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ run-id: ${{ inputs.source-run-id }}
+ artifact-ids: ${{ inputs.source-artifact-id }}
+ github-token: ${{ github.token }}
+
+ - name: Extract tarball
+ run: |
+ mkdir dist
+ tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
+
+ - uses: flatpak/flatpak-github-actions/flatpak-builder@92ae9851ad316786193b1fd3f40c4b51eb5cb101 # v6.6
+ with:
+ bundle: com.mitchellh.ghostty
+ manifest-path: dist/flatpak/com.mitchellh.ghostty.yml
+ cache-key: flatpak-builder-${{ github.sha }}
+ arch: ${{ matrix.variant.arch }}
+ verbose: true
diff --git a/vendor/libghostty-vt/.github/workflows/milestone.yml b/vendor/libghostty-vt/.github/workflows/milestone.yml
new file mode 100644
index 00000000..34e7652a
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/milestone.yml
@@ -0,0 +1,33 @@
+# Description:
+# - Add milestone to a merged PR automatically
+# - Add milestone to a closed issue that has a merged PR fix (if any)
+
+name: Milestone Action
+on:
+ issues:
+ types: [closed]
+ pull_request_target:
+ types: [closed]
+
+jobs:
+ update-milestone:
+ # Ignore bot-authored pull requests (dependabot, app bots, etc)
+ # and CI-only PRs.
+ if: github.event_name == 'issues' || (github.event.pull_request.user.type != 'Bot' && !startsWith(github.event.pull_request.title, 'ci:'))
+ runs-on: namespace-profile-ghostty-sm
+ name: Milestone Update
+ steps:
+ - name: Set Milestone for PR
+ uses: hustcer/milestone-action@ebed8d5daafd855a600d7e665c1b130f06d24130 # v3.1
+ if: github.event.pull_request.merged == true && !contains(github.event.pull_request.title, 'VOUCHED') && !startsWith(github.event.pull_request.title, 'ci:')
+ with:
+ action: bind-pr # `bind-pr` is the default action
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ # Bind milestone to closed issue that has a merged PR fix
+ - name: Set Milestone for Issue
+ uses: hustcer/milestone-action@ebed8d5daafd855a600d7e665c1b130f06d24130 # v3.1
+ if: github.event.issue.state == 'closed'
+ with:
+ action: bind-issue
+ github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/vendor/libghostty-vt/.github/workflows/nix.yml b/vendor/libghostty-vt/.github/workflows/nix.yml
new file mode 100644
index 00000000..f0f175b6
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/nix.yml
@@ -0,0 +1,59 @@
+on: [push, pull_request]
+name: Nix
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref_name != 'main' && github.ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ required:
+ name: "Required Checks: Nix"
+ runs-on: namespace-profile-ghostty-sm
+ needs:
+ - check-zig-cache-hash
+ steps:
+ - id: status
+ name: Determine status
+ run: |
+ results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}')
+ if ! grep -q -v -E '(failure|cancelled)' <<< "$results"; then
+ result="failed"
+ else
+ result="success"
+ fi
+ {
+ echo "result=${result}"
+ echo "results=${results}"
+ } | tee -a "$GITHUB_OUTPUT"
+ - if: always() && steps.status.outputs.result != 'success'
+ name: Check for failed status
+ run: |
+ echo "One or more required build workflows failed: ${{ steps.status.outputs.results }}"
+ exit 1
+
+ check-zig-cache-hash:
+ if: github.repository == 'ghostty-org/ghostty'
+ runs-on: namespace-profile-ghostty-sm
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - name: Setup Nix
+ uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ useDaemon: false # sometimes fails on short jobs
+ - name: Check Zig cache
+ run: nix develop -c ./nix/build-support/check-zig-cache.sh
diff --git a/vendor/libghostty-vt/.github/workflows/publish-tag.yml b/vendor/libghostty-vt/.github/workflows/publish-tag.yml
new file mode 100644
index 00000000..acb1ab1f
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/publish-tag.yml
@@ -0,0 +1,74 @@
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: "Version to deploy (format: vX.Y.Z)"
+ required: true
+
+name: Publish Tagged Release
+
+# We must only run one release workflow at a time to prevent corrupting
+# our release artifacts.
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: false
+
+jobs:
+ setup:
+ runs-on: namespace-profile-ghostty-sm
+ outputs:
+ version: ${{ steps.extract_version.outputs.version }}
+ steps:
+ - name: Validate Version Input
+ run: |
+ if [[ ! "${{ github.event.inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ echo "Error: Version must follow the format vX.Y.Z (e.g., v1.0.0)."
+ exit 1
+ fi
+
+ echo "Version is valid: ${{ github.event.inputs.version }}"
+
+ - name: Extract the Version
+ id: extract_version
+ run: |
+ VERSION=${{ github.event.inputs.version }}
+ VERSION=${VERSION#v}
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+
+ upload:
+ needs: [setup]
+ runs-on: namespace-profile-ghostty-sm
+ env:
+ GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
+ steps:
+ - name: Validate Release Files
+ run: |
+ BASE="https://release.files.ghostty.org/${GHOSTTY_VERSION}"
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-${GHOSTTY_VERSION}.tar.gz" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-${GHOSTTY_VERSION}.tar.gz.minisig" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-source.tar.gz" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-source.tar.gz.minisig" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-macos-universal.zip" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/ghostty-macos-universal-dsym.zip" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/Ghostty.dmg" | grep -q "^200$" || exit 1
+ curl -I -s -o /dev/null -w "%{http_code}" "${BASE}/appcast-staged.xml" | grep -q "^200$" || exit 1
+
+ - name: Download Staged Appcast
+ run: |
+ curl -L https://release.files.ghostty.org/${GHOSTTY_VERSION}/appcast-staged.xml > appcast-staged.xml
+ mv appcast-staged.xml appcast.xml
+
+ - name: Upload Appcast
+ run: |
+ rm -rf blob
+ mkdir blob
+ mv appcast.xml blob/appcast.xml
+ - name: Upload Appcast to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_RELEASE_SECRET_KEY }}
+ r2-bucket: ghostty-release
+ source-dir: blob
+ destination-dir: ./
diff --git a/vendor/libghostty-vt/.github/workflows/release-tag.yml b/vendor/libghostty-vt/.github/workflows/release-tag.yml
new file mode 100644
index 00000000..1a945f49
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/release-tag.yml
@@ -0,0 +1,410 @@
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: "Version to deploy (format: vX.Y.Z)"
+ required: true
+ upload:
+ description: "Upload final artifacts to R2"
+ default: false
+
+ push:
+ tags:
+ - "v[0-9]+.[0-9]+.[0-9]+"
+
+name: Release Tag
+
+# We must only run one release workflow at a time to prevent corrupting
+# our release artifacts.
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: false
+
+jobs:
+ setup:
+ runs-on: namespace-profile-ghostty-sm
+ outputs:
+ version: ${{ steps.extract_version.outputs.version }}
+ build: ${{ steps.extract_build_info.outputs.build }}
+ commit: ${{ steps.extract_build_info.outputs.commit }}
+ commit_long: ${{ steps.extract_build_info.outputs.commit_long }}
+ steps:
+ - name: Validate Version Input
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ if [[ ! "${{ github.event.inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ echo "Error: Version must follow the format vX.Y.Z (e.g., v1.0.0)."
+ exit 1
+ fi
+
+ echo "Version is valid: ${{ github.event.inputs.version }}"
+
+ - name: Extract the Version
+ id: extract_version
+ run: |
+ if [[ "${{ github.event_name }}" == "push" ]]; then
+ # Remove the leading 'v' from the tag
+ VERSION=${GITHUB_REF#refs/tags/v}
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
+ VERSION=${{ github.event.inputs.version }}
+ VERSION=${VERSION#v}
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ else
+ echo "Error: Unsupported event type."
+ exit 1
+ fi
+
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Important so that build number generation works
+ fetch-depth: 0
+
+ - name: Extract build info
+ id: extract_build_info
+ run: |
+ GHOSTTY_BUILD=$(git rev-list --count HEAD)
+ GHOSTTY_COMMIT=$(git rev-parse --short HEAD)
+ GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
+ echo "build=$GHOSTTY_BUILD" >> $GITHUB_OUTPUT
+ echo "commit=$GHOSTTY_COMMIT" >> $GITHUB_OUTPUT
+ echo "commit_long=$GHOSTTY_COMMIT_LONG" >> $GITHUB_OUTPUT
+ cat $GITHUB_OUTPUT
+
+ source-tarball:
+ runs-on: namespace-profile-ghostty-md
+ needs: [setup]
+ env:
+ GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Create Tarball
+ run: |
+ rm -rf zig-out/dist
+ nix develop -c zig build distcheck
+ cp zig-out/dist/ghostty-${GHOSTTY_VERSION}.tar.gz .
+ cp zig-out/dist/ghostty-${GHOSTTY_VERSION}.tar.gz ghostty-source.tar.gz
+
+ - name: Sign Tarball
+ run: |
+ echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
+ echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
+ nix develop -c minisign -S -m "ghostty-${GHOSTTY_VERSION}.tar.gz" -s minisign.key < minisign.password
+ nix develop -c minisign -S -m "ghostty-source.tar.gz" -s minisign.key < minisign.password
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ with:
+ name: source-tarball
+ path: |-
+ ghostty-${{ env.GHOSTTY_VERSION }}.tar.gz
+ ghostty-${{ env.GHOSTTY_VERSION }}.tar.gz.minisig
+ ghostty-source.tar.gz
+ ghostty-source.tar.gz.minisig
+
+ build-macos:
+ needs: [setup]
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ timeout-minutes: 90
+ env:
+ GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
+ GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
+ GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: XCode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ - name: Setup Sparkle
+ env:
+ SPARKLE_VERSION: 2.9.0
+ run: |
+ mkdir -p .action/sparkle
+ cd .action/sparkle
+ curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
+ unzip sparkle.zip
+ echo "$(pwd)/bin" >> $GITHUB_PATH
+
+ # GhosttyKit is the framework that is built from Zig for our native
+ # Mac app to access. Build this in release mode.
+ - name: Build GhosttyKit
+ run: |
+ nix develop -c \
+ zig build \
+ -Doptimize=ReleaseFast \
+ -Demit-macos-app=false \
+ -Dversion-string=${GHOSTTY_VERSION}
+
+ # The native app is built with native XCode tooling. This also does
+ # codesigning. IMPORTANT: this must NOT run in a Nix environment.
+ # Nix breaks xcodebuild so this has to be run outside.
+ - name: Build Ghostty.app
+ run: |
+ cd macos
+ xcodebuild -target Ghostty -configuration Release \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ # Add all our metadata to Info.plist so we can reference it later.
+ - name: Update Info.plist
+ env:
+ SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
+ run: |
+ # Version Info
+ /usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_VERSION" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ # Updater
+ /usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ - name: Codesign app bundle
+ env:
+ MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
+ MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
+ run: |
+ # Turn our base64-encoded certificate back to a regular .p12 file
+ echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
+
+ # We need to create a new keychain, otherwise using the certificate will prompt
+ # with a UI dialog asking for the certificate password, which we can't
+ # use in a headless CI environment
+ security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+
+ # Codesign Sparkle. Some notes here:
+ # - The XPC services aren't used since we don't sandbox Ghostty,
+ # but since they're part of the build, they still need to be
+ # codesigned.
+ # - The binaries in the "Versions" folders need to NOT be symlinks.
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/PlugIns/DockTilePlugin.plugin"
+
+ # Codesign the app bundle
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
+
+ - name: Create DMG
+ env:
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ run: |
+ npm install --global create-dmg
+ create-dmg \
+ --identity="$MACOS_CERTIFICATE_NAME" \
+ ./macos/build/Release/Ghostty.app \
+ ./
+ mv ./Ghostty*.dmg ./Ghostty.dmg
+
+ - name: "Notarize DMG"
+ env:
+ APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
+ APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
+ APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
+ run: |
+ # Store the notarization credentials so that we can prevent a UI password dialog
+ # from blocking the CI
+ echo "Create keychain profile"
+ echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
+ xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
+ rm notarization_key.p8
+
+ # Here we send the notarization request to the Apple's Notarization service, waiting for the result.
+ # This typically takes a few seconds inside a CI environment, but it might take more depending on the App
+ # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
+ # you're curious
+ echo "Notarize dmg"
+ xcrun notarytool submit "Ghostty.dmg" --keychain-profile "notarytool-profile" --wait
+
+ # Finally, we need to "attach the staple" to our executable, which will allow our app to be
+ # validated by macOS even when an internet connection is not available. We do this to
+ # both the app and the dmg
+ echo "Attach staple"
+ xcrun stapler staple "Ghostty.dmg"
+ xcrun stapler staple "macos/build/Release/Ghostty.app"
+
+ # Zip up the app and symbols
+ - name: Zip App
+ run: |
+ cd macos/build/Release
+ zip -9 -r --symlinks ../../../ghostty-macos-universal.zip Ghostty.app
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-dsym.zip Ghostty.app.dSYM/
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ with:
+ name: macos
+ path: |-
+ Ghostty.dmg
+ ghostty-macos-universal.zip
+ ghostty-macos-universal-dsym.zip
+
+ sentry-dsym:
+ runs-on: namespace-profile-ghostty-sm
+ needs: [build-macos]
+ steps:
+ - name: Install sentry-cli
+ run: |
+ curl -sL https://sentry.io/get-cli/ | bash
+
+ - name: Download macOS Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: macos
+
+ - name: Upload dSYM to Sentry
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: |
+ sentry-cli dif upload --project ghostty --wait ghostty-macos-universal-dsym.zip
+
+ appcast:
+ needs: [setup, build-macos]
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ env:
+ GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
+ GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
+ GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Download macOS Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: macos
+
+ - name: Setup Sparkle
+ env:
+ SPARKLE_VERSION: 2.9.0
+ run: |
+ mkdir -p .action/sparkle
+ cd .action/sparkle
+ curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
+ unzip sparkle.zip
+ echo "$(pwd)/bin" >> $GITHUB_PATH
+
+ - name: Generate Appcast
+ env:
+ SPARKLE_KEY: ${{ secrets.PROD_MACOS_SPARKLE_KEY }}
+ run: |
+ echo "GHOSTTY_VERSION=$GHOSTTY_VERSION"
+ echo "GHOSTTY_BUILD=$GHOSTTY_BUILD"
+ echo "GHOSTTY_COMMIT=$GHOSTTY_COMMIT"
+ echo "GHOSTTY_COMMIT_LONG=$GHOSTTY_COMMIT_LONG"
+
+ echo $SPARKLE_KEY > signing.key
+ sign_update -f signing.key Ghostty.dmg > sign_update.txt
+ curl -L https://release.files.ghostty.org/appcast.xml > appcast.xml
+ python3 ./dist/macos/update_appcast_tag.py
+ test -f appcast_new.xml
+ mv appcast_new.xml appcast.xml
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ with:
+ name: sparkle
+ path: |-
+ appcast.xml
+
+ upload:
+ if: |-
+ (github.event_name == 'workflow_dispatch' &&
+ github.event.inputs.upload == 'true') ||
+ github.event_name == 'push'
+ needs: [setup, source-tarball, build-macos, appcast]
+ runs-on: namespace-profile-ghostty-sm
+ env:
+ GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
+ steps:
+ - name: Download macOS Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: macos
+
+ - name: Download Sparkle Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: sparkle
+
+ - name: Download Source Tarball Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: source-tarball
+
+ # Upload all of our files EXCEPT the appcast. The appcast triggers
+ # updates in clients and we don't want to do that until we're
+ # sure these are uploaded.
+ - name: Prep Files
+ run: |
+ mkdir blob
+ mkdir -p blob/${GHOSTTY_VERSION}
+ mv "ghostty-${GHOSTTY_VERSION}.tar.gz" blob/${GHOSTTY_VERSION}/ghostty-${GHOSTTY_VERSION}.tar.gz
+ mv "ghostty-${GHOSTTY_VERSION}.tar.gz.minisig" blob/${GHOSTTY_VERSION}/ghostty-${GHOSTTY_VERSION}.tar.gz.minisig
+ mv ghostty-source.tar.gz blob/${GHOSTTY_VERSION}/ghostty-source.tar.gz
+ mv ghostty-source.tar.gz.minisig blob/${GHOSTTY_VERSION}/ghostty-source.tar.gz.minisig
+ mv ghostty-macos-universal.zip blob/${GHOSTTY_VERSION}/ghostty-macos-universal.zip
+ mv ghostty-macos-universal-dsym.zip blob/${GHOSTTY_VERSION}/ghostty-macos-universal-dsym.zip
+ mv Ghostty.dmg blob/${GHOSTTY_VERSION}/Ghostty.dmg
+ mv appcast.xml blob/${GHOSTTY_VERSION}/appcast-staged.xml
+ - name: Upload to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_RELEASE_SECRET_KEY }}
+ r2-bucket: ghostty-release
+ source-dir: blob
+ destination-dir: ./
diff --git a/vendor/libghostty-vt/.github/workflows/release-tip.yml b/vendor/libghostty-vt/.github/workflows/release-tip.yml
new file mode 100644
index 00000000..28e56e7f
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/release-tip.yml
@@ -0,0 +1,911 @@
+on:
+ workflow_run:
+ workflows: [Test]
+ types: [completed]
+ branches: [main]
+
+ workflow_dispatch:
+ inputs:
+ pr:
+ type: number
+ required: false
+
+name: Release Tip
+
+# We must only run one release workflow at a time to prevent corrupting
+# our release artifacts.
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: false
+
+jobs:
+ setup:
+ if: |
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ runs-on: namespace-profile-ghostty-sm
+ outputs:
+ should_skip: ${{ steps.check.outputs.should_skip }}
+ build: ${{ steps.extract_build_info.outputs.build }}
+ commit: ${{ steps.extract_build_info.outputs.commit }}
+ commit_long: ${{ steps.extract_build_info.outputs.commit_long }}
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Important so that build number generation works
+ fetch-depth: 0
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ - name: Extract build info
+ id: extract_build_info
+ run: |
+ GHOSTTY_BUILD=$(git rev-list --count HEAD)
+ GHOSTTY_COMMIT=$(git rev-parse --short HEAD)
+ GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
+ echo "build=$GHOSTTY_BUILD" >> $GITHUB_OUTPUT
+ echo "commit=$GHOSTTY_COMMIT" >> $GITHUB_OUTPUT
+ echo "commit_long=$GHOSTTY_COMMIT_LONG" >> $GITHUB_OUTPUT
+ - name: Check if tip already exists
+ id: check
+ run: |
+ GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
+ if nix develop -c nu .github/scripts/ghostty-tip $GHOSTTY_COMMIT_LONG; then
+ echo "Tip release already exists for commit $GHOSTTY_COMMIT_LONG"
+ echo "should_skip=true" >> $GITHUB_OUTPUT
+ else
+ echo "No tip release found for commit $GHOSTTY_COMMIT_LONG"
+ echo "should_skip=false" >> $GITHUB_OUTPUT
+ fi
+
+ tag:
+ runs-on: namespace-profile-ghostty-sm
+ needs: [setup, build-macos]
+ if: needs.setup.outputs.should_skip != 'true'
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Tip Tag
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git tag -fa tip -m "Latest Continuous Release" ${GITHUB_SHA}
+ git push --force origin tip
+
+ sentry-dsym-debug-slow:
+ runs-on: namespace-profile-ghostty-sm
+ needs: [setup, build-macos-debug-slow]
+ if: needs.setup.outputs.should_skip != 'true'
+ env:
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Install sentry-cli
+ run: |
+ curl -sL https://sentry.io/get-cli/ | bash
+
+ - name: Download dSYM
+ run: |
+ curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip > dsym.zip
+
+ - name: Upload dSYM to Sentry
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: |
+ sentry-cli dif upload --project ghostty --wait dsym.zip
+
+ sentry-dsym-debug-fast:
+ runs-on: namespace-profile-ghostty-sm
+ needs: [setup, build-macos-debug-fast]
+ if: needs.setup.outputs.should_skip != 'true'
+ env:
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Install sentry-cli
+ run: |
+ curl -sL https://sentry.io/get-cli/ | bash
+
+ - name: Download dSYM
+ run: |
+ curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip > dsym.zip
+
+ - name: Upload dSYM to Sentry
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: |
+ sentry-cli dif upload --project ghostty --wait dsym.zip
+
+ sentry-dsym:
+ runs-on: namespace-profile-ghostty-sm
+ needs: [setup, build-macos]
+ if: needs.setup.outputs.should_skip != 'true'
+ env:
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Install sentry-cli
+ run: |
+ curl -sL https://sentry.io/get-cli/ | bash
+
+ - name: Download dSYM
+ run: |
+ curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip > dsym.zip
+
+ - name: Upload dSYM to Sentry
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: |
+ sentry-cli dif upload --project ghostty --wait dsym.zip
+
+ source-tarball:
+ needs: [setup]
+ if: |
+ needs.setup.outputs.should_skip != 'true' &&
+ (
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ )
+ runs-on: namespace-profile-ghostty-sm
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ - name: Create Tarball
+ run: |
+ rm -rf zig-out/dist
+ nix develop -c zig build distcheck
+ cp zig-out/dist/*.tar.gz ghostty-source.tar.gz
+
+ - name: Sign Tarball
+ run: |
+ echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
+ echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
+ nix develop -c minisign -S -m ghostty-source.tar.gz -s minisign.key < minisign.password
+
+ - name: Update Release
+ uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
+ with:
+ name: 'Ghostty Tip ("Nightly")'
+ prerelease: true
+ tag_name: tip
+ target_commitish: ${{ github.sha }}
+ files: |
+ ghostty-source.tar.gz
+ ghostty-source.tar.gz.minisig
+ token: ${{ secrets.GH_RELEASE_TOKEN }}
+
+ source-tarball-lib-vt:
+ needs: [setup]
+ if: |
+ needs.setup.outputs.should_skip != 'true' &&
+ (
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ )
+ runs-on: namespace-profile-ghostty-sm
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ - name: Create Tarball
+ run: |
+ rm -rf zig-out/dist
+ nix develop -c zig build dist -Demit-lib-vt=true
+ cp zig-out/dist/*.tar.gz libghostty-vt-source.tar.gz
+
+ - name: Sign Tarball
+ run: |
+ echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
+ echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
+ nix develop -c minisign -S -m libghostty-vt-source.tar.gz -s minisign.key < minisign.password
+
+ - name: Update Release
+ uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
+ with:
+ name: 'Ghostty Tip ("Nightly")'
+ prerelease: true
+ tag_name: tip
+ target_commitish: ${{ github.sha }}
+ files: |
+ libghostty-vt-source.tar.gz
+ libghostty-vt-source.tar.gz.minisig
+ token: ${{ secrets.GH_RELEASE_TOKEN }}
+
+ build-macos:
+ needs: [setup]
+ if: |
+ needs.setup.outputs.should_skip != 'true' &&
+ (
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ )
+
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ timeout-minutes: 90
+ env:
+ GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
+ GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Important so that build number generation works
+ fetch-depth: 0
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: XCode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ # Setup Sparkle
+ - name: Setup Sparkle
+ env:
+ SPARKLE_VERSION: 2.9.0
+ run: |
+ mkdir -p .action/sparkle
+ cd .action/sparkle
+ curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
+ unzip sparkle.zip
+ echo "$(pwd)/bin" >> $GITHUB_PATH
+
+ # GhosttyKit is the framework that is built from Zig for our native
+ # Mac app to access. Build this in release mode.
+ - name: Build GhosttyKit
+ run: nix develop -c zig build -Doptimize=ReleaseFast -Demit-macos-app=false
+
+ # The native app is built with native XCode tooling. This also does
+ # codesigning. IMPORTANT: this must NOT run in a Nix environment.
+ # Nix breaks xcodebuild so this has to be run outside.
+ - name: Build Ghostty.app
+ run: |
+ cd macos
+ xcodebuild -target Ghostty -configuration Release \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ # We inject the "build number" as simply the number of commits since HEAD.
+ # This will be a monotonically always increasing build number that we use.
+ - name: Update Info.plist
+ env:
+ SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
+ run: |
+ # Version Info
+ /usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ # Updater
+ /usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ - name: Codesign app bundle
+ env:
+ MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
+ MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
+ run: |
+ # Turn our base64-encoded certificate back to a regular .p12 file
+ echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
+
+ # We need to create a new keychain, otherwise using the certificate will prompt
+ # with a UI dialog asking for the certificate password, which we can't
+ # use in a headless CI environment
+ security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+
+ # Codesign Sparkle. Some notes here:
+ # - The XPC services aren't used since we don't sandbox Ghostty,
+ # but since they're part of the build, they still need to be
+ # codesigned.
+ # - The binaries in the "Versions" folders need to NOT be symlinks.
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/PlugIns/DockTilePlugin.plugin"
+
+ # Codesign the app bundle
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
+
+ - name: Create DMG
+ env:
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ run: |
+ npm install --global create-dmg
+ create-dmg \
+ --identity="$MACOS_CERTIFICATE_NAME" \
+ ./macos/build/Release/Ghostty.app \
+ ./
+ mv ./Ghostty*.dmg ./Ghostty.dmg
+
+ - name: "Notarize DMG"
+ env:
+ APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
+ APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
+ APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
+ run: |
+ # Store the notarization credentials so that we can prevent a UI password dialog
+ # from blocking the CI
+ echo "Create keychain profile"
+ echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
+ xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
+ rm notarization_key.p8
+
+ # Here we send the notarization request to the Apple's Notarization service, waiting for the result.
+ # This typically takes a few seconds inside a CI environment, but it might take more depending on the App
+ # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
+ # you're curious
+ echo "Notarize dmg"
+ xcrun notarytool submit "Ghostty.dmg" --keychain-profile "notarytool-profile" --wait
+
+ # Finally, we need to "attach the staple" to our executable, which will allow our app to be
+ # validated by macOS even when an internet connection is not available. We do this to
+ # both the app and the dmg
+ echo "Attach staple"
+ xcrun stapler staple "Ghostty.dmg"
+ xcrun stapler staple "macos/build/Release/Ghostty.app"
+
+ # Zip up the app and symbols
+ - name: Zip App
+ run: |
+ cd macos/build/Release
+ zip -9 -r --symlinks ../../../ghostty-macos-universal.zip Ghostty.app
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-dsym.zip Ghostty.app.dSYM/
+
+ # Update Release
+ - name: Release
+ uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
+ with:
+ name: 'Ghostty Tip ("Nightly")'
+ prerelease: true
+ tag_name: tip
+ target_commitish: ${{ github.sha }}
+ files: |
+ ghostty-macos-universal.zip
+ Ghostty.dmg
+ token: ${{ secrets.GH_RELEASE_TOKEN }}
+
+ # Create our appcast for Sparkle
+ - name: Generate Appcast
+ if: |
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ env:
+ SPARKLE_KEY: ${{ secrets.PROD_MACOS_SPARKLE_KEY }}
+ run: |
+ echo $SPARKLE_KEY > signing.key
+ sign_update -f signing.key Ghostty.dmg > sign_update.txt
+ curl -L https://tip.files.ghostty.org/appcast.xml > appcast.xml
+ python3 ./dist/macos/update_appcast_tip.py
+ test -f appcast_new.xml
+
+ # Upload our binaries first
+ - name: Prep R2 Storage
+ run: |
+ mkdir blob
+ mkdir -p blob/${GHOSTTY_COMMIT_LONG}
+ cp ghostty-macos-universal.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal.zip
+ cp ghostty-macos-universal-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip
+ cp Ghostty.dmg blob/${GHOSTTY_COMMIT_LONG}/Ghostty.dmg
+
+ - name: Upload to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
+ r2-bucket: ghostty-tip
+ source-dir: blob
+ destination-dir: ./
+
+ # Now upload our appcast. This ensures that the appcast never
+ # gets out of sync with the binaries.
+ - name: Prep R2 Storage for Appcast
+ if: |
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ run: |
+ rm -r blob
+ mkdir blob
+ cp appcast_new.xml blob/appcast.xml
+
+ - name: Upload Appcast to R2
+ if: |
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
+ r2-bucket: ghostty-tip
+ source-dir: blob
+ destination-dir: ./
+
+ - name: Show and Save Release URLs
+ run: |
+ cat << EOF | tee release-urls.txt
+ Release URLs:
+ App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal.zip
+ Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip
+ DMG: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/Ghostty.dmg
+ EOF
+
+ - name: Upload Release URLs
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v6.0
+ with:
+ name: release-urls-${{ inputs.pr || '0' }}
+ path: release-urls.txt
+ retention-days: 2
+
+ build-macos-debug-slow:
+ needs: [setup]
+ if: |
+ needs.setup.outputs.should_skip != 'true' &&
+ (
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ )
+
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ timeout-minutes: 90
+ env:
+ GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
+ GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Important so that build number generation works
+ fetch-depth: 0
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: XCode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ # Setup Sparkle
+ - name: Setup Sparkle
+ env:
+ SPARKLE_VERSION: 2.9.0
+ run: |
+ mkdir -p .action/sparkle
+ cd .action/sparkle
+ curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
+ unzip sparkle.zip
+ echo "$(pwd)/bin" >> $GITHUB_PATH
+
+ # GhosttyKit is the framework that is built from Zig for our native
+ # Mac app to access. Build this in release mode.
+ - name: Build GhosttyKit
+ run: nix develop -c zig build -Doptimize=Debug -Demit-macos-app=false
+
+ # The native app is built with native XCode tooling. This also does
+ # codesigning. IMPORTANT: this must NOT run in a Nix environment.
+ # Nix breaks xcodebuild so this has to be run outside.
+ - name: Build Ghostty.app
+ run: |
+ cd macos
+ xcodebuild -target Ghostty -configuration Release \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ # We inject the "build number" as simply the number of commits since HEAD.
+ # This will be a monotonically always increasing build number that we use.
+ - name: Update Info.plist
+ env:
+ SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
+ run: |
+ # Version Info
+ /usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ # Updater
+ /usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ - name: Codesign app bundle
+ env:
+ MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
+ MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
+ run: |
+ # Turn our base64-encoded certificate back to a regular .p12 file
+ echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
+
+ # We need to create a new keychain, otherwise using the certificate will prompt
+ # with a UI dialog asking for the certificate password, which we can't
+ # use in a headless CI environment
+ security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+
+ # Codesign Sparkle. Some notes here:
+ # - The XPC services aren't used since we don't sandbox Ghostty,
+ # but since they're part of the build, they still need to be
+ # codesigned.
+ # - The binaries in the "Versions" folders need to NOT be symlinks.
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/PlugIns/DockTilePlugin.plugin"
+
+ # Codesign the app bundle
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
+
+ - name: "Notarize app bundle"
+ env:
+ APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
+ APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
+ APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
+ run: |
+ # Store the notarization credentials so that we can prevent a UI password dialog
+ # from blocking the CI
+ echo "Create keychain profile"
+ echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
+ xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
+ rm notarization_key.p8
+
+ # We can't notarize an app bundle directly, but we need to compress it as an archive.
+ # Therefore, we create a zip file containing our app bundle, so that we can send it to the
+ # notarization service
+ echo "Creating temp notarization archive"
+ ditto -c -k --keepParent "macos/build/Release/Ghostty.app" "notarization.zip"
+
+ # Here we send the notarization request to the Apple's Notarization service, waiting for the result.
+ # This typically takes a few seconds inside a CI environment, but it might take more depending on the App
+ # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
+ # you're curious
+ echo "Notarize app"
+ xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
+
+ # Finally, we need to "attach the staple" to our executable, which will allow our app to be
+ # validated by macOS even when an internet connection is not available.
+ echo "Attach staple"
+ xcrun stapler staple "macos/build/Release/Ghostty.app"
+
+ # Zip up the app
+ - name: Zip App
+ run: |
+ cd macos/build/Release
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-debug-slow.zip Ghostty.app
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-debug-slow-dsym.zip Ghostty.app.dSYM/
+
+ # Update Release
+ - name: Release
+ uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
+ with:
+ name: 'Ghostty Tip ("Nightly")'
+ prerelease: true
+ tag_name: tip
+ target_commitish: ${{ github.sha }}
+ files: ghostty-macos-universal-debug-slow.zip
+ token: ${{ secrets.GH_RELEASE_TOKEN }}
+
+ # Update Blob Storage
+ - name: Prep R2 Storage
+ run: |
+ mkdir blob
+ mkdir -p blob/${GHOSTTY_COMMIT_LONG}
+ cp ghostty-macos-universal-debug-slow.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow.zip
+ cp ghostty-macos-universal-debug-slow-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip
+ - name: Upload to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
+ r2-bucket: ghostty-tip
+ source-dir: blob
+ destination-dir: ./
+
+ - name: Echo Release URLs
+ run: |
+ echo "Release URLs:"
+ echo " App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow.zip"
+ echo " Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip"
+
+ build-macos-debug-fast:
+ needs: [setup]
+ if: |
+ needs.setup.outputs.should_skip != 'true' &&
+ (
+ github.event_name == 'workflow_dispatch' ||
+ (
+ github.repository_owner == 'ghostty-org' &&
+ github.ref_name == 'main'
+ )
+ )
+
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ timeout-minutes: 90
+ env:
+ GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
+ GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
+ GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Important so that build number generation works
+ fetch-depth: 0
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: XCode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ # Setup Sparkle
+ - name: Setup Sparkle
+ env:
+ SPARKLE_VERSION: 2.9.0
+ run: |
+ mkdir -p .action/sparkle
+ cd .action/sparkle
+ curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
+ unzip sparkle.zip
+ echo "$(pwd)/bin" >> $GITHUB_PATH
+
+ # GhosttyKit is the framework that is built from Zig for our native
+ # Mac app to access. Build this in release mode.
+ - name: Build GhosttyKit
+ run: nix develop -c zig build -Doptimize=ReleaseSafe -Demit-macos-app=false
+
+ # The native app is built with native XCode tooling. This also does
+ # codesigning. IMPORTANT: this must NOT run in a Nix environment.
+ # Nix breaks xcodebuild so this has to be run outside.
+ - name: Build Ghostty.app
+ run: |
+ cd macos
+ xcodebuild -target Ghostty -configuration Release \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ # We inject the "build number" as simply the number of commits since HEAD.
+ # This will be a monotonically always increasing build number that we use.
+ - name: Update Info.plist
+ env:
+ SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
+ run: |
+ # Version Info
+ /usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ # Updater
+ /usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+ /usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
+
+ - name: Codesign app bundle
+ env:
+ MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
+ MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
+ MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
+ MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
+ run: |
+ # Turn our base64-encoded certificate back to a regular .p12 file
+ echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
+
+ # We need to create a new keychain, otherwise using the certificate will prompt
+ # with a UI dialog asking for the certificate password, which we can't
+ # use in a headless CI environment
+ security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+ security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
+
+ # Codesign Sparkle. Some notes here:
+ # - The XPC services aren't used since we don't sandbox Ghostty,
+ # but since they're part of the build, they still need to be
+ # codesigned.
+ # - The binaries in the "Versions" folders need to NOT be symlinks.
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/PlugIns/DockTilePlugin.plugin"
+
+ # Codesign the app bundle
+ /usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
+
+ - name: "Notarize app bundle"
+ env:
+ APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
+ APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
+ APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
+ run: |
+ # Store the notarization credentials so that we can prevent a UI password dialog
+ # from blocking the CI
+ echo "Create keychain profile"
+ echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
+ xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
+ rm notarization_key.p8
+
+ # We can't notarize an app bundle directly, but we need to compress it as an archive.
+ # Therefore, we create a zip file containing our app bundle, so that we can send it to the
+ # notarization service
+ echo "Creating temp notarization archive"
+ ditto -c -k --keepParent "macos/build/Release/Ghostty.app" "notarization.zip"
+
+ # Here we send the notarization request to the Apple's Notarization service, waiting for the result.
+ # This typically takes a few seconds inside a CI environment, but it might take more depending on the App
+ # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
+ # you're curious
+ echo "Notarize app"
+ xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
+
+ # Finally, we need to "attach the staple" to our executable, which will allow our app to be
+ # validated by macOS even when an internet connection is not available.
+ echo "Attach staple"
+ xcrun stapler staple "macos/build/Release/Ghostty.app"
+
+ # Zip up the app
+ - name: Zip App
+ run: |
+ cd macos/build/Release
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-debug-fast.zip Ghostty.app
+ zip -9 -r --symlinks ../../../ghostty-macos-universal-debug-fast-dsym.zip Ghostty.app.dSYM/
+
+ # Update Release
+ - name: Release
+ uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
+ with:
+ name: 'Ghostty Tip ("Nightly")'
+ prerelease: true
+ tag_name: tip
+ target_commitish: ${{ github.sha }}
+ files: ghostty-macos-universal-debug-fast.zip
+ token: ${{ secrets.GH_RELEASE_TOKEN }}
+
+ # Update Blob Storage
+ - name: Prep R2 Storage
+ run: |
+ mkdir blob
+ mkdir -p blob/${GHOSTTY_COMMIT_LONG}
+ cp ghostty-macos-universal-debug-fast.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast.zip
+ cp ghostty-macos-universal-debug-fast-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip
+ - name: Upload to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_TIP_SECRET_KEY }}
+ r2-bucket: ghostty-tip
+ source-dir: blob
+ destination-dir: ./
+
+ - name: Echo Release URLs
+ run: |
+ echo "Release URLs:"
+ echo " App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast.zip"
+ echo " Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip"
diff --git a/vendor/libghostty-vt/.github/workflows/snap.yml b/vendor/libghostty-vt/.github/workflows/snap.yml
new file mode 100644
index 00000000..67f29160
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/snap.yml
@@ -0,0 +1,59 @@
+on:
+ workflow_dispatch:
+ inputs:
+ source-run-id:
+ description: run id of the workflow that generated the artifact
+ required: true
+ type: string
+ source-artifact-id:
+ description: source tarball built during build-dist
+ required: true
+ type: string
+
+name: Snap
+
+jobs:
+ build:
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ [namespace-profile-ghostty-snap, namespace-profile-ghostty-snap-arm64]
+ runs-on: ${{ matrix.os }}
+ timeout-minutes: 45
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Download Source Tarball Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ run-id: ${{ inputs.source-run-id }}
+ artifact-ids: ${{ inputs.source-artifact-id }}
+ github-token: ${{ github.token }}
+
+ - name: Extract tarball
+ run: |
+ mkdir dist
+ tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ - run: sudo apt install -y udev
+
+ - run: sudo systemctl start systemd-udevd
+
+ # Workaround until this is fixed: https://github.com/canonical/lxd-pkg-snap/pull/789
+ - run: |
+ _LXD_SNAP_DEVCGROUP_CONFIG="/var/lib/snapd/cgroup/snap.lxd.device"
+ sudo mkdir -p /var/lib/snapd/cgroup
+ echo 'self-managed=true' | sudo tee "${_LXD_SNAP_DEVCGROUP_CONFIG}"
+
+ - uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 # v1.3.0
+ with:
+ path: dist
diff --git a/vendor/libghostty-vt/.github/workflows/test.yml b/vendor/libghostty-vt/.github/workflows/test.yml
new file mode 100644
index 00000000..9e292c07
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/test.yml
@@ -0,0 +1,1760 @@
+on:
+ push: {}
+ pull_request: {}
+ workflow_dispatch: {}
+
+name: Test
+
+# We only want the latest commit to test for any non-main ref.
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref_name != 'main' && github.ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ # Determines whether other jobs should be skipped. Modify this if there
+ # are other fast skip conditions, and add it as an output. Then modify
+ # other tests `needs/if` to check them. Document the outputs.
+ skip:
+ if: github.repository == 'ghostty-org/ghostty'
+ runs-on: namespace-profile-ghostty-xsm
+ outputs:
+ # 'true' when all changed files are non-code (e.g. only VOUCHED.td),
+ # signaling that all other jobs can be skipped entirely.
+ skip: ${{ steps.determine.outputs.skip }}
+ # Path-based filters to gate specific linter/formatter jobs.
+ actions_pins: ${{ steps.filter_any.outputs.actions_pins }}
+ blueprints: ${{ steps.filter_any.outputs.blueprints }}
+ macos: ${{ steps.filter_any.outputs.macos }}
+ nix: ${{ steps.filter_any.outputs.nix }}
+ shell: ${{ steps.filter_any.outputs.shell }}
+ zig: ${{ steps.filter_any.outputs.zig }}
+
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
+ id: filter_every
+ with:
+ token: ""
+ predicate-quantifier: "every"
+ filters: |
+ code:
+ - '**'
+ - '!.github/VOUCHED.td'
+ - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
+ id: filter_any
+ with:
+ token: ""
+ filters: |
+ macos:
+ - '.swiftlint.yml'
+ - 'macos/**'
+ actions_pins:
+ - '.github/workflows/**'
+ - '.github/pinact.yml'
+ shell:
+ - '**/*.sh'
+ - '**/*.bash'
+ nix:
+ - 'nix/**'
+ - '*.nix'
+ - 'flake.nix'
+ - 'flake.lock'
+ - 'default.nix'
+ - 'shell.nix'
+ zig:
+ - '**/*.zig'
+ - 'build.zig*'
+ blueprints:
+ - 'src/apprt/gtk/**/*.blp'
+ - 'nix/build-support/check-blueprints.sh'
+
+ - id: determine
+ name: Determine skip
+ run: |
+ if [ "${{ steps.filter_every.outputs.code }}" = "false" ]; then
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "skip=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ required:
+ name: "Required Checks: Test"
+ if: always()
+ runs-on: namespace-profile-ghostty-xsm
+ needs:
+ - skip
+ - build-bench
+ - build-dist
+ - build-dist-lib-vt
+ - build-examples-zig
+ - build-examples-cmake
+ - build-examples-cmake-windows
+ - build-cmake
+ - build-flatpak
+ - build-libghostty-vt
+ - build-libghostty-vt-android
+ - build-libghostty-vt-macos
+ - build-libghostty-vt-windows
+ - build-linux
+ - build-linux-libghostty
+ - build-nix
+ - build-macos
+ - build-macos-freetype
+ - build-snap
+ - test
+ - test-simd
+ - test-gtk
+ - test-sentry-linux
+ - test-i18n
+ - test-fuzz-libghostty
+ - test-lib-vt
+ - test-lib-vt-pkgconfig
+ - test-macos
+ - test-windows
+ - pinact
+ - prettier
+ - swiftlint
+ - alejandra
+ - typos
+ - shellcheck
+ - translations
+ - blueprint-compiler
+ - test-pkg-linux
+ - test-debian-13
+ - valgrind
+ - zig-fmt
+
+ steps:
+ - id: status
+ name: Determine status
+ run: |
+ results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}')
+ if ! grep -q -v -E '(failure|cancelled)' <<< "$results"; then
+ result="failed"
+ else
+ result="success"
+ fi
+ {
+ echo "result=${result}"
+ echo "results=${results}"
+ } | tee -a "$GITHUB_OUTPUT"
+ - if: always() && steps.status.outputs.result != 'success'
+ name: Check for failed status
+ run: |
+ echo "One or more required build workflows failed: ${{ steps.status.outputs.results }}"
+ exit 1
+
+ build-bench:
+ # We build benchmarks on large because it uses ReleaseFast
+ runs-on: namespace-profile-ghostty-lg
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build Benchmarks
+ run: nix develop -c zig build -Demit-bench
+
+ list-examples:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ outputs:
+ zig: ${{ steps.list.outputs.zig }}
+ cmake: ${{ steps.list.outputs.cmake }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - id: list
+ name: List example directories
+ run: |
+ zig=$(ls example/*/build.zig.zon 2>/dev/null | xargs -n1 dirname | xargs -n1 basename | jq -R -s -c 'split("\n") | map(select(. != ""))')
+ echo "$zig" | jq .
+ echo "zig=$zig" >> "$GITHUB_OUTPUT"
+ cmake=$(ls example/*/CMakeLists.txt 2>/dev/null | xargs -n1 dirname | xargs -n1 basename | jq -R -s -c 'split("\n") | map(select(. != ""))')
+ echo "$cmake" | jq .
+ echo "cmake=$cmake" >> "$GITHUB_OUTPUT"
+
+ build-examples-zig:
+ strategy:
+ fail-fast: false
+ matrix:
+ dir: ${{ fromJSON(needs.list-examples.outputs.zig) }}
+ name: Example ${{ matrix.dir }}
+ runs-on: namespace-profile-ghostty-xsm
+ needs: [test, list-examples]
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build Example
+ run: |
+ cd example/${{ matrix.dir }}
+ nix develop -c zig build
+
+ build-examples-cmake:
+ strategy:
+ fail-fast: false
+ matrix:
+ dir: ${{ fromJSON(needs.list-examples.outputs.cmake) }}
+ name: Example ${{ matrix.dir }}
+ runs-on: namespace-profile-ghostty-xsm
+ needs: [test, list-examples]
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build Example
+ run: |
+ cd example/${{ matrix.dir }}
+ nix develop -c cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=${{ github.workspace }}
+ nix develop -c cmake --build build
+
+ build-examples-cmake-windows:
+ strategy:
+ fail-fast: false
+ matrix:
+ dir: ${{ fromJSON(needs.list-examples.outputs.cmake) }}
+ name: Example ${{ matrix.dir }} (Windows)
+ runs-on: namespace-profile-ghostty-windows
+ timeout-minutes: 45
+ needs: [test, list-examples]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Install zig
+ uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
+
+ - name: Build Example
+ shell: pwsh
+ run: |
+ cd example/${{ matrix.dir }}
+ cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=${{ github.workspace }}
+ cmake --build build
+
+ build-cmake:
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build
+ run: |
+ nix develop -c cmake -B build
+ nix develop -c cmake --build build
+
+ - name: Verify artifacts
+ run: |
+ test -f zig-out/lib/libghostty-vt.so.0.1.0
+ test -d zig-out/include/ghostty
+ ls -la zig-out/lib/
+ ls -la zig-out/include/ghostty/
+
+ test-lib-vt-pkgconfig:
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build libghostty-vt
+ run: nix develop -c zig build -Demit-lib-vt
+
+ - name: Verify pkg-config file
+ run: |
+ export PKG_CONFIG_PATH="$PWD/zig-out/share/pkgconfig"
+ pkg-config --validate libghostty-vt
+ echo "Cflags: $(pkg-config --cflags libghostty-vt)"
+ echo "Libs: $(pkg-config --libs libghostty-vt)"
+ echo "Static: $(pkg-config --libs --static libghostty-vt)"
+
+ # Libs.private must include the C++ standard library
+ pkg-config --libs --static libghostty-vt | grep -q -- '-lc++'
+
+ - name: Verify static archive contains SIMD deps
+ run: |
+ nm -g zig-out/lib/libghostty-vt.a | grep -q ' T .*simdutf'
+ nm -g zig-out/lib/libghostty-vt.a | grep -q ' T .*3hwy'
+
+ - name: Write test program
+ run: |
+ cat > /tmp/test_libghostty_vt.c << 'TESTEOF'
+ #include <ghostty/vt.h>
+ #include <stdio.h>
+ int main(void) {
+ bool simd = false;
+ GhosttyResult r = ghostty_build_info(GHOSTTY_BUILD_INFO_SIMD, &simd);
+ if (r != GHOSTTY_SUCCESS) return 1;
+ printf("SIMD: %s\n", simd ? "yes" : "no");
+ return 0;
+ }
+ TESTEOF
+
+ - name: Test shared link via pkg-config
+ run: |
+ export PKG_CONFIG_PATH="$PWD/zig-out/share/pkgconfig"
+ nix develop -c cc -o /tmp/test_shared /tmp/test_libghostty_vt.c \
+ $(pkg-config --cflags --libs libghostty-vt) \
+ -Wl,-rpath,"$PWD/zig-out/lib"
+ /tmp/test_shared
+
+ - name: Test static link via pkg-config
+ run: |
+ export PKG_CONFIG_PATH="$PWD/zig-out/share/pkgconfig"
+ # The static library is compiled with LLVM libc++ (not GNU
+ # libstdc++), so linking requires a libc++-compatible toolchain.
+ # zig cc, clang, or gcc with libc++-dev installed all work.
+ nix develop -c zig cc -o /tmp/test_static /tmp/test_libghostty_vt.c \
+ $(pkg-config --cflags libghostty-vt) \
+ "$PWD/zig-out/lib/libghostty-vt.a" \
+ $(pkg-config --libs-only-l --static libghostty-vt | sed 's/-lghostty-vt//')
+ /tmp/test_static
+ # Verify it's truly statically linked (no libghostty-vt.so dependency)
+ ! ldd /tmp/test_static 2>/dev/null | grep -q libghostty-vt
+
+ # Test system integration: rebuild with -Dsystem-simdutf=true so
+ # simdutf comes from the system instead of being vendored. This
+ # verifies the .pc file uses Requires.private for system deps and
+ # the fat archive only bundles the remaining vendored deps.
+ - name: Rebuild with system simdutf
+ run: |
+ rm -rf zig-out
+ nix develop -c zig build -Demit-lib-vt -fsys=simdutf
+
+ - name: Verify pkg-config with system simdutf
+ run: |
+ export PKG_CONFIG_PATH="$PWD/zig-out/share/pkgconfig"
+ pc_content=$(cat zig-out/share/pkgconfig/libghostty-vt.pc)
+ echo "$pc_content"
+
+ # Requires.private must reference simdutf
+ echo "$pc_content" | grep -q 'Requires.private:.*simdutf'
+
+ # Requires.private must NOT reference libhwy (still vendored)
+ ! echo "$pc_content" | grep -q 'Requires.private:.*libhwy'
+
+ - name: Verify archive with system simdutf
+ run: |
+ # simdutf symbols must NOT be defined (comes from system)
+ ! nm -g zig-out/lib/libghostty-vt.a | grep -q ' T .*simdutf'
+
+ # highway symbols must still be defined (vendored)
+ nm -g zig-out/lib/libghostty-vt.a | grep -q ' T .*3hwy'
+
+ build-flatpak:
+ strategy:
+ fail-fast: false
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build with Flatpak
+ run: |
+ nix develop -c \
+ zig build \
+ -Dflatpak
+
+ build-snap:
+ strategy:
+ fail-fast: false
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build with Snap
+ run: |
+ nix develop -c \
+ zig build \
+ -Dsnap
+
+ build-libghostty-vt:
+ strategy:
+ matrix:
+ target:
+ [
+ aarch64-macos,
+ x86_64-macos,
+ aarch64-linux,
+ x86_64-linux,
+ x86_64-linux-musl,
+ x86_64-windows,
+ wasm32-freestanding,
+ ]
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build
+ run: |
+ nix develop -c zig build -Demit-lib-vt \
+ -Dtarget=${{ matrix.target }} \
+ -Dsimd=false
+
+ # lib-vt requires macOS runner for macOS/iOS builds because it requires the `apple_sdk` path
+ build-libghostty-vt-macos:
+ strategy:
+ matrix:
+ target: [aarch64-macos, x86_64-macos, aarch64-ios]
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Xcode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Build
+ run: |
+ nix develop -c zig build -Demit-lib-vt \
+ -Dtarget=${{ matrix.target }}
+
+ # lib-vt requires the Android NDK for Android builds
+ build-libghostty-vt-android:
+ strategy:
+ matrix:
+ target:
+ [aarch64-linux-android, x86_64-linux-android, arm-linux-androideabi]
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ ANDROID_NDK_VERSION: r29
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Setup Android NDK
+ uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
+ id: setup-ndk
+ with:
+ ndk-version: r29
+ add-to-path: false
+ link-to-sdk: false
+ local-cache: true
+
+ - name: Build
+ run: |
+ nix develop -c zig build -Demit-lib-vt \
+ -Dtarget=${{ matrix.target }}
+ env:
+ ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+
+ build-libghostty-vt-windows:
+ runs-on: namespace-profile-ghostty-windows
+ timeout-minutes: 45
+ needs: test
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Zig
+ uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
+
+ - name: Test libghostty-vt
+ run: zig build test-lib-vt
+
+ - name: Build libghostty-vt
+ run: zig build -Demit-lib-vt
+
+ build-linux:
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [namespace-profile-ghostty-md, namespace-profile-ghostty-md-arm64]
+ runs-on: ${{ matrix.os }}
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test Build
+ run: nix develop -c zig build
+
+ build-linux-libghostty:
+ runs-on: namespace-profile-ghostty-md
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build Libghostty
+ run: nix develop -c zig build -Dapp-runtime=none
+
+ build-nix:
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [namespace-profile-ghostty-md, namespace-profile-ghostty-md-arm64]
+ runs-on: ${{ matrix.os }}
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test release NixOS package build
+ run: nix build .#ghostty-releasefast
+
+ - name: Check version
+ run: result/bin/ghostty +version | grep -q '.ReleaseFast'
+
+ - name: Check to see if the binary has been stripped
+ run: nm result/bin/.ghostty-wrapped 2>&1 | grep -q 'no symbols'
+
+ - name: Test debug NixOS package build
+ run: nix build .#ghostty-debug
+
+ - name: Check version
+ run: result/bin/ghostty +version | grep -q '.Debug'
+
+ - name: Check to see if the binary has not been stripped
+ run: nm result/bin/.ghostty-wrapped 2>&1 | grep -q 'main_ghostty.main'
+
+ - name: Test ReleaseFast build of libghostty-vt
+ run: nix build .#libghostty-vt-releasefast
+
+ - name: Check to see if the library looks sane
+ run: nm result/lib/libghostty-vt.so.0.1.0 2>&1 | grep -q 'ghostty_terminal_new'
+
+ - name: Test Debug build of libghostty-vt
+ run: nix build .#libghostty-vt-debug
+
+ - name: Check to see if the library looks sane
+ run: nm result/lib/libghostty-vt.so.0.1.0 2>&1 | grep -q 'ghostty_terminal_new'
+
+ build-dist:
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ outputs:
+ artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build and Check Source Tarball
+ run: |
+ rm -rf zig-out/dist
+ nix develop -c zig build distcheck
+ cp zig-out/dist/*.tar.gz ghostty-source.tar.gz
+
+ - name: Upload artifact
+ id: upload-artifact
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ with:
+ name: source-tarball
+ path: |-
+ ghostty-source.tar.gz
+
+ build-dist-lib-vt:
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Build and Check Source Tarball
+ run: |
+ rm -rf zig-out/dist
+ nix develop -c zig build distcheck -Demit-lib-vt=true
+
+ - name: Verify tarball size
+ run: |
+ tarball=$(ls zig-out/dist/*.tar.gz)
+ size=$(stat --format=%s "$tarball")
+ max=$((5 * 1024 * 1024))
+ echo "Tarball size: $size bytes (max: $max)"
+ if [ "$size" -gt "$max" ]; then
+ echo "ERROR: tarball exceeds 5 MB"
+ exit 1
+ fi
+
+ trigger-snap:
+ if: github.event_name != 'pull_request'
+ runs-on: namespace-profile-ghostty-xsm
+ needs: [build-dist, build-snap]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Trigger Snap workflow
+ run: |
+ gh workflow run \
+ snap.yml \
+ --ref ${{ github.ref_name || 'main' }} \
+ --field source-run-id=${{ github.run_id }} \
+ --field source-artifact-id=${{ needs.build-dist.outputs.artifact-id }}
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ trigger-flatpak:
+ if: github.event_name != 'pull_request'
+ runs-on: namespace-profile-ghostty-xsm
+ needs: [build-dist, build-flatpak]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Trigger Flatpak workflow
+ run: |
+ gh workflow run \
+ flatpak.yml \
+ --ref ${{ github.ref_name || 'main' }} \
+ --field source-run-id=${{ github.run_id }} \
+ --field source-artifact-id=${{ needs.build-dist.outputs.artifact-id }}
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ build-macos:
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Xcode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ - name: get the Zig deps
+ id: deps
+ run: nix build -L .#deps && echo "deps=$(readlink ./result)" >> $GITHUB_OUTPUT
+
+ # GhosttyKit is the framework that is built from Zig for our native
+ # Mac app to access.
+ - name: Build GhosttyKit
+ run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false
+
+ # The native app is built with native Xcode tooling. This also does
+ # codesigning. IMPORTANT: this must NOT run in a Nix environment.
+ # Nix breaks xcodebuild so this has to be run outside.
+ - name: Build Ghostty.app
+ run: |
+ cd macos
+ xcodebuild -target Ghostty \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ # Build the iOS target without code signing just to verify it works.
+ - name: Build Ghostty iOS
+ run: |
+ cd macos
+ xcodebuild -target Ghostty-iOS "CODE_SIGNING_ALLOWED=NO" \
+ COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \
+ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES
+
+ build-macos-freetype:
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Xcode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ - name: get the Zig deps
+ id: deps
+ run: nix build -L .#deps && echo "deps=$(readlink ./result)" >> $GITHUB_OUTPUT
+
+ # We run tests with an empty test filter so it runs all unit tests
+ # but skips Xcode tests
+ - name: Test All
+ run: |
+ nix develop -c zig build test --system ${{ steps.deps.outputs.deps }} -Drenderer=metal -Dfont-backend=coretext_freetype -Dtest-filter=""
+
+ - name: Build All
+ run: |
+ nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false -Drenderer=metal -Dfont-backend=coretext_freetype
+
+ test:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-md
+ outputs:
+ zig_version: ${{ steps.zig.outputs.version }}
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Get required Zig version
+ id: zig
+ run: |
+ echo "version=$(sed -n -E 's/^\s*\.?minimum_zig_version\s*=\s*"([^"]+)".*/\1/p' build.zig.zon)" >> $GITHUB_OUTPUT
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: test
+ run: nix develop -c zig build -Dapp-runtime=none test
+
+ - name: Test GTK Build
+ run: nix develop -c zig build -Dapp-runtime=gtk -Demit-docs -Demit-webdata
+
+ # This relies on the cache being populated by the commands above.
+ - name: Test System Build
+ run: nix develop -c zig build --system ${ZIG_GLOBAL_CACHE_DIR}/p
+
+ test-lib-vt:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-md
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test
+ run: nix develop -c zig build test-lib-vt
+
+ test-gtk:
+ strategy:
+ fail-fast: false
+ matrix:
+ x11: ["true", "false"]
+ wayland: ["true", "false"]
+ name: GTK x11=${{ matrix.x11 }} wayland=${{ matrix.wayland }}
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test
+ run: |
+ nix develop -c \
+ zig build \
+ -Dapp-runtime=gtk \
+ -Dgtk-x11=${{ matrix.x11 }} \
+ -Dgtk-wayland=${{ matrix.wayland }} \
+ test
+
+ - name: Build
+ run: |
+ nix develop -c \
+ zig build \
+ -Dapp-runtime=gtk \
+ -Dgtk-x11=${{ matrix.x11 }} \
+ -Dgtk-wayland=${{ matrix.wayland }}
+
+ test-simd:
+ strategy:
+ fail-fast: false
+ matrix:
+ simd: ["true", "false"]
+ name: Build -Dsimd=${{ matrix.simd }}
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test
+ run: |
+ nix develop -c zig build test -Dsimd=${{ matrix.simd }}
+
+ test-sentry-linux:
+ strategy:
+ fail-fast: false
+ matrix:
+ sentry: ["true", "false"]
+ name: Build -Dsentry=${{ matrix.sentry }}
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test Sentry Build
+ run: |
+ nix develop -c zig build -Dsentry=${{ matrix.sentry }}
+
+ test-macos:
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Xcode Select
+ run: sudo xcode-select -s /Applications/Xcode_26.3.app
+
+ - name: Xcode Version
+ run: xcodebuild -version
+
+ - name: get the Zig deps
+ id: deps
+ run: nix build -L .#deps && echo "deps=$(readlink ./result)" >> $GITHUB_OUTPUT
+
+ - name: test
+ run: nix develop -c zig build test --system ${{ steps.deps.outputs.deps }}
+
+ test-windows:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-windows
+ timeout-minutes: 45
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Zig
+ uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
+
+ - name: Test
+ run: zig build -Dapp-runtime=none test
+
+ test-i18n:
+ strategy:
+ fail-fast: false
+ matrix:
+ i18n: ["true", "false"]
+ name: Build -Di18n=${{ matrix.i18n }}
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test
+ run: |
+ nix develop -c zig build -Di18n=${{ matrix.i18n }}
+
+ test-fuzz-libghostty:
+ name: Build test/fuzz-libghostty
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Install AFL++ and LLVM
+ run: |
+ sudo apt-get update
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y afl++ llvm
+
+ - name: Verify AFL++ and LLVM are available
+ run: |
+ afl-cc --version
+ if command -v llvm-config >/dev/null 2>&1; then
+ llvm-config --version
+ else
+ llvm-config-18 --version
+ fi
+
+ - name: Build fuzzer harness
+ run: |
+ nix develop -c sh -c 'cd test/fuzz-libghostty && zig build'
+
+ zig-fmt:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.zig == 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: zig fmt
+ run: nix develop -c zig fmt --check .
+
+ pinact:
+ name: "GitHub Actions Pins"
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.actions_pins == 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ permissions:
+ contents: read
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: pinact check
+ run: nix develop -c pinact run --check
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ prettier:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: prettier check
+ run: nix develop -c prettier --check .
+
+ swiftlint:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.macos == 'true'
+ runs-on: namespace-profile-ghostty-macos-tahoe
+ needs: skip
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ cache: |
+ xcode
+ path: |
+ /Users/runner/zig
+
+ # TODO(tahoe): https://github.com/NixOS/nix/issues/13342
+ - uses: DeterminateSystems/nix-installer-action@main
+ with:
+ determinate: true
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+
+ - name: swiftlint check
+ run: nix develop -c swiftlint lint --strict
+
+ alejandra:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.nix == 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: alejandra check
+ run: nix develop -c alejandra --check .
+
+ typos:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: typos check
+ run: nix develop -c typos
+
+ shellcheck:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.shell == 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: shellcheck
+ run: |
+ nix develop -c shellcheck \
+ --check-sourced \
+ --color=always \
+ --severity=warning \
+ $(find . \( -name "*.sh" -o -name "*.bash" \) -type f ! -path "./zig-out/*" ! -path "./macos/build/*" ! -path "./.git/*" | sort)
+
+ translations:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: check translations
+ run: nix develop -c .github/scripts/check-translations.sh
+
+ blueprint-compiler:
+ if: github.repository == 'ghostty-org/ghostty' && needs.skip.outputs.skip != 'true' && needs.skip.outputs.blueprints == 'true'
+ needs: skip
+ runs-on: namespace-profile-ghostty-xsm
+ timeout-minutes: 60
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ skipPush: true
+ useDaemon: false # sometimes fails on short jobs
+ - name: check blueprints
+ run: nix develop -c ./nix/build-support/check-blueprints.sh
+ - name: check unchanged
+ run: git diff --exit-code
+
+ test-pkg-linux:
+ strategy:
+ fail-fast: false
+ matrix:
+ pkg: ["wuffs"]
+ name: Test pkg/${{ matrix.pkg }}
+ runs-on: namespace-profile-ghostty-sm
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Test ${{ matrix.pkg }} Build
+ run: |
+ nix develop -c sh -c "cd pkg/${{ matrix.pkg }} ; zig build test"
+
+ test-debian-13:
+ name: Test build on Debian 13
+ runs-on: namespace-profile-ghostty-sm
+ timeout-minutes: 10
+ needs: [test, build-dist]
+ steps:
+ - name: Install and configure Namespace CLI
+ uses: namespacelabs/nscloud-setup@df198f982fcecfb8264bea3f1274b56a61b6dfdc # v0.0.12
+
+ - name: Configure Namespace powered Buildx
+ uses: namespacelabs/nscloud-setup-buildx-action@d059ed7184f0bc7c8b27e8810cea153d02bcc6dd # v0.0.23
+
+ - name: Download Source Tarball Artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: source-tarball
+
+ - name: Extract tarball
+ run: |
+ mkdir dist
+ tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
+
+ - name: Build and push
+ uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
+ with:
+ context: dist
+ file: dist/src/build/docker/debian/Dockerfile
+ build-args: |
+ DISTRO_VERSION=13
+
+ valgrind:
+ if: github.repository == 'ghostty-org/ghostty'
+ runs-on: namespace-profile-ghostty-lg
+ timeout-minutes: 30
+ needs: test
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ # Install Nix and use that to run our tests so our environment matches exactly.
+ - uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: valgrind deps
+ run: |
+ sudo apt update -y
+ sudo apt install -y valgrind libc6-dbg
+
+ - name: valgrind
+ run: |
+ nix develop -c zig build test-valgrind
+
+ # build-freebsd:
+ # name: Build on FreeBSD
+ # needs: test
+ # runs-on: namespace-profile-mitchellh-sm-systemd
+ # strategy:
+ # matrix:
+ # release:
+ # - "14.3"
+ # - "15.0"
+ # timeout-minutes: 10
+ # steps:
+ # - name: Checkout Ghostty
+ # uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ #
+ # - name: Start SSH
+ # run: |
+ # sudo systemctl start ssh
+ #
+ # - name: Set up FreeBSD VM
+ # uses: vmactions/freebsd-vm@487ce35b96fae3e60d45b521735f5aa436ecfade # v1.2.4
+ # with:
+ # release: ${{ matrix.release }}
+ # copyback: false
+ # usesh: true
+ # prepare: |
+ # pkg install -y \
+ # devel/blueprint-compiler \
+ # devel/gettext \
+ # devel/git \
+ # devel/pkgconf \
+ # ftp/curl \
+ # graphics/wayland \
+ # security/ca_root_nss \
+ # textproc/hs-pandoc \
+ # x11-fonts/jetbrains-mono \
+ # x11-toolkits/libadwaita \
+ # x11-toolkits/gtk40 \
+ # x11-toolkits/gtk4-layer-shell
+ # curl -L -o /tmp/zig.tar.xz "https://ziglang.org/download/${{ needs.test.outputs.zig_version }}/zig-x86_64-freebsd-${{ needs.test.outputs.zig_version }}.tar.xz" && \
+ # mkdir /opt && \
+ # tar -xf /tmp/zig.tar.xz -C /opt && \
+ # rm /tmp/zig.tar.xz && \
+ # ln -s "/opt/zig-x86_64-freebsd-${{ needs.test.outputs.zig_version }}/zig" /usr/local/bin/zig
+ #
+ # run: |
+ # zig env
+ #
+ # - name: Run tests
+ # shell: freebsd {0}
+ # run: |
+ # cd $GITHUB_WORKSPACE
+ # zig build test
+ #
+ # - name: Build GTK app runtime
+ # shell: freebsd {0}
+ # run: |
+ # cd $GITHUB_WORKSPACE
+ # zig build
+ # ./zig-out/bin/ghostty +version
diff --git a/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml b/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml
new file mode 100644
index 00000000..4c9ff66f
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/update-colorschemes.yml
@@ -0,0 +1,96 @@
+name: Update iTerm2 colorschemes
+on:
+ schedule:
+ # Once a week
+ - cron: "0 0 * * 0"
+ workflow_dispatch:
+jobs:
+ update-iterm2-schemes:
+ if: github.repository == 'ghostty-org/ghostty'
+ runs-on: namespace-profile-ghostty-sm
+ permissions:
+ # Needed for create-pull-request action
+ contents: write
+ pull-requests: write
+ env:
+ ZIG_LOCAL_CACHE_DIR: /zig/local-cache
+ ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: 0
+
+ - name: Setup Cache
+ uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
+ with:
+ path: |
+ /nix
+ /zig
+
+ - name: Setup Nix
+ uses: cachix/install-nix-action@96951a368ba55167b55f1c916f7d416bac6505fe # v31.10.3
+ with:
+ nix_path: nixpkgs=channel:nixos-unstable
+ - uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
+ with:
+ name: ghostty
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+
+ - name: Download colorschemes
+ id: download
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: |
+ # Get the latest release from iTerm2-Color-Schemes
+ RELEASE_INFO=$(gh api repos/mbadolato/iTerm2-Color-Schemes/releases/latest)
+ TAG_NAME=$(echo "$RELEASE_INFO" | jq -r '.tag_name')
+ FILENAME="ghostty-themes-${TAG_NAME}.tgz"
+ mkdir -p upload
+ curl -L -o "upload/${FILENAME}" "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/${TAG_NAME}/ghostty-themes.tgz"
+ echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
+ echo "filename=$FILENAME" >> $GITHUB_OUTPUT
+
+ - name: Upload to R2
+ uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
+ with:
+ r2-account-id: ${{ secrets.CF_R2_DEPS_ACCOUNT_ID }}
+ r2-access-key-id: ${{ secrets.CF_R2_DEPS_AWS_KEY }}
+ r2-secret-access-key: ${{ secrets.CF_R2_DEPS_SECRET_KEY }}
+ r2-bucket: ghostty-deps
+ source-dir: upload
+ destination-dir: ./
+
+ - name: Run zig fetch
+ run: |
+ nix develop -c zig fetch --save="iterm2_themes" "https://deps.files.ghostty.org/${{ steps.download.outputs.filename }}"
+
+ - name: Update zig cache hash
+ run: |
+ # Only proceed if build.zig.zon has changed
+ if ! git diff --exit-code build.zig.zon; then
+ nix develop -c ./nix/build-support/check-zig-cache.sh --update
+ nix develop -c ./nix/build-support/check-zig-cache.sh
+ fi
+
+ # Verify the build still works. We choose an arbitrary build type
+ # as a canary instead of testing all build types.
+ - name: Test Build
+ run: nix build .#ghostty
+
+ - name: Create pull request
+ uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
+ with:
+ title: Update iTerm2 colorschemes
+ base: main
+ branch: iterm2_colors_action
+ commit-message: "deps: Update iTerm2 color schemes"
+ add-paths: |
+ build.zig.zon
+ build.zig.zon.nix
+ build.zig.zon.txt
+ build.zig.zon.json
+ flatpak/zig-packages.json
+ body: |
+ Upstream release: https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/${{ steps.download.outputs.tag_name }}
+ labels: dependencies
diff --git a/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml b/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml
new file mode 100644
index 00000000..d0456b00
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/vouch-check-issue.yml
@@ -0,0 +1,22 @@
+on:
+ issues:
+ types: [opened, reopened]
+
+name: "Vouch - Check Issue"
+
+jobs:
+ check:
+ runs-on: namespace-profile-ghostty-xsm
+ steps:
+ - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
+ id: app-token
+ with:
+ app-id: ${{ secrets.VOUCH_APP_ID }}
+ private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
+
+ - uses: mitchellh/vouch/action/check-issue@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
+ with:
+ issue-number: ${{ github.event.issue.number }}
+ auto-close: true
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/vendor/libghostty-vt/.github/workflows/vouch-check-pr.yml b/vendor/libghostty-vt/.github/workflows/vouch-check-pr.yml
new file mode 100644
index 00000000..0602553c
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/vouch-check-pr.yml
@@ -0,0 +1,22 @@
+on:
+ pull_request_target:
+ types: [opened, reopened]
+
+name: "Vouch - Check PR"
+
+jobs:
+ check:
+ runs-on: namespace-profile-ghostty-xsm
+ steps:
+ - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
+ id: app-token
+ with:
+ app-id: ${{ secrets.VOUCH_APP_ID }}
+ private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
+
+ - uses: mitchellh/vouch/action/check-pr@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
+ with:
+ pr-number: ${{ github.event.pull_request.number }}
+ auto-close: true
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml
new file mode 100644
index 00000000..7288c4ab
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-discussion.yml
@@ -0,0 +1,35 @@
+on:
+ discussion_comment:
+ types: [created]
+
+name: "Vouch - Manage by Discussion"
+
+concurrency:
+ group: vouch-manage
+ cancel-in-progress: false
+
+jobs:
+ manage:
+ runs-on: namespace-profile-ghostty-xsm
+ steps:
+ - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
+ id: app-token
+ with:
+ app-id: ${{ secrets.VOUCH_APP_ID }}
+ private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
+
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ token: ${{ steps.app-token.outputs.token }}
+
+ - uses: mitchellh/vouch/action/manage-by-discussion@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
+ with:
+ discussion-number: ${{ github.event.discussion.number }}
+ comment-node-id: ${{ github.event.comment.node_id }}
+ vouch-keyword: "!vouch"
+ denounce-keyword: "!denounce"
+ unvouch-keyword: "!unvouch"
+ pull-request: "true"
+ merge-immediately: "true"
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml
new file mode 100644
index 00000000..6f61592f
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/vouch-manage-by-issue.yml
@@ -0,0 +1,36 @@
+on:
+ issue_comment:
+ types: [created]
+
+name: "Vouch - Manage by Issue"
+
+concurrency:
+ group: vouch-manage
+ cancel-in-progress: false
+
+jobs:
+ manage:
+ runs-on: namespace-profile-ghostty-xsm
+ steps:
+ - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
+ id: app-token
+ with:
+ app-id: ${{ secrets.VOUCH_APP_ID }}
+ private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
+
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ token: ${{ steps.app-token.outputs.token }}
+
+ - uses: mitchellh/vouch/action/manage-by-issue@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
+ with:
+ repo: ${{ github.repository }}
+ issue-id: ${{ github.event.issue.number }}
+ comment-id: ${{ github.event.comment.id }}
+ vouch-keyword: "!vouch"
+ denounce-keyword: "!denounce"
+ unvouch-keyword: "!unvouch"
+ pull-request: "true"
+ merge-immediately: "true"
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml b/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml
new file mode 100644
index 00000000..0879c972
--- /dev/null
+++ b/vendor/libghostty-vt/.github/workflows/vouch-sync-codeowners.yml
@@ -0,0 +1,32 @@
+on:
+ schedule:
+ - cron: "0 0 * * 1" # Every Monday at midnight UTC
+ workflow_dispatch:
+
+name: "Vouch - Sync CODEOWNERS"
+
+concurrency:
+ group: vouch-manage
+ cancel-in-progress: false
+
+jobs:
+ sync:
+ runs-on: namespace-profile-ghostty-xsm
+ steps:
+ - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
+ id: app-token
+ with:
+ app-id: ${{ secrets.VOUCH_APP_ID }}
+ private-key: ${{ secrets.VOUCH_APP_PRIVATE_KEY }}
+
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ token: ${{ steps.app-token.outputs.token }}
+
+ - uses: mitchellh/vouch/action/sync-codeowners@c6d80ead49839655b61b422700b7a3bc9d0804a9 # v1.4.2
+ with:
+ repo: ${{ github.repository }}
+ pull-request: "true"
+ merge-immediately: "true"
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}