summaryrefslogtreecommitdiffstats
path: root/internal/pkg/client
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/client')
-rw-r--r--internal/pkg/client/client.go19
-rw-r--r--internal/pkg/client/header.go11
-rw-r--r--internal/pkg/client/http.go82
-rw-r--r--internal/pkg/client/mocks/Client.go219
4 files changed, 331 insertions, 0 deletions
diff --git a/internal/pkg/client/client.go b/internal/pkg/client/client.go
new file mode 100644
index 0000000..57f91ad
--- /dev/null
+++ b/internal/pkg/client/client.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package client
+
+import (
+ "code.gitea.io/actions-proto-go/ping/v1/pingv1connect"
+ "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect"
+)
+
+// A Client manages communication with the runner.
+//
+//go:generate mockery --name Client
+type Client interface {
+ pingv1connect.PingServiceClient
+ runnerv1connect.RunnerServiceClient
+ Address() string
+ Insecure() bool
+}
diff --git a/internal/pkg/client/header.go b/internal/pkg/client/header.go
new file mode 100644
index 0000000..24844fa
--- /dev/null
+++ b/internal/pkg/client/header.go
@@ -0,0 +1,11 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package client
+
+const (
+ UUIDHeader = "x-runner-uuid"
+ TokenHeader = "x-runner-token"
+ // Deprecated: could be removed after Gitea 1.20 released
+ VersionHeader = "x-runner-version"
+)
diff --git a/internal/pkg/client/http.go b/internal/pkg/client/http.go
new file mode 100644
index 0000000..d365a77
--- /dev/null
+++ b/internal/pkg/client/http.go
@@ -0,0 +1,82 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package client
+
+import (
+ "context"
+ "crypto/tls"
+ "net/http"
+ "strings"
+
+ "code.gitea.io/actions-proto-go/ping/v1/pingv1connect"
+ "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect"
+ "connectrpc.com/connect"
+)
+
+func getHTTPClient(endpoint string, insecure bool) *http.Client {
+ if strings.HasPrefix(endpoint, "https://") && insecure {
+ return &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{
+ InsecureSkipVerify: true,
+ },
+ },
+ }
+ }
+ return http.DefaultClient
+}
+
+// New returns a new runner client.
+func New(endpoint string, insecure bool, uuid, token, version string, opts ...connect.ClientOption) *HTTPClient {
+ baseURL := strings.TrimRight(endpoint, "/") + "/api/actions"
+
+ opts = append(opts, connect.WithInterceptors(connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc {
+ return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
+ if uuid != "" {
+ req.Header().Set(UUIDHeader, uuid)
+ }
+ if token != "" {
+ req.Header().Set(TokenHeader, token)
+ }
+ // TODO: version will be removed from request header after Gitea 1.20 released.
+ if version != "" {
+ req.Header().Set(VersionHeader, version)
+ }
+ return next(ctx, req)
+ }
+ })))
+
+ return &HTTPClient{
+ PingServiceClient: pingv1connect.NewPingServiceClient(
+ getHTTPClient(endpoint, insecure),
+ baseURL,
+ opts...,
+ ),
+ RunnerServiceClient: runnerv1connect.NewRunnerServiceClient(
+ getHTTPClient(endpoint, insecure),
+ baseURL,
+ opts...,
+ ),
+ endpoint: endpoint,
+ insecure: insecure,
+ }
+}
+
+func (c *HTTPClient) Address() string {
+ return c.endpoint
+}
+
+func (c *HTTPClient) Insecure() bool {
+ return c.insecure
+}
+
+var _ Client = (*HTTPClient)(nil)
+
+// An HTTPClient manages communication with the runner API.
+type HTTPClient struct {
+ pingv1connect.PingServiceClient
+ runnerv1connect.RunnerServiceClient
+ endpoint string
+ insecure bool
+}
diff --git a/internal/pkg/client/mocks/Client.go b/internal/pkg/client/mocks/Client.go
new file mode 100644
index 0000000..a8bfdb1
--- /dev/null
+++ b/internal/pkg/client/mocks/Client.go
@@ -0,0 +1,219 @@
+// Code generated by mockery v2.26.1. DO NOT EDIT.
+
+package mocks
+
+import (
+ context "context"
+
+ connect "connectrpc.com/connect"
+
+ mock "github.com/stretchr/testify/mock"
+
+ pingv1 "code.gitea.io/actions-proto-go/ping/v1"
+
+ runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
+)
+
+// Client is an autogenerated mock type for the Client type
+type Client struct {
+ mock.Mock
+}
+
+// Address provides a mock function with given fields:
+func (_m *Client) Address() string {
+ ret := _m.Called()
+
+ var r0 string
+ if rf, ok := ret.Get(0).(func() string); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Get(0).(string)
+ }
+
+ return r0
+}
+
+// Declare provides a mock function with given fields: _a0, _a1
+func (_m *Client) Declare(_a0 context.Context, _a1 *connect.Request[runnerv1.DeclareRequest]) (*connect.Response[runnerv1.DeclareResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[runnerv1.DeclareResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.DeclareRequest]) (*connect.Response[runnerv1.DeclareResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.DeclareRequest]) *connect.Response[runnerv1.DeclareResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[runnerv1.DeclareResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[runnerv1.DeclareRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// FetchTask provides a mock function with given fields: _a0, _a1
+func (_m *Client) FetchTask(_a0 context.Context, _a1 *connect.Request[runnerv1.FetchTaskRequest]) (*connect.Response[runnerv1.FetchTaskResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[runnerv1.FetchTaskResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.FetchTaskRequest]) (*connect.Response[runnerv1.FetchTaskResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.FetchTaskRequest]) *connect.Response[runnerv1.FetchTaskResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[runnerv1.FetchTaskResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[runnerv1.FetchTaskRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// Insecure provides a mock function with given fields:
+func (_m *Client) Insecure() bool {
+ ret := _m.Called()
+
+ var r0 bool
+ if rf, ok := ret.Get(0).(func() bool); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ return r0
+}
+
+// Ping provides a mock function with given fields: _a0, _a1
+func (_m *Client) Ping(_a0 context.Context, _a1 *connect.Request[pingv1.PingRequest]) (*connect.Response[pingv1.PingResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[pingv1.PingResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[pingv1.PingRequest]) (*connect.Response[pingv1.PingResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[pingv1.PingRequest]) *connect.Response[pingv1.PingResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[pingv1.PingResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[pingv1.PingRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// Register provides a mock function with given fields: _a0, _a1
+func (_m *Client) Register(_a0 context.Context, _a1 *connect.Request[runnerv1.RegisterRequest]) (*connect.Response[runnerv1.RegisterResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[runnerv1.RegisterResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.RegisterRequest]) (*connect.Response[runnerv1.RegisterResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.RegisterRequest]) *connect.Response[runnerv1.RegisterResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[runnerv1.RegisterResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[runnerv1.RegisterRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// UpdateLog provides a mock function with given fields: _a0, _a1
+func (_m *Client) UpdateLog(_a0 context.Context, _a1 *connect.Request[runnerv1.UpdateLogRequest]) (*connect.Response[runnerv1.UpdateLogResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[runnerv1.UpdateLogResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.UpdateLogRequest]) (*connect.Response[runnerv1.UpdateLogResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.UpdateLogRequest]) *connect.Response[runnerv1.UpdateLogResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[runnerv1.UpdateLogResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[runnerv1.UpdateLogRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// UpdateTask provides a mock function with given fields: _a0, _a1
+func (_m *Client) UpdateTask(_a0 context.Context, _a1 *connect.Request[runnerv1.UpdateTaskRequest]) (*connect.Response[runnerv1.UpdateTaskResponse], error) {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 *connect.Response[runnerv1.UpdateTaskResponse]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.UpdateTaskRequest]) (*connect.Response[runnerv1.UpdateTaskResponse], error)); ok {
+ return rf(_a0, _a1)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[runnerv1.UpdateTaskRequest]) *connect.Response[runnerv1.UpdateTaskResponse]); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*connect.Response[runnerv1.UpdateTaskResponse])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[runnerv1.UpdateTaskRequest]) error); ok {
+ r1 = rf(_a0, _a1)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+type mockConstructorTestingTNewClient interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewClient(t mockConstructorTestingTNewClient) *Client {
+ mock := &Client{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}