// Package giteaactions provides the authenticated Gitea RunnerService client. package giteaactions import ( "context" "net/http" "strings" "connectrpc.com/connect" "gitea.dev/actionslib/pkg/protocol" runnerv1 "gitea.dev/actionslib/runner/v1" "gitea.dev/actionslib/runner/v1/runnerv1connect" ) // Client is the subset of RunnerService owned by the scheduler. type Client struct { runner runnerv1connect.RunnerServiceClient } // NewClient authenticates every RPC with the persistent scheduler runner. func NewClient(httpClient connect.HTTPClient, instanceURL, uuid, token string) *Client { auth := connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, request connect.AnyRequest) (connect.AnyResponse, error) { request.Header().Set("User-Agent", "gitea-dynamic-runner-go/0") request.Header().Set(protocol.UUIDHeader, uuid) request.Header().Set(protocol.TokenHeader, token) return next(ctx, request) } }) baseURL := strings.TrimRight(instanceURL, "/") + "/api/actions" return &Client{runner: runnerv1connect.NewRunnerServiceClient( httpClient, baseURL, connect.WithInterceptors(auth), )} } // Declare advertises the scheduler labels before tasks are fetched. func (c *Client) Declare(ctx context.Context, version string, labels []string) error { _, err := c.runner.Declare(ctx, connect.NewRequest(&runnerv1.DeclareRequest{ Version: version, Labels: labels, })) return err } // FetchTask asks Gitea to atomically assign the next matching task. func (c *Client) FetchTask(ctx context.Context, tasksVersion int64) (*runnerv1.FetchTaskResponse, error) { response, err := c.runner.FetchTask(ctx, connect.NewRequest(&runnerv1.FetchTaskRequest{ TasksVersion: tasksVersion, })) if err != nil { return nil, err } return response.Msg, nil } // UpdateTask forwards executor state through the scheduler runner identity. func (c *Client) UpdateTask(ctx context.Context, request *connect.Request[runnerv1.UpdateTaskRequest]) (*connect.Response[runnerv1.UpdateTaskResponse], error) { return c.runner.UpdateTask(ctx, request) } // UpdateLog forwards executor log rows through the scheduler runner identity. func (c *Client) UpdateLog(ctx context.Context, request *connect.Request[runnerv1.UpdateLogRequest]) (*connect.Response[runnerv1.UpdateLogResponse], error) { return c.runner.UpdateLog(ctx, request) } // DefaultHTTPClient is suitable for the scheduler's long-lived connection. func DefaultHTTPClient() *http.Client { return &http.Client{Transport: http.DefaultTransport} }