refactor: drop logrus and other direct dependencies (#1319)

After https://gitea.com/gitea/runner/pulls/1304, logrus stayed only to forward logs from docker/cli and moby/go-archive. The runner used a small part of those: volume parsing, the build context tar, the `ssh://` connection and registry credentials. Own code that matches them replaces them, so logrus leaves the module graph. docker/cli stays for its logrus-free `opts` and `connhelper/ssh` packages.

Other dependencies that the standard library or existing ones cover go too: mergo, httprouter (replaced by `http.ServeMux`), retry-go, go-isatty, go-selinux, container-device-interface, gotest.tools and go-cmp (replaced by testify). The binary shrinks by 5%.

Behaviour differences:

1. An unreadable file in a build context is skipped with a warning, where go-archive left a truncated tar.
2. Build contexts no longer carry `security.capability` xattrs.
3. The cache and artifact servers answer HEAD on GET routes, and no longer redirect trailing slashes or answer OPTIONS.

*Written by Claude.*

---------

Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1319
Reviewed-by: bircni <[email protected]>
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: silverwind <[email protected]>
This commit is contained in:
silverwindandbircni authored and Lunny Xiao committed 2026-10-18 18:57:08 +00:00
1 parent e356c2ed85
commit 4158e05dae
43 files changed
+1188 -510

No files matched your search

+18 -19
View File
@@ -33,9 +33,8 @@ import (
"connectrpc.com/connect"
runnerv1 "gitea.dev/actionslib/runner/v1"
"github.com/avast/retry-go/v5"
"github.com/mattn/go-isatty"
"github.com/spf13/cobra"
"golang.org/x/term"
)
func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) func(cmd *cobra.Command, args []string) error {
@@ -189,22 +188,22 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
}()
// declare the labels of the runner before fetching tasks
resp, err := retry.NewWithData[*connect.Response[runnerv1.DeclareResponse]](
retry.Context(ctx),
retry.UntilSucceeded(),
retry.Delay(declareRetryDelay),
retry.DelayType(retry.FixedDelay),
retry.RetryIf(shouldRetryDeclare),
retry.OnRetry(func(attempt uint, err error) {
if attempt == 0 {
logging.WithError(err).Warn("fail to invoke Declare, retrying until Gitea is reachable")
} else {
logging.WithError(err).Debug("fail to invoke Declare, retrying")
}
}),
).Do(func() (*connect.Response[runnerv1.DeclareResponse], error) {
return runner.Declare(ctx, ls.Names())
})
var resp *connect.Response[runnerv1.DeclareResponse]
for attempt := 0; ; attempt++ {
resp, err = runner.Declare(ctx, ls.Names())
if err == nil || !shouldRetryDeclare(err) || ctx.Err() != nil {
break
}
if attempt == 0 {
logging.WithError(err).Warn("fail to invoke Declare, retrying until Gitea is reachable")
} else {
logging.WithError(err).Debug("fail to invoke Declare, retrying")
}
select {
case <-time.After(declareRetryDelay):
case <-ctx.Done():
}
}
switch {
case err != nil && ctx.Err() != nil && !client.IsRegistrationRejected(err):
return nil
@@ -340,7 +339,7 @@ func initLogging(cfg *config.Config) {
return funcname, filename
}
isTerm := isatty.IsTerminal(os.Stdout.Fd())
isTerm := term.IsTerminal(int(os.Stdout.Fd()))
logging.SetTextFormat(logging.TextOptions{
DisableColors: !isTerm,
FullTimestamp: true,
-7
View File
@@ -188,10 +188,3 @@ func TestShouldRetryDeclare(t *testing.T) {
require.Equal(t, tc.retry, shouldRetryDeclare(tc.err), tc.err.Error())
}
}
// A dependency that reconfigures logrus's global logger when it is loaded makes its own log lines
// show up twice or not at all, so this fails when upgrading one starts doing that. It does not
// cover a dependency that does so later, while running.
func TestLogrusBridgeSurvivesDependencies(t *testing.T) {
require.True(t, logging.LogrusBridgeIntact())
}
+2 -2
View File
@@ -24,15 +24,15 @@ import (
"connectrpc.com/connect"
pingv1 "gitea.dev/actionslib/ping/v1"
runnerv1 "gitea.dev/actionslib/runner/v1"
"github.com/mattn/go-isatty"
"github.com/spf13/cobra"
"golang.org/x/term"
)
// runRegister registers a runner to the server
func runRegister(ctx context.Context, regArgs *registerArgs, configFile *string) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
logging.SetReportCaller(false)
isTerm := isatty.IsTerminal(os.Stdout.Fd())
isTerm := term.IsTerminal(int(os.Stdout.Fd()))
logging.SetTextFormat(logging.TextOptions{
DisableColors: !isTerm,
DisableTimestamp: true,
+3 -4
View File
@@ -14,7 +14,6 @@ import (
"gitea.com/gitea/runner/internal/pkg/config"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
)
func TestRegisterNonInteractiveReturnsLabelValidationError(t *testing.T) {
@@ -23,7 +22,7 @@ func TestRegisterNonInteractiveReturnsLabelValidationError(t *testing.T) {
Token: "token",
InstanceAddr: "http://localhost:3000",
})
assert.ErrorContains(t, err, "empty label")
require.ErrorContains(t, err, "empty label")
}
func TestRegisterInputsValidate(t *testing.T) {
@@ -262,6 +261,6 @@ func TestDoRegisterReturnsPingErrorWithoutRetrying(t *testing.T) {
cfg := &config.Config{}
cfg.Runner.File = filepath.Join(t.TempDir(), ".runner")
err := doRegister(t.Context(), cfg, &registerInputs{InstanceAddr: server.URL, RunnerName: "runner"})
assert.ErrorContains(t, err, "cannot ping the Gitea instance server")
assert.Equal(t, int32(1), requests.Load())
require.ErrorContains(t, err, "cannot ping the Gitea instance server")
require.Equal(t, int32(1), requests.Load())
}