Help us shape the future of Go! Take the 2026 Go Developer Survey

github

package
v0.67.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 17 Imported by: 0

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

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
const SourceKind = "github"

SourceKind is the inbox source_kind GitHub observations carry.

Variables

View Source
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

func NewFactory(fetchers *Fetchers) connector.Factory

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.

func (*Config) Validate

func (c *Config) Validate() error

Validate mirrors the GitHub API's own constraints: search needs a query and caps at one page of 100, notifications takes no query and caps at 50.

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

func NewFetchers(client *ghclient.Client, creds credentials.Store, logger zerolog.Logger) *Fetchers

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

func (f *Fetchers) SetRecorder(r activity.Recorder)

SetRecorder attaches an activity recorder to every fetcher, now and later.

func (*Fetchers) SetSearchTTL

func (f *Fetchers) SetSearchTTL(ttl time.Duration)

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).

Jump to

Keyboard shortcuts

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