forge

package
v0.19.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 15, 2026 License: BSD-2-Clause Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckRepoExists

func CheckRepoExists(repoName string, existsFn RepoExistsFunc) (bool, error)

CheckRepoExists normalizes repo-existence check error handling.

func DeleteStatusError

func DeleteStatusError(statusCode int, body string) error

DeleteStatusError maps common forge delete status codes into stable errors.

func EnsureRepoExists

func EnsureRepoExists(org, repoName string, existsFn RepoExistsFunc) error

EnsureRepoExists validates that a repository exists before destructive actions.

func ReadProtectedTokenFile added in v0.19.3

func ReadProtectedTokenFile(path string) (string, error)

ReadProtectedTokenFile reads a credential file at path using hardened semantics shared by every forge client (GitHub, Codeberg, Forgejo, and the CLI's release token loading). Token files live at well-known paths under the user's home directory, so a local attacker able to plant something at that path before gitsyncer runs could otherwise cause it to:

  • follow a symlink and read an unrelated, possibly sensitive file, or
  • open a FIFO and block the process indefinitely, or
  • read a token file that is also readable by other local users/groups, leaking the credential.

openProtectedTokenFile (platform-specific) opens the path with O_NOFOLLOW|O_NONBLOCK so a symlink is rejected outright and a FIFO cannot block the open call. The Stat check below then rejects anything that isn't a plain regular file and any file with group/other permission bits set (mode&0077 != 0), i.e. it only accepts owner-only files such as 0600 or 0400. The returned token has leading/trailing whitespace trimmed, since tokens are commonly stored with a trailing newline.

func ResolveToken added in v0.19.3

func ResolveToken(configToken, envVar, tokenFileName string) string

ResolveToken resolves a forge API token via the shared config -> env var -> token file cascade. This is the single source of truth for token precedence: it used to be reimplemented separately by the GitHub client's loadToken, the Codeberg client's loadToken and loadForgejoToken, and the CLI release pipeline's loadTokenWithFallback, with subtly different trimming behavior between the copies (task g01 consolidated them here, building on the shared ReadProtectedTokenFile extracted for task 901).

Precedence, matching every caller's prior behavior:

  1. configToken, if non-empty (e.g. a value from gitsyncer's config file).
  2. The environment variable named envVar, if set and non-empty.
  3. A protected token file named tokenFileName under the user's home directory, read via ReadProtectedTokenFile.

configToken and the environment variable are both trimmed here for consistency with the token file (ReadProtectedTokenFile already trims its result), since tokens are commonly copy-pasted or piped from a secret store with a trailing newline.

Returns "" if none of the three sources yield a non-empty token, including when the home directory cannot be determined or the token file cannot be read (missing, wrong permissions, etc.) - callers treat "" as "no token configured" rather than a hard error, exactly as before consolidation.

Types

type OwnerType added in v0.19.3

type OwnerType string

OwnerType identifies whether a repository owner is a user or organization.

const (
	// OwnerTypeUser creates repositories for the authenticated user.
	OwnerTypeUser OwnerType = "user"
	// OwnerTypeOrganization creates repositories in the named organization.
	OwnerTypeOrganization OwnerType = "organization"
)

func (OwnerType) Valid added in v0.19.3

func (t OwnerType) Valid() bool

Valid reports whether the owner type is supported.

type PublicRepo added in v0.19.3

type PublicRepo struct {
	Name        string
	Description string
}

PublicRepo is a forge-agnostic view of a repository returned by a public repository listing. github.Client and codeberg.Client each list repositories as their own concrete Repository DTO (with many forge-specific fields); callers that only need name/description convert into this shared type via a thin adapter (see internal/cli's githubPublicRepoLister/codebergPublicRepoLister), so public-sync code depends on this package instead of importing github/codeberg for their concrete types.

type PublicRepoEnsurer added in v0.19.3

type PublicRepoEnsurer interface {
	EnsurePublicRepo(name, description string) error
}

PublicRepoEnsurer is implemented by forge clients that can idempotently ensure a public repository exists: create it if absent, or validate that an existing repository is a compatible (public, same-name) target. internal/sync depends on this narrow interface instead of importing a concrete forge package (e.g. codeberg) directly, so the backup-repo bootstrapping in ensureForgejoBackups stays decoupled from any single forge implementation. codeberg.Client implements this method.

type PublicRepoLister added in v0.19.3

type PublicRepoLister interface {
	HasToken() bool
	ListPublicRepos() ([]PublicRepo, error)
}

PublicRepoLister lists public repositories for a forge account. HasToken is part of the contract because GitHub's public-listing API requires an auth token even for public repositories, unlike Codeberg's; callers check it before calling ListPublicRepos.

type ReleaseClient added in v0.19.3

type ReleaseClient interface {
	// GetReleases returns the tag names of existing releases for the
	// repository. A missing repository is reported as an empty slice and a
	// nil error so callers can treat it as "no releases yet".
	GetReleases(owner, repo string) ([]string, error)
	CreateRelease(owner, repo, tag, releaseNotes string) error
	UpdateRelease(owner, repo, tag, releaseNotes string) error
}

ReleaseClient defines release CRUD operations shared across forges. Each forge (GitHub, Codeberg/Gitea) implements this against its own API so the release pipeline can talk to any forge through a single abstraction instead of hand-rolled per-forge HTTP in the caller.

type ReleasesEnabler added in v0.19.3

type ReleasesEnabler interface {
	EnsureReleasesEnabled(owner, repo string) error
}

ReleasesEnabler is optionally implemented by forges that require releases to be enabled per-repository before release creation can succeed (e.g. Codeberg/Gitea, where the repository's Releases feature may be disabled). Callers check for this interface rather than assuming every forge needs it.

type RepoClient

type RepoClient interface {
	HasToken() bool
	RepoExists(repoName string) (bool, error)
	CreateRepo(repoName, description string, private bool) error
	DeleteRepo(repoName string) error
}

RepoClient defines shared repository lifecycle operations across forges.

type RepoDescriptionClient

type RepoDescriptionClient interface {
	RepoClient
	GetRepoDescription(repoName string) (string, bool, error)
	UpdateRepoDescription(repoName, description string) error
}

RepoDescriptionClient defines shared description operations across forges.

type RepoExistsFunc

type RepoExistsFunc func(repoName string) (bool, error)

RepoExistsFunc checks if a repository exists.

type UserFallbackPublicRepoLister added in v0.19.3

type UserFallbackPublicRepoLister interface {
	ListPublicRepos() ([]PublicRepo, error)
	ListUserPublicRepos() ([]PublicRepo, error)
}

UserFallbackPublicRepoLister is implemented by forges (Codeberg/Gitea) whose public-repo listing must retry as a user-scoped listing when the organization-scoped listing fails, e.g. because the configured account is a user rather than an organization. Unlike PublicRepoLister it has no HasToken method because Codeberg's public listing does not require a token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL