Documentation
¶
Overview ¶
@index Repository/branch admission, ref normalization, and namespace policy for repository sync.
@index Clone URL resolution for webhook-triggered repository sync.
@index Deduplicating work queue for webhook-driven repository sync.
@index Repository checkout-to-graph synchronization application workflow.
Index ¶
- Variables
- func AllowRuleOwners(rules []RepoRule) []string
- func AllowRulesSpanMultipleOwners(rules []RepoRule) (bool, []string)
- func ExtractNamespace(repoFullName string) string
- func IsNonRetryable(err error) bool
- func NonRetryable(err error) error
- func NormalizeBranchRef(ref string) (string, bool)
- func ResolveCloneURL(repoFullName, payloadCloneURL string, baseURLs []string, allowPayload bool) (string, error)
- func ValidateRepoNameNamespaceRules(rules []RepoRule) error
- type BuildScope
- type BuildScopeLoader
- type CacheInvalidator
- type CacheInvalidatorFunc
- type Checkout
- type CheckoutRequest
- type GraphRequest
- type GraphUpdater
- type Observability
- type QueueConfig
- type RepoFilter
- type RepoRule
- type RepoStats
- type RetryConfig
- type Service
- type SyncHandlerFunc
- type SyncQueue
- func NewSyncQueue(workers int, handler SyncHandlerFunc) *SyncQueue
- func NewSyncQueueWithConfig(ctx context.Context, workers int, handler SyncHandlerFunc, cfg QueueConfig) *SyncQueue
- func NewSyncQueueWithContext(ctx context.Context, workers int, handler SyncHandlerFunc) *SyncQueue
- func NewSyncQueueWithOptions(ctx context.Context, workers int, handler SyncHandlerFunc, retry RetryConfig) *SyncQueue
- type SyncQueueStats
- type UpdateStats
Constants ¶
This section is empty.
Variables ¶
var ( ErrSyncQueueFull = errors.New("sync queue full") ErrSyncQueueShuttingDown = errors.New("sync queue shutting down") )
Functions ¶
func AllowRuleOwners ¶
AllowRuleOwners returns the positive repository owner prefixes present in allow rules. @intent let server startup warn when repo-name namespace extraction is used with multi-owner webhook allowlists. @domainRule deny rules are ignored because they only narrow the positive admission surface.
func AllowRulesSpanMultipleOwners ¶
AllowRulesSpanMultipleOwners reports whether webhook rules admit repositories under more than one owner prefix. @intent identify configurations that can collide under the current repo-name namespace strategy.
func ExtractNamespace ¶
ExtractNamespace derives the existing repo-name namespace strategy. @intent preserve repository-backed namespace compatibility while removing owner segments.
func IsNonRetryable ¶
IsNonRetryable reports whether a sync error should bypass queue retries. @intent let retry logic stop early when a failure is known to be permanent for the current payload. @param err is the sync failure returned by the queue handler. @return returns true when err unwraps to nonRetryableError.
func NonRetryable ¶
@intent wrap permanent sync failures so queue retry logic can short-circuit them.
func NormalizeBranchRef ¶
NormalizeBranchRef extracts a branch name only from refs/heads references. @intent reject tags and other Git refs before repository sync admission.
func ResolveCloneURL ¶
func ResolveCloneURL(repoFullName, payloadCloneURL string, baseURLs []string, allowPayload bool) (string, error)
ResolveCloneURL selects a safe clone target from configured base URLs or the payload. @intent keep repository sync deterministic and prevent untrusted webhook payloads from choosing arbitrary clone endpoints unless explicitly allowed.
func ValidateRepoNameNamespaceRules ¶
ValidateRepoNameNamespaceRules rejects admission surfaces that can map distinct repositories to one repo-name namespace. @intent fail webhook startup before equal repo names from different owners can share checkout and graph state. @domainRule repo-name namespaces are safe only when all positive allow rules are constrained to one non-wildcard owner.
Types ¶
type BuildScope ¶
BuildScope captures the repository-local source selection policy for one webhook sync. @intent carry include and exclude configuration together so every webhook update uses one coherent build scope.
type BuildScopeLoader ¶
type BuildScopeLoader interface {
Load(repoDir string) (BuildScope, error)
}
BuildScopeLoader loads repository-local graph source selection configuration. @intent separate repository config file parsing from repository sync orchestration.
type CacheInvalidator ¶
type CacheInvalidator interface{ Invalidate() }
CacheInvalidator drops query results only after a successful graph update. @intent keep derived query cache invalidation after successful repository graph commit.
type CacheInvalidatorFunc ¶
type CacheInvalidatorFunc func()
CacheInvalidatorFunc adapts a runtime closure to the application port. @intent adapt runtime cache invalidation closures to the app-owned port.
func (CacheInvalidatorFunc) Invalidate ¶
func (f CacheInvalidatorFunc) Invalidate()
Invalidate adapts a closure to the cache invalidation port. @intent invoke the configured cache invalidation only when one exists.
type Checkout ¶
type Checkout interface {
Sync(ctx context.Context, request CheckoutRequest) (repoDir string, err error)
}
Checkout synchronizes a remote branch into its isolated repository directory. @intent isolate checkout locking and Git implementation from sync ordering policy.
type CheckoutRequest ¶
type CheckoutRequest struct{ RepoFullName, CloneURL, Namespace, Branch string }
CheckoutRequest identifies one admitted remote branch and its local namespace. @intent carry only trusted admission output into the checkout adapter.
type GraphRequest ¶
type GraphRequest struct {
RepoDir, Namespace string
IncludePaths []string
ExcludePatterns []string
MaxFileBytes, MaxTotalParsedBytes int64
FailOnUnreadable bool
}
GraphRequest carries the exact webhook update contract to the ingest adapter. @intent preserve namespace, source scope, replace limits, and readability policy across the app boundary.
type GraphUpdater ¶
type GraphUpdater interface {
Update(ctx context.Context, request GraphRequest) (UpdateStats, error)
}
GraphUpdater replaces one repository namespace from its synchronized checkout. @intent adapt repository sync to the ingest application without importing workflow types.
type Observability ¶
type Observability interface {
Start(ctx context.Context, operation, repo, branch string) (context.Context, func())
LogArgs(ctx context.Context) []any
}
Observability wraps queue process/attempt lifecycles without coupling app policy to tracing infrastructure. @intent allow tracing adapters to enrich contexts and logs while queue behavior remains infrastructure-free.
type QueueConfig ¶
type QueueConfig struct {
RetryConfig
ShutdownTimeout time.Duration
MaxTrackedRepos int
Observability Observability
}
@intent configure queue retry policy and memory bounds when constructing a SyncQueue.
type RepoFilter ¶
type RepoFilter struct {
// contains filtered or unexported fields
}
RepoFilter holds the ordered rule list used to decide repo and branch admission. @intent provide a single matcher whose result depends on rule declaration order, where later matching rules override earlier ones.
func NewRepoFilter ¶
func NewRepoFilter(patterns []string) *RepoFilter
NewRepoFilter expands simple string patterns into webhook repo rules. @intent keep CLI-style allowlist configuration compatible with the richer rule matcher. @param patterns is the ordered allow/deny rule list in compact string form. @ensures returns a filter whose rule order matches the caller input order.
func NewRepoFilterFromRules ¶
func NewRepoFilterFromRules(rules []RepoRule) *RepoFilter
NewRepoFilterFromRules compiles repository and branch rules into a matcher. @intent centralize Atlantis-style repo filtering so webhook dispatch can make one consistent allow decision. @param rules is the ordered repo rule list whose later matches override earlier ones. @ensures returns a filter that preserves the source rule order for evaluation.
func (*RepoFilter) IsAllowed ¶
func (f *RepoFilter) IsAllowed(repoFullName string) bool
IsAllowed reports whether a repository matches the configured allow and deny rules. @intent let callers gate repository-level sync before looking at branch-specific restrictions. @domainRule rules are evaluated in declaration order and the last matching rule wins; a later allow rule overrides an earlier deny match and vice versa. @domainRule a repository with no matching rule is denied (default-deny).
func (*RepoFilter) IsAllowedBranch ¶
func (f *RepoFilter) IsAllowedBranch(repoFullName, branch string) bool
IsAllowedBranch reports whether a repository and branch pair should be processed. @intent combine repo allowlist and branch policy so webhook handlers can skip unsupported pushes cheaply. @domainRule with no rules configured the result is always false (default-deny). @domainRule rules are evaluated in declaration order; each later matching rule replaces the prior decision, so a negate rule clears any previous allow and a subsequent allow rule re-enables the repo. @domainRule when a non-negate rule matches but specifies no branches, the built-in defaults ("main", "master") are used.
func (*RepoFilter) IsAllowedRef ¶
func (f *RepoFilter) IsAllowedRef(repoFullName, ref string) bool
IsAllowedRef resolves a git ref to a branch and applies branch allowlist rules. @intent reject non-branch webhook refs before they can enter the sync pipeline. @return returns false for non-branch refs and otherwise defers to branch policy evaluation.
type RepoRule ¶
RepoRule is the user-facing config form pairing a repo pattern with optional branch globs. @intent expose a stable shape for CLI/YAML config without leaking the internal compiled rule layout.
func ParseRepoRule ¶
ParseRepoRule decodes a repo rule string with optional comma-separated branch patterns. @intent preserve compact CLI config while still supporting per-repository branch restrictions. @param s follows pattern or pattern:branch1,branch2 syntax. @return returns a RepoRule with branch restrictions only when the colon form is present.
type RepoStats ¶
type RepoStats struct {
Repo string `json:"repo"`
Branch string `json:"branch"`
Queued bool `json:"queued"`
Processing bool `json:"processing"`
EnqueuedAt time.Time `json:"enqueued_at,omitempty"`
ProcessingAt time.Time `json:"processing_at,omitempty"`
LastSuccessTime time.Time `json:"last_success_time,omitempty"`
LastErrorTime time.Time `json:"last_error_time,omitempty"`
LastError string `json:"last_error,omitempty"`
}
@intent expose per-repository queue state so operators can inspect backlog and failure hotspots.
type RetryConfig ¶
type RetryConfig struct {
// MaxAttempts is the total number of attempts (1 = no retry). Default: 3.
MaxAttempts int
// BaseDelay is the initial backoff duration. Default: 1s.
BaseDelay time.Duration
// MaxDelay caps the backoff duration. Default: 30s.
MaxDelay time.Duration
}
RetryConfig configures exponential backoff retry for sync handlers. @intent tune retry backoff so transient webhook sync failures can recover without overwhelming the remote.
type Service ¶
type Service struct {
Checkout Checkout
BuildScope BuildScopeLoader
Graph GraphUpdater
Cache CacheInvalidator
Observability Observability
AttemptTimeout time.Duration
MaxFileBytes int64
MaxTotalParsedBytes int64
FailOnUnreadable bool
Logger *slog.Logger
}
@intent coordinate admitted repository checkout, config loading, graph replacement, and cache invalidation.
type SyncHandlerFunc ¶
SyncHandlerFunc processes one deduplicated repository sync payload. @intent provide the queue-to-service invocation contract without transport ownership.
type SyncQueue ¶
type SyncQueue struct {
// contains filtered or unexported fields
}
@intent coordinate deduplicated per-repository sync execution across a worker pool.
func NewSyncQueue ¶
func NewSyncQueue(workers int, handler SyncHandlerFunc) *SyncQueue
NewSyncQueue creates a queue with background workers and default lifecycle settings. @intent provide the smallest constructor for production webhook dispatch. @param workers is the number of background workers to start. @param handler processes one deduplicated repository sync payload. @sideEffect starts background worker goroutines immediately.
func NewSyncQueueWithConfig ¶
func NewSyncQueueWithConfig(ctx context.Context, workers int, handler SyncHandlerFunc, cfg QueueConfig) *SyncQueue
NewSyncQueueWithConfig creates a deduplicating repo work queue and starts its workers. @intent coalesce bursty webhook pushes per repository while still allowing different repos to sync concurrently. @param cfg controls retry behavior and how many repositories may be tracked at once. @sideEffect starts worker goroutines and allocates queue state maps. @ensures non-positive MaxAttempts becomes 1, non-positive ShutdownTimeout becomes 30s, and non-positive MaxTrackedRepos becomes 1024.
func NewSyncQueueWithContext ¶
func NewSyncQueueWithContext(ctx context.Context, workers int, handler SyncHandlerFunc) *SyncQueue
NewSyncQueueWithContext binds queue workers to a parent lifecycle context. @intent allow server shutdown to cancel retries and worker waits cleanly. @param ctx controls worker lifetime and retry cancellation. @sideEffect starts background worker goroutines immediately.
func NewSyncQueueWithOptions ¶
func NewSyncQueueWithOptions(ctx context.Context, workers int, handler SyncHandlerFunc, retry RetryConfig) *SyncQueue
NewSyncQueueWithOptions applies retry tuning while keeping default queue limits. @intent expose backoff customization without forcing every caller to build a full queue config. @param retry overrides exponential backoff behavior for sync retries. @ensures queue memory bounds still use default MaxTrackedRepos when not specified.
func (*SyncQueue) Add ¶
Add records the latest payload for a repository and enqueues it if needed. @intent collapse repeated push events into one queued sync while preserving the newest branch and clone data. @mutates SyncQueue.queue, SyncQueue.dirty, SyncQueue.payloads. @param repoFullName identifies the deduplication key for queueing. @return returns ErrSyncQueueFull when a new repository would exceed the bounded tracked-repo set and ErrSyncQueueShuttingDown after graceful shutdown begins. @domainRule repeated events for the same repository replace payload data instead of enqueueing duplicate work.
func (*SyncQueue) Shutdown ¶
func (q *SyncQueue) Shutdown()
Shutdown stops accepting new work and waits for workers to finish or time out. @intent give the server a bounded, graceful shutdown path for in-flight webhook sync. @sideEffect flips queue shutdown state, wakes waiting workers, and may record a timeout failure.
func (*SyncQueue) Stats ¶
func (q *SyncQueue) Stats() SyncQueueStats
Stats snapshots queue health and recent repository activity for operators. @intent expose enough queue state to diagnose backlog, failures, and hot repositories. @return returns a point-in-time snapshot without mutating queue execution state.
type SyncQueueStats ¶
type SyncQueueStats struct {
Queued int `json:"queued"`
Dirty int `json:"dirty"`
Processing int `json:"processing"`
TrackedRepos int `json:"tracked_repos"`
MaxTrackedRepos int `json:"max_tracked_repos"`
QueueFullTotal int64 `json:"queue_full_total"`
FailureTotal int64 `json:"failure_total"`
LastError string `json:"last_error,omitempty"`
LastErrorTime time.Time `json:"last_error_time,omitempty"`
OldestQueuedAge time.Duration `json:"oldest_queued_age"`
OldestProcessingAge time.Duration `json:"oldest_processing_age"`
LastSuccessTime time.Time `json:"last_success_time,omitempty"`
Shutdown bool `json:"shutdown"`
RecentRepos []RepoStats `json:"recent_repos,omitempty"`
}
@intent summarize queue-wide health and recent repository activity for observability.
type UpdateStats ¶
type UpdateStats struct{ Added, Modified, Skipped, Deleted int }
UpdateStats is the sync result needed for repository operation logging. @intent report only update counts needed by repository sync observability.