Skip to content

go-forge

forge.lthn.ai/core/go-forge is a Go client library for the Forgejo REST API. It provides typed access to 18 API domains (repositories, issues, pull requests, organisations, and more) through a single top-level Forge client. Types are generated directly from Forgejo's swagger.v1.json specification, keeping the library in lockstep with the server.

Module path: forge.lthn.ai/core/go-forge Go version: 1.26+ Licence: EUPL-1.2

Quick start

package main

import (
    "context"
    "fmt"
    "log"

    "forge.lthn.ai/core/go-forge"
)

func main() {
    // Create a client with your Forgejo URL and API token.
    f := forge.NewForge("https://forge.lthn.ai", "your-token")

    ctx := context.Background()

    // List repositories for an organisation (first page, 50 per page).
    result, err := f.Repos.List(ctx, forge.Params{"org": "core"}, forge.DefaultList)
    if err != nil {
        log.Fatal(err)
    }
    for _, repo := range result.Items {
        fmt.Println(repo.Name)
    }

    // Get a single repository.
    repo, err := f.Repos.Get(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s — %s\n", repo.FullName, repo.Description)
}

Configuration from environment

If you prefer to resolve the URL and token from environment variables rather than hard-coding them, use NewForgeFromConfig:

// Priority: flags > env (FORGE_URL, FORGE_TOKEN) > defaults (http://localhost:3000)
f, err := forge.NewForgeFromConfig("", "", forge.WithUserAgent("my-tool/1.0"))
if err != nil {
    log.Fatal(err) // no token configured
}

Environment variables:

Variable Purpose Default
FORGE_URL Base URL of the Forgejo instance http://localhost:3000
FORGE_TOKEN API token for authentication (none -- required)

Package layout

go-forge/
├── client.go          HTTP client, auth, error handling, rate limits
├── config.go          Config resolution: flags > env > defaults
├── forge.go           Top-level Forge struct aggregating all 18 services
├── resource.go        Generic Resource[T, C, U] for CRUD operations
├── pagination.go      ListPage, ListAll, ListIter — paginated requests
├── params.go          Path variable resolution ({owner}/{repo} -> values)
├── repos.go           RepoService — repositories, forks, transfers, mirrors
├── issues.go          IssueService — issues, comments, labels, reactions
├── pulls.go           PullService — pull requests, merges, reviews
├── orgs.go            OrgService — organisations, members
├── users.go           UserService — users, followers, stars
├── teams.go           TeamService — teams, members, repositories
├── admin.go           AdminService — site admin, cron, user management
├── branches.go        BranchService — branches, branch protections
├── releases.go        ReleaseService — releases, assets, tags
├── labels.go          LabelService — repo and org labels
├── webhooks.go        WebhookService — repo and org webhooks
├── notifications.go   NotificationService — notifications, threads
├── packages.go        PackageService — package registry
├── actions.go         ActionsService — CI/CD secrets, variables, dispatches
├── contents.go        ContentService — file read/write/delete
├── wiki.go            WikiService — wiki pages
├── commits.go         CommitService — statuses, notes
├── misc.go            MiscService — markdown, licences, gitignore, version
├── types/             229 generated Go types from swagger.v1.json
│   ├── generate.go    go:generate directive
│   ├── repo.go        Repository, CreateRepoOption, EditRepoOption, ...
│   ├── issue.go       Issue, CreateIssueOption, ...
│   ├── pr.go          PullRequest, CreatePullRequestOption, ...
│   └── ... (36 files total, grouped by domain)
├── cmd/forgegen/      Code generator: swagger spec -> types/*.go
│   ├── main.go        CLI entry point
│   ├── parser.go      Swagger spec parsing, type extraction, CRUD pair detection
│   └── generator.go   Template-based Go source file generation
└── testdata/
    └── swagger.v1.json   Forgejo API specification (input for codegen)

Services

The Forge struct exposes 18 service fields, each handling a different API domain:

Service Struct Embedding Domain
Repos RepoService Resource[Repository, ...] Repositories, forks, transfers
Issues IssueService Resource[Issue, ...] Issues, comments, labels, reactions
Pulls PullService Resource[PullRequest, ...] Pull requests, merges, reviews
Orgs OrgService Resource[Organization, ...] Organisations, members
Users UserService Resource[User, ...] Users, followers, stars
Teams TeamService Resource[Team, ...] Teams, members, repos
Admin AdminService (standalone) Site admin, cron, user management
Branches BranchService Resource[Branch, ...] Branches, protections
Releases ReleaseService Resource[Release, ...] Releases, assets, tags
Labels LabelService (standalone) Repo and org labels
Webhooks WebhookService Resource[Hook, ...] Repo and org webhooks
Notifications NotificationService (standalone) Notifications, threads
Packages PackageService (standalone) Package registry
Actions ActionsService (standalone) CI/CD secrets, variables, dispatches
Contents ContentService (standalone) File read/write/delete
Wiki WikiService (standalone) Wiki pages
Commits CommitService (standalone) Commit statuses, git notes
Misc MiscService (standalone) Markdown, licences, gitignore, version

Services that embed Resource[T, C, U] inherit List, ListAll, Iter, Get, Create, Update, and Delete methods automatically. Standalone services have hand-written methods because their API endpoints are heterogeneous and do not fit a uniform CRUD pattern.

Dependencies

This module has zero external dependencies. It relies solely on the Go standard library (net/http, encoding/json, context, iter, etc.) and requires Go 1.26 or later.

module forge.lthn.ai/core/go-forge

go 1.26.0