Install
Most applications only need gitea4s-backend-zio — it pulls in
client and core.
"io.worxbend" %% "gitea4s-core" % "1.0.0"
"io.worxbend" %% "gitea4s-client" % "1.0.0"
"io.worxbend" %% "gitea4s-backend-zio" % "1.0.0"
"io.worxbend" %% "gitea4s-backend-okhttp" % "1.0.0"
Maven Central is the canonical channel. GitHub Packages, JitPack and prebuilt jars attached to each release are also available — see distribution channels for resolvers and authentication.
Quickstart
import io.worxbend.gitea4s.GiteaClient
import io.worxbend.gitea4s.backend.zio.ZioGiteaBackend
import io.worxbend.gitea4s.http.RepoListParams
import sttp.client4.*
import zio.{Console, ZIO, ZIOAppDefault}
object Main extends ZIOAppDefault:
private val layer =
ZioGiteaBackend.withToken(uri"https://gitea.example", sys.env("GITEA_TOKEN"))
def run =
ZIO.serviceWithZIO[GiteaClient] { client =>
for
me <- client.users.me
login <- ZIO.fromOption(me.login).orElseFail(new RuntimeException("missing login"))
repos <- client.repos.list(login, RepoListParams(limit = Some(25))).take(25).runCollect
_ <- Console.printLine(s"Repositories for $login")
_ <- ZIO.foreachDiscard(repos)(r =>
Console.printLine(s"- ${r.fullName.orElse(r.name).getOrElse("<unknown>")}"))
yield ()
}.provideLayer(layer)
Note. GITEA_URL is the server root, not the API root:
use https://gitea.example, not https://gitea.example/api/v1. The
/api/v1 prefix is added for you, so including it yields
/api/v1/api/v1/… and a NotFound on every call.
Namespaces
The client is organized into resource namespaces; every call goes through one.
| Namespace | Covers |
|---|---|
client.repos | repositories, Git data, contents, collaborators, statuses |
client.issues | issues, comments, labels, reactions, tracked time |
client.pulls | pull requests, reviews, merges, diffs |
client.releases | releases and release assets |
client.notifications | notification threads and counts |
client.users | the current user (users.me), lookup, search, followers |
client.orgs | organizations and their members/repositories |
What the design buys you
Audited against the contract
Every endpoint's method, path, parameters and response labels are checked against the
vendored plugin-redoc-2.yaml, and the URI a builder produces is checked against
the path template it declares.
Bounded failure
Retries cover only GET and HEAD, so they cannot duplicate a write. Attempts, rate-limit waits, response bodies and stalled downloads all have explicit ceilings.
Survives server drift
An enum value a newer Gitea introduces decodes as None rather than failing the
page it arrived in — one unreadable field instead of a lost collection.
Credentials stay put
toString redacts tokens, passwords and one-time passwords; config errors name
the setting and never the value; URL userinfo is stripped.
Modules
core
client -> core
backend-zio -> client
backend-okhttp -> client
OkHttp is confined to backend-okhttp; core, client and
backend-zio do not depend on it. backend-zio is the default and the only
one that can stream binary downloads, because that needs a ZioStreams-capable
backend.
The public API of all four published modules is pinned by a snapshot in
api-snapshot/ and guarded by ./mill compatibility.check, so a change to
a published signature cannot land unnoticed.