Documentation
¶
Overview ¶
Package sync implements forge accessory synchronization.
Two sync classes exist, ordered and not peers:
Git mirror — transport-level replication via git push --mirror. All refs, branches, tags, deletions, force updates. Mirrored from the authoritative local worktree.
Artifact projection — API-level for forge-native objects (releases). Runs only after git mirror succeeds for that accessory.
Core invariant: Git is the source of truth; everything else is downstream projection.
Index ¶
- func IsImmutableTagTemplate(tmpl string) bool
- func RollingAliasTagSet(cfg *config.Config, vi *gitver.VersionInfo) map[string]bool
- func ScopedReleases(primary []forge.ReleaseInfo, spec *config.FacetSpec, currentTag string) []forge.ReleaseInfo
- type MirrorFailureReason
- type MirrorResult
- type RefContext
- type ReleaseData
- type ReleaseResult
- type SyncStatus
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsImmutableTagTemplate ¶ added in v0.9.0
IsImmutableTagTemplate reports whether a tag template names a version/sha identity — the marker that it is immutable: outside the rolling-alias force set on the mirror, and never delete-and-recreated by the alias-tagging path.
func RollingAliasTagSet ¶ added in v0.9.0
RollingAliasTagSet returns the concrete tag names that are ROLLING aliases — mutable pointers declared in kind:release targets' aliases that advance each release (e.g. "latest", "latest-dev"). Classification is FROM CONFIG, not hardcoded names: an alias whose template carries a version/sha placeholder is an immutable identity and is EXCLUDED, so the mirror force-updates rolling aliases without ever forcing a version tag. Concrete names come from gitver.ResolveTags; with no version info available only literal (placeholder-free) templates are admitted, which the rolling ones already are.
func ScopedReleases ¶ added in v0.8.0
func ScopedReleases(primary []forge.ReleaseInfo, spec *config.FacetSpec, currentTag string) []forge.ReleaseInfo
ScopedReleases filters primary releases to those a releases facet should project. scope:current keeps only the current tag's release; drafts are excluded unless spec.Drafts; a match glob restricts by tag name. all/exact keep everything (minus filtered). Returns nil for a nil facet.
Types ¶
type MirrorFailureReason ¶
type MirrorFailureReason string
MirrorFailureReason classifies git mirror push failures. Classification is best-effort via stderr substring matching. Fallback is always MirrorUnknown — classification must never crash.
const ( MirrorAuthFailed MirrorFailureReason = "auth_failed" MirrorProtectedRefRejected MirrorFailureReason = "protected_ref_rejected" MirrorNetworkFailed MirrorFailureReason = "network_failed" MirrorRemoteNotFound MirrorFailureReason = "remote_not_found" MirrorPushRejected MirrorFailureReason = "push_rejected" // MirrorDiverged: the push was rejected because an in-scope mirror ref diverged // (differs and the facet did not opt into force) — keep-divergent working as // intended, not a transport or remote fault. Named explicitly so it is not // substring-guessed from go-git's generic "object not found" wording. MirrorDiverged MirrorFailureReason = "diverged" MirrorUnknown MirrorFailureReason = "unknown" )
type MirrorResult ¶
type MirrorResult struct {
AccessoryID string
Status SyncStatus
Duration time.Duration
Degraded bool // true when mirror failed — accessory is diverged
FailureReason MirrorFailureReason
Message string // sanitized human-readable message (never contains credentials)
// The push plan, as counts. Structured so the reporter renders fixed-width
// fields — a plan rendered as a list of refspecs grows with the repo and
// turns one scannable line into hundreds of characters.
Refspecs int // refspecs the push attempted
Pruned int // remote-only refs the plan deletes
Foreign int // remote refs outside the ownership boundary, left alone
}
MirrorResult reports the outcome of a git mirror push to one accessory.
func MirrorPush ¶
func MirrorPush(ctx context.Context, worktree string, mirror config.ResolvedRepo, refCtx RefContext, rollingAliases map[string]bool, cfg *config.Config) (*MirrorResult, error)
MirrorPush performs an authoritative git mirror push from the primary forge (origin) to a mirror forge using go-git. Clones from origin into a temp bare repo and pushes all heads + tags with force.
Invariants:
- Never mutates the user's working repo (temp bare clone only)
- Credentials passed via go-git BasicAuth, never in URLs
- No git binary required
type RefContext ¶ added in v0.8.0
type RefContext struct {
Branch string // short branch name, "" if none
Tag string // short tag name, "" if not a tag run
}
RefContext is the ref the current run addresses — used by scope: current to pick the single branch/tag to replicate. Empty fields mean "no current ref of that kind" (Tag is empty on a branch build, Branch empty on a tag build).
type ReleaseData ¶
type ReleaseData struct {
Tag string
Name string
Description string // markdown body
Draft bool
Prerelease bool
Assets []forge.Asset
Links []forge.ReleaseLink
}
ReleaseData holds all data needed to project a release to an accessory.
type ReleaseResult ¶
type ReleaseResult struct {
AccessoryID string
Status SyncStatus
Message string
}
ReleaseResult reports the outcome of release projection to one accessory.
func SyncRelease ¶
func SyncRelease(ctx context.Context, accessory config.ResolvedRepo, data ReleaseData) *ReleaseResult
SyncRelease projects a release to an accessory forge. Tag is the identity key — if a release for this tag already exists, it is not recreated (idempotent). Assets are uploaded if missing.
Artifact sync must never mutate repository content (files, refs). Only forge-native surfaces.
type SyncStatus ¶
type SyncStatus string
SyncStatus represents the outcome of a sync operation.
const ( SyncSuccess SyncStatus = "success" SyncFailed SyncStatus = "failed" SyncSkipped SyncStatus = "skipped" )