Forji/README.md

134 lines
5.3 KiB
Markdown
Raw Normal View History

# Forji
A native iOS client for [Forgejo](https://forgejo.org)
---
Forji is a native iOS app for managing your Forgejo repositories, issues, pull requests, and notifications from your phone. Built with SwiftUI and Swift concurrency.
## Screenshots
![Repositories](screenshots/01_repositories.png)
![Code browser](screenshots/02_code_browser.png)
![Pull request detail](screenshots/03_pull_request.png)
![Notifications](screenshots/04_notifications.png)
2026-03-09 10:02:07 -07:00
## App Store
Foji is availbe on the Apple App Store for free: [Forji App Store](https://apps.apple.com/us/app/forji/id6759843639)
## Features
### Repositories
- Browse and search your repositories
- Filter by All or Starred
- Star/unstar repositories
- View repository stats (stars, forks, language, open issues)
### Code Browser
- Navigate file trees
- View files with syntax highlighting
- Render Markdown previews
- Edit files and commit changes directly
- Browse commit history with diffs
- Switch branches
### Issues
- View issues across all repositories or per-repo
- Filter by open/closed state and search
- Create, edit, and close/reopen issues
- Manage labels, milestones, and assignees
- Comment with Markdown support
### Pull Requests
- View PRs across all repositories or per-repo
- Create PRs with branch selection, labels, milestones, assignees, and reviewers
- Review diffs with inline comments
- Submit reviews (comment, approve, request changes)
- Merge with merge commit, rebase, or squash
- Close, reopen, and edit PRs
[Draft] feat: Actions tab — depends on ForgejoKit#1 (#28) Closes #3. Adds an "Actions" tab to the repository view, surfacing Forgejo Actions runs and (experimentally) their jobs, steps, and logs. ## What's in this branch 1. ~~**`chore: point ForgejoKit at local checkout for Actions PR`** — temporary `XCLocalSwiftPackageReference` so the feature commit compiles against the unreleased ForgejoKit changes. Drop this commit before merge and replace with `chore: bump ForgejoKit to <new version>` once the ForgejoKit PR ships in a release.~~ **`chore: update ForgejoKit to released version 0.4.0`** + **`chore: add ForgejoKit 0.4.0 to Package.resolved`** — switches from local path override to a remote pin at `secana/ForgejoKit` `0.4.0`. 2. **`feat: add Actions tab to repository view`** — the actual feature. ## UI scope - New `Actions` tab, shown only when `repository.hasActions == true`. - Runs list with All / Running / Success / Failed filter, pagination, pull-to-refresh, empty state. - Run detail with header, metadata (workflow file, event, trigger user, started/duration — zero-Date suppressed), and an experimental Jobs section. - Job view with collapsible step rows; logs lazy-load on expand via `logCursors`. - "Open in browser" toolbar item using each run's `html_url`. ## Experimental jobs/steps view Forgejo's `/api/v1` doesn't expose jobs, steps, or step logs for a run. This PR opts into ForgejoKit's experimental `fetchRunView` (backed by Forgejo's web-UI route) so we can render a GitHub-Actions-style view today. The Jobs section and Steps screen are explicitly labelled "Experimental" in the UI, and a footer notes the output may change between Forgejo versions. Happy to drop this section if you'd rather ship public-API only first. ## Defensive handling - Forgejo serialises an unset `time.Time` as `0001-01-01T00:00:00Z` (showed up as "Started 56 yrs, 4 mths" / "Duration 493 906h" on a cancelled run). Sanitised display helpers suppress any pre-2000 date. - The experimental `fetchRunView` resolves Forgejo's `RedirectToLatestAttempt` server-side before POSTing, so attempts with non-zero attempt numbers work. (Without this, Forgejo returns 500 "task with job_id N and attempt 0: resource does not exist".) ## Tests - Unit: `WorkflowRunFilterTests`, `WorkflowStatusIconTests` (filter mapping, status enum compatibility against Forgejo's documented values, status icon mapping, run helpers, zero-date guard). - UI: `ActionsUITests` (read-only smoke test). Co-authored-by: Voislav Vasiljevski <voislav@voioo.cz> Reviewed-on: https://codeberg.org/secana/Forji/pulls/28
2026-05-07 09:06:17 -07:00
### Actions
- Browse Forgejo Actions workflows defined in a repository
2026-05-07 10:17:49 -07:00
- View workflow runs filtered by status (running, success, failed)
[Draft] feat: Actions tab — depends on ForgejoKit#1 (#28) Closes #3. Adds an "Actions" tab to the repository view, surfacing Forgejo Actions runs and (experimentally) their jobs, steps, and logs. ## What's in this branch 1. ~~**`chore: point ForgejoKit at local checkout for Actions PR`** — temporary `XCLocalSwiftPackageReference` so the feature commit compiles against the unreleased ForgejoKit changes. Drop this commit before merge and replace with `chore: bump ForgejoKit to <new version>` once the ForgejoKit PR ships in a release.~~ **`chore: update ForgejoKit to released version 0.4.0`** + **`chore: add ForgejoKit 0.4.0 to Package.resolved`** — switches from local path override to a remote pin at `secana/ForgejoKit` `0.4.0`. 2. **`feat: add Actions tab to repository view`** — the actual feature. ## UI scope - New `Actions` tab, shown only when `repository.hasActions == true`. - Runs list with All / Running / Success / Failed filter, pagination, pull-to-refresh, empty state. - Run detail with header, metadata (workflow file, event, trigger user, started/duration — zero-Date suppressed), and an experimental Jobs section. - Job view with collapsible step rows; logs lazy-load on expand via `logCursors`. - "Open in browser" toolbar item using each run's `html_url`. ## Experimental jobs/steps view Forgejo's `/api/v1` doesn't expose jobs, steps, or step logs for a run. This PR opts into ForgejoKit's experimental `fetchRunView` (backed by Forgejo's web-UI route) so we can render a GitHub-Actions-style view today. The Jobs section and Steps screen are explicitly labelled "Experimental" in the UI, and a footer notes the output may change between Forgejo versions. Happy to drop this section if you'd rather ship public-API only first. ## Defensive handling - Forgejo serialises an unset `time.Time` as `0001-01-01T00:00:00Z` (showed up as "Started 56 yrs, 4 mths" / "Duration 493 906h" on a cancelled run). Sanitised display helpers suppress any pre-2000 date. - The experimental `fetchRunView` resolves Forgejo's `RedirectToLatestAttempt` server-side before POSTing, so attempts with non-zero attempt numbers work. (Without this, Forgejo returns 500 "task with job_id N and attempt 0: resource does not exist".) ## Tests - Unit: `WorkflowRunFilterTests`, `WorkflowStatusIconTests` (filter mapping, status enum compatibility against Forgejo's documented values, status icon mapping, run helpers, zero-date guard). - UI: `ActionsUITests` (read-only smoke test). Co-authored-by: Voislav Vasiljevski <voislav@voioo.cz> Reviewed-on: https://codeberg.org/secana/Forji/pulls/28
2026-05-07 09:06:17 -07:00
- Inspect a run's jobs with status and duration
- Read job logs
### Notifications
- View unread, read, and all notifications
- Swipe to mark as read or dismiss
- Unread badge on the tab bar
### Other
- Connect to any Forgejo instance (including self-hosted)
- Self-signed certificate support
- Multiple instance management
- Light, dark, and system theme
- Mermaid diagram rendering
## Development
Requires Xcode 26. The project uses [ForgejoKit](https://codeberg.org/secana/ForgejoKit) as a remote Swift package dependency.
### Dev Environment
A [Nix flake](flake.nix) provides all CLI tooling (`just`, `xcbeautify`, `swiftlint`, `swiftformat`):
```bash
nix develop # Enter dev shell with all tools available
```
### Building & Testing
A [justfile](https://github.com/casey/just) is provided for common tasks:
```bash
just build # Build the app
just test # Run app unit tests
just run # Build, install, and launch in the simulator
just lint # Lint Swift code with SwiftLint
just format # Format Swift code with SwiftFormat
just test-ui # Run UI integration tests (requires Docker)
just test-one Class # Run a single integration test
just test-list # List all available integration tests
```
Integration tests spin up Forgejo instances in Docker, seed test data, and run UI tests against them. See [integration/](integration/) for details.
## Architecture
| Layer | Location | Purpose |
|-------|----------|---------|
| **[ForgejoKit](https://codeberg.org/secana/ForgejoKit)** | Remote SPM package | Platform-agnostic Swift package with all Forgejo API logic, models, and services |
| **Forji** | `Forji/` | SwiftUI iOS app with views, authentication, and persistence |
ForgejoKit has no SwiftUI or platform dependencies, making it reusable for other clients (macOS, CLI, etc.). It is published as a separate package at [codeberg.org/secana/ForgejoKit](https://codeberg.org/secana/ForgejoKit).
## Acknowledgments
The Forji logo is based on the [Forgejo logo](https://codeberg.org/forgejo/forgejo) by Caesar Schinas and is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
### Libraries
- [ForgejoKit](https://codeberg.org/secana/ForgejoKit) — Forgejo API client (MIT)
- [Textual](https://github.com/gonzalezreal/textual) — Markdown rendering (MIT)
- [HighlightSwift](https://github.com/appstefan/HighlightSwift) — Code syntax highlighting (MIT)
- [mermaid](https://github.com/mermaid-js/mermaid) — Diagram rendering (MIT)
- [marked](https://github.com/markedjs/marked) — Markdown parser (MIT)
- [DOMPurify](https://github.com/cure53/DOMPurify) — HTML sanitizer (Apache 2.0 / MPL 2.0)
- [github-markdown-css](https://github.com/sindresorhus/github-markdown-css) — GitHub-style Markdown styling (MIT)
## Contributing
Contributions are welcome! By submitting a pull request, you agree that your contributions are licensed under the [GNU General Public License v3.0](LICENSE) and may be distributed through Apple's App Store under the [App Store Exception](LICENSE#app-store-exception) included in the license.
2026-03-09 12:46:31 -07:00
You need to inlude this sentence in your PR or a comment to agree to the distribution in the App Store:
"I grant Stefan Hausotte an irrevocable, worldwide, royalty-free license to use, sublicense, and distribute my contribution, including through Apple's App Store under the project's App Store exception."
## License
Forji is licensed under the [GNU General Public License v3.0](LICENSE) with an [App Store Exception](LICENSE#app-store-exception) that permits distribution of the compiled application through Apple's App Store.
ForgejoKit is licensed under the [MIT License](https://codeberg.org/secana/ForgejoKit/src/branch/main/LICENSE).