diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/.github | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/.github')
24 files changed, 4092 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml new file mode 100644 index 00000000..270bb86f --- /dev/null +++ b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/issue-triage.yml @@ -0,0 +1,162 @@ +labels: ["needs-confirmation"] +body: + - type: markdown + attributes: + value: | + > [!IMPORTANT] + > Please read through [the Discussion rules](https://github.com/ghostty-org/ghostty/discussions/6937), review [the FAQs](https://ghostty.org/docs/help#common-issues-and-solutions), and check for both existing [Discussions](https://github.com/ghostty-org/ghostty/discussions?discussions_q=) and [Issues](https://github.com/ghostty-org/ghostty/issues?q=sort%3Areactions-desc) prior to opening a new Discussion. + - type: markdown + attributes: + value: "# Issue Details" + - type: textarea + attributes: + label: Issue Description + description: | + Provide a detailed description of the issue. Include relevant information, such as: + - The feature or configuration option you encounter the issue with. + - Screenshots, screen recordings, or other supporting media (as needed). + - If this is a regression of an existing issue that was closed or resolved, please include the previous item reference (Discussion, Issue, PR, commit) in your description. + + > [!TIP] + > **Not sure what information to include?** + > Here are some recommendations: + > - **Input issues:** include your keyboard layout, a screenshot of logged keystrokes from the terminal inspector's "Keyboard" tab (Linux: <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>i</kbd>; MacOS: <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>i</kbd>), input method, Linux input method engine (IBus, Fcitx 5, or none) and its version. + > - **Font issues:** include the problematic character(s), the output of `ghostty +show-face` for these character(s), and if they work in other applications. + > - **Terminal emulation issues (including image rendering issues):** attach an [asciinema](https://docs.asciinema.org/getting-started/) cast file, shell script, or text file for reproduction. + > - **Renderer issues:** (Linux) include your OpenGL version, graphics card, driver version. + > - **Crashes:** (macOS) include the [Sentry UUID](https://github.com/ghostty-org/ghostty?tab=readme-ov-file#crash-reports); (Linux) try to reproduce using a debug build and provide the stack trace. + placeholder: | + When using SSH to connect to my remote Linux machine from my local macOS device in Ghostty, I try to run `clear`, and the screen does not clear. Instead, I see the following error message printed to the terminal: `Error opening terminal: xterm-ghostty.` + validations: + required: true + - type: textarea + attributes: + label: Expected Behavior + description: | + Describe how you expect Ghostty to behave in this situation. Include any relevant documentation links. + placeholder: | + The screen is cleared and the prompt is redrawn at the top of the window. + validations: + required: true + - type: textarea + attributes: + label: Actual Behavior + description: | + Describe how Ghostty actually behaves in this situation. If it is not immediately obvious how the actual behavior differs from the expected behavior described above, please be sure to mention the deviation specifically. + placeholder: | + The screen is not cleared, and an error is printed: `Error opening terminal: xterm-ghostty`. + validations: + required: true + - type: textarea + attributes: + label: Reproduction Steps + description: | + Provide a detailed set of step-by-step instructions for reproducing this issue. + placeholder: | + 1. Open Ghostty. + 2. Connect to a remote server via SSH. + 3. Try to execute `clear`. + 4. Observe `xterm-ghostty` error message above. + validations: + required: true + - type: textarea + attributes: + label: Ghostty Logs + description: | + Provide any captured Ghostty logs or stacktraces during your issue reproduction in this field. On Linux, logs can be found by running `ghostty` from the command-line; on macOS, logs can be viewed with `sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'` from another terminal emulator. + render: text + - type: textarea + attributes: + label: Ghostty Version + description: Paste the output of `ghostty +version` here. + placeholder: | + Ghostty 1.1.3 + + Version + - version: 1.1.3 + - channel: stable + Build Config + - Zig version: 0.13.0 + - build mode : builtin.OptimizeMode.ReleaseFast + - app runtime: apprt.Runtime.none + - font engine: font.main.Backend.coretext + - renderer : renderer.Metal + - libxev : main.Backend.kqueue + render: text + validations: + required: true + - type: input + attributes: + label: OS Version Information + description: | + Please tell us what operating system (name and version) you are using. + placeholder: Ubuntu 24.04.1 (Noble Numbat) + validations: + required: true + - type: dropdown + attributes: + label: (Linux only) Display Server + description: | + If you run Linux, please tell us if you use X11 or Wayland. If you aren't sure, you can determine this by running `[ -z "$WAYLAND_DISPLAY" ] && echo X11 || echo Wayland`. + options: + - X11 + - Wayland + - Other + validations: + required: false + - type: input + attributes: + label: (Linux only) Desktop Environment/Window Manager + description: | + If you run Linux, please tell us what Desktop Environment/Window Manager you are using (include the name and version). + placeholder: GNOME 47.4 + validations: + required: false + - type: textarea + attributes: + label: Minimal Ghostty Configuration + description: | + Please provide the **minimum** configuration needed to reproduce this issue. If you can still reproduce the issue with one of the lines removed, do not include that line. If and **only** if you are not able to determine this, paste the contents of your Ghostty configuration file here. + placeholder: | + font-family = CommitMono Nerd Font + font-family-bold = CommitMono Nerd Font + font-family-italic = CommitMono Nerd Font + font-family-bold-italic = CommitMono Nerd Font + font-feature = +cv07 + font-size = 16 + font-thicken = true + theme = catppuccin-mocha + render: ini + validations: + required: true + - type: textarea + attributes: + label: Additional Relevant Configuration + description: | + If your issue involves other programs, tools, or applications in addition to Ghostty (e.g. Neovim, tmux, Zellij, etc.), please provide the minimum configuration and versions needed for all relevant programs to reproduce the issue here. If you use custom CSS or shaders for Ghostty, also include them here, if applicable to your issue. + placeholder: | + #### `tmux.conf` (tmux 3.5a) + ``` + set -g default-terminal "tmux-256color" + set-option -sa terminal-overrides ",xterm*:Tc" + set -g base-index 1 + setw -g pane-base-index 1 + ``` + validations: + required: false + - type: markdown + attributes: + value: | + # User Acknowledgements + > [!TIP] + > Use these links to review the existing Ghostty [Discussions](https://github.com/ghostty-org/ghostty/discussions?discussions_q=) and [Issues](https://github.com/ghostty-org/ghostty/issues?q=sort%3Areactions-desc). + - type: checkboxes + attributes: + label: "I acknowledge that:" + options: + - label: I have reviewed the FAQ and confirm that my issue is NOT among them. + required: true + - label: I have searched the Ghostty repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion. + required: true + - label: I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (` ``` `) on separate lines. + required: true diff --git a/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/vouch-request.yml b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/vouch-request.yml new file mode 100644 index 00000000..c243f0f8 --- /dev/null +++ b/vendor/libghostty-vt/.github/DISCUSSION_TEMPLATE/vouch-request.yml @@ -0,0 +1,42 @@ +body: + - type: markdown + attributes: + value: | + > [!IMPORTANT] + > This form is for **first-time contributors** who need to be vouched before submitting pull requests. Please read the [Contributing Guide](https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md) and [AI Usage Policy](https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md) before submitting. + > + > Keep your request **concise** and write it **in your own voice** — do not have an AI write this for you. A maintainer will comment `!vouch` if your request is approved, after which you can submit PRs. + - type: textarea + attributes: + label: What do you want to change? + description: | + Describe the change you'd like to make to Ghostty. If there is an existing issue or discussion, link to it. + placeholder: | + I'd like to fix the rendering issue described in #1234 where... + validations: + required: true + - type: textarea + attributes: + label: Why do you want to make this change? + description: | + Explain your motivation. Why is this change important or useful? + placeholder: | + This bug affects users who... + validations: + required: true + - type: checkboxes + attributes: + label: "I acknowledge that:" + options: + - label: >- + I have read the [Contributing Guide](https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md) + and understand the contribution process. + required: true + - label: >- + I have read and agree to follow the + [AI Usage Policy](https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md). + required: true + - label: >- + I wrote this vouch request myself, in my + own voice, without AI generating it. + required: true diff --git a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..9c4455c4 --- /dev/null +++ b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Features, Bug Reports, Questions + url: https://github.com/ghostty-org/ghostty/discussions/new/choose + about: Our preferred starting point if you have any questions or suggestions about configuration, features or behavior. diff --git a/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md new file mode 100644 index 00000000..485e727e --- /dev/null +++ b/vendor/libghostty-vt/.github/ISSUE_TEMPLATE/preapproved.md @@ -0,0 +1,9 @@ +--- +name: Pre-Discussed and Approved Topics +about: |- + Only for topics already discussed and approved in the GitHub Discussions section. +--- + +**DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.** + +**I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.** diff --git a/vendor/libghostty-vt/.github/VOUCHED.td b/vendor/libghostty-vt/.github/VOUCHED.td new file mode 100644 index 00000000..1438c2f7 --- /dev/null +++ b/vendor/libghostty-vt/.github/VOUCHED.td @@ -0,0 +1,211 @@ +# The list of vouched (or actively denounced) users for this repository. +# +# The high-level idea is that only vouched users can participate in +# contributing to this project. And a denounced user is explicitly +# blocked from contributing (issues, PRs, etc. auto-closed). +# +# We choose to maintain a denouncement list rather than or in addition to +# using the platform's block features so other projects can slurp in our +# list of denounced users if they trust us and want to adopt our prior +# knowledge about bad actors. +# +# Syntax: +# - One handle per line (without @). Sorted alphabetically. +# - Optionally specify platform: `platform:username` (e.g., `github:mitchellh`). +# - To denounce a user, prefix with minus: `-username` or `-platform:username`. +# - Optionally, add comments after a space following the handle. +# +# Maintainers can vouch for new contributors by commenting "!vouch" on a +# discussion by the author. Maintainers can denounce users by commenting +# "!denounce" or "!denounce [username]" on a discussion. +00-kat +04cb +aalhendi +abdurrahmanski +abudvytis +adrum +aindriu80 +alaasdk +alanmoyano +alexfeijoo44 +alexjuca +alosarjos +amadeus +andrejdaskalov +anhthang +anmitalidev +anthonyzhoon +atomk +balazs-szucs +barutsrb +bennettp123 +benodiwal +bernsno +beryesa +bitigchi +bkircher +bo2themax +brentschroeter +brianc442 +cespare +charliie-dev +chernetskyi +chronologos +cmwetherell +crayxt +craziestowl +curtismoncoq +d-dudas +-daedaevibin +daiimus +damyanbogoev +danneu +danulqua +dariogriffo +davidsanchez222 +deblasis +dervedro +devsunb +diaaeddin +dmehala +doprz +douglance +douglas +douglas-macgregor +drepper +dzhlobo +ekaterinepapava +elias8 +ephemera +eriksremess +faukah +filip7 +flou +francescarpi +gagbo +ghokun +gmile +gordonbondon +gpanders +guilhermetk +h3nock +hakonhagland +halosatrio +heaths +heddxh heddxh +-highimpact-dev Disrespectful AI user +hlcfan +hqnna +hulet +i999rri +icodesign +j0hnm4r5 +jacobsandlund +jake-stewart +jarred-sumner +jcollie +jesusvazquez +jguthmiller +jmcgover +johnslavik +jordandm +josephmart +jparise +juniqlim +justonia +karesansui-u +kawarimidoll +kenvandine +khipp +kirwiisp +kjvdven +kloneets +-kody-w +koranir +kristina8888 +kristofersoler +laxystem +liby +linustalacko +lonsagisawa +louisunlimited +luisnquin +lynicis +mac0ne +mahnokropotkinvich +marijagjorgjieva +markdorison +markhuot +marler8997 +marrocco-simone +matkotiric +micaeljarniac +michielvk +miguelelgallo +mihi314 +mikailmm +misairuzame +mischief +mitchellh +miupa +molechowski +mrconnorkenway +mrmage +mtak +natesmyth +neo773 +nicholas-ochoa +nicosuave +nmggithub +noib3 +nwehg +ocean6954 +oshdubh +paaloeye +pan93412 +pangoraw +pauley-unsaturated +peilingjiang +peterdavehello +philocalyst +phush0 +piedrahitac +pluiedev +pouwerkerk +poweruser64 +prakhar54-byte +priyans-hu +puzza007 +qwerasd205 +reo101 +rgehan +rhodes-b +rmengelbrecht +rmunn +rockorager +rpfaeffle +secrus +seruman +silveirapf +slsrepo +sunshine-syz +tdgroot +tdslot +ticclick +tnagatomi +trag1c +tristan957 +turbolent +tweedbeetle +uhojin +unphased +uzaaft +vaughanandrews +viruslobster +vlsi +wyounas +yabbal +yamshta +ydah +zenyr +zeshi09 diff --git a/vendor/libghostty-vt/.github/dependabot.yml b/vendor/libghostty-vt/.github/dependabot.yml new file mode 100644 index 00000000..012385d7 --- /dev/null +++ b/vendor/libghostty-vt/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" diff --git a/vendor/libghostty-vt/.github/pinact.yml b/vendor/libghostty-vt/.github/pinact.yml new file mode 100644 index 00000000..3a29d18a --- /dev/null +++ b/vendor/libghostty-vt/.github/pinact.yml @@ -0,0 +1,4 @@ +version: 3 +ignore_actions: + - name: "DeterminateSystems/nix-installer-action" + ref: "main" diff --git a/vendor/libghostty-vt/.github/scripts/check-translations.sh b/vendor/libghostty-vt/.github/scripts/check-translations.sh new file mode 100755 index 00000000..cd918fdd --- /dev/null +++ b/vendor/libghostty-vt/.github/scripts/check-translations.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +old_pot=$(mktemp) +cp po/com.mitchellh.ghostty.pot "$old_pot" +zig build update-translations + +# Compare previous POT to current POT +msgcmp "$old_pot" po/com.mitchellh.ghostty.pot --use-untranslated + +# Compare all other POs to current POT +for f in po/*.po; do + # Ignore untranslated entries + msgcmp --use-untranslated "$f" po/com.mitchellh.ghostty.pot; +done diff --git a/vendor/libghostty-vt/.github/scripts/ghostty-tip b/vendor/libghostty-vt/.github/scripts/ghostty-tip new file mode 100755 index 00000000..8b577bca --- /dev/null +++ b/vendor/libghostty-vt/.github/scripts/ghostty-tip @@ -0,0 +1,19 @@ +#!/usr/bin/env nu + +# Check if a given commit SHA has a corresponding tip release. +# +# This does not validate that the commit SHA is valid for the +# Ghostty repository, only that a tip release exists for it. +def main [ + commit: string, # The full length commit SHA +] { + let url = $"https://tip.files.ghostty.org/($commit)/ghostty-macos-universal.zip" + + try { + http head $url + exit 0 + } catch { + print -e $"The SHA ($commit) does not have a corresponding tip release." + exit 1 + } +} 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 }} |
