Forji/README.md
Voislav Vasiljevski 3d3de81f2b [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 18:06:17 +02:00

5.3 KiB

Forji

A native iOS client for Forgejo


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 Code browser Pull request detail Notifications

App Store

Foji is availbe on the Apple App Store for free: Forji App Store

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

Actions

  • Browse Forgejo Actions workflows defined in a repository
  • View workflow runs filtered by status (running, completed, queued)
  • 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 as a remote Swift package dependency.

Dev Environment

A Nix flake provides all CLI tooling (just, xcbeautify, swiftlint, swiftformat):

nix develop        # Enter dev shell with all tools available

Building & Testing

A justfile is provided for common tasks:

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/ for details.

Architecture

Layer Location Purpose
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.

Acknowledgments

The Forji logo is based on the Forgejo logo by Caesar Schinas and is licensed under CC BY-SA 4.0.

Libraries

Contributing

Contributions are welcome! By submitting a pull request, you agree that your contributions are licensed under the GNU General Public License v3.0 and may be distributed through Apple's App Store under the App Store Exception included in the license.

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 with an App Store Exception that permits distribution of the compiled application through Apple's App Store.

ForgejoKit is licensed under the MIT License.