Maintaining¶
How to keep the repository healthy and ship PlexusOne Desktop releases. For setting up a development environment and making changes, see Contributing.
Documentation layout¶
The MkDocs site is built from docs/, with the navigation in mkdocs.yml.
| Directory | Contents |
|---|---|
docs/guides/ |
User guides (getting started, desktop, mobile, reference) and developer guides (development/) |
docs/design/architecture/ |
How the system is built |
docs/design/adrs/ |
Architecture decision records, one decision per numbered file |
docs/specs/ |
PRD, TRD, feature specs (features/), and initiative roadmaps (initiatives/) |
docs/releases/ |
Release notes per version and the generated changelog |
docs/images/ |
Screenshots and images |
Check the site before committing documentation changes. --strict fails on
broken links:
Everyday checks¶
Run the checks for each component you changed:
# Desktop (Swift)
cd apps/desktop && swift build && swift test
# Native iOS
cd apps/ios && xcodebuild -project PlexusOneiOS.xcodeproj -scheme PlexusOneiOS \
-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' build
# Flutter
cd apps/flutter && flutter analyze && flutter test
# TUI Parser (Go)
cd services/tuiparser && go build ./... && go test ./... && golangci-lint run
Continuous integration¶
| Workflow | Runs on | Builds with | Does |
|---|---|---|---|
Desktop CI (desktop.yaml) |
Pushes and pull requests to main that touch apps/desktop/ |
The shared org Swift workflow, on a macOS 26 runner with the latest stable Xcode | Builds and tests the desktop app |
Desktop Release (desktop-release.yaml) |
v* tags, or a manual run |
macos-26 runners (Xcode 26) |
Builds, signs, and packages the DMGs; on a tag, publishes the GitHub release |
The two workflows use different Xcode versions. Desktop CI is the stricter check for Swift language and dependency support; the release workflow is the one that produces what users install.
Dependencies¶
Dependabot opens weekly pull requests for the desktop and iOS Swift packages,
the Flutter app, the Go service, and GitHub Actions (.github/dependabot.yml).
- SwiftTerm is pinned to an exact version in
apps/desktop/Package.swift. SwiftTerm 1.99 and later declareswift-tools-version: 6.2, which needs Xcode 26, so Dependabot skips them until Desktop CI builds with Xcode 26. The desktop app overrides SwiftTerm behavior (input, scrolling, process handling), so test a SwiftTerm update by hand as well as withswift test. - The iOS Xcode project pins its packages in
PlexusOneiOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved, separately fromapps/ios/Package.resolved. Update both when changing an iOS dependency. - Before merging a dependency pull request, check that Desktop CI passed.
A failing update left on
mainblocks every later release.
Releases¶
Releases are versioned vX.Y.Z and follow Semantic Versioning.
Pushing a vX.Y.Z tag builds the DMGs and publishes the GitHub release.
1. Prepare the release¶
Bring main up to date first. The changelog records commit hashes, so write
it after the last rebase:
Then, in topical commits:
-
Changelog. Add the version to
CHANGELOG.json, then regenerate and copy it: -
Release notes. Write
docs/releases/vX.Y.Z.mdfollowing the previous release. The release workflow uses this file as the GitHub release page, followed by GitHub's generated list of changes, so link to docs with full GitHub URLs rather than relative paths. - Navigation. Add the release notes to the Releases section of
mkdocs.yml. - Version. Set
CFBundleShortVersionStringandCFBundleVersioninapps/desktop/Sources/PlexusOneDesktop/Info.plist. Edit the two strings directly;PlistBuddyrewrites the file's formatting.
If main moves before you push and you rebase again, the changelog hashes
change. Update them in the changelog commit itself rather than adding a
separate commit.
2. Push and wait for CI¶
git push origin main
gh run watch "$(gh run list --workflow 'Desktop CI' --branch main --limit 1 --json databaseId --jq '.[0].databaseId')"
Do not tag until Desktop CI passes on the commit you intend to release.
3. Trial run of the release build¶
Build the DMGs on the release runners without publishing anything:
gh workflow run desktop-release.yaml -f version=X.Y.Z
gh run watch "$(gh run list --workflow 'Desktop Release' --limit 1 --json databaseId --jq '.[0].databaseId')"
A manual run builds the arm64, Intel, and universal DMGs and uploads them as workflow artifacts. It does not create a tag or a release. To try a DMG:
This is the first build with the release runners' Xcode, which can be newer than Desktop CI's, so it catches compiler and packaging problems before a tag makes them public.
4. Tag and publish¶
The Desktop Release workflow then:
- Builds release binaries for arm64 and x86_64, and a universal binary.
- Assembles
PlexusOne Desktop.app, sets the bundle version from the tag, and ad-hoc signs and verifies the bundle. - Packages each bundle as a DMG with an Applications link:
PlexusOneDesktop-X.Y.Z-macos-{arm64,x86_64,universal}.dmg. - Publishes the GitHub release "PlexusOne Desktop vX.Y.Z" with
docs/releases/vX.Y.Z.mdas its notes and the three DMGs attached. Tags containingalpha,beta, orrcare published as pre-releases.
5. Verify the release¶
- Download a DMG from the release page with a browser, so it is quarantined like a user's download.
- Drag the app to Applications and open it. Builds are ad-hoc signed and not notarized, so macOS asks first: open System Settings > Privacy & Security and click Open Anyway.
- Check PlexusOne Desktop > About shows the new version, and try the release's main changes.
6. Publish the documentation¶
The documentation site is not deployed by CI:
If a release fails¶
- The trial run or tag build fails before publishing: fix the problem on
main, then release the next patch version with a new tag. Do not reuse a version that has been pushed as a tag. - A published release has a problem: release a fixed patch version and note the problem in its release notes.
Signing¶
Release builds are ad-hoc signed so Gatekeeper offers Open Anyway instead of reporting the app as damaged. Developer ID signing and notarization, which would remove the first-launch prompt, require an Apple Developer Program membership and are not set up yet.