Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/publish-ghostty-flatpak.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Publish Ghostty Flatpak

# Republish stock upstream Ghostty (com.mitchellh.ghostty) onto the TunaOS
# Flatpak remote, alongside BlueShell. No TunaOS patches: the app is built
# from a clean checkout of ghostty-org/ghostty using *upstream's own*
# manifest, dependencies.yml and zig-packages.json, so upstream dependency
# and runtime bumps need no change in this repo.
#
# Because the app IDs differ (com.mitchellh.ghostty vs org.tunaos.BlueShell),
# a user can install both side by side from the one remote.
#
# This lives in blueshell rather than in a tuna-os/ghostty fork because a
# fork would be a repo whose only original content is this file, with a
# second FLATPAK_INDEX_TOKEN to provision and an upstream-sync mechanism to
# maintain. The registry path and index entry are still ghostty's own
# (tuna-os/ghostty), separate from blueshell's.
#
# The body is the canonical tuna-os pipeline in tuna-os/.github, the same
# reusable workflow finupdate, mariner, mandelbrot, dualcut and the four
# installer frontends call. This file is only the trigger policy.

on:
schedule:
# Sundays 05:00 UTC. Weekly rather than daily because the reusable
# pipeline has no "upstream unchanged" short-circuit -- every run is two
# full Zig builds (x86_64 + aarch64, ~11 min each), and a republished
# upstream terminal does not need same-day freshness. Dispatch the
# workflow to pull in a specific upstream commit sooner.
- cron: '0 5 * * 0'
workflow_dispatch:
inputs:
source-ref:
description: 'Ghostty ref to build (branch, tag or SHA). Empty = ghostty-org/ghostty default branch.'
required: false
type: string
default: ''

permissions:
contents: read
packages: write

jobs:
publish:
# Forks don't publish. A fork running this on dispatch would push to its
# own ghcr namespace, and -- if it also carried FLATPAK_INDEX_TOKEN --
# would write an image nobody in the org built into the shared index.
if: github.repository == 'tuna-os/blueshell'
uses: tuna-os/.github/.github/workflows/publish-flatpak.yml@main
with:
app-id: com.mitchellh.ghostty
manifest-path: flatpak/com.mitchellh.ghostty.yml
# Registry path and central-index entry, deliberately not this repo:
# ghcr.io/tuna-os/ghostty, so it doesn't collide with blueshell's own
# entry. The package is created under the org by this repo's
# GITHUB_TOKEN and must be made public once, by hand, after the first
# successful run -- a private package fails to install exactly like a
# missing one.
repo-name: tuna-os/ghostty
source-repo: ghostty-org/ghostty
source-ref: ${{ inputs.source-ref }}
# No bundles on the GitHub release: these are upstream's builds, and
# this repo's releases are BlueShell's.
attach-bundles: false
secrets: inherit
94 changes: 72 additions & 22 deletions docs/TUNA_OS_PROMOTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,38 +92,88 @@ flatpak remote-add --if-not-exists tuna-os https://tunaos.org/flatpak/tuna-os.fl
flatpak install tuna-os org.tunaos.BlueShell
```

Status: ✅ live. `app/org.tunaos.BlueShell/{x86_64,aarch64}/master` is in
`tuna-os/docs:static/flatpak/index/static` and every push to `ptyxis-port`
refreshes it.

## 3b. Stock upstream Ghostty in the same remote

The remote also carries unmodified upstream Ghostty
(`com.mitchellh.ghostty`), published by
`.github/workflows/publish-ghostty-flatpak.yml`. That file is trigger
policy only — the body is the same reusable
`tuna-os/.github/.github/workflows/publish-flatpak.yml` every other
tuna-os app calls. Three things differ from BlueShell's own publish:

- It builds from a clean checkout of `ghostty-org/ghostty` (the reusable
workflow's `source-repo` input) using **upstream's own** manifest,
`dependencies.yml` and `zig-packages.json`. Nothing about the app is
vendored here, so upstream dependency and runtime bumps need no action
in this repo.
- It runs weekly (Sundays 05:00 UTC) plus `workflow_dispatch`, rather
than on push. The reusable pipeline has no "upstream unchanged"
short-circuit, so every run is two full Zig builds.
- It publishes to `ghcr.io/tuna-os/ghostty` and gets its own index
entry, separate from blueshell's.

Two traps worth knowing, because both were nearly landmines:

- Upstream's manifest sets `default-branch: tip`, but the remote's
`tuna-os.flatpakrepo` declares `DefaultBranch=master` — a `tip` ref
would make `flatpak install tuna-os com.mitchellh.ghostty` fail with
"Nothing matches" (the 2026-07-27 incident, which
`check-flatpak-remote.py` exists to catch). No patch is needed:
flatpak-builder resolves the branch as manifest `branch:` →
`--default-branch` → manifest `default-branch:`, and
`flatpak-github-actions` always passes `--default-branch=master`. The
ref published is `master`. Keep that in mind before "simplifying" the
build away from that action.
- The GHCR package must be made **public** by hand after the first
successful run. A private package fails to install exactly like a
missing one.

## 4. tunaos.org site listing + install instructions

Being installable is not the finish line — the app must be discoverable:

1. **tunaos.org listing**: the site is a Docusaurus build from
`tuna-os/docs` with one `docs/<app>/index.md` page per app. A
ready-to-copy BlueShell page in the finupdate page's format lives at
[`docs/site/blueshell/index.md`](site/blueshell/index.md) in this
repo — PR it to `tuna-os/docs:docs/blueshell/index.md` (add a
`sidebars.ts` entry if pages aren't auto-discovered). Short blurb if
an apps-overview list also needs a row:

> **BlueShell** — container-native terminal for GNOME. Ptyxis's
> container-first UX (Toolbox / Distrobox / Podman tabs, profiles,
> preferences) powered by the Ghostty rendering engine (GPU
> acceleration, Kitty graphics, ligatures, splits).
>
> `flatpak install tuna-os org.tunaos.BlueShell`

Include a screenshot from the CI `ui-walkthrough` artifact
(`02-prefs-appearance.png` shows the app best) and a link back to
`tuna-os/blueshell`.
1. **tunaos.org listing** — the site is a Docusaurus build from
`tuna-os/docs`, and an app is listed in more places than one page:

- `src/data/projects.ts` — drives the `/projects` card, the `/<app>`
landing page and `/install?app=<id>`.
- `src/pages/<app>.tsx` — a thin wrapper over `ProjectLanding`.
- `docs/<app>/index.md` — the reference page.
- `sidebars.ts` — the entry under **Apps**.
- `src/pages/flatpak.tsx` and `docs/flatpak/index.mdx` — both install
catalogs.

One trap: `tuna-os/docs` runs `scripts/sync-org-docs.mjs`, which
overwrites `docs/<slug>/` from each org repo's README
unconditionally — and `docs/blueshell/` is such a tree. Both slugs
have to be in that script's `HAND_AUTHORED` set or the next sync
reverts the page.

`docs/site/blueshell/index.md` in this repo was the original draft for
that page. The published copy lives in `tuna-os/docs` and has moved on
from it; treat the local file as history rather than a source to
re-copy.

Still worth adding: a screenshot from the CI `ui-walkthrough` artifact
(`02-prefs-appearance.png` shows the app best).

2. **README install instructions**: ✅ DONE — the "available once…"
note is gone and the remote is the recommended path.

## 5. Post-promotion checklist

- [x] `ptyxis-tests` and `ghostty-ptyxis` (bundle) workflows green in the org repo
- [x] `publish-flatpak` run pushed an image to `ghcr.io/tuna-os/blueshell` and the index PR/commit landed in `tuna-os/docs`
- [ ] Fresh-machine install from the remote verified (`flatpak install tuna-os org.tunaos.BlueShell`)
- [x] `publish-flatpak` run pushed an image to `ghcr.io/tuna-os/blueshell` and the index commit landed in `tuna-os/docs`
- [x] BlueShell present in the remote index as `app/org.tunaos.BlueShell/{x86_64,aarch64}/master`
- [x] README install section switched to the remote as the primary path (the rolling `tip` release is the "bleeding edge" alternative)
- [ ] tunaos.org apps page lists BlueShell with install command + screenshot (PR to `tuna-os/docs`)
- [ ] `upstream-sync.yml` weekly run confirmed working under the org (issue/PR creation permissions)
- [x] `upstream-sync.yml` failure fixed — the `upstream-sync` label does not survive a repo transfer, and every weekly run since 2026-08-17 failed at `gh issue create --label upstream-sync`. Label recreated 2026-09-06.
- [ ] Ghostty: first `publish-ghostty-flatpak` run green, `ghcr.io/tuna-os/ghostty` package made **public**, index entry confirmed
- [ ] Fresh-machine install of both verified: `flatpak install tuna-os org.tunaos.BlueShell` and `flatpak install tuna-os com.mitchellh.ghostty`
- [ ] tunaos.org site PR merged (section 4) — do this *after* the install check, since the pages present both commands as working
- [ ] Both apps added to `tuna-os/docs:static/flatpak/expected-apps.json` with `archs: ["amd64", "arm64"]`. Deliberately last: `check-flatpak-remote.py` fails on an app listed there but absent from the index, so this turns a standing warning into a real check only once the entries exist.
- [ ] `hanthor/blueshell` fork archived, its PR closed
- [ ] Old repo redirect verified; announce the move in tunaOS channels
Loading