gbar is a single-target SwiftUI menu bar app: Swift 6 with strict concurrency, macOS 14+, built with Tuist and driven by a justfile. Checkout to a running app is four commands.
Prerequisites
- Xcode with the macOS 14 SDK
- mise, which pins the toolchain from
.mise.toml(Tuist, Swift 6, typos);mise installin the repo brings in the exact versions CI uses - just, installed with
brew install just; run barejustto list every recipe
Clone and run
git clone https://github.com/jaylann/gbar && cd gbar
just bootstrap # wire git hooks + materialize local xcconfigs
just gen # tuist install + generate the Xcode project
just run # build and launchbootstrap wires the tracked git hooks (a commit-msg hook validates Conventional Commits) and materializes the gitignored Tuist xcconfigs from templates. The OAuth client ID stays blank, so your build prompts at runtime, exactly like the self-host setup. The committed signing defaults are ad-hoc and teamless: a fresh clone builds with no Apple Developer account.
The day-to-day loop is a handful of recipes:
| Recipe | Does |
|---|---|
just run | Build and launch the app |
just test | Full unit test suite |
just check | SwiftFormat + SwiftLint + spellcheck, the same set CI runs |
just dmg | Release .dmg into dist/, ad-hoc signed |
A locally built
.dmgis not notarized, so first launch needs right-click → Open. Only the release pipeline produces the signed, stapled build.
Project layout
| Path | What lives there |
|---|---|
gbar/Sources/ | App code: Auth, GitHub, Menu, Model, Notifications, Settings, Store, Design |
gbarTests/ | Unit tests |
Project.swift | Tuist manifest: version, signing, Info.plist config |
justfile | Every dev task, one verb each |
Contributing
Branch off stage (main is release-only) with a type/slug name like fix/menu-flicker. PRs into stage are squash-merged, so the PR title must be a Conventional Commit. Run just check and just test before pushing; CI runs the same set. Full details in CONTRIBUTING.md.
Just want the app? Getting started installs the signed build in a minute.