An app for all my recommendations + history of places I've been, things I've read, etc, work in progress
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A native Swift app (iOS, macOS) for keeping track of what I've read, watched, played, and experienced. The vision is a personal knowledge base with full editing capabilities, synced via Contentful.
./run bootstrap # first time (before shell function exists)
source ~/.zshrc # activate completions
Bootstrap handles all one-time setup:
brew bundle: 1Password CLI, swift-format)Config.xcconfig with Contentful credentials from the saga vault (CONTENTFUL_SPACE_ID and CONTENTFUL_ACCESS_TOKEN items).zshrc for the run commandAfter setup, use run (with tab completion) instead of ./run. Re-run bootstrap any time to refresh credentials.
Saga follows an MVVM architecture with SwiftUI views:
NavigationHistory with a home-based sidebar layoutSwift-based scripts live in scripts/Sources/ and are run via the run wrapper at the repo root. Use run --help to see available scripts, or run <script> --help for script-specific options.
| Script | Description |
|---|---|
app | Build, launch, or run unit tests |
bootstrap | Set up shell completions and pull secrets from 1Password |
config | Write Config.xcconfig from the environment |
checks | Run Swift format and/or lint checks |
clean | Remove build artifacts and SwiftPM build caches |
version-and-release | Manage version tags and Github releases |
Saga is a plain SwiftPM package (Package.swift at the repo root); there is no Xcode project.
scripts/build-macos.sh runs swift build, compiles Saga.xcdatamodeld (momc) and the asset
catalogs (actool), embeds Sparkle, writes Info.plist, and ad-hoc signs build/Saga.app.
momc and actool ship with Xcode, so Xcode must be installed and selected (xcode-select),
but you never open it.
run app # build build/Saga.app (debug) and launch it in the background
run app -b # build only
run app -r # release configuration
run app -t # swift test
run app --ui # iOS Simulator screenshots of the main screens into build/captures/
run app --help # show usage
scripts/build-ios-sim.sh [--install] # build/Saga-iOS.app for the iOS Simulator
Build settings live where SwiftPM and the scripts can read them: bundle ID and minimum OS in
scripts/lib/app-config.sh, the marketing version in VERSION, entitlements in
Saga.entitlements, and the Sparkle public key in sparkle-public-key.txt.
All Swift code is formatted and linted using swift-format with the repo config in .swift-format.
run checks # format and lint
run checks --format # format only
run checks --lint # lint only
run checks --help # show usage
CI runs this on every PR and fails if formatting produces any changes.
When adding a new Core Data model:
Saga.xcdatamodeldapply(_:) mapping@objc(EntityName) so the unqualified representedClassName resolvesGitHub Actions automatically compute versions and create releases when PRs merge to main:
# What changed? section for release notesrelease.yml computes the next semantic version and Sparkle build number from the latest release tag and PR release type, packages and signs the macOS app, checks it is a valid Sparkle update for the latest published release (scripts/verify-release.sh, also run on every PR), updates appcast.xml with cumulative versioned release notes (capped at the last 10 versions via scripts/release-notes.sh and scripts/generate-appcast.sh), and publishes a GitHub Release using the # What changed? text as release notes. Nothing is committed back to main: https://saga.gattey.com/appcast.xml, the feed the app polls, redirects to the latest release's appcastShouldn't be necessary, but you can run version-and-release for manual version management (see --help for subcommands).