Documentation
¶
Overview ¶
Package github is the GitHub source connector: the config a github source node carries, the descriptor declaring what the connector supports, and the instance the producer drains on a tick.
Index ¶
Constants ¶
const ( KindSearch = "search" KindNotifications = "notifications" )
The two fetch shapes a GitHub source can take. A search source runs a query; a notifications source drains the authenticated user's inbox.
const ( StateDisconnected = "disconnected" StateConnected = "connected" )
Connection states on the wire. Connected/disconnected, not authenticated/unauthenticated: GitHub is one connector among several, and nothing about the app is gated on holding a credential for it. The frontend narrows these strings, so they are strings rather than an enum.
const EnvClientID = "HIVE_GITHUB_CLIENT_ID"
EnvClientID overrides the OAuth app client ID used by the device flow, e.g. to test against a different OAuth app registration.
const Provider = "github"
Provider is the credentials provider name every GitHub credential is filed under. A ref is "github/<login>": the account half is the authenticated user's login, which the single-slot token store it replaced — pinned to one constant keychain account — had no room to express.
const SourceKind = "github"
SourceKind is the inbox source_kind GitHub observations carry.
Variables ¶
var Descriptor = connector.Descriptor{ Type: "sources.github", Title: "GitHub source", Provider: Provider, Mode: connector.ModePull, Stability: connector.Stable, Capabilities: connector.CapClassify | connector.CapConfirmAbsence | connector.CapBatchPrefetch, NewConfig: func() connector.Config { return &Config{} }, }
Descriptor declares the connector. Everything it says is static — the registry holds it as package data, and the flow package derives a node type from it — while anything needing a live GitHub fetcher goes through NewFactory instead.
The capabilities are the declaration that used to be three type assertions in the producer. A missed assertion silently downgraded a GitHub source to generic ingestion: no classifier, no absence confirmation, no batched prefetch. Declaring them means a connector that promises one and does not wire it fails a test instead.
Functions ¶
func NewFactory ¶
NewFactory builds the instance half of the declaration over the live GitHub fetch path. The node's credential is resolved here, at construction: two nodes on the same account share one fetcher — and therefore one API request for identical fetch config, since LiveProvider keys its cache on kind+query+limit rather than on id — while nodes on different accounts get separate fetchers and cannot see each other's items.
Types ¶
type Config ¶
type Config struct {
// Credential names the account this source fetches as, "github/<login>".
// A ref and never a token: flows/ is dotfiles-managed, so an embedded
// token would be a token in a git repo.
Credential string `` /* 140-byte string literal not displayed */
// Kind selects the fetch shape.
Kind string `` /* 178-byte string literal not displayed */
// Query is the GitHub search query. Required for kind "search"; a
// notifications source takes none.
Query string `` /* 166-byte string literal not displayed */
// Limit bounds items per fetch. 0 means the per-kind default.
Limit int `` /* 199-byte string literal not displayed */
// Interval is the floor between fetches, for a query that spends more
// rate-limit budget than its freshness is worth.
Interval duration.Duration `` /* 248-byte string literal not displayed */
}
Config is a GitHub source node's configuration. The framework decodes it — strictly, so an unknown key is an error — and calls Validate for the cross-field rules a schema cannot state.
func (*Config) CredentialRef ¶
func (c *Config) CredentialRef() (credentials.Ref, error)
CredentialRef is the parsed credential ref. A ref naming another provider is rejected here rather than at fetch time: "grafana/prod" on a GitHub source is a config mistake, and failing it at load says so, where failing it at fetch surfaces as an empty feed.
type Connection ¶
type Connection interface {
Status(ctx context.Context) ConnectionStatus
StartDeviceFlow(ctx context.Context) (DeviceFlowInfo, error)
CancelDeviceFlow()
SetToken(ctx context.Context, token string) (ConnectionStatus, error)
Disconnect() error
}
Connection acquires and releases this connector's credentials. liveConnection talks to GitHub; mockConnection drives deterministic connect/disconnect for tests and e2e.
Acquisition is the only provider-specific half of credentials — lookup is generic and lives in platform/credentials — which is why this interface is declared by the connector that implements it rather than by the app. A connector with no state machine (an API token pasted into a secret-marked config field) needs none of it.
func NewLiveConnection ¶
func NewLiveConnection(client *ghclient.Client, creds credentials.Store, onChange func()) Connection
NewLiveConnection builds the real GitHub connection over a credential store.
func NewMockConnection ¶
func NewMockConnection(connected bool, creds credentials.Store, onChange func()) Connection
NewMockConnection builds the offline connection the mock modes use.
type ConnectionStatus ¶
type ConnectionStatus struct {
State string `json:"state"` // StateDisconnected | StateConnected
Login string `json:"login"`
Name string `json:"name"`
AvatarURL string `json:"avatarUrl"`
// Message carries a user-facing problem description (invalid stored
// token, device flow failure) without changing the state machine.
Message string `json:"message"`
}
ConnectionStatus is this connector's own connection state. It is the connector's, not the app's: Login/Name/AvatarURL describe the connected GitHub account and belong on an Integrations card, not in app chrome.
type DeviceFlowInfo ¶
type DeviceFlowInfo struct {
UserCode string `json:"userCode"`
VerificationURI string `json:"verificationUri"`
}
DeviceFlowInfo is the pending device authorization the connect screen renders: the user opens VerificationURI and enters UserCode.
type Fetchers ¶
type Fetchers struct {
// contains filtered or unexported fields
}
Fetchers hands out one feed.LiveProvider per credential, constructing them on first use.
A LiveProvider is already a per-account object even though it was written as a singleton: its response cache and conditional-request state hold one account's items, and its rate-limit cooldown "pauses all fetches for the current token". Sharing one across accounts would serve one account's items to another and let one account's rate limit stall every other. So accounts get one each, and the shared thing is this registry.
Providers are never evicted. The set is bounded by the number of connected accounts, and a disconnected account's provider holds only a response cache that its next resolve would miss anyway.
func NewFetchers ¶
NewFetchers builds the per-account provider registry over the owned GitHub client.
func (*Fetchers) For ¶
func (f *Fetchers) For(ref credentials.Ref) *feed.LiveProvider
For returns the fetcher for one credential. The provider resolves its token through the credential store on every request, so connecting, rotating, or disconnecting the account takes effect on the next fetch.
func (*Fetchers) InvalidateAll ¶
func (f *Fetchers) InvalidateAll()
InvalidateAll drops every account's fetch cache.
func (*Fetchers) SetRecorder ¶
SetRecorder attaches an activity recorder to every fetcher, now and later.
func (*Fetchers) SetSearchTTL ¶
SetSearchTTL applies the search cache TTL to every fetcher, now and on every one built later. The poll interval is a global setting, so a fetcher created after the user changed it must not silently keep the default.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package feed is the desktop's GitHub fetch layer: the wire Item type and a cached, coalesced LiveProvider the pipeline producer uses to turn a source into event_log rows.
|
Package feed is the desktop's GitHub fetch layer: the wire Item type and a cached, coalesced LiveProvider the pipeline producer uses to turn a source into event_log rows. |
|
Package ghclient is the desktop's own GitHub REST/GraphQL client: in-app authentication (OAuth device flow, PAT validation via User) and the typed API calls the connector needs (batched search, notifications, single-issue hydration).
|
Package ghclient is the desktop's own GitHub REST/GraphQL client: in-app authentication (OAuth device flow, PAT validation via User) and the typed API calls the connector needs (batched search, notifications, single-issue hydration). |