go-devops/cmd/dev/forge_client.go
Snider cbe95aa490 feat: migrate ci/issues/reviews from gh CLI to Forgejo SDK
Replace shell-outs to `gh` with native Gitea SDK calls via shared
forge_client.go helper. Supports both ListRepoActionRuns (1.25+) and
ListRepoActionTasks (older Forgejo) for CI status. Issues and reviews
now use SDK list endpoints with proper filtering.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-12 19:04:41 +00:00

73 lines
1.9 KiB
Go

package dev
import (
"fmt"
"os"
"path/filepath"
"strings"
"code.gitea.io/sdk/gitea"
"forge.lthn.ai/core/go-scm/forge"
)
// forgeAPIClient creates a Gitea SDK client configured for the Forge instance.
// Forgejo is API-compatible with Gitea, so the Gitea SDK works directly.
func forgeAPIClient() (*gitea.Client, error) {
forgeURL, token, err := forge.ResolveConfig("", "")
if err != nil {
return nil, err
}
if token == "" {
return nil, fmt.Errorf("no Forge API token configured (set FORGE_TOKEN or run: core forge config --token TOKEN)")
}
return gitea.NewClient(forgeURL, gitea.SetToken(token))
}
// forgeRepoIdentity extracts the Forge owner/repo from a repo's git remote.
// Falls back to fallbackOrg/repoName if no forge.lthn.ai remote is found.
func forgeRepoIdentity(repoPath, fallbackOrg, repoName string) (owner, repo string) {
configPath := filepath.Join(repoPath, ".git", "config")
content, err := os.ReadFile(configPath)
if err != nil {
return fallbackOrg, repoName
}
for _, line := range strings.Split(string(content), "\n") {
line = strings.TrimSpace(line)
if !strings.HasPrefix(line, "url = ") {
continue
}
remoteURL := strings.TrimPrefix(line, "url = ")
if !strings.Contains(remoteURL, "forge.lthn.ai") {
continue
}
// ssh://git@forge.lthn.ai:2223/core/go-devops.git
// https://forge.lthn.ai/core/go-devops.git
parts := strings.SplitN(remoteURL, "forge.lthn.ai", 2)
if len(parts) < 2 {
continue
}
path := parts[1]
// Remove port if present (e.g., ":2223/")
if strings.HasPrefix(path, ":") {
idx := strings.Index(path[1:], "/")
if idx >= 0 {
path = path[idx+1:]
}
}
path = strings.TrimPrefix(path, "/")
path = strings.TrimSuffix(path, ".git")
ownerRepo := strings.SplitN(path, "/", 2)
if len(ownerRepo) == 2 {
return ownerRepo[0], ownerRepo[1]
}
}
return fallbackOrg, repoName
}