Documentation
¶
Index ¶
- type AppAuth
- type Client
- func (c *Client) CleanStaleWebhooks(ctx context.Context)
- func (c *Client) DeregisterWebhooks(ctx context.Context, hooks []ManagedWebhook)
- func (c *Client) FetchJobImage(ctx context.Context, repo string, runID int64, jobID int64) string
- func (c *Client) IsOrgLevel() bool
- func (c *Client) PingWebhook(ctx context.Context, m ManagedWebhook) error
- func (c *Client) PollJobs(ctx context.Context) ([]JobEvent, error)
- func (c *Client) RateSnapshot() (remaining, limit int64, reset, updated time.Time)
- func (c *Client) RegisterJITRunner(ctx context.Context, repo string, name string, labels []string) (*gh.JITRunnerConfig, error)
- func (c *Client) RegisterWebhooks(ctx context.Context, webhookURL, secret string) ([]ManagedWebhook, error)
- func (c *Client) RemoveRunner(ctx context.Context, repo string, runnerID int64) error
- func (c *Client) SetHTTPClient(ghClient *gh.Client)
- func (c *Client) WebhookHandler(secret string) (http.Handler, <-chan JobEvent)
- type Config
- type JobEvent
- type ManagedWebhook
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppAuth ¶
type AppAuth struct {
// contains filtered or unexported fields
}
AppAuth manages GitHub App installation tokens with automatic refresh. Installation tokens expire after 1 hour; this refreshes at 45 minutes.
func NewAppAuth ¶
NewAppAuth loads the PEM key and returns an AppAuth that mints and refreshes GitHub App installation tokens.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client handles GitHub API interactions and webhook events.
func New ¶
New creates a GitHub client. Uses AppAuth for dynamic token refresh when configured, otherwise a static PAT.
All GitHub API responses flow through rateTrackingTransport, which parses the X-RateLimit-* headers and updates the ephemerd_github_api_rate_* gauges. Operators use ephemerd_github_api_rate_updated_seconds to tell a current-but-exhausted budget from a stale reading.
func (*Client) CleanStaleWebhooks ¶
CleanStaleWebhooks removes any workflow_job webhooks left behind by previous ephemerd instances that crashed or were killed without cleanup. Called on startup before registering new webhooks to avoid hitting GitHub's 20-hook limit.
Skipped entirely in pool mode: this sweep deletes every workflow_job hook it can see, and in a pooled fleet those are live hooks belonging to pool-mates (or other pools). Adoption in RegisterWebhooks makes the sweep unnecessary for pooled nodes — same-URL hooks are reused, not duplicated.
func (*Client) DeregisterWebhooks ¶
func (c *Client) DeregisterWebhooks(ctx context.Context, hooks []ManagedWebhook)
DeregisterWebhooks removes all managed webhooks. Called on shutdown. No-op in pool mode: the hook is shared with pool-mates that are still serving; the pool's lifecycle owner (e.g. mayfly destroying the pool) removes it when the last member goes away.
func (*Client) FetchJobImage ¶
FetchJobImage fetches the workflow run's job definition and reads the container image declared in the job's `container:` field. This requires an extra API call per job but lets users specify the image directly in their workflow:
jobs:
build:
runs-on: [self-hosted, linux, x64]
container:
image: ghcr.io/myorg/custom-build:latest
quick:
runs-on: [self-hosted, linux, x64]
container: ghcr.io/myorg/quick:latest # shorthand
Returns empty string if no container image is set.
func (*Client) IsOrgLevel ¶
IsOrgLevel returns true when no repos are configured, meaning ephemerd registers runners at the organization level (available to all repos).
func (*Client) PingWebhook ¶
func (c *Client) PingWebhook(ctx context.Context, m ManagedWebhook) error
PingWebhook triggers a ping event for a managed webhook.
func (*Client) PollJobs ¶
PollJobs checks for queued workflow jobs targeting self-hosted runners. If repos are configured, polls those repos. Otherwise, polls all repos in the org.
func (*Client) RateSnapshot ¶
RateSnapshot returns the last-observed rate-limit state. The scheduler uses this to bias retry backoff — when remaining==0 and now < reset, the next attempt is scheduled just after reset instead of blindly falling through the exponential-backoff ladder. Fields are zero-valued when the client hasn't yet made a request or was created via the bare test constructor.
func (*Client) RegisterJITRunner ¶
func (c *Client) RegisterJITRunner(ctx context.Context, repo string, name string, labels []string) (*gh.JITRunnerConfig, error)
RegisterJITRunner creates a just-in-time runner. If repos are configured, registers at the repo level. If repos are empty, registers at the org level (available to all repos in the org).
func (*Client) RegisterWebhooks ¶
func (c *Client) RegisterWebhooks(ctx context.Context, webhookURL, secret string) ([]ManagedWebhook, error)
RegisterWebhooks creates workflow_job webhooks on each configured repo (or the org) pointing at the given URL with the given secret. Returns the managed hooks for cleanup.
It is idempotent: before creating a hook it lists the existing hooks and, if one already points at webhookURL, reuses it instead of creating a duplicate. GitHub rejects a duplicate hook config with HTTP 422, so without this the external-tunnel path (which re-registers on every startup) would fail on the second boot.
In pool mode the reuse is upgraded to adopt: the existing hook (registered by a pool-mate) is edited in place so secret/events/active converge on this member's config — pool members must present one shared secret. A create that still races a pool-mate to a 422 resolves by adopting the winner's hook.
func (*Client) RemoveRunner ¶
RemoveRunner removes a self-hosted runner by ID. Uses org-level or repo-level API depending on configuration.
func (*Client) SetHTTPClient ¶
SetHTTPClient replaces the underlying go-github client. Used by test infrastructure to point at a fake server.
type Config ¶
type Config struct {
Token string
Owner string
Repos []string
Log *slog.Logger
// App auth (used instead of Token when set)
AppAuth *AppAuth
// PoolMode changes webhook lifecycle semantics for nodes sharing one
// public webhook URL: registration adopts an existing same-URL hook,
// deregistration is a no-op, and the stale-hook sweep is skipped.
PoolMode bool
}
Config for the GitHub client.
type JobEvent ¶
type JobEvent struct {
Action string
Repo string
Job *gh.WorkflowJob
}
JobEvent is emitted when a workflow_job webhook fires.
type ManagedWebhook ¶
ManagedWebhook tracks a webhook created by ephemerd so it can be cleaned up on shutdown.