diff --git a/cli/admin/admin.go b/cli/admin/admin.go index 39187c2c9e..351efc0d55 100644 --- a/cli/admin/admin.go +++ b/cli/admin/admin.go @@ -15,7 +15,7 @@ package admin import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/admin/registry" ) @@ -24,7 +24,7 @@ import ( var Command = &cli.Command{ Name: "admin", Usage: "administer server settings", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ registry.Command, }, } diff --git a/cli/admin/registry/registry.go b/cli/admin/registry/registry.go index 4f091d0e3c..3d9c4de500 100644 --- a/cli/admin/registry/registry.go +++ b/cli/admin/registry/registry.go @@ -15,14 +15,14 @@ package registry import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Command exports the registry command set. var Command = &cli.Command{ Name: "registry", Usage: "manage global registries", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ registryCreateCmd, registryDeleteCmd, registryUpdateCmd, diff --git a/cli/admin/registry/registry_add.go b/cli/admin/registry/registry_add.go index 9f779ad8f3..a378a8a2f6 100644 --- a/cli/admin/registry/registry_add.go +++ b/cli/admin/registry/registry_add.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -45,14 +46,14 @@ var registryCreateCmd = &cli.Command{ }, } -func registryCreate(c *cli.Context) error { +func registryCreate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/admin/registry/registry_info.go b/cli/admin/registry/registry_info.go index 770a7074e7..80b78546f5 100644 --- a/cli/admin/registry/registry_info.go +++ b/cli/admin/registry/registry_info.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -38,13 +39,13 @@ var registryInfoCmd = &cli.Command{ }, } -func registryInfo(c *cli.Context) error { +func registryInfo(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") format = c.String("format") + "\n" ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/admin/registry/registry_list.go b/cli/admin/registry/registry_list.go index f40f15ed80..6f57889672 100644 --- a/cli/admin/registry/registry_list.go +++ b/cli/admin/registry/registry_list.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,10 +34,10 @@ var registryListCmd = &cli.Command{ }, } -func registryList(c *cli.Context) error { +func registryList(ctx context.Context, c *cli.Command) error { format := c.String("format") + "\n" - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/admin/registry/registry_rm.go b/cli/admin/registry/registry_rm.go index 752696aff7..3dfb02c1fb 100644 --- a/cli/admin/registry/registry_rm.go +++ b/cli/admin/registry/registry_rm.go @@ -15,7 +15,9 @@ package registry import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -33,10 +35,10 @@ var registryDeleteCmd = &cli.Command{ }, } -func registryDelete(c *cli.Context) error { +func registryDelete(ctx context.Context, c *cli.Command) error { hostname := c.String("hostname") - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/admin/registry/registry_set.go b/cli/admin/registry/registry_set.go index 26daa140a0..4196a982de 100644 --- a/cli/admin/registry/registry_set.go +++ b/cli/admin/registry/registry_set.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -47,14 +48,14 @@ var registryUpdateCmd = &cli.Command{ }, } -func registryUpdate(c *cli.Context) error { +func registryUpdate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/common/flags.go b/cli/common/flags.go index 6a74312495..4b81505a95 100644 --- a/cli/common/flags.go +++ b/cli/common/flags.go @@ -15,49 +15,49 @@ package common import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/shared/logger" ) var GlobalFlags = append([]cli.Flag{ &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_CONFIG"}, + Sources: cli.EnvVars("WOODPECKER_CONFIG"), Name: "config", Aliases: []string{"c"}, Usage: "path to config file", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER"}, + Sources: cli.EnvVars("WOODPECKER_SERVER"), Name: "server", Aliases: []string{"s"}, Usage: "server address", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_TOKEN"}, + Sources: cli.EnvVars("WOODPECKER_TOKEN"), Name: "token", Aliases: []string{"t"}, Usage: "server auth token", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_DISABLE_UPDATE_CHECK"}, + Sources: cli.EnvVars("WOODPECKER_DISABLE_UPDATE_CHECK"), Name: "disable-update-check", Usage: "disable update check", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_SKIP_VERIFY"}, + Sources: cli.EnvVars("WOODPECKER_SKIP_VERIFY"), Name: "skip-verify", Usage: "skip ssl verification", Hidden: true, }, &cli.StringFlag{ - EnvVars: []string{"SOCKS_PROXY"}, + Sources: cli.EnvVars("SOCKS_PROXY"), Name: "socks-proxy", Usage: "socks proxy address", Hidden: true, }, &cli.BoolFlag{ - EnvVars: []string{"SOCKS_PROXY_OFF"}, + Sources: cli.EnvVars("SOCKS_PROXY_OFF"), Name: "socks-proxy-off", Usage: "socks proxy ignored", Hidden: true, diff --git a/cli/common/hooks.go b/cli/common/hooks.go index 952742cba2..7a54435384 100644 --- a/cli/common/hooks.go +++ b/cli/common/hooks.go @@ -6,7 +6,7 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal/config" "go.woodpecker-ci.org/woodpecker/v2/cli/update" @@ -17,12 +17,12 @@ var ( cancelWaitForUpdate context.CancelCauseFunc ) -func Before(c *cli.Context) error { - if err := setupGlobalLogger(c); err != nil { +func Before(ctx context.Context, c *cli.Command) error { + if err := setupGlobalLogger(ctx, c); err != nil { return err } - go func() { + go func(context.Context) { if c.Bool("disable-update-check") { return } @@ -37,23 +37,23 @@ func Before(c *cli.Context) error { log.Debug().Msg("Checking for updates ...") - newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) + newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) //nolint:contextcheck if err != nil { log.Error().Err(err).Msgf("Failed to check for updates") return } if newVersion != nil { - log.Warn().Msgf("A new version of woodpecker-cli is available: %s. Update by running: %s update", newVersion.Version, c.App.Name) + log.Warn().Msgf("A new version of woodpecker-cli is available: %s. Update by running: %s update", newVersion.Version, c.Root().Name) } else { log.Debug().Msgf("No update required") } - }() + }(ctx) - return config.Load(c) + return config.Load(ctx, c) } -func After(_ *cli.Context) error { +func After(_ context.Context, _ *cli.Command) error { if waitForUpdateCheck != nil { select { case <-waitForUpdateCheck.Done(): diff --git a/cli/common/pipeline.go b/cli/common/pipeline.go index b479e56937..fba8cb54ac 100644 --- a/cli/common/pipeline.go +++ b/cli/common/pipeline.go @@ -15,11 +15,12 @@ package common import ( + "context" "fmt" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/shared/constant" ) @@ -37,16 +38,16 @@ func DetectPipelineConfig() (isDir bool, config string, _ error) { return false, "", fmt.Errorf("could not detect pipeline config") } -func RunPipelineFunc(c *cli.Context, fileFunc, dirFunc func(*cli.Context, string) error) error { +func RunPipelineFunc(ctx context.Context, c *cli.Command, fileFunc, dirFunc func(context.Context, *cli.Command, string) error) error { if c.Args().Len() == 0 { isDir, path, err := DetectPipelineConfig() if err != nil { return err } if isDir { - return dirFunc(c, path) + return dirFunc(ctx, c, path) } - return fileFunc(c, path) + return fileFunc(ctx, c, path) } multiArgs := c.Args().Len() > 1 @@ -59,11 +60,11 @@ func RunPipelineFunc(c *cli.Context, fileFunc, dirFunc func(*cli.Context, string fmt.Println("#", fi.Name()) } if fi.IsDir() { - if err := dirFunc(c, arg); err != nil { + if err := dirFunc(ctx, c, arg); err != nil { return err } } else { - if err := fileFunc(c, arg); err != nil { + if err := fileFunc(ctx, c, arg); err != nil { return err } } diff --git a/cli/common/zerologger.go b/cli/common/zerologger.go index d3e275898b..7c932c83db 100644 --- a/cli/common/zerologger.go +++ b/cli/common/zerologger.go @@ -15,11 +15,13 @@ package common import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/shared/logger" ) -func setupGlobalLogger(c *cli.Context) error { - return logger.SetupGlobalLogger(c, false) +func setupGlobalLogger(ctx context.Context, c *cli.Command) error { + return logger.SetupGlobalLogger(ctx, c, false) } diff --git a/cli/cron/cron.go b/cli/cron/cron.go index 97b9ac43cc..efcfa2c17e 100644 --- a/cli/cron/cron.go +++ b/cli/cron/cron.go @@ -15,14 +15,14 @@ package cron import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Command exports the cron command set. var Command = &cli.Command{ Name: "cron", Usage: "manage cron jobs", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ cronCreateCmd, cronDeleteCmd, cronUpdateCmd, diff --git a/cli/cron/cron_add.go b/cli/cron/cron_add.go index 2eb5eddd42..2ab730e0d2 100644 --- a/cli/cron/cron_add.go +++ b/cli/cron/cron_add.go @@ -15,10 +15,11 @@ package cron import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -50,9 +51,9 @@ var cronCreateCmd = &cli.Command{ }, } -func cronCreate(c *cli.Context) error { +func cronCreate(ctx context.Context, c *cli.Command) error { var ( - jobName = c.String("name") + cronName = c.String("name") branch = c.String("branch") schedule = c.String("schedule") repoIDOrFullName = c.String("repository") @@ -62,7 +63,7 @@ func cronCreate(c *cli.Context) error { repoIDOrFullName = c.Args().First() } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } @@ -73,7 +74,7 @@ func cronCreate(c *cli.Context) error { } cron := &woodpecker.Cron{ - Name: jobName, + Name: cronName, Branch: branch, Schedule: schedule, } diff --git a/cli/cron/cron_info.go b/cli/cron/cron_info.go index fd6f16bc17..276ed15a91 100644 --- a/cli/cron/cron_info.go +++ b/cli/cron/cron_info.go @@ -15,10 +15,11 @@ package cron import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -40,16 +41,16 @@ var cronInfoCmd = &cli.Command{ }, } -func cronInfo(c *cli.Context) error { +func cronInfo(ctx context.Context, c *cli.Command) error { var ( - jobID = c.Int64("id") + cronID = c.Int("id") repoIDOrFullName = c.String("repository") format = c.String("format") + "\n" ) if repoIDOrFullName == "" { repoIDOrFullName = c.Args().First() } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } @@ -58,7 +59,7 @@ func cronInfo(c *cli.Context) error { return err } - cron, err := client.CronGet(repoID, jobID) + cron, err := client.CronGet(repoID, cronID) if err != nil { return err } diff --git a/cli/cron/cron_list.go b/cli/cron/cron_list.go index edd6c88d35..b51a7aaee6 100644 --- a/cli/cron/cron_list.go +++ b/cli/cron/cron_list.go @@ -15,10 +15,11 @@ package cron import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -35,7 +36,7 @@ var cronListCmd = &cli.Command{ }, } -func cronList(c *cli.Context) error { +func cronList(ctx context.Context, c *cli.Command) error { var ( format = c.String("format") + "\n" repoIDOrFullName = c.String("repository") @@ -43,7 +44,7 @@ func cronList(c *cli.Context) error { if repoIDOrFullName == "" { repoIDOrFullName = c.Args().First() } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/cron/cron_rm.go b/cli/cron/cron_rm.go index 0e6fbc4c08..048dcd605f 100644 --- a/cli/cron/cron_rm.go +++ b/cli/cron/cron_rm.go @@ -15,9 +15,10 @@ package cron import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -38,15 +39,15 @@ var cronDeleteCmd = &cli.Command{ }, } -func cronDelete(c *cli.Context) error { +func cronDelete(ctx context.Context, c *cli.Command) error { var ( - jobID = c.Int64("id") + cronID = c.Int("id") repoIDOrFullName = c.String("repository") ) if repoIDOrFullName == "" { repoIDOrFullName = c.Args().First() } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } @@ -54,7 +55,7 @@ func cronDelete(c *cli.Context) error { if err != nil { return err } - err = client.CronDelete(repoID, jobID) + err = client.CronDelete(repoID, cronID) if err != nil { return err } diff --git a/cli/cron/cron_update.go b/cli/cron/cron_update.go index 0c25f03f7f..de66e9a1fc 100644 --- a/cli/cron/cron_update.go +++ b/cli/cron/cron_update.go @@ -15,10 +15,11 @@ package cron import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -53,10 +54,10 @@ var cronUpdateCmd = &cli.Command{ }, } -func cronUpdate(c *cli.Context) error { +func cronUpdate(ctx context.Context, c *cli.Command) error { var ( repoIDOrFullName = c.String("repository") - jobID = c.Int64("id") + cronID = c.Int("id") jobName = c.String("name") branch = c.String("branch") schedule = c.String("schedule") @@ -65,7 +66,7 @@ func cronUpdate(c *cli.Context) error { if repoIDOrFullName == "" { repoIDOrFullName = c.Args().First() } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } @@ -74,7 +75,7 @@ func cronUpdate(c *cli.Context) error { return err } cron := &woodpecker.Cron{ - ID: jobID, + ID: cronID, Name: jobName, Branch: branch, Schedule: schedule, diff --git a/cli/deploy/deploy.go b/cli/deploy/deploy.go index d5786e110d..a037d109d0 100644 --- a/cli/deploy/deploy.go +++ b/cli/deploy/deploy.go @@ -15,12 +15,13 @@ package deploy import ( + "context" "fmt" "html/template" "os" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -57,8 +58,8 @@ var Command = &cli.Command{ }, } -func deploy(c *cli.Context) error { - client, err := internal.NewClient(c) +func deploy(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/exec/exec.go b/cli/exec/exec.go index 76e4da5380..df5885ef59 100644 --- a/cli/exec/exec.go +++ b/cli/exec/exec.go @@ -26,7 +26,7 @@ import ( "github.com/drone/envsubst" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/lint" @@ -59,11 +59,11 @@ var backends = []backend_types.Backend{ local.New(), } -func run(c *cli.Context) error { - return common.RunPipelineFunc(c, execFile, execDir) +func run(ctx context.Context, c *cli.Command) error { + return common.RunPipelineFunc(ctx, c, execFile, execDir) } -func execDir(c *cli.Context, dir string) error { +func execDir(ctx context.Context, c *cli.Command, dir string) error { // TODO: respect pipeline dependency repoPath := c.String("repo-path") if repoPath != "" { @@ -82,7 +82,7 @@ func execDir(c *cli.Context, dir string) error { // check if it is a regular file (not dir) if info.Mode().IsRegular() && (strings.HasSuffix(info.Name(), ".yaml") || strings.HasSuffix(info.Name(), ".yml")) { fmt.Println("#", info.Name()) - _ = runExec(c, path, repoPath) // TODO: should we drop errors or store them and report back? + _ = runExec(ctx, c, path, repoPath) // TODO: should we drop errors or store them and report back? fmt.Println("") return nil } @@ -91,7 +91,7 @@ func execDir(c *cli.Context, dir string) error { }) } -func execFile(c *cli.Context, file string) error { +func execFile(ctx context.Context, c *cli.Command, file string) error { repoPath := c.String("repo-path") if repoPath != "" { repoPath, _ = filepath.Abs(repoPath) @@ -101,10 +101,10 @@ func execFile(c *cli.Context, file string) error { if runtime.GOOS == "windows" { repoPath = convertPathForWindows(repoPath) } - return runExec(c, file, repoPath) + return runExec(ctx, c, file, repoPath) } -func runExec(c *cli.Context, file, repoPath string) error { +func runExec(ctx context.Context, c *cli.Command, file, repoPath string) error { dat, err := os.ReadFile(file) if err != nil { return err @@ -119,7 +119,7 @@ func runExec(c *cli.Context, file, repoPath string) error { axes = append(axes, matrix.Axis{}) } for _, axis := range axes { - err := execWithAxis(c, file, repoPath, axis) + err := execWithAxis(ctx, c, file, repoPath, axis) if err != nil { return err } @@ -127,8 +127,8 @@ func runExec(c *cli.Context, file, repoPath string) error { return nil } -func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error { - metadata := metadataFromContext(c, axis) +func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, axis matrix.Axis) error { + metadata := metadataFromContext(ctx, c, axis) environ := metadata.Environ() var secrets []compiler.Secret for key, val := range metadata.Workflow.Matrix { @@ -235,7 +235,7 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error return err } - backendCtx := context.WithValue(c.Context, backend_types.CliContext, c) + backendCtx := context.WithValue(ctx, backend_types.CliCommand, c) backendEngine, err := backend.FindBackend(backendCtx, backends, c.String("backend-engine")) if err != nil { return err @@ -245,21 +245,21 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error return err } - ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout")) + pipelineCtx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout")) defer cancel() - ctx = utils.WithContextSigtermCallback(ctx, func() { - fmt.Println("ctrl+c received, terminating process") + pipelineCtx = utils.WithContextSigtermCallback(pipelineCtx, func() { + fmt.Printf("ctrl+c received, terminating current pipeline '%s'\n", confStr) }) return pipeline.New(compiled, - pipeline.WithContext(ctx), + pipeline.WithContext(pipelineCtx), //nolint:contextcheck pipeline.WithTracer(pipeline.DefaultTracer), pipeline.WithLogger(defaultLogger), pipeline.WithBackend(backendEngine), pipeline.WithDescription(map[string]string{ "CLI": "exec", }), - ).Run(c.Context) + ).Run(ctx) } // convertPathForWindows converts a path to use slash separators diff --git a/cli/exec/flags.go b/cli/exec/flags.go index 66178188fd..3b0c5d2955 100644 --- a/cli/exec/flags.go +++ b/cli/exec/flags.go @@ -17,41 +17,41 @@ package exec import ( "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/shared/constant" ) var flags = []cli.Flag{ &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_LOCAL"}, + Sources: cli.EnvVars("WOODPECKER_LOCAL"), Name: "local", Usage: "run from local directory", Value: true, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_REPO_PATH"}, + Sources: cli.EnvVars("WOODPECKER_REPO_PATH"), Name: "repo-path", Usage: "path to local repository", }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_TIMEOUT"}, + Sources: cli.EnvVars("WOODPECKER_TIMEOUT"), Name: "timeout", Usage: "pipeline timeout", Value: time.Hour, }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_VOLUMES"}, + Sources: cli.EnvVars("WOODPECKER_VOLUMES"), Name: "volumes", Usage: "pipeline volumes", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_NETWORKS"}, + Sources: cli.EnvVars("WOODPECKER_NETWORKS"), Name: "network", Usage: "external networks", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_PREFIX"}, + Sources: cli.EnvVars("WOODPECKER_PREFIX"), Name: "prefix", Value: "woodpecker", Usage: "prefix used for containers, volumes, networks, ... created by woodpecker", @@ -60,10 +60,10 @@ var flags = []cli.Flag{ &cli.StringSliceFlag{ Name: "privileged", Usage: "privileged plugins", - Value: cli.NewStringSlice(constant.PrivilegedPlugins...), + Value: constant.PrivilegedPlugins, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND"), Name: "backend-engine", Usage: "backend engine to run pipelines on", Value: "auto-detect", @@ -73,17 +73,17 @@ var flags = []cli.Flag{ // backend options for pipeline compiler // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_NO_PROXY", "NO_PROXY", "no_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_NO_PROXY", "NO_PROXY", "no_proxy"), Usage: "if set, pass the environment variable down as \"NO_PROXY\" to steps", Name: "backend-no-proxy", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_HTTP_PROXY", "HTTP_PROXY", "http_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_HTTP_PROXY", "HTTP_PROXY", "http_proxy"), Usage: "if set, pass the environment variable down as \"HTTP_PROXY\" to steps", Name: "backend-http-proxy", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_HTTPS_PROXY", "HTTPS_PROXY", "https_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_HTTPS_PROXY", "HTTPS_PROXY", "https_proxy"), Usage: "if set, pass the environment variable down as \"HTTPS_PROXY\" to steps", Name: "backend-https-proxy", }, @@ -97,12 +97,12 @@ var flags = []cli.Flag{ // workspace default // &cli.StringFlag{ - EnvVars: []string{"CI_WORKSPACE_BASE"}, + Sources: cli.EnvVars("CI_WORKSPACE_BASE"), Name: "workspace-base", Value: "/woodpecker", }, &cli.StringFlag{ - EnvVars: []string{"CI_WORKSPACE_PATH"}, + Sources: cli.EnvVars("CI_WORKSPACE_PATH"), Name: "workspace-path", Value: "src", }, @@ -110,218 +110,218 @@ var flags = []cli.Flag{ // netrc parameters // &cli.StringFlag{ - EnvVars: []string{"CI_NETRC_USERNAME"}, + Sources: cli.EnvVars("CI_NETRC_USERNAME"), Name: "netrc-username", }, &cli.StringFlag{ - EnvVars: []string{"CI_NETRC_PASSWORD"}, + Sources: cli.EnvVars("CI_NETRC_PASSWORD"), Name: "netrc-password", }, &cli.StringFlag{ - EnvVars: []string{"CI_NETRC_MACHINE"}, + Sources: cli.EnvVars("CI_NETRC_MACHINE"), Name: "netrc-machine", }, // // metadata parameters // &cli.StringFlag{ - EnvVars: []string{"CI_SYSTEM_PLATFORM"}, + Sources: cli.EnvVars("CI_SYSTEM_PLATFORM"), Name: "system-platform", }, &cli.StringFlag{ - EnvVars: []string{"CI_SYSTEM_NAME"}, + Sources: cli.EnvVars("CI_SYSTEM_NAME"), Name: "system-name", Value: "woodpecker", }, &cli.StringFlag{ - EnvVars: []string{"CI_SYSTEM_URL"}, + Sources: cli.EnvVars("CI_SYSTEM_URL"), Name: "system-url", Value: "https://github.com/woodpecker-ci/woodpecker", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO"}, + Sources: cli.EnvVars("CI_REPO"), Name: "repo", Usage: "full repo name", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO_REMOTE_ID"}, + Sources: cli.EnvVars("CI_REPO_REMOTE_ID"), Name: "repo-remote-id", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO_URL"}, + Sources: cli.EnvVars("CI_REPO_URL"), Name: "repo-url", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO_CLONE_URL"}, + Sources: cli.EnvVars("CI_REPO_CLONE_URL"), Name: "repo-clone-url", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO_CLONE_SSH_URL"}, + Sources: cli.EnvVars("CI_REPO_CLONE_SSH_URL"), Name: "repo-clone-ssh-url", }, &cli.StringFlag{ - EnvVars: []string{"CI_REPO_PRIVATE"}, + Sources: cli.EnvVars("CI_REPO_PRIVATE"), Name: "repo-private", }, &cli.BoolFlag{ - EnvVars: []string{"CI_REPO_TRUSTED"}, + Sources: cli.EnvVars("CI_REPO_TRUSTED"), Name: "repo-trusted", }, &cli.IntFlag{ - EnvVars: []string{"CI_PIPELINE_NUMBER"}, + Sources: cli.EnvVars("CI_PIPELINE_NUMBER"), Name: "pipeline-number", }, &cli.IntFlag{ - EnvVars: []string{"CI_PIPELINE_PARENT"}, + Sources: cli.EnvVars("CI_PIPELINE_PARENT"), Name: "pipeline-parent", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PIPELINE_CREATED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PIPELINE_CREATED"), Name: "pipeline-created", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PIPELINE_STARTED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PIPELINE_STARTED"), Name: "pipeline-started", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PIPELINE_FINISHED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PIPELINE_FINISHED"), Name: "pipeline-finished", }, &cli.StringFlag{ - EnvVars: []string{"CI_PIPELINE_STATUS"}, + Sources: cli.EnvVars("CI_PIPELINE_STATUS"), Name: "pipeline-status", }, &cli.StringFlag{ - EnvVars: []string{"CI_PIPELINE_EVENT"}, + Sources: cli.EnvVars("CI_PIPELINE_EVENT"), Name: "pipeline-event", Value: "manual", }, &cli.StringFlag{ - EnvVars: []string{"CI_PIPELINE_URL"}, + Sources: cli.EnvVars("CI_PIPELINE_URL"), Name: "pipeline-url", }, &cli.StringFlag{ - EnvVars: []string{"CI_PIPELINE_DEPLOY_TARGET", "CI_PIPELINE_TARGET"}, // TODO: remove CI_PIPELINE_TARGET in 3.x + Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TARGET", "CI_PIPELINE_TARGET"), // TODO: remove CI_PIPELINE_TARGET in 3.x Name: "pipeline-deploy-to", }, &cli.StringFlag{ - EnvVars: []string{"CI_PIPELINE_DEPLOY_TASK", "CI_PIPELINE_TASK"}, // TODO: remove CI_PIPELINE_TASK in 3.x + Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TASK", "CI_PIPELINE_TASK"), // TODO: remove CI_PIPELINE_TASK in 3.x Name: "pipeline-deploy-task", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_SHA"}, + Sources: cli.EnvVars("CI_COMMIT_SHA"), Name: "commit-sha", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_REF"}, + Sources: cli.EnvVars("CI_COMMIT_REF"), Name: "commit-ref", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_REFSPEC"}, + Sources: cli.EnvVars("CI_COMMIT_REFSPEC"), Name: "commit-refspec", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_BRANCH"}, + Sources: cli.EnvVars("CI_COMMIT_BRANCH"), Name: "commit-branch", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_MESSAGE"}, + Sources: cli.EnvVars("CI_COMMIT_MESSAGE"), Name: "commit-message", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_AUTHOR_NAME"}, + Sources: cli.EnvVars("CI_COMMIT_AUTHOR_NAME"), Name: "commit-author-name", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_AUTHOR_AVATAR"}, + Sources: cli.EnvVars("CI_COMMIT_AUTHOR_AVATAR"), Name: "commit-author-avatar", }, &cli.StringFlag{ - EnvVars: []string{"CI_COMMIT_AUTHOR_EMAIL"}, + Sources: cli.EnvVars("CI_COMMIT_AUTHOR_EMAIL"), Name: "commit-author-email", }, &cli.IntFlag{ - EnvVars: []string{"CI_PREV_PIPELINE_NUMBER"}, + Sources: cli.EnvVars("CI_PREV_PIPELINE_NUMBER"), Name: "prev-pipeline-number", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PREV_PIPELINE_CREATED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PREV_PIPELINE_CREATED"), Name: "prev-pipeline-created", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PREV_PIPELINE_STARTED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PREV_PIPELINE_STARTED"), Name: "prev-pipeline-started", }, - &cli.Int64Flag{ - EnvVars: []string{"CI_PREV_PIPELINE_FINISHED"}, + &cli.IntFlag{ + Sources: cli.EnvVars("CI_PREV_PIPELINE_FINISHED"), Name: "prev-pipeline-finished", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_PIPELINE_STATUS"}, + Sources: cli.EnvVars("CI_PREV_PIPELINE_STATUS"), Name: "prev-pipeline-status", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_PIPELINE_EVENT"}, + Sources: cli.EnvVars("CI_PREV_PIPELINE_EVENT"), Name: "prev-pipeline-event", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_PIPELINE_URL"}, + Sources: cli.EnvVars("CI_PREV_PIPELINE_URL"), Name: "prev-pipeline-url", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_SHA"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_SHA"), Name: "prev-commit-sha", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_REF"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_REF"), Name: "prev-commit-ref", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_REFSPEC"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_REFSPEC"), Name: "prev-commit-refspec", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_BRANCH"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_BRANCH"), Name: "prev-commit-branch", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_MESSAGE"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_MESSAGE"), Name: "prev-commit-message", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_AUTHOR_NAME"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_NAME"), Name: "prev-commit-author-name", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_AUTHOR_AVATAR"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_AVATAR"), Name: "prev-commit-author-avatar", }, &cli.StringFlag{ - EnvVars: []string{"CI_PREV_COMMIT_AUTHOR_EMAIL"}, + Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_EMAIL"), Name: "prev-commit-author-email", }, &cli.IntFlag{ - EnvVars: []string{"CI_WORKFLOW_NAME"}, + Sources: cli.EnvVars("CI_WORKFLOW_NAME"), Name: "workflow-name", }, &cli.IntFlag{ - EnvVars: []string{"CI_WORKFLOW_NUMBER"}, + Sources: cli.EnvVars("CI_WORKFLOW_NUMBER"), Name: "workflow-number", }, &cli.IntFlag{ - EnvVars: []string{"CI_STEP_NAME"}, + Sources: cli.EnvVars("CI_STEP_NAME"), Name: "step-name", }, &cli.StringSliceFlag{ - EnvVars: []string{"CI_ENV"}, + Sources: cli.EnvVars("CI_ENV"), Name: "env", }, &cli.StringFlag{ - EnvVars: []string{"CI_FORGE_TYPE"}, + Sources: cli.EnvVars("CI_FORGE_TYPE"), Name: "forge-type", }, &cli.StringFlag{ - EnvVars: []string{"CI_FORGE_URL"}, + Sources: cli.EnvVars("CI_FORGE_URL"), Name: "forge-url", }, } diff --git a/cli/exec/metadata.go b/cli/exec/metadata.go index add3822929..20a89da66c 100644 --- a/cli/exec/metadata.go +++ b/cli/exec/metadata.go @@ -15,10 +15,11 @@ package exec import ( + "context" "runtime" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/metadata" "go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/matrix" @@ -26,7 +27,7 @@ import ( ) // return the metadata from the cli context. -func metadataFromContext(c *cli.Context, axis matrix.Axis) metadata.Metadata { +func metadataFromContext(_ context.Context, c *cli.Command, axis matrix.Axis) metadata.Metadata { platform := c.String("system-platform") if platform == "" { platform = runtime.GOOS + "/" + runtime.GOARCH @@ -52,11 +53,11 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) metadata.Metadata { Trusted: c.Bool("repo-trusted"), }, Curr: metadata.Pipeline{ - Number: c.Int64("pipeline-number"), - Parent: c.Int64("pipeline-parent"), - Created: c.Int64("pipeline-created"), - Started: c.Int64("pipeline-started"), - Finished: c.Int64("pipeline-finished"), + Number: c.Int("pipeline-number"), + Parent: c.Int("pipeline-parent"), + Created: c.Int("pipeline-created"), + Started: c.Int("pipeline-started"), + Finished: c.Int("pipeline-finished"), Status: c.String("pipeline-status"), Event: c.String("pipeline-event"), ForgeURL: c.String("pipeline-url"), @@ -76,10 +77,10 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) metadata.Metadata { }, }, Prev: metadata.Pipeline{ - Number: c.Int64("prev-pipeline-number"), - Created: c.Int64("prev-pipeline-created"), - Started: c.Int64("prev-pipeline-started"), - Finished: c.Int64("prev-pipeline-finished"), + Number: c.Int("prev-pipeline-number"), + Created: c.Int("prev-pipeline-created"), + Started: c.Int("prev-pipeline-started"), + Finished: c.Int("prev-pipeline-finished"), Status: c.String("prev-pipeline-status"), Event: c.String("prev-pipeline-event"), ForgeURL: c.String("prev-pipeline-url"), @@ -98,12 +99,12 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) metadata.Metadata { }, Workflow: metadata.Workflow{ Name: c.String("workflow-name"), - Number: c.Int("workflow-number"), + Number: int(c.Int("workflow-number")), Matrix: axis, }, Step: metadata.Step{ Name: c.String("step-name"), - Number: c.Int("step-number"), + Number: int(c.Int("step-number")), }, Sys: metadata.System{ Name: c.String("system-name"), diff --git a/cli/info/info.go b/cli/info/info.go index 5963f44256..2d17680d4e 100644 --- a/cli/info/info.go +++ b/cli/info/info.go @@ -15,10 +15,11 @@ package info import ( + "context" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,8 +34,8 @@ var Command = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplInfo, true)}, } -func info(c *cli.Context) error { - client, err := internal.NewClient(c) +func info(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/internal/config/config.go b/cli/internal/config/config.go index 29741212e6..817a859c38 100644 --- a/cli/internal/config/config.go +++ b/cli/internal/config/config.go @@ -1,6 +1,7 @@ package config import ( + "context" "encoding/json" "errors" "os" @@ -8,7 +9,7 @@ import ( "github.com/adrg/xdg" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/zalando/go-keyring" ) @@ -32,12 +33,12 @@ func (c *Config) MergeIfNotSet(c2 *Config) { var skipSetupForCommands = []string{"setup", "help", "h", "version", "update", "lint", "exec", ""} -func Load(c *cli.Context) error { +func Load(ctx context.Context, c *cli.Command) error { if firstArg := c.Args().First(); slices.Contains(skipSetupForCommands, firstArg) { return nil } - config, err := Get(c, c.String("config")) + config, err := Get(ctx, c, c.String("config")) if err != nil { return err } @@ -80,11 +81,11 @@ func getConfigPath(configPath string) (string, error) { return configPath, nil } -func Get(ctx *cli.Context, _configPath string) (*Config, error) { - c := &Config{ - LogLevel: ctx.String("log-level"), - Token: ctx.String("token"), - ServerURL: ctx.String("server"), +func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error) { + conf := &Config{ + LogLevel: c.String("log-level"), + Token: c.String("token"), + ServerURL: c.String("server"), } configPath, err := getConfigPath(_configPath) @@ -109,33 +110,33 @@ func Get(ctx *cli.Context, _configPath string) (*Config, error) { if err != nil { return nil, err } - c.MergeIfNotSet(configFromFile) + conf.MergeIfNotSet(configFromFile) log.Debug().Msg("Loaded config from file") } // if server or token are explicitly set, use them - if ctx.IsSet("server") || ctx.IsSet("token") { - return c, nil + if c.IsSet("server") || c.IsSet("token") { + return conf, nil } // load token from keyring - service := ctx.App.Name - secret, err := keyring.Get(service, c.ServerURL) + service := c.Root().Name + secret, err := keyring.Get(service, conf.ServerURL) if errors.Is(err, keyring.ErrUnsupportedPlatform) { log.Warn().Msg("Keyring is not supported on this platform") - return c, nil + return conf, nil } if errors.Is(err, keyring.ErrNotFound) { log.Warn().Msg("Token not found in keyring") - return c, nil + return conf, nil } - c.Token = secret + conf.Token = secret - return c, nil + return conf, nil } -func Save(ctx *cli.Context, _configPath string, c *Config) error { - config, err := json.Marshal(c) +func Save(_ context.Context, c *cli.Command, _configPath string, conf *Config) error { + config, err := json.Marshal(conf) if err != nil { return err } @@ -146,8 +147,8 @@ func Save(ctx *cli.Context, _configPath string, c *Config) error { } // save token to keyring - service := ctx.App.Name - err = keyring.Set(service, c.ServerURL, c.Token) + service := c.Root().Name + err = keyring.Set(service, conf.ServerURL, conf.Token) if err != nil { return err } diff --git a/cli/internal/util.go b/cli/internal/util.go index 001752ed3d..e372d52bd0 100644 --- a/cli/internal/util.go +++ b/cli/internal/util.go @@ -15,6 +15,7 @@ package internal import ( + "context" "crypto/tls" "crypto/x509" "fmt" @@ -25,7 +26,7 @@ import ( vsc_url "github.com/gitsight/go-vcsurl" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/net/proxy" "golang.org/x/oauth2" @@ -33,7 +34,7 @@ import ( ) // NewClient returns a new client from the CLI context. -func NewClient(c *cli.Context) (woodpecker.Client, error) { +func NewClient(ctx context.Context, c *cli.Command) (woodpecker.Client, error) { var ( skip = c.Bool("skip-verify") socks = c.String("socks-proxy") @@ -63,8 +64,7 @@ func NewClient(c *cli.Context) (woodpecker.Client, error) { } config := new(oauth2.Config) - client := config.Client( - c.Context, + client := config.Client(ctx, &oauth2.Token{ AccessToken: token, }, diff --git a/cli/lint/lint.go b/cli/lint/lint.go index f77d6cfe0b..1e053369df 100644 --- a/cli/lint/lint.go +++ b/cli/lint/lint.go @@ -15,13 +15,14 @@ package lint import ( + "context" "fmt" "os" "path" "path/filepath" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml" @@ -36,11 +37,11 @@ var Command = &cli.Command{ Action: lint, } -func lint(c *cli.Context) error { - return common.RunPipelineFunc(c, lintFile, lintDir) +func lint(ctx context.Context, c *cli.Command) error { + return common.RunPipelineFunc(ctx, c, lintFile, lintDir) } -func lintDir(c *cli.Context, dir string) error { +func lintDir(ctx context.Context, c *cli.Command, dir string) error { var errorStrings []string if err := filepath.Walk(dir, func(path string, info os.FileInfo, e error) error { if e != nil { @@ -50,7 +51,7 @@ func lintDir(c *cli.Context, dir string) error { // check if it is a regular file (not dir) if info.Mode().IsRegular() && (strings.HasSuffix(info.Name(), ".yaml") || strings.HasSuffix(info.Name(), ".yml")) { fmt.Println("#", info.Name()) - if err := lintFile(c, path); err != nil { + if err := lintFile(ctx, c, path); err != nil { errorStrings = append(errorStrings, err.Error()) } fmt.Println("") @@ -68,7 +69,7 @@ func lintDir(c *cli.Context, dir string) error { return nil } -func lintFile(_ *cli.Context, file string) error { +func lintFile(_ context.Context, _ *cli.Command, file string) error { fi, err := os.Open(file) if err != nil { return err diff --git a/cli/log/log.go b/cli/log/log.go index b9436c534e..2ca1e1c90f 100644 --- a/cli/log/log.go +++ b/cli/log/log.go @@ -15,14 +15,14 @@ package log import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Command exports the log command set. var Command = &cli.Command{ Name: "log", Usage: "manage logs", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ logPurgeCmd, }, } diff --git a/cli/log/log_purge.go b/cli/log/log_purge.go index 8a62ac79d7..f9dc536d24 100644 --- a/cli/log/log_purge.go +++ b/cli/log/log_purge.go @@ -15,10 +15,11 @@ package log import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,8 +31,8 @@ var logPurgeCmd = &cli.Command{ Action: logPurge, } -func logPurge(c *cli.Context) (err error) { - client, err := internal.NewClient(c) +func logPurge(ctx context.Context, c *cli.Command) (err error) { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/loglevel/loglevel.go b/cli/loglevel/loglevel.go index 1908260e0e..947e99eaf2 100644 --- a/cli/loglevel/loglevel.go +++ b/cli/loglevel/loglevel.go @@ -15,9 +15,11 @@ package loglevel import ( + "context" + "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -31,8 +33,8 @@ var Command = &cli.Command{ Action: logLevel, } -func logLevel(c *cli.Context) error { - client, err := internal.NewClient(c) +func logLevel(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/org/org.go b/cli/org/org.go index 862d5eba8f..c7b9cd840f 100644 --- a/cli/org/org.go +++ b/cli/org/org.go @@ -15,7 +15,7 @@ package org import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/org/registry" ) @@ -24,7 +24,7 @@ import ( var Command = &cli.Command{ Name: "org", Usage: "manage organizations", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ registry.Command, }, } diff --git a/cli/org/registry/registry.go b/cli/org/registry/registry.go index 6d8904958d..aa4f9f23ba 100644 --- a/cli/org/registry/registry.go +++ b/cli/org/registry/registry.go @@ -17,7 +17,7 @@ package registry import ( "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" ) @@ -26,7 +26,7 @@ import ( var Command = &cli.Command{ Name: "registry", Usage: "manage organization registries", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ registryCreateCmd, registryDeleteCmd, registryUpdateCmd, @@ -35,7 +35,7 @@ var Command = &cli.Command{ }, } -func parseTargetArgs(client woodpecker.Client, c *cli.Context) (orgID int64, err error) { +func parseTargetArgs(client woodpecker.Client, c *cli.Command) (orgID int64, err error) { orgIDOrName := c.String("organization") if orgIDOrName == "" { orgIDOrName = c.Args().First() diff --git a/cli/org/registry/registry_add.go b/cli/org/registry/registry_add.go index f3cdf5f5ff..d82859f00b 100644 --- a/cli/org/registry/registry_add.go +++ b/cli/org/registry/registry_add.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -48,14 +49,14 @@ var registryCreateCmd = &cli.Command{ }, } -func registryCreate(c *cli.Context) error { +func registryCreate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/org/registry/registry_info.go b/cli/org/registry/registry_info.go index a28a4fdd6a..752c54c189 100644 --- a/cli/org/registry/registry_info.go +++ b/cli/org/registry/registry_info.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -40,13 +41,13 @@ var registryInfoCmd = &cli.Command{ }, } -func registryInfo(c *cli.Context) error { +func registryInfo(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") format = c.String("format") + "\n" ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/org/registry/registry_list.go b/cli/org/registry/registry_list.go index 4fd1134ae1..1829d04017 100644 --- a/cli/org/registry/registry_list.go +++ b/cli/org/registry/registry_list.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -35,10 +36,10 @@ var registryListCmd = &cli.Command{ }, } -func registryList(c *cli.Context) error { +func registryList(ctx context.Context, c *cli.Command) error { format := c.String("format") + "\n" - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/org/registry/registry_rm.go b/cli/org/registry/registry_rm.go index e56322c95c..8157e1626d 100644 --- a/cli/org/registry/registry_rm.go +++ b/cli/org/registry/registry_rm.go @@ -15,7 +15,9 @@ package registry import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -36,10 +38,10 @@ var registryDeleteCmd = &cli.Command{ }, } -func registryDelete(c *cli.Context) error { +func registryDelete(ctx context.Context, c *cli.Command) error { hostname := c.String("hostname") - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/org/registry/registry_set.go b/cli/org/registry/registry_set.go index a79a0331b7..e08e2af4f2 100644 --- a/cli/org/registry/registry_set.go +++ b/cli/org/registry/registry_set.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -48,14 +49,14 @@ var registryUpdateCmd = &cli.Command{ }, } -func registryUpdate(c *cli.Context) error { +func registryUpdate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/approve.go b/cli/pipeline/approve.go index 4e2185b27b..ae99324f5e 100644 --- a/cli/pipeline/approve.go +++ b/cli/pipeline/approve.go @@ -15,10 +15,11 @@ package pipeline import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,9 +31,9 @@ var pipelineApproveCmd = &cli.Command{ Action: pipelineApprove, } -func pipelineApprove(c *cli.Context) (err error) { +func pipelineApprove(ctx context.Context, c *cli.Command) (err error) { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/create.go b/cli/pipeline/create.go index 008a27f3e4..e343c24a05 100644 --- a/cli/pipeline/create.go +++ b/cli/pipeline/create.go @@ -15,9 +15,10 @@ package pipeline import ( + "context" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -42,9 +43,9 @@ var pipelineCreateCmd = &cli.Command{ }...), } -func pipelineCreate(c *cli.Context) error { +func pipelineCreate(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/decline.go b/cli/pipeline/decline.go index b99b13452c..f44179ba8d 100644 --- a/cli/pipeline/decline.go +++ b/cli/pipeline/decline.go @@ -15,10 +15,11 @@ package pipeline import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,9 +31,9 @@ var pipelineDeclineCmd = &cli.Command{ Action: pipelineDecline, } -func pipelineDecline(c *cli.Context) (err error) { +func pipelineDecline(ctx context.Context, c *cli.Command) (err error) { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/info.go b/cli/pipeline/info.go index 91cae47430..660c1c72b1 100644 --- a/cli/pipeline/info.go +++ b/cli/pipeline/info.go @@ -15,9 +15,10 @@ package pipeline import ( + "context" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -32,9 +33,9 @@ var pipelineInfoCmd = &cli.Command{ Flags: common.OutputFlags("table"), } -func pipelineInfo(c *cli.Context) error { +func pipelineInfo(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/kill.go b/cli/pipeline/kill.go index 3c8fa3fb98..872719765e 100644 --- a/cli/pipeline/kill.go +++ b/cli/pipeline/kill.go @@ -15,10 +15,11 @@ package pipeline import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -31,14 +32,14 @@ var pipelineKillCmd = &cli.Command{ Hidden: true, } -func pipelineKill(c *cli.Context) (err error) { +func pipelineKill(ctx context.Context, c *cli.Command) (err error) { number, err := strconv.ParseInt(c.Args().Get(1), 10, 64) if err != nil { return err } repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/last.go b/cli/pipeline/last.go index e0af7d17f7..3d911d0faa 100644 --- a/cli/pipeline/last.go +++ b/cli/pipeline/last.go @@ -15,7 +15,9 @@ package pipeline import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -36,9 +38,9 @@ var pipelineLastCmd = &cli.Command{ }...), } -func pipelineLast(c *cli.Context) error { +func pipelineLast(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/list.go b/cli/pipeline/list.go index 6a35763239..f8b798674b 100644 --- a/cli/pipeline/list.go +++ b/cli/pipeline/list.go @@ -15,7 +15,9 @@ package pipeline import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -49,19 +51,19 @@ var pipelineListCmd = &cli.Command{ }...), } -func List(c *cli.Context) error { - client, err := internal.NewClient(c) +func List(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } - resources, err := pipelineList(c, client) + resources, err := pipelineList(ctx, c, client) if err != nil { return err } return pipelineOutput(c, resources) } -func pipelineList(c *cli.Context, client woodpecker.Client) ([]woodpecker.Pipeline, error) { +func pipelineList(_ context.Context, c *cli.Command, client woodpecker.Client) ([]woodpecker.Pipeline, error) { resources := make([]woodpecker.Pipeline, 0) repoIDOrFullName := c.Args().First() @@ -78,7 +80,7 @@ func pipelineList(c *cli.Context, client woodpecker.Client) ([]woodpecker.Pipeli branch := c.String("branch") event := c.String("event") status := c.String("status") - limit := c.Int("limit") + limit := int(c.Int("limit")) var count int for _, pipeline := range pipelines { diff --git a/cli/pipeline/list_test.go b/cli/pipeline/list_test.go index 0f913bf71e..55ce4578c7 100644 --- a/cli/pipeline/list_test.go +++ b/cli/pipeline/list_test.go @@ -1,13 +1,14 @@ package pipeline import ( + "context" "errors" "io" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker/mocks" @@ -109,12 +110,10 @@ func TestPipelineList(t *testing.T) { mockClient.On("PipelineList", mock.Anything).Return(tt.pipelines, tt.pipelineErr) mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil) - app := &cli.App{Writer: io.Discard} - c := cli.NewContext(app, nil, nil) - command := pipelineListCmd - command.Action = func(c *cli.Context) error { - pipelines, err := pipelineList(c, mockClient) + command.Writer = io.Discard + command.Action = func(ctx context.Context, c *cli.Command) error { + pipelines, err := pipelineList(ctx, c, mockClient) if tt.wantErr != nil { assert.EqualError(t, err, tt.wantErr.Error()) return nil @@ -126,7 +125,7 @@ func TestPipelineList(t *testing.T) { return nil } - _ = command.Run(c, tt.args...) + _ = command.Run(context.Background(), tt.args) }) } } diff --git a/cli/pipeline/logs.go b/cli/pipeline/logs.go index 116d68a4d2..ce3bacb408 100644 --- a/cli/pipeline/logs.go +++ b/cli/pipeline/logs.go @@ -15,10 +15,11 @@ package pipeline import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,9 +31,9 @@ var pipelineLogsCmd = &cli.Command{ Action: pipelineLogs, } -func pipelineLogs(c *cli.Context) error { +func pipelineLogs(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/pipeline.go b/cli/pipeline/pipeline.go index 27044cac34..38fba42d17 100644 --- a/cli/pipeline/pipeline.go +++ b/cli/pipeline/pipeline.go @@ -20,7 +20,7 @@ import ( "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/output" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -30,7 +30,7 @@ import ( var Command = &cli.Command{ Name: "pipeline", Usage: "manage pipelines", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ pipelineListCmd, pipelineLastCmd, pipelineLogsCmd, @@ -46,7 +46,7 @@ var Command = &cli.Command{ }, } -func pipelineOutput(c *cli.Context, resources []woodpecker.Pipeline, fd ...io.Writer) error { +func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Writer) error { outFmt, outOpt := output.ParseOutputOptions(c.String("output")) noHeader := c.Bool("output-no-headers") diff --git a/cli/pipeline/pipeline_test.go b/cli/pipeline/pipeline_test.go index 3ff2080ae7..9812813d05 100644 --- a/cli/pipeline/pipeline_test.go +++ b/cli/pipeline/pipeline_test.go @@ -2,11 +2,12 @@ package pipeline import ( "bytes" + "context" "io" "testing" "github.com/stretchr/testify/assert" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -59,28 +60,27 @@ func TestPipelineOutput(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - app := &cli.App{Writer: io.Discard} - c := cli.NewContext(app, nil, nil) + command := &cli.Command{ + Writer: io.Discard, + Name: "output", + Flags: common.OutputFlags("table"), + Action: func(_ context.Context, c *cli.Command) error { + var buf bytes.Buffer + err := pipelineOutput(c, pipelines, &buf) - command := &cli.Command{} - command.Name = "output" - command.Flags = common.OutputFlags("table") - command.Action = func(c *cli.Context) error { - var buf bytes.Buffer - err := pipelineOutput(c, pipelines, &buf) + if tt.wantErr { + assert.Error(t, err) + return nil + } - if tt.wantErr { - assert.Error(t, err) - return nil - } - - assert.NoError(t, err) - assert.Equal(t, tt.expected, buf.String()) + assert.NoError(t, err) + assert.Equal(t, tt.expected, buf.String()) - return nil + return nil + }, } - _ = command.Run(c, tt.args...) + _ = command.Run(context.Background(), tt.args) }) } } diff --git a/cli/pipeline/ps.go b/cli/pipeline/ps.go index bba6f40430..737ef73010 100644 --- a/cli/pipeline/ps.go +++ b/cli/pipeline/ps.go @@ -15,11 +15,12 @@ package pipeline import ( + "context" "os" "strconv" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,9 +34,9 @@ var pipelinePsCmd = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplPipelinePs)}, } -func pipelinePs(c *cli.Context) error { +func pipelinePs(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/queue.go b/cli/pipeline/queue.go index 1fbccd8a31..ffa123d4e8 100644 --- a/cli/pipeline/queue.go +++ b/cli/pipeline/queue.go @@ -15,11 +15,12 @@ package pipeline import ( + "context" "fmt" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,8 +34,8 @@ var pipelineQueueCmd = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplPipelineQueue)}, } -func pipelineQueue(c *cli.Context) error { - client, err := internal.NewClient(c) +func pipelineQueue(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/start.go b/cli/pipeline/start.go index c3d870982e..4eeeaf5f25 100644 --- a/cli/pipeline/start.go +++ b/cli/pipeline/start.go @@ -15,11 +15,12 @@ package pipeline import ( + "context" "errors" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -38,9 +39,9 @@ var pipelineStartCmd = &cli.Command{ }, } -func pipelineStart(c *cli.Context) (err error) { +func pipelineStart(ctx context.Context, c *cli.Command) (err error) { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/pipeline/stop.go b/cli/pipeline/stop.go index 4d949f9cb3..a693522498 100644 --- a/cli/pipeline/stop.go +++ b/cli/pipeline/stop.go @@ -15,10 +15,11 @@ package pipeline import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,9 +31,9 @@ var pipelineStopCmd = &cli.Command{ Action: pipelineStop, } -func pipelineStop(c *cli.Context) (err error) { +func pipelineStop(ctx context.Context, c *cli.Command) (err error) { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/registry/registry.go b/cli/repo/registry/registry.go index 29c8d35fa9..df3f094468 100644 --- a/cli/repo/registry/registry.go +++ b/cli/repo/registry/registry.go @@ -15,7 +15,7 @@ package registry import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -25,7 +25,7 @@ import ( var Command = &cli.Command{ Name: "registry", Usage: "manage registries", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ registryCreateCmd, registryDeleteCmd, registryUpdateCmd, @@ -34,7 +34,7 @@ var Command = &cli.Command{ }, } -func parseTargetArgs(client woodpecker.Client, c *cli.Context) (repoID int64, err error) { +func parseTargetArgs(client woodpecker.Client, c *cli.Command) (repoID int64, err error) { repoIDOrFullName := c.String("repository") if repoIDOrFullName == "" { repoIDOrFullName = c.Args().First() diff --git a/cli/repo/registry/registry_add.go b/cli/repo/registry/registry_add.go index dae2310482..e894a698c1 100644 --- a/cli/repo/registry/registry_add.go +++ b/cli/repo/registry/registry_add.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -48,14 +49,14 @@ var registryCreateCmd = &cli.Command{ }, } -func registryCreate(c *cli.Context) error { +func registryCreate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/registry/registry_info.go b/cli/repo/registry/registry_info.go index 1f984c4151..f171d1d23a 100644 --- a/cli/repo/registry/registry_info.go +++ b/cli/repo/registry/registry_info.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -40,13 +41,13 @@ var registryInfoCmd = &cli.Command{ }, } -func registryInfo(c *cli.Context) error { +func registryInfo(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") format = c.String("format") + "\n" ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/registry/registry_list.go b/cli/repo/registry/registry_list.go index cd0a89a6bf..0cb6f80b89 100644 --- a/cli/repo/registry/registry_list.go +++ b/cli/repo/registry/registry_list.go @@ -15,10 +15,11 @@ package registry import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -35,10 +36,10 @@ var registryListCmd = &cli.Command{ }, } -func registryList(c *cli.Context) error { +func registryList(ctx context.Context, c *cli.Command) error { format := c.String("format") + "\n" - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/registry/registry_rm.go b/cli/repo/registry/registry_rm.go index d1b058a172..4b3437d48a 100644 --- a/cli/repo/registry/registry_rm.go +++ b/cli/repo/registry/registry_rm.go @@ -15,7 +15,9 @@ package registry import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -36,10 +38,10 @@ var registryDeleteCmd = &cli.Command{ }, } -func registryDelete(c *cli.Context) error { +func registryDelete(ctx context.Context, c *cli.Command) error { hostname := c.String("hostname") - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/registry/registry_set.go b/cli/repo/registry/registry_set.go index 5b6497f49d..4af39f5c25 100644 --- a/cli/repo/registry/registry_set.go +++ b/cli/repo/registry/registry_set.go @@ -15,10 +15,11 @@ package registry import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -48,14 +49,14 @@ var registryUpdateCmd = &cli.Command{ }, } -func registryUpdate(c *cli.Context) error { +func registryUpdate(ctx context.Context, c *cli.Command) error { var ( hostname = c.String("hostname") username = c.String("username") password = c.String("password") ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo.go b/cli/repo/repo.go index ea42c5616f..1be57743e0 100644 --- a/cli/repo/repo.go +++ b/cli/repo/repo.go @@ -15,7 +15,7 @@ package repo import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/repo/registry" ) @@ -24,7 +24,7 @@ import ( var Command = &cli.Command{ Name: "repo", Usage: "manage repositories", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ repoListCmd, repoInfoCmd, repoAddCmd, diff --git a/cli/repo/repo_add.go b/cli/repo/repo_add.go index 00094b40cc..594b8dd73a 100644 --- a/cli/repo/repo_add.go +++ b/cli/repo/repo_add.go @@ -15,10 +15,11 @@ package repo import ( + "context" "fmt" "strconv" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -30,14 +31,14 @@ var repoAddCmd = &cli.Command{ Action: repoAdd, } -func repoAdd(c *cli.Context) error { +func repoAdd(ctx context.Context, c *cli.Command) error { _forgeRemoteID := c.Args().First() forgeRemoteID, err := strconv.Atoi(_forgeRemoteID) if err != nil { return fmt.Errorf("invalid forge remote id: %s", _forgeRemoteID) } - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_chown.go b/cli/repo/repo_chown.go index 050a3975a3..118940184c 100644 --- a/cli/repo/repo_chown.go +++ b/cli/repo/repo_chown.go @@ -15,9 +15,10 @@ package repo import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -29,9 +30,9 @@ var repoChownCmd = &cli.Command{ Action: repoChown, } -func repoChown(c *cli.Context) error { +func repoChown(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_info.go b/cli/repo/repo_info.go index 72d4bf7a6f..e92d55be12 100644 --- a/cli/repo/repo_info.go +++ b/cli/repo/repo_info.go @@ -15,10 +15,11 @@ package repo import ( + "context" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -32,9 +33,9 @@ var repoInfoCmd = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplRepoInfo)}, } -func repoInfo(c *cli.Context) error { +func repoInfo(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_list.go b/cli/repo/repo_list.go index 9aa569338d..d3e4d1dd30 100644 --- a/cli/repo/repo_list.go +++ b/cli/repo/repo_list.go @@ -15,10 +15,11 @@ package repo import ( + "context" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -38,8 +39,8 @@ var repoListCmd = &cli.Command{ }, } -func repoList(c *cli.Context) error { - client, err := internal.NewClient(c) +func repoList(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_repair.go b/cli/repo/repo_repair.go index 15ab3157f3..35ca8f398d 100644 --- a/cli/repo/repo_repair.go +++ b/cli/repo/repo_repair.go @@ -15,9 +15,10 @@ package repo import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -29,9 +30,9 @@ var repoRepairCmd = &cli.Command{ Action: repoRepair, } -func repoRepair(c *cli.Context) error { +func repoRepair(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_rm.go b/cli/repo/repo_rm.go index 5603cd3365..b884dccf37 100644 --- a/cli/repo/repo_rm.go +++ b/cli/repo/repo_rm.go @@ -15,9 +15,10 @@ package repo import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -29,9 +30,9 @@ var repoRemoveCmd = &cli.Command{ Action: repoRemove, } -func repoRemove(c *cli.Context) error { +func repoRemove(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_sync.go b/cli/repo/repo_sync.go index 14f13401fa..17727eb83e 100644 --- a/cli/repo/repo_sync.go +++ b/cli/repo/repo_sync.go @@ -15,10 +15,11 @@ package repo import ( + "context" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,8 +34,8 @@ var repoSyncCmd = &cli.Command{ } // TODO: remove this and add an option to the list cmd as we do not store the remote repo list anymore -func repoSync(c *cli.Context) error { - client, err := internal.NewClient(c) +func repoSync(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/repo/repo_update.go b/cli/repo/repo_update.go index 51999bc767..049bf02427 100644 --- a/cli/repo/repo_update.go +++ b/cli/repo/repo_update.go @@ -15,10 +15,11 @@ package repo import ( + "context" "fmt" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -61,9 +62,9 @@ var repoUpdateCmd = &cli.Command{ }, } -func repoUpdate(c *cli.Context) error { +func repoUpdate(ctx context.Context, c *cli.Command) error { repoIDOrFullName := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } @@ -78,7 +79,7 @@ func repoUpdate(c *cli.Context) error { timeout = c.Duration("timeout") trusted = c.Bool("trusted") gated = c.Bool("gated") - pipelineCounter = c.Int("pipeline-counter") + pipelineCounter = int(c.Int("pipeline-counter")) unsafe = c.Bool("unsafe") ) diff --git a/cli/secret/secret.go b/cli/secret/secret.go index 0e78d8d0d9..e441492416 100644 --- a/cli/secret/secret.go +++ b/cli/secret/secret.go @@ -19,7 +19,7 @@ import ( "strconv" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -29,7 +29,7 @@ import ( var Command = &cli.Command{ Name: "secret", Usage: "manage secrets", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ secretCreateCmd, secretDeleteCmd, secretUpdateCmd, @@ -38,7 +38,7 @@ var Command = &cli.Command{ }, } -func parseTargetArgs(client woodpecker.Client, c *cli.Context) (global bool, orgID, repoID int64, err error) { +func parseTargetArgs(client woodpecker.Client, c *cli.Command) (global bool, orgID, repoID int64, err error) { if c.Bool("global") { return true, -1, -1, nil } diff --git a/cli/secret/secret_add.go b/cli/secret/secret_add.go index 16b75e0e02..452ddc46df 100644 --- a/cli/secret/secret_add.go +++ b/cli/secret/secret_add.go @@ -15,10 +15,11 @@ package secret import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -56,8 +57,8 @@ var secretCreateCmd = &cli.Command{ }, } -func secretCreate(c *cli.Context) error { - client, err := internal.NewClient(c) +func secretCreate(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/secret/secret_info.go b/cli/secret/secret_info.go index 02d1a5d5ea..4f69cbada9 100644 --- a/cli/secret/secret_info.go +++ b/cli/secret/secret_info.go @@ -15,10 +15,11 @@ package secret import ( + "context" "html/template" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -45,12 +46,12 @@ var secretInfoCmd = &cli.Command{ }, } -func secretInfo(c *cli.Context) error { +func secretInfo(ctx context.Context, c *cli.Command) error { var ( secretName = c.String("name") format = c.String("format") + "\n" ) - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/secret/secret_list.go b/cli/secret/secret_list.go index e698cb505c..4645089bc8 100644 --- a/cli/secret/secret_list.go +++ b/cli/secret/secret_list.go @@ -15,11 +15,12 @@ package secret import ( + "context" "html/template" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -42,10 +43,10 @@ var secretListCmd = &cli.Command{ }, } -func secretList(c *cli.Context) error { +func secretList(ctx context.Context, c *cli.Command) error { format := c.String("format") + "\n" - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/secret/secret_rm.go b/cli/secret/secret_rm.go index 0dbc0c188d..fa7d5b82fc 100644 --- a/cli/secret/secret_rm.go +++ b/cli/secret/secret_rm.go @@ -15,7 +15,9 @@ package secret import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -40,10 +42,10 @@ var secretDeleteCmd = &cli.Command{ }, } -func secretDelete(c *cli.Context) error { +func secretDelete(ctx context.Context, c *cli.Command) error { secretName := c.String("name") - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/secret/secret_set.go b/cli/secret/secret_set.go index c1e0d1443f..d8c0c38ceb 100644 --- a/cli/secret/secret_set.go +++ b/cli/secret/secret_set.go @@ -15,10 +15,11 @@ package secret import ( + "context" "os" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -56,8 +57,8 @@ var secretUpdateCmd = &cli.Command{ }, } -func secretUpdate(c *cli.Context) error { - client, err := internal.NewClient(c) +func secretUpdate(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/setup/setup.go b/cli/setup/setup.go index 1d3126efe5..6705482e94 100644 --- a/cli/setup/setup.go +++ b/cli/setup/setup.go @@ -1,11 +1,12 @@ package setup import ( + "context" "errors" "strings" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal/config" "go.woodpecker-ci.org/woodpecker/v2/cli/setup/ui" @@ -15,7 +16,6 @@ import ( var Command = &cli.Command{ Name: "setup", Usage: "setup the woodpecker-cli for the first time", - Args: true, ArgsUsage: "[server]", Flags: []cli.Flag{ &cli.StringFlag{ @@ -30,8 +30,8 @@ var Command = &cli.Command{ Action: setup, } -func setup(c *cli.Context) error { - _config, err := config.Get(c, c.String("config")) +func setup(ctx context.Context, c *cli.Command) error { + _config, err := config.Get(ctx, c, c.String("config")) if err != nil { return err } else if _config != nil { @@ -68,7 +68,7 @@ func setup(c *cli.Context) error { token := c.String("token") if token == "" { - token, err = receiveTokenFromUI(c.Context, serverURL) + token, err = receiveTokenFromUI(ctx, serverURL) if err != nil { return err } @@ -78,7 +78,7 @@ func setup(c *cli.Context) error { } } - err = config.Save(c, c.String("config"), &config.Config{ + err = config.Save(ctx, c, c.String("config"), &config.Config{ ServerURL: serverURL, Token: token, LogLevel: "info", diff --git a/cli/update/command.go b/cli/update/command.go index 786a5c62b2..ad856402f4 100644 --- a/cli/update/command.go +++ b/cli/update/command.go @@ -1,12 +1,13 @@ package update import ( + "context" "fmt" "os" "path/filepath" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Command exports the update command. @@ -22,10 +23,10 @@ var Command = &cli.Command{ Action: update, } -func update(c *cli.Context) error { +func update(ctx context.Context, c *cli.Command) error { log.Info().Msg("Checking for updates ...") - newVersion, err := CheckForUpdate(c.Context, c.Bool("force")) + newVersion, err := CheckForUpdate(ctx, c.Bool("force")) if err != nil { return err } @@ -38,7 +39,7 @@ func update(c *cli.Context) error { log.Info().Msgf("New version %s is available! Updating ...", newVersion.Version) var tarFilePath string - tarFilePath, err = downloadNewVersion(c.Context, newVersion.AssetURL) + tarFilePath, err = downloadNewVersion(ctx, newVersion.AssetURL) if err != nil { return err } diff --git a/cli/user/user.go b/cli/user/user.go index a2323b6724..78b552b366 100644 --- a/cli/user/user.go +++ b/cli/user/user.go @@ -15,14 +15,14 @@ package user import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Command exports the user command set. var Command = &cli.Command{ Name: "user", Usage: "manage users", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ userListCmd, userInfoCmd, userAddCmd, diff --git a/cli/user/user_add.go b/cli/user/user_add.go index f3828b6992..80012158e4 100644 --- a/cli/user/user_add.go +++ b/cli/user/user_add.go @@ -15,9 +15,10 @@ package user import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" @@ -30,10 +31,10 @@ var userAddCmd = &cli.Command{ Action: userAdd, } -func userAdd(c *cli.Context) error { +func userAdd(ctx context.Context, c *cli.Command) error { login := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/user/user_info.go b/cli/user/user_info.go index 7747f5d189..bfebed93fd 100644 --- a/cli/user/user_info.go +++ b/cli/user/user_info.go @@ -15,11 +15,12 @@ package user import ( + "context" "fmt" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -33,8 +34,8 @@ var userInfoCmd = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplUserInfo)}, } -func userInfo(c *cli.Context) error { - client, err := internal.NewClient(c) +func userInfo(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/user/user_list.go b/cli/user/user_list.go index 63863b95f1..4e721f0f47 100644 --- a/cli/user/user_list.go +++ b/cli/user/user_list.go @@ -15,10 +15,11 @@ package user import ( + "context" "os" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" @@ -32,8 +33,8 @@ var userListCmd = &cli.Command{ Flags: []cli.Flag{common.FormatFlag(tmplUserList)}, } -func userList(c *cli.Context) error { - client, err := internal.NewClient(c) +func userList(ctx context.Context, c *cli.Command) error { + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cli/user/user_rm.go b/cli/user/user_rm.go index 081b0cf230..962fc03a13 100644 --- a/cli/user/user_rm.go +++ b/cli/user/user_rm.go @@ -15,9 +15,10 @@ package user import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" ) @@ -29,10 +30,10 @@ var userRemoveCmd = &cli.Command{ Action: userRemove, } -func userRemove(c *cli.Context) error { +func userRemove(ctx context.Context, c *cli.Command) error { login := c.Args().First() - client, err := internal.NewClient(c) + client, err := internal.NewClient(ctx, c) if err != nil { return err } diff --git a/cmd/agent/core/agent.go b/cmd/agent/core/agent.go index b4da071a2a..e37ded55ec 100644 --- a/cmd/agent/core/agent.go +++ b/cmd/agent/core/agent.go @@ -27,7 +27,7 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -62,11 +62,7 @@ var ( shutdownCtx = context.Background() ) -func run(c *cli.Context, backends []types.Backend) error { - ctx := utils.WithContextSigtermCallback(c.Context, func() { - log.Info().Msg("termination signal is received, shutting down agent") - }) - +func run(ctx context.Context, c *cli.Command, backends []types.Backend) error { agentCtx, ctxCancel := context.WithCancelCause(ctx) stopAgentFunc = func(err error) { msg := "shutdown of whole agent" @@ -90,7 +86,7 @@ func run(c *cli.Context, backends []types.Backend) error { hostname, _ = os.Hostname() } - counter.Polling = c.Int("max-workflows") + counter.Polling = int(c.Int("max-workflows")) counter.Running = 0 if c.Bool("healthcheck") { @@ -139,7 +135,7 @@ func run(c *cli.Context, backends []types.Backend) error { grpcClientCtx, grpcClientCtxCancel := context.WithCancelCause(context.Background()) defer grpcClientCtxCancel(nil) authClient := agent_rpc.NewAuthGrpcClient(authConn, agentToken, agentConfig.AgentID) - authInterceptor, err := agent_rpc.NewAuthInterceptor(grpcClientCtx, authClient, authInterceptorRefreshInterval) + authInterceptor, err := agent_rpc.NewAuthInterceptor(grpcClientCtx, authClient, authInterceptorRefreshInterval) //nolint:contextcheck if err != nil { return err } @@ -165,7 +161,7 @@ func run(c *cli.Context, backends []types.Backend) error { grpcCtx := metadata.NewOutgoingContext(grpcClientCtx, metadata.Pairs("hostname", hostname)) // check if grpc server version is compatible with agent - grpcServerVersion, err := client.Version(grpcCtx) + grpcServerVersion, err := client.Version(grpcCtx) //nolint:contextcheck if err != nil { log.Error().Err(err).Msg("could not get grpc server version") return err @@ -180,7 +176,7 @@ func run(c *cli.Context, backends []types.Backend) error { } // new engine - backendCtx := context.WithValue(agentCtx, types.CliContext, c) + backendCtx := context.WithValue(agentCtx, types.CliCommand, c) backendName := c.String("backend-engine") backendEngine, err := backend.FindBackend(backendCtx, backends, backendName) if err != nil { @@ -200,8 +196,8 @@ func run(c *cli.Context, backends []types.Backend) error { } log.Debug().Msgf("loaded %s backend engine", backendEngine.Name()) - maxWorkflows := c.Int("max-workflows") - agentConfig.AgentID, err = client.RegisterAgent(grpcCtx, engInfo.Platform, backendEngine.Name(), version.String(), maxWorkflows) + maxWorkflows := int(c.Int("max-workflows")) + agentConfig.AgentID, err = client.RegisterAgent(grpcCtx, engInfo.Platform, backendEngine.Name(), version.String(), maxWorkflows) //nolint:contextcheck if err != nil { return err } @@ -291,19 +287,19 @@ func run(c *cli.Context, backends []types.Backend) error { return serviceWaitingGroup.Wait() } -func runWithRetry(backendEngines []types.Backend) func(c *cli.Context) error { - return func(c *cli.Context) error { - if err := logger.SetupGlobalLogger(c, true); err != nil { +func runWithRetry(backendEngines []types.Backend) func(ctx context.Context, c *cli.Command) error { + return func(ctx context.Context, c *cli.Command) error { + if err := logger.SetupGlobalLogger(ctx, c, true); err != nil { return err } initHealth() - retryCount := c.Int("connect-retry-count") + retryCount := int(c.Int("connect-retry-count")) retryDelay := c.Duration("connect-retry-delay") var err error for i := 0; i < retryCount; i++ { - if err = run(c, backendEngines); status.Code(err) == codes.Unavailable { + if err = run(ctx, c, backendEngines); status.Code(err) == codes.Unavailable { log.Warn().Err(err).Msg(fmt.Sprintf("cannot connect to server, retrying in %v", retryDelay)) time.Sleep(retryDelay) } else { diff --git a/cmd/agent/core/flags.go b/cmd/agent/core/flags.go index f0ab7cbcd7..6770e36bd5 100644 --- a/cmd/agent/core/flags.go +++ b/cmd/agent/core/flags.go @@ -19,93 +19,94 @@ import ( "os" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) //nolint:mnd var flags = []cli.Flag{ &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER"}, + Sources: cli.EnvVars("WOODPECKER_SERVER"), Name: "server", Usage: "server address", Value: "localhost:9000", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_AGENT_SECRET"}, - Name: "grpc-token", - Usage: "server-agent shared token", - FilePath: os.Getenv("WOODPECKER_AGENT_SECRET_FILE"), + Name: "grpc-token", + Usage: "server-agent shared token", + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_AGENT_SECRET_FILE")), + cli.EnvVar("WOODPECKER_AGENT_SECRET")), }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GRPC_SECURE"}, + Sources: cli.EnvVars("WOODPECKER_GRPC_SECURE"), Name: "grpc-secure", Usage: "should the connection to WOODPECKER_SERVER be made using a secure transport", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GRPC_VERIFY"}, + Sources: cli.EnvVars("WOODPECKER_GRPC_VERIFY"), Name: "grpc-skip-insecure", Usage: "should the grpc server certificate be verified, only valid when WOODPECKER_GRPC_SECURE is true", Value: true, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_HOSTNAME"}, + Sources: cli.EnvVars("WOODPECKER_HOSTNAME"), Name: "hostname", Usage: "agent hostname", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_AGENT_CONFIG_FILE"}, + Sources: cli.EnvVars("WOODPECKER_AGENT_CONFIG_FILE"), Name: "agent-config", Usage: "agent config file path, if set empty the agent will be stateless and unregister on termination", Value: "/etc/woodpecker/agent.conf", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_FILTER_LABELS"}, + Sources: cli.EnvVars("WOODPECKER_FILTER_LABELS"), Name: "filter", Usage: "List of labels to filter tasks on. An agent must be assigned every tag listed in a task to be selected.", }, &cli.IntFlag{ - EnvVars: []string{"WOODPECKER_MAX_WORKFLOWS", "WOODPECKER_MAX_PROCS"}, // cspell:words PROCS + Sources: cli.EnvVars("WOODPECKER_MAX_WORKFLOWS", "WOODPECKER_MAX_PROCS"), // cspell:words PROCS Name: "max-workflows", Usage: "agent parallel workflows", Value: 1, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_HEALTHCHECK"}, + Sources: cli.EnvVars("WOODPECKER_HEALTHCHECK"), Name: "healthcheck", Usage: "enable healthcheck endpoint", Value: true, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_HEALTHCHECK_ADDR"}, + Sources: cli.EnvVars("WOODPECKER_HEALTHCHECK_ADDR"), Name: "healthcheck-addr", Usage: "healthcheck endpoint address", Value: ":3000", }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_KEEPALIVE_TIME"}, + Sources: cli.EnvVars("WOODPECKER_KEEPALIVE_TIME"), Name: "keepalive-time", Usage: "after a duration of this time of no activity, the agent pings the server to check if the transport is still alive", }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_KEEPALIVE_TIMEOUT"}, + Sources: cli.EnvVars("WOODPECKER_KEEPALIVE_TIMEOUT"), Name: "keepalive-timeout", Usage: "after pinging for a keepalive check, the agent waits for a duration of this time before closing the connection if no activity", Value: time.Second * 20, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND"), Name: "backend-engine", Usage: "backend to run pipelines on", Value: "auto-detect", }, &cli.IntFlag{ - EnvVars: []string{"WOODPECKER_CONNECT_RETRY_COUNT"}, + Sources: cli.EnvVars("WOODPECKER_CONNECT_RETRY_COUNT"), Name: "connect-retry-count", Usage: "number of times to retry connecting to the server", Value: 5, }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_CONNECT_RETRY_DELAY"}, + Sources: cli.EnvVars("WOODPECKER_CONNECT_RETRY_DELAY"), Name: "connect-retry-delay", Usage: "duration to wait before retrying to connect to the server", Value: time.Second * 2, diff --git a/cmd/agent/core/health.go b/cmd/agent/core/health.go index fddf688c7f..b9c6398b15 100644 --- a/cmd/agent/core/health.go +++ b/cmd/agent/core/health.go @@ -15,13 +15,14 @@ package core import ( + "context" "encoding/json" "fmt" "net/http" "strings" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/agent" "go.woodpecker-ci.org/woodpecker/v2/version" @@ -81,8 +82,7 @@ var counter = &agent.State{ // handles pinging the endpoint and returns an error if the // agent is in an unhealthy state. -func pinger(c *cli.Context) error { - ctx := c.Context +func pinger(ctx context.Context, c *cli.Command) error { healthcheckAddress := c.String("healthcheck-addr") if strings.HasPrefix(healthcheckAddress, ":") { // this seems sufficient according to https://pkg.go.dev/net#Dial diff --git a/cmd/agent/core/run.go b/cmd/agent/core/run.go index 9c64fec3dc..3b01c2dc78 100644 --- a/cmd/agent/core/run.go +++ b/cmd/agent/core/run.go @@ -15,12 +15,13 @@ package core import ( + "context" "os" // Load config from .env file. _ "github.com/joho/godotenv/autoload" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types" "go.woodpecker-ci.org/woodpecker/v2/shared/logger" @@ -28,8 +29,8 @@ import ( "go.woodpecker-ci.org/woodpecker/v2/version" ) -func RunAgent(backends []backend.Backend) { - app := cli.NewApp() +func RunAgent(ctx context.Context, backends []backend.Backend) { + app := &cli.Command{} app.Name = "woodpecker-agent" app.Version = version.String() app.Usage = "woodpecker agent" @@ -47,7 +48,7 @@ func RunAgent(backends []backend.Backend) { } app.Flags = agentFlags - if err := app.Run(os.Args); err != nil { + if err := app.Run(ctx, os.Args); err != nil { log.Fatal().Err(err).Msg("error running agent") //nolint:forbidigo } } diff --git a/cmd/agent/main.go b/cmd/agent/main.go index cb18939f45..37316195e9 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -15,11 +15,16 @@ package main import ( + "context" + + "github.com/rs/zerolog/log" + "go.woodpecker-ci.org/woodpecker/v2/cmd/agent/core" "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/docker" "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/kubernetes" "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/local" backendTypes "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types" + "go.woodpecker-ci.org/woodpecker/v2/shared/utils" ) var backends = []backendTypes.Backend{ @@ -29,5 +34,8 @@ var backends = []backendTypes.Backend{ } func main() { - core.RunAgent(backends) + ctx := utils.WithContextSigtermCallback(context.Background(), func() { + log.Info().Msg("termination signal is received, shutting down agent") + }) + core.RunAgent(ctx, backends) } diff --git a/cmd/cli/app.go b/cmd/cli/app.go index 8b78b3ecde..4b3fe66985 100644 --- a/cmd/cli/app.go +++ b/cmd/cli/app.go @@ -15,7 +15,7 @@ package main import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/cli/admin" "go.woodpecker-ci.org/woodpecker/v2/cli/common" @@ -38,12 +38,12 @@ import ( ) //go:generate go run docs.go app.go -func newApp() *cli.App { - app := cli.NewApp() +func newApp() *cli.Command { + app := &cli.Command{} app.Name = "woodpecker-cli" app.Description = "Woodpecker command line utility" app.Version = version.String() - app.EnableBashCompletion = true + app.Usage = "command line utility" app.Flags = common.GlobalFlags app.Before = common.Before app.After = common.After diff --git a/cmd/cli/docs.go b/cmd/cli/docs.go index 9ed83ef476..d8dae41dec 100644 --- a/cmd/cli/docs.go +++ b/cmd/cli/docs.go @@ -19,11 +19,13 @@ package main import ( "os" + + docs "github.com/urfave/cli-docs/v3" ) func main() { app := newApp() - md, err := app.ToMarkdown() + md, err := docs.ToMarkdown(app) if err != nil { panic(err) } diff --git a/cmd/cli/main.go b/cmd/cli/main.go index d0b1558685..eb0f309dfe 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -15,15 +15,22 @@ package main import ( + "context" "os" _ "github.com/joho/godotenv/autoload" "github.com/rs/zerolog/log" + + "go.woodpecker-ci.org/woodpecker/v2/shared/utils" ) func main() { + ctx := utils.WithContextSigtermCallback(context.Background(), func() { + log.Info().Msg("termination signal is received, terminate cli") + }) + app := newApp() - if err := app.Run(os.Args); err != nil { + if err := app.Run(ctx, os.Args); err != nil { log.Fatal().Err(err).Msg("error running cli") //nolint:forbidigo } } diff --git a/cmd/server/flags.go b/cmd/server/flags.go index a511a4b837..697ff455fc 100644 --- a/cmd/server/flags.go +++ b/cmd/server/flags.go @@ -1,3 +1,4 @@ +// Copyright 2023 Woodpecker Authors // Copyright 2019 Laszlo Fogas // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +19,7 @@ import ( "os" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/shared/constant" "go.woodpecker-ci.org/woodpecker/v2/shared/logger" @@ -26,229 +27,232 @@ import ( var flags = append([]cli.Flag{ &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_LOG_XORM"}, + Sources: cli.EnvVars("WOODPECKER_LOG_XORM"), Name: "log-xorm", Usage: "enable xorm logging", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_LOG_XORM_SQL"}, + Sources: cli.EnvVars("WOODPECKER_LOG_XORM_SQL"), Name: "log-xorm-sql", Usage: "enable xorm sql command logging", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_HOST"}, + Sources: cli.EnvVars("WOODPECKER_HOST"), Name: "server-host", Usage: "server fully qualified url. Format: ://[/]", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER_ADDR"}, + Sources: cli.EnvVars("WOODPECKER_SERVER_ADDR"), Name: "server-addr", Usage: "server address", Value: ":8000", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER_ADDR_TLS"}, + Sources: cli.EnvVars("WOODPECKER_SERVER_ADDR_TLS"), Name: "server-addr-tls", Usage: "port https with tls (:443)", Value: ":443", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER_CERT"}, + Sources: cli.EnvVars("WOODPECKER_SERVER_CERT"), Name: "server-cert", Usage: "server ssl cert path", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_SERVER_KEY"}, + Sources: cli.EnvVars("WOODPECKER_SERVER_KEY"), Name: "server-key", Usage: "server ssl key path", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_CUSTOM_CSS_FILE"}, + Sources: cli.EnvVars("WOODPECKER_CUSTOM_CSS_FILE"), Name: "custom-css-file", Usage: "file path for the server to serve a custom .CSS file, used for customizing the UI", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_CUSTOM_JS_FILE"}, + Sources: cli.EnvVars("WOODPECKER_CUSTOM_JS_FILE"), Name: "custom-js-file", Usage: "file path for the server to serve a custom .JS file, used for customizing the UI", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LETS_ENCRYPT_EMAIL"}, + Sources: cli.EnvVars("WOODPECKER_LETS_ENCRYPT_EMAIL"), Name: "lets-encrypt-email", Usage: "let's encrypt email", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_LETS_ENCRYPT"}, + Sources: cli.EnvVars("WOODPECKER_LETS_ENCRYPT"), Name: "lets-encrypt", Usage: "enable let's encrypt", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_GRPC_ADDR"}, + Sources: cli.EnvVars("WOODPECKER_GRPC_ADDR"), Name: "grpc-addr", Usage: "grpc address", Value: ":9000", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_GRPC_SECRET"}, - Name: "grpc-secret", - Usage: "grpc jwt secret", - Value: "secret", - FilePath: os.Getenv("WOODPECKER_GRPC_SECRET_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_GRPC_SECRET_FILE")), + cli.EnvVar("WOODPECKER_GRPC_SECRET")), + Name: "grpc-secret", + Usage: "grpc jwt secret", + Value: "secret", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_METRICS_SERVER_ADDR"}, + Sources: cli.EnvVars("WOODPECKER_METRICS_SERVER_ADDR"), Name: "metrics-server-addr", Usage: "metrics server address", Value: "", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_ADMIN"}, + Sources: cli.EnvVars("WOODPECKER_ADMIN"), Name: "admin", Usage: "list of admin users", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_ORGS"}, + Sources: cli.EnvVars("WOODPECKER_ORGS"), Name: "orgs", Usage: "list of approved organizations", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_REPO_OWNERS"}, + Sources: cli.EnvVars("WOODPECKER_REPO_OWNERS"), Name: "repo-owners", Usage: "Repositories by those owners will be allowed to be used in woodpecker", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_OPEN"}, + Sources: cli.EnvVars("WOODPECKER_OPEN"), Name: "open", Usage: "enable open user registration", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_AUTHENTICATE_PUBLIC_REPOS"}, + Sources: cli.EnvVars("WOODPECKER_AUTHENTICATE_PUBLIC_REPOS"), Name: "authenticate-public-repos", Usage: "Always use authentication to clone repositories even if they are public. Needed if the SCM requires to always authenticate as used by many companies.", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS"}, + Sources: cli.EnvVars("WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS"), Name: "default-cancel-previous-pipeline-events", Usage: "List of event names that will be canceled when a new pipeline for the same context (tag, branch) is created.", - Value: cli.NewStringSlice("push", "pull_request"), + Value: []string{"push", "pull_request"}, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DEFAULT_CLONE_IMAGE"}, + Sources: cli.EnvVars("WOODPECKER_DEFAULT_CLONE_IMAGE"), Name: "default-clone-image", Usage: "The default docker image to be used when cloning the repo", Value: constant.DefaultCloneImage, }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_DEFAULT_PIPELINE_TIMEOUT"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_DEFAULT_PIPELINE_TIMEOUT"), Name: "default-pipeline-timeout", Usage: "The default time in minutes for a repo in minutes before a pipeline gets killed", Value: 60, }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_MAX_PIPELINE_TIMEOUT"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_MAX_PIPELINE_TIMEOUT"), Name: "max-pipeline-timeout", Usage: "The maximum time in minutes you can set in the repo settings before a pipeline gets killed", Value: 120, }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_SESSION_EXPIRES"}, + Sources: cli.EnvVars("WOODPECKER_SESSION_EXPIRES"), Name: "session-expires", Usage: "session expiration time", Value: time.Hour * 72, }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_ESCALATE"}, + Sources: cli.EnvVars("WOODPECKER_ESCALATE"), Name: "escalate", Usage: "images to run in privileged mode", - Value: cli.NewStringSlice(constant.PrivilegedPlugins...), + Value: constant.PrivilegedPlugins, }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_VOLUME"}, + Sources: cli.EnvVars("WOODPECKER_VOLUME"), Name: "volume", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DOCKER_CONFIG"}, + Sources: cli.EnvVars("WOODPECKER_DOCKER_CONFIG"), Name: "docker-config", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_ENVIRONMENT"}, + Sources: cli.EnvVars("WOODPECKER_ENVIRONMENT"), Name: "environment", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_NETWORK"}, + Sources: cli.EnvVars("WOODPECKER_NETWORK"), Name: "network", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_AGENT_SECRET"}, - Name: "agent-secret", - Usage: "server-agent shared password", - FilePath: os.Getenv("WOODPECKER_AGENT_SECRET_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_AGENT_SECRET_FILE")), + cli.EnvVar("WOODPECKER_AGENT_SECRET")), + Name: "agent-secret", + Usage: "server-agent shared password", }, &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_KEEPALIVE_MIN_TIME"}, + Sources: cli.EnvVars("WOODPECKER_KEEPALIVE_MIN_TIME"), Name: "keepalive-min-time", Usage: "server-side enforcement policy on the minimum amount of time a client should wait before sending a keepalive ping.", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_CONFIG_SERVICE_ENDPOINT"}, + Sources: cli.EnvVars("WOODPECKER_CONFIG_SERVICE_ENDPOINT"), Name: "config-service-endpoint", Usage: "url used for calling configuration service endpoint", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DATABASE_DRIVER"}, + Sources: cli.EnvVars("WOODPECKER_DATABASE_DRIVER"), Name: "driver", Usage: "database driver", Value: "sqlite3", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DATABASE_DATASOURCE"}, - Name: "datasource", - Usage: "database driver configuration string", - Value: datasourceDefaultValue(), - FilePath: os.Getenv("WOODPECKER_DATABASE_DATASOURCE_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_DATABASE_DATASOURCE_FILE")), + cli.EnvVar("WOODPECKER_DATABASE_DATASOURCE")), + Name: "datasource", + Usage: "database driver configuration string", + Value: datasourceDefaultValue(), }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_PROMETHEUS_AUTH_TOKEN"}, - Name: "prometheus-auth-token", - Usage: "token to secure prometheus metrics endpoint", - Value: "", - FilePath: os.Getenv("WOODPECKER_PROMETHEUS_AUTH_TOKEN_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_PROMETHEUS_AUTH_TOKEN_FILE")), + cli.EnvVar("WOODPECKER_PROMETHEUS_AUTH_TOKEN")), + Name: "prometheus-auth-token", + Usage: "token to secure prometheus metrics endpoint", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_STATUS_CONTEXT", "WOODPECKER_GITHUB_CONTEXT", "WOODPECKER_GITEA_CONTEXT"}, + Sources: cli.EnvVars("WOODPECKER_STATUS_CONTEXT", "WOODPECKER_GITHUB_CONTEXT", "WOODPECKER_GITEA_CONTEXT"), Name: "status-context", Usage: "status context prefix", Value: "ci/woodpecker", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_STATUS_CONTEXT_FORMAT"}, + Sources: cli.EnvVars("WOODPECKER_STATUS_CONTEXT_FORMAT"), Name: "status-context-format", Usage: "status context format", Value: "{{ .context }}/{{ .event }}/{{ .workflow }}{{if not (eq .axis_id 0)}}/{{.axis_id}}{{end}}", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_MIGRATIONS_ALLOW_LONG"}, + Sources: cli.EnvVars("WOODPECKER_MIGRATIONS_ALLOW_LONG"), Name: "migrations-allow-long", Value: false, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_ENABLE_SWAGGER"}, + Sources: cli.EnvVars("WOODPECKER_ENABLE_SWAGGER"), Name: "enable-swagger", Value: true, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_DISABLE_VERSION_CHECK"}, + Sources: cli.EnvVars("WOODPECKER_DISABLE_VERSION_CHECK"), Usage: "Disable version check in admin web ui.", Name: "skip-version-check", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LOG_STORE"}, + Sources: cli.EnvVars("WOODPECKER_LOG_STORE"), Name: "log-store", Usage: "log store to use ('database' or 'file')", Value: "database", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LOG_STORE_FILE_PATH"}, + Sources: cli.EnvVars("WOODPECKER_LOG_STORE_FILE_PATH"), Name: "log-store-file-path", Usage: "directory used for file based log storage", }, @@ -256,17 +260,17 @@ var flags = append([]cli.Flag{ // backend options for pipeline compiler // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_NO_PROXY", "NO_PROXY", "no_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_NO_PROXY", "NO_PROXY", "no_proxy"), Usage: "if set, pass the environment variable down as \"NO_PROXY\" to steps", Name: "backend-no-proxy", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_HTTP_PROXY", "HTTP_PROXY", "http_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_HTTP_PROXY", "HTTP_PROXY", "http_proxy"), Usage: "if set, pass the environment variable down as \"HTTP_PROXY\" to steps", Name: "backend-http-proxy", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_HTTPS_PROXY", "HTTPS_PROXY", "https_proxy"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_HTTPS_PROXY", "HTTPS_PROXY", "https_proxy"), Usage: "if set, pass the environment variable down as \"HTTPS_PROXY\" to steps", Name: "backend-https-proxy", }, @@ -274,44 +278,44 @@ var flags = append([]cli.Flag{ // resource limit parameters // &cli.DurationFlag{ - EnvVars: []string{"WOODPECKER_FORGE_TIMEOUT"}, + Sources: cli.EnvVars("WOODPECKER_FORGE_TIMEOUT"), Name: "forge-timeout", Usage: "how many seconds before timeout when fetching the Woodpecker configuration from a Forge", Value: time.Second * 3, }, &cli.UintFlag{ - EnvVars: []string{"WOODPECKER_FORGE_RETRY"}, + Sources: cli.EnvVars("WOODPECKER_FORGE_RETRY"), Name: "forge-retry", Usage: "How many retries of fetching the Woodpecker configuration from a forge are done before we fail", Value: 3, }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_LIMIT_MEM_SWAP"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_LIMIT_MEM_SWAP"), Name: "limit-mem-swap", Usage: "maximum memory used for swap in bytes", }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_LIMIT_MEM"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_LIMIT_MEM"), Name: "limit-mem", Usage: "maximum memory allowed in bytes", }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_LIMIT_SHM_SIZE"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_LIMIT_SHM_SIZE"), Name: "limit-shm-size", Usage: "docker compose /dev/shm allowed in bytes", }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_LIMIT_CPU_QUOTA"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_QUOTA"), Name: "limit-cpu-quota", Usage: "impose a cpu quota", }, - &cli.Int64Flag{ - EnvVars: []string{"WOODPECKER_LIMIT_CPU_SHARES"}, + &cli.IntFlag{ + Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_SHARES"), Name: "limit-cpu-shares", Usage: "change the cpu shares", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LIMIT_CPU_SET"}, + Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_SET"), Name: "limit-cpu-set", Usage: "set the cpus allowed to execute containers", }, @@ -319,27 +323,62 @@ var flags = append([]cli.Flag{ &cli.StringFlag{ Name: "forge-url", Usage: "url of the forge", - EnvVars: []string{"WOODPECKER_FORGE_URL", "WOODPECKER_GITHUB_URL", "WOODPECKER_GITLAB_URL", "WOODPECKER_GITEA_URL", "WOODPECKER_FORGEJO_URL", "WOODPECKER_BITBUCKET_URL", "WOODPECKER_BITBUCKET_DC_URL"}, - }, - &cli.StringFlag{ - Name: "forge-oauth-client", - Usage: "oauth2 client id", - EnvVars: []string{"WOODPECKER_FORGE_CLIENT", "WOODPECKER_GITHUB_CLIENT", "WOODPECKER_GITLAB_CLIENT", "WOODPECKER_GITEA_CLIENT", "WOODPECKER_FORGEJO_CLIENT", "WOODPECKER_BITBUCKET_CLIENT", "WOODPECKER_BITBUCKET_DC_CLIENT_ID"}, - FilePath: getFirstNonEmptyEnvVar([]string{"WOODPECKER_FORGE_CLIENT_FILE", "WOODPECKER_GITHUB_CLIENT_FILE", "WOODPECKER_GITLAB_CLIENT_FILE", "WOODPECKER_GITEA_CLIENT_FILE", "WOODPECKER_FORGEJO_CLIENT_FILE", "WOODPECKER_BITBUCKET_CLIENT_FILE", "WOODPECKER_BITBUCKET_DC_CLIENT_ID_FILE"}), - }, - &cli.StringFlag{ - Name: "forge-oauth-secret", - Usage: "oauth2 client secret", - EnvVars: []string{"WOODPECKER_FORGE_SECRET", "WOODPECKER_GITHUB_SECRET", "WOODPECKER_GITLAB_SECRET", "WOODPECKER_GITEA_SECRET", "WOODPECKER_FORGEJO_SECRET", "WOODPECKER_BITBUCKET_SECRET", "WOODPECKER_BITBUCKET_DC_CLIENT_SECRET"}, - FilePath: getFirstNonEmptyEnvVar([]string{"WOODPECKER_FORGE_SECRET_FILE", "WOODPECKER_GITHUB_SECRET_FILE", "WOODPECKER_GITLAB_SECRET_FILE", "WOODPECKER_GITEA_SECRET_FILE", "WOODPECKER_FORGEJO_SECRET_FILE", "WOODPECKER_BITBUCKET_SECRET_FILE", "WOODPECKER_BITBUCKET_DC_CLIENT_SECRET_FILE"}), + Sources: cli.EnvVars("WOODPECKER_FORGE_URL", "WOODPECKER_GITHUB_URL", "WOODPECKER_GITLAB_URL", "WOODPECKER_GITEA_URL", "WOODPECKER_FORGEJO_URL", "WOODPECKER_BITBUCKET_URL", "WOODPECKER_BITBUCKET_DC_URL"), + }, + &cli.StringFlag{ + Sources: cli.NewValueSourceChain( + cli.File(getFirstNonEmptyEnvVar( + "WOODPECKER_FORGE_CLIENT_FILE", + "WOODPECKER_GITHUB_CLIENT_FILE", + "WOODPECKER_GITLAB_CLIENT_FILE", + "WOODPECKER_GITEA_CLIENT_FILE", + "WOODPECKER_FORGEJO_CLIENT_FILE", + "WOODPECKER_BITBUCKET_CLIENT_FILE", + "WOODPECKER_BITBUCKET_DC_CLIENT_ID_FILE")), + cli.EnvVar("WOODPECKER_FORGE_CLIENT"), + cli.EnvVar("WOODPECKER_GITHUB_CLIENT"), + cli.EnvVar("WOODPECKER_GITLAB_CLIENT"), + cli.EnvVar("WOODPECKER_GITEA_CLIENT"), + cli.EnvVar("WOODPECKER_FORGEJO_CLIENT"), + cli.EnvVar("WOODPECKER_BITBUCKET_CLIENT"), + cli.EnvVar("WOODPECKER_BITBUCKET_DC_CLIENT_ID")), + Name: "forge-oauth-client", + Usage: "oauth2 client id", + }, + &cli.StringFlag{ + Sources: cli.NewValueSourceChain( + cli.File(getFirstNonEmptyEnvVar( + "WOODPECKER_FORGE_SECRET_FILE", + "WOODPECKER_GITHUB_SECRET_FILE", + "WOODPECKER_GITLAB_SECRET_FILE", + "WOODPECKER_GITEA_SECRET_FILE", + "WOODPECKER_FORGEJO_SECRET_FILE", + "WOODPECKER_BITBUCKET_SECRET_FILE", + "WOODPECKER_BITBUCKET_DC_CLIENT_SECRET_FILE", + )), + cli.EnvVar("WOODPECKER_FORGE_SECRET"), + cli.EnvVar("WOODPECKER_GITHUB_SECRET"), + cli.EnvVar("WOODPECKER_GITLAB_SECRET"), + cli.EnvVar("WOODPECKER_GITEA_SECRET"), + cli.EnvVar("WOODPECKER_FORGEJO_SECRET"), + cli.EnvVar("WOODPECKER_BITBUCKET_SECRET"), + cli.EnvVar("WOODPECKER_BITBUCKET_DC_CLIENT_SECRET")), + Name: "forge-oauth-secret", + Usage: "oauth2 client secret", }, &cli.BoolFlag{ - Name: "forge-skip-verify", - Usage: "skip ssl verification", - EnvVars: []string{"WOODPECKER_FORGE_SKIP_VERIFY", "WOODPECKER_GITHUB_SKIP_VERIFY", "WOODPECKER_GITLAB_SKIP_VERIFY", "WOODPECKER_GITEA_SKIP_VERIFY", "WOODPECKER_FORGEJO_SKIP_VERIFY", "WOODPECKER_BITBUCKET_SKIP_VERIFY"}, - }, - &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_EXPERT_FORGE_OAUTH_HOST", "WOODPECKER_DEV_GITEA_OAUTH_URL"}, // TODO: remove WOODPECKER_DEV_GITEA_OAUTH_URL in next major release + Name: "forge-skip-verify", + Usage: "skip ssl verification", + Sources: cli.EnvVars( + "WOODPECKER_FORGE_SKIP_VERIFY", + "WOODPECKER_GITHUB_SKIP_VERIFY", + "WOODPECKER_GITLAB_SKIP_VERIFY", + "WOODPECKER_GITEA_SKIP_VERIFY", + "WOODPECKER_FORGEJO_SKIP_VERIFY", + "WOODPECKER_BITBUCKET_SKIP_VERIFY"), + }, + &cli.StringFlag{ + Sources: cli.EnvVars("WOODPECKER_EXPERT_FORGE_OAUTH_HOST", "WOODPECKER_DEV_GITEA_OAUTH_URL"), // TODO: remove WOODPECKER_DEV_GITEA_OAUTH_URL in next major release Name: "forge-oauth-host", Usage: "!!!for experts!!! fully qualified public forge url. Use it if your forge url WOODPECKER_FORGE_URL or WOODPECKER_GITEA_URL, ... isn't a public url. Format: ://[/]", }, @@ -347,7 +386,7 @@ var flags = append([]cli.Flag{ // Addon // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_ADDON_FORGE"}, + Sources: cli.EnvVars("WOODPECKER_ADDON_FORGE"), Name: "addon-forge", Usage: "path to forge addon executable", }, @@ -355,18 +394,18 @@ var flags = append([]cli.Flag{ // GitHub // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GITHUB"}, + Sources: cli.EnvVars("WOODPECKER_GITHUB"), Name: "github", Usage: "github driver is enabled", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GITHUB_MERGE_REF"}, + Sources: cli.EnvVars("WOODPECKER_GITHUB_MERGE_REF"), Name: "github-merge-ref", Usage: "github pull requests use merge ref", Value: true, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GITHUB_PUBLIC_ONLY"}, + Sources: cli.EnvVars("WOODPECKER_GITHUB_PUBLIC_ONLY"), Name: "github-public-only", Usage: "github tokens should only get access to public repos", Value: false, @@ -375,7 +414,7 @@ var flags = append([]cli.Flag{ // Gitea // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GITEA"}, + Sources: cli.EnvVars("WOODPECKER_GITEA"), Name: "gitea", Usage: "gitea driver is enabled", }, @@ -383,7 +422,7 @@ var flags = append([]cli.Flag{ // Forgejo // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_FORGEJO"}, + Sources: cli.EnvVars("WOODPECKER_FORGEJO"), Name: "forgejo", Usage: "forgejo driver is enabled", }, @@ -391,7 +430,7 @@ var flags = append([]cli.Flag{ // Bitbucket // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BITBUCKET"}, + Sources: cli.EnvVars("WOODPECKER_BITBUCKET"), Name: "bitbucket", Usage: "bitbucket driver is enabled", }, @@ -399,7 +438,7 @@ var flags = append([]cli.Flag{ // Gitlab // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_GITLAB"}, + Sources: cli.EnvVars("WOODPECKER_GITLAB"), Name: "gitlab", Usage: "gitlab driver is enabled", }, @@ -407,27 +446,29 @@ var flags = append([]cli.Flag{ // Bitbucket DataCenter/Server (previously Stash) // &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BITBUCKET_DC"}, + Sources: cli.EnvVars("WOODPECKER_BITBUCKET_DC"), Name: "bitbucket-dc", Usage: "Bitbucket DataCenter/Server driver is enabled", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BITBUCKET_DC_GIT_USERNAME"}, - Name: "bitbucket-dc-git-username", - Usage: "Bitbucket DataCenter/Server service account username", - FilePath: os.Getenv("WOODPECKER_BITBUCKET_DC_GIT_USERNAME_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_BITBUCKET_DC_GIT_USERNAME_FILE")), + cli.EnvVar("WOODPECKER_BITBUCKET_DC_GIT_USERNAME")), + Name: "bitbucket-dc-git-username", + Usage: "Bitbucket DataCenter/Server service account username", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BITBUCKET_DC_GIT_PASSWORD"}, - Name: "bitbucket-dc-git-password", - Usage: "Bitbucket DataCenter/Server service account password", - FilePath: os.Getenv("WOODPECKER_BITBUCKET_DC_GIT_PASSWORD_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_BITBUCKET_DC_GIT_PASSWORD_FILE")), + cli.EnvVar("WOODPECKER_BITBUCKET_DC_GIT_PASSWORD")), + Name: "bitbucket-dc-git-password", + Usage: "Bitbucket DataCenter/Server service account password", }, // // development flags // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DEV_WWW_PROXY"}, + Sources: cli.EnvVars("WOODPECKER_DEV_WWW_PROXY"), Name: "www-proxy", Usage: "serve the website by using a proxy (used for development)", Hidden: true, @@ -436,13 +477,13 @@ var flags = append([]cli.Flag{ // expert flags // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_EXPERT_WEBHOOK_HOST", "WOODPECKER_WEBHOOK_HOST"}, // TODO: remove WOODPECKER_WEBHOOK_HOST in next major release + Sources: cli.EnvVars("WOODPECKER_EXPERT_WEBHOOK_HOST", "WOODPECKER_WEBHOOK_HOST"), // TODO: remove WOODPECKER_WEBHOOK_HOST in next major release Name: "server-webhook-host", Usage: "!!!for experts!!! fully qualified woodpecker server url called by forge's webhooks. Format: ://[/]", }, // TODO: remove in next major release &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_DEV_OAUTH_HOST"}, + Sources: cli.EnvVars("WOODPECKER_DEV_OAUTH_HOST"), Name: "server-dev-oauth-host-deprecated", Usage: "DEPRECATED: use WOODPECKER_EXPERT_FORGE_OAUTH_HOST instead\nfully qualified url used for oauth redirects. Format: ://[/]", Value: "", @@ -452,18 +493,19 @@ var flags = append([]cli.Flag{ // secrets encryption in DB // &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_ENCRYPTION_KEY"}, - Name: "encryption-raw-key", - Usage: "Raw encryption key", - FilePath: os.Getenv("WOODPECKER_ENCRYPTION_KEY_FILE"), + Sources: cli.NewValueSourceChain( + cli.File(os.Getenv("WOODPECKER_ENCRYPTION_KEY_FILE")), + cli.EnvVar("WOODPECKER_ENCRYPTION_KEY")), + Name: "encryption-raw-key", + Usage: "Raw encryption key", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_ENCRYPTION_TINK_KEYSET_FILE"}, + Sources: cli.EnvVars("WOODPECKER_ENCRYPTION_TINK_KEYSET_FILE"), Name: "encryption-tink-keyset", Usage: "Google tink AEAD-compatible keyset file to encrypt secrets in DB", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_ENCRYPTION_DISABLE"}, + Sources: cli.EnvVars("WOODPECKER_ENCRYPTION_DISABLE"), Name: "encryption-disable-flag", Usage: "Flag to decrypt all encrypted data and disable encryption on server", }, @@ -479,7 +521,7 @@ func datasourceDefaultValue() string { return "woodpecker.sqlite" } -func getFirstNonEmptyEnvVar(envVars []string) string { +func getFirstNonEmptyEnvVar(envVars ...string) string { for _, envVar := range envVars { val := os.Getenv(envVar) if val != "" { diff --git a/cmd/server/grpc_server.go b/cmd/server/grpc_server.go index e573d8381f..16da47f05d 100644 --- a/cmd/server/grpc_server.go +++ b/cmd/server/grpc_server.go @@ -20,7 +20,7 @@ import ( "net" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "google.golang.org/grpc" "google.golang.org/grpc/keepalive" @@ -30,7 +30,7 @@ import ( "go.woodpecker-ci.org/woodpecker/v2/server/store" ) -func runGrpcServer(ctx context.Context, c *cli.Context, _store store.Store) error { +func runGrpcServer(ctx context.Context, c *cli.Command, _store store.Store) error { lis, err := net.Listen("tcp", c.String("grpc-addr")) if err != nil { log.Fatal().Err(err).Msg("failed to listen on grpc-addr") //nolint:forbidigo diff --git a/cmd/server/health.go b/cmd/server/health.go index eb780b9a92..10780889f1 100644 --- a/cmd/server/health.go +++ b/cmd/server/health.go @@ -16,20 +16,21 @@ package main import ( + "context" "fmt" "net/http" "strings" "time" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) const pingTimeout = 1 * time.Second // handles pinging the endpoint and returns an error if the // server is in an unhealthy state. -func pinger(c *cli.Context) error { +func pinger(_ context.Context, c *cli.Command) error { scheme := "http" serverAddr := c.String("server-addr") if strings.HasPrefix(serverAddr, ":") { diff --git a/cmd/server/main.go b/cmd/server/main.go index f8050418a4..71b17b23b0 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -15,18 +15,24 @@ package main import ( + "context" "os" _ "github.com/joho/godotenv/autoload" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" _ "go.woodpecker-ci.org/woodpecker/v2/cmd/server/docs" + "go.woodpecker-ci.org/woodpecker/v2/shared/utils" "go.woodpecker-ci.org/woodpecker/v2/version" ) func main() { - app := cli.NewApp() + ctx := utils.WithContextSigtermCallback(context.Background(), func() { + log.Info().Msg("termination signal is received, shutting down server") + }) + + app := cli.Command{} app.Name = "woodpecker-server" app.Version = version.String() app.Usage = "woodpecker server" @@ -42,7 +48,7 @@ func main() { setupSwaggerStaticConfig() - if err := app.Run(os.Args); err != nil { + if err := app.Run(ctx, os.Args); err != nil { log.Error().Err(err).Msgf("error running server") } } diff --git a/cmd/server/server.go b/cmd/server/server.go index c411861326..42338ddd5d 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -30,7 +30,7 @@ import ( prometheus_http "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/sync/errgroup" "go.woodpecker-ci.org/woodpecker/v2/server" @@ -39,7 +39,6 @@ import ( "go.woodpecker-ci.org/woodpecker/v2/server/router/middleware" "go.woodpecker-ci.org/woodpecker/v2/server/web" "go.woodpecker-ci.org/woodpecker/v2/shared/logger" - "go.woodpecker-ci.org/woodpecker/v2/shared/utils" "go.woodpecker-ci.org/woodpecker/v2/version" ) @@ -53,15 +52,11 @@ var ( shutdownCtx = context.Background() ) -func run(c *cli.Context) error { - if err := logger.SetupGlobalLogger(c, true); err != nil { +func run(ctx context.Context, c *cli.Command) error { + if err := logger.SetupGlobalLogger(ctx, c, true); err != nil { return err } - ctx := utils.WithContextSigtermCallback(c.Context, func() { - log.Info().Msg("termination signal is received, shutting down server") - }) - ctx, ctxCancel := context.WithCancelCause(ctx) stopServerFunc = func(err error) { if err != nil { diff --git a/cmd/server/setup.go b/cmd/server/setup.go index 858d79375e..71c2ac71d4 100644 --- a/cmd/server/setup.go +++ b/cmd/server/setup.go @@ -27,7 +27,7 @@ import ( "github.com/gorilla/securecookie" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server" "go.woodpecker-ci.org/woodpecker/v2/server/cache" @@ -51,7 +51,7 @@ const ( storeInfoRefreshInterval = 10 * time.Second ) -func setupStore(ctx context.Context, c *cli.Context) (store.Store, error) { +func setupStore(ctx context.Context, c *cli.Command) (store.Store, error) { datasource := c.String("datasource") driver := c.String("driver") xorm := store.XORM{ @@ -112,7 +112,7 @@ func setupMembershipService(_ context.Context, _store store.Store) cache.Members return cache.NewMembershipService(_store) } -func setupLogStore(c *cli.Context, s store.Store) (logService.Service, error) { +func setupLogStore(c *cli.Command, s store.Store) (logService.Service, error) { switch c.String("log-store") { case "file": return file.NewLogStore(c.String("log-store-file-path")) @@ -144,7 +144,7 @@ func setupJWTSecret(_store store.Store) (string, error) { return jwtSecret, nil } -func setupEvilGlobals(ctx context.Context, c *cli.Context, s store.Store) error { +func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error { // services server.Config.Services.Queue = setupQueue(ctx, s) server.Config.Services.Logs = logging.New() @@ -175,15 +175,15 @@ func setupEvilGlobals(ctx context.Context, c *cli.Context, s store.Store) error events = append(events, model.WebhookEvent(v)) } server.Config.Pipeline.DefaultCancelPreviousPipelineEvents = events - server.Config.Pipeline.DefaultTimeout = c.Int64("default-pipeline-timeout") - server.Config.Pipeline.MaxTimeout = c.Int64("max-pipeline-timeout") + server.Config.Pipeline.DefaultTimeout = c.Int("default-pipeline-timeout") + server.Config.Pipeline.MaxTimeout = c.Int("max-pipeline-timeout") // limits - server.Config.Pipeline.Limits.MemSwapLimit = c.Int64("limit-mem-swap") - server.Config.Pipeline.Limits.MemLimit = c.Int64("limit-mem") - server.Config.Pipeline.Limits.ShmSize = c.Int64("limit-shm-size") - server.Config.Pipeline.Limits.CPUQuota = c.Int64("limit-cpu-quota") - server.Config.Pipeline.Limits.CPUShares = c.Int64("limit-cpu-shares") + server.Config.Pipeline.Limits.MemSwapLimit = c.Int("limit-mem-swap") + server.Config.Pipeline.Limits.MemLimit = c.Int("limit-mem") + server.Config.Pipeline.Limits.ShmSize = c.Int("limit-shm-size") + server.Config.Pipeline.Limits.CPUQuota = c.Int("limit-cpu-quota") + server.Config.Pipeline.Limits.CPUShares = c.Int("limit-cpu-shares") server.Config.Pipeline.Limits.CPUSet = c.String("limit-cpu-set") // backend options for pipeline compiler diff --git a/go.mod b/go.mod index d20698c112..5ec592f407 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,8 @@ require ( github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.3 - github.com/urfave/cli/v2 v2.27.2 + github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4 + github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1 github.com/xanzy/go-gitlab v0.106.0 github.com/xeipuuv/gojsonschema v1.2.0 github.com/zalando/go-keyring v0.2.5 @@ -180,7 +181,6 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect github.com/zeebo/blake3 v0.2.3 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.8.0 // indirect diff --git a/go.sum b/go.sum index 7f34fbc5cb..d1e6fbe3ee 100644 --- a/go.sum +++ b/go.sum @@ -482,8 +482,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= -github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= +github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4 h1:exFN/ZOxXslYr9t2AjrniP7wPjp/VLLAJhgazj92EBg= +github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4/go.mod h1:AIqom6Q60U4tiqHp41i7+/AB2XHgi1WvQ7jOFlccmZ4= +github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1 h1:oxO/Jem1QPy4lxbDtX8PMiFbL79dNMA6CNAfbC06rn4= +github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1/go.mod h1:Z1ItyMma7t6I7zHG9OpbExhHQOSkFf/96n+mAZ9MtVI= github.com/xanzy/go-gitlab v0.106.0 h1:EDfD03K74cIlQo2EducfiupVrip+Oj02bq9ofw5F8sA= github.com/xanzy/go-gitlab v0.106.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -495,8 +497,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= -github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/pipeline/backend/docker/docker.go b/pipeline/backend/docker/docker.go index 7b7d313261..8b3603e744 100644 --- a/pipeline/backend/docker/docker.go +++ b/pipeline/backend/docker/docker.go @@ -31,7 +31,7 @@ import ( std_copy "github.com/moby/moby/pkg/stdcopy" "github.com/moby/term" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types" "go.woodpecker-ci.org/woodpecker/v2/shared/utils" @@ -63,7 +63,7 @@ func (e *docker) Name() string { } func (e *docker) IsAvailable(ctx context.Context) bool { - if c, ok := ctx.Value(backend.CliContext).(*cli.Context); ok { + if c, ok := ctx.Value(backend.CliCommand).(*cli.Command); ok { if c.IsSet("backend-docker-host") { return true } @@ -101,7 +101,7 @@ func (e *docker) Flags() []cli.Flag { // Load new client for Docker Backend using environment variables. func (e *docker) Load(ctx context.Context) (*backend.BackendInfo, error) { - c, ok := ctx.Value(backend.CliContext).(*cli.Context) + c, ok := ctx.Value(backend.CliCommand).(*cli.Command) if !ok { return nil, backend.ErrNoCliContextFound } diff --git a/pipeline/backend/docker/flags.go b/pipeline/backend/docker/flags.go index 293bbdfba2..379cf59961 100644 --- a/pipeline/backend/docker/flags.go +++ b/pipeline/backend/docker/flags.go @@ -15,44 +15,44 @@ package docker import ( - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var Flags = []cli.Flag{ &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_HOST", "DOCKER_HOST"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_HOST", "DOCKER_HOST"), Name: "backend-docker-host", Usage: "path to docker socket or url to the docker server", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_API_VERSION", "DOCKER_API_VERSION"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_API_VERSION", "DOCKER_API_VERSION"), Name: "backend-docker-api-version", Usage: "the version of the API to reach, leave empty for latest.", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_CERT_PATH", "DOCKER_CERT_PATH"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_CERT_PATH", "DOCKER_CERT_PATH"), Name: "backend-docker-cert", Usage: "path to load the TLS certificates for connecting to docker server", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_TLS_VERIFY", "DOCKER_TLS_VERIFY"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_TLS_VERIFY", "DOCKER_TLS_VERIFY"), Name: "backend-docker-tls-verify", Usage: "enable or disable TLS verification for connecting to docker server", Value: true, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6"), Name: "backend-docker-ipv6", Usage: "backend docker enable IPV6", Value: false, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_NETWORK"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_NETWORK"), Name: "backend-docker-network", Usage: "backend docker network", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_VOLUMES"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_DOCKER_VOLUMES"), Name: "backend-docker-volumes", Usage: "backend docker volumes (comma separated)", }, diff --git a/pipeline/backend/dummy/dummy.go b/pipeline/backend/dummy/dummy.go index 4eadd1c656..cdf08c8aa6 100644 --- a/pipeline/backend/dummy/dummy.go +++ b/pipeline/backend/dummy/dummy.go @@ -27,7 +27,7 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types" ) diff --git a/pipeline/backend/kubernetes/flags.go b/pipeline/backend/kubernetes/flags.go index 7b69ff5400..8ba9b079c8 100644 --- a/pipeline/backend/kubernetes/flags.go +++ b/pipeline/backend/kubernetes/flags.go @@ -14,76 +14,78 @@ package kubernetes -import "github.com/urfave/cli/v2" +import ( + "github.com/urfave/cli/v3" +) var Flags = []cli.Flag{ &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_NAMESPACE"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_NAMESPACE"), Name: "backend-k8s-namespace", Usage: "backend k8s namespace", Value: "woodpecker", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_VOLUME_SIZE"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_VOLUME_SIZE"), Name: "backend-k8s-volume-size", Usage: "backend k8s volume size (default 10G)", Value: "10G", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_STORAGE_CLASS"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_STORAGE_CLASS"), Name: "backend-k8s-storage-class", Usage: "backend k8s storage class", Value: "", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_STORAGE_RWX"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_STORAGE_RWX"), Name: "backend-k8s-storage-rwx", Usage: "backend k8s storage access mode, should ReadWriteMany (RWX) instead of ReadWriteOnce (RWO) be used? (default: true)", Value: true, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_LABELS"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_POD_LABELS"), Name: "backend-k8s-pod-labels", Usage: "backend k8s additional Agent-wide worker pod labels", Value: "", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_LABELS_ALLOW_FROM_STEP"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_POD_LABELS_ALLOW_FROM_STEP"), Name: "backend-k8s-pod-labels-allow-from-step", Usage: "whether to allow using labels from step's backend options", Value: false, }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS"), Name: "backend-k8s-pod-annotations", Usage: "backend k8s additional Agent-wide worker pod annotations", Value: "", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_NODE_SELECTOR"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_POD_NODE_SELECTOR"), Name: "backend-k8s-pod-node-selector", Usage: "backend k8s Agent-wide worker pod node selector", Value: "", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS_ALLOW_FROM_STEP"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS_ALLOW_FROM_STEP"), Name: "backend-k8s-pod-annotations-allow-from-step", Usage: "whether to allow using annotations from step's backend options", Value: false, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_SECCTX_NONROOT"}, // cspell:words secctx nonroot + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_SECCTX_NONROOT"), // cspell:words secctx nonroot Name: "backend-k8s-secctx-nonroot", Usage: "`run as non root` Kubernetes security context option", }, &cli.StringSliceFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES"), Name: "backend-k8s-pod-image-pull-secret-names", Usage: "backend k8s pull secret names for private registries", - Value: cli.NewStringSlice("regcred"), + Value: []string{"regcred"}, }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_BACKEND_K8S_ALLOW_NATIVE_SECRETS"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_ALLOW_NATIVE_SECRETS"), Name: "backend-k8s-allow-native-secrets", Usage: "whether to allow existing Kubernetes secrets to be referenced from steps", Value: false, diff --git a/pipeline/backend/kubernetes/kubernetes.go b/pipeline/backend/kubernetes/kubernetes.go index e0dc18b0dc..d68dbae593 100644 --- a/pipeline/backend/kubernetes/kubernetes.go +++ b/pipeline/backend/kubernetes/kubernetes.go @@ -25,7 +25,7 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -83,7 +83,7 @@ func newDefaultDeleteOptions() meta_v1.DeleteOptions { func configFromCliContext(ctx context.Context) (*config, error) { if ctx != nil { - if c, ok := ctx.Value(types.CliContext).(*cli.Context); ok { + if c, ok := ctx.Value(types.CliCommand).(*cli.Command); ok { config := config{ Namespace: c.String("backend-k8s-namespace"), StorageClass: c.String("backend-k8s-storage-class"), diff --git a/pipeline/backend/local/flags.go b/pipeline/backend/local/flags.go index 64ec61fb95..f4b621ea75 100644 --- a/pipeline/backend/local/flags.go +++ b/pipeline/backend/local/flags.go @@ -17,13 +17,13 @@ package local import ( "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var Flags = []cli.Flag{ &cli.StringFlag{ Name: "backend-local-temp-dir", - EnvVars: []string{"WOODPECKER_BACKEND_LOCAL_TEMP_DIR"}, + Sources: cli.EnvVars("WOODPECKER_BACKEND_LOCAL_TEMP_DIR"), Usage: "set a different temp dir to clone workflows into", Value: os.TempDir(), }, diff --git a/pipeline/backend/local/local.go b/pipeline/backend/local/local.go index 08f6abd16d..3ea42ba0f2 100644 --- a/pipeline/backend/local/local.go +++ b/pipeline/backend/local/local.go @@ -27,7 +27,7 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" @@ -71,7 +71,7 @@ func (e *local) Flags() []cli.Flag { } func (e *local) Load(ctx context.Context) (*types.BackendInfo, error) { - c, ok := ctx.Value(types.CliContext).(*cli.Context) + c, ok := ctx.Value(types.CliCommand).(*cli.Command) if ok { e.tempDir = c.String("backend-local-temp-dir") } diff --git a/pipeline/backend/types/backend.go b/pipeline/backend/types/backend.go index 0ef6b68595..4687018f86 100644 --- a/pipeline/backend/types/backend.go +++ b/pipeline/backend/types/backend.go @@ -18,7 +18,7 @@ import ( "context" "io" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Backend defines a container orchestration backend and is used diff --git a/pipeline/backend/types/config.go b/pipeline/backend/types/config.go index 16843a8305..bf07e9e7a3 100644 --- a/pipeline/backend/types/config.go +++ b/pipeline/backend/types/config.go @@ -22,10 +22,10 @@ type Config struct { Secrets []*Secret `json:"secrets"` // secret definitions } -// CliContext is the context key to pass cli context to backends if needed. -var CliContext ContextKey +// CliCommand is the context key to pass cli context to backends if needed. +var CliCommand contextKey -// ContextKey is just an empty struct. It exists so CliContext can be +// contextKey is just an empty struct. It exists so CliCommand can be // an immutable public variable with a unique type. It's immutable // because nobody else can create a ContextKey, being unexported. -type ContextKey struct{} +type contextKey struct{} diff --git a/pipeline/rpc/proto/woodpecker.pb.go b/pipeline/rpc/proto/woodpecker.pb.go index f66e9be5bf..e7cfcad3c9 100644 --- a/pipeline/rpc/proto/woodpecker.pb.go +++ b/pipeline/rpc/proto/woodpecker.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.1 -// protoc v4.25.1 +// protoc v4.25.3 // source: woodpecker.proto package proto diff --git a/pipeline/rpc/proto/woodpecker_grpc.pb.go b/pipeline/rpc/proto/woodpecker_grpc.pb.go index 837ce74e09..5b4ee588c4 100644 --- a/pipeline/rpc/proto/woodpecker_grpc.pb.go +++ b/pipeline/rpc/proto/woodpecker_grpc.pb.go @@ -15,8 +15,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc v4.25.1 +// - protoc-gen-go-grpc v1.4.0 +// - protoc v4.25.3 // source: woodpecker.proto package proto @@ -30,8 +30,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( Woodpecker_Version_FullMethodName = "/proto.Woodpecker/Version" @@ -50,6 +50,8 @@ const ( // WoodpeckerClient is the client API for Woodpecker service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Woodpecker Server Service type WoodpeckerClient interface { Version(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*VersionResponse, error) Next(ctx context.Context, in *NextRequest, opts ...grpc.CallOption) (*NextResponse, error) @@ -73,8 +75,9 @@ func NewWoodpeckerClient(cc grpc.ClientConnInterface) WoodpeckerClient { } func (c *woodpeckerClient) Version(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*VersionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(VersionResponse) - err := c.cc.Invoke(ctx, Woodpecker_Version_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Version_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -82,8 +85,9 @@ func (c *woodpeckerClient) Version(ctx context.Context, in *Empty, opts ...grpc. } func (c *woodpeckerClient) Next(ctx context.Context, in *NextRequest, opts ...grpc.CallOption) (*NextResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(NextResponse) - err := c.cc.Invoke(ctx, Woodpecker_Next_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Next_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -91,8 +95,9 @@ func (c *woodpeckerClient) Next(ctx context.Context, in *NextRequest, opts ...gr } func (c *woodpeckerClient) Init(ctx context.Context, in *InitRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Init_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Init_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -100,8 +105,9 @@ func (c *woodpeckerClient) Init(ctx context.Context, in *InitRequest, opts ...gr } func (c *woodpeckerClient) Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Wait_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Wait_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -109,8 +115,9 @@ func (c *woodpeckerClient) Wait(ctx context.Context, in *WaitRequest, opts ...gr } func (c *woodpeckerClient) Done(ctx context.Context, in *DoneRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Done_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Done_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -118,8 +125,9 @@ func (c *woodpeckerClient) Done(ctx context.Context, in *DoneRequest, opts ...gr } func (c *woodpeckerClient) Extend(ctx context.Context, in *ExtendRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Extend_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Extend_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -127,8 +135,9 @@ func (c *woodpeckerClient) Extend(ctx context.Context, in *ExtendRequest, opts . } func (c *woodpeckerClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Update_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Update_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -136,8 +145,9 @@ func (c *woodpeckerClient) Update(ctx context.Context, in *UpdateRequest, opts . } func (c *woodpeckerClient) Log(ctx context.Context, in *LogRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_Log_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_Log_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -145,8 +155,9 @@ func (c *woodpeckerClient) Log(ctx context.Context, in *LogRequest, opts ...grpc } func (c *woodpeckerClient) RegisterAgent(ctx context.Context, in *RegisterAgentRequest, opts ...grpc.CallOption) (*RegisterAgentResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RegisterAgentResponse) - err := c.cc.Invoke(ctx, Woodpecker_RegisterAgent_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_RegisterAgent_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -154,8 +165,9 @@ func (c *woodpeckerClient) RegisterAgent(ctx context.Context, in *RegisterAgentR } func (c *woodpeckerClient) UnregisterAgent(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_UnregisterAgent_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_UnregisterAgent_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -163,8 +175,9 @@ func (c *woodpeckerClient) UnregisterAgent(ctx context.Context, in *Empty, opts } func (c *woodpeckerClient) ReportHealth(ctx context.Context, in *ReportHealthRequest, opts ...grpc.CallOption) (*Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Empty) - err := c.cc.Invoke(ctx, Woodpecker_ReportHealth_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Woodpecker_ReportHealth_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -174,6 +187,8 @@ func (c *woodpeckerClient) ReportHealth(ctx context.Context, in *ReportHealthReq // WoodpeckerServer is the server API for Woodpecker service. // All implementations must embed UnimplementedWoodpeckerServer // for forward compatibility +// +// Woodpecker Server Service type WoodpeckerServer interface { Version(context.Context, *Empty) (*VersionResponse, error) Next(context.Context, *NextRequest) (*NextResponse, error) @@ -513,8 +528,9 @@ func NewWoodpeckerAuthClient(cc grpc.ClientConnInterface) WoodpeckerAuthClient { } func (c *woodpeckerAuthClient) Auth(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(AuthResponse) - err := c.cc.Invoke(ctx, WoodpeckerAuth_Auth_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, WoodpeckerAuth_Auth_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } diff --git a/server/services/encryption/aes_builder.go b/server/services/encryption/aes_builder.go index 1da6df8a04..bd6800e5db 100644 --- a/server/services/encryption/aes_builder.go +++ b/server/services/encryption/aes_builder.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server/services/encryption/types" "go.woodpecker-ci.org/woodpecker/v2/server/store" @@ -30,8 +30,8 @@ type aesConfiguration struct { clients []types.EncryptionClient } -func newAES(ctx *cli.Context, s store.Store) types.EncryptionServiceBuilder { - key := ctx.String(rawKeyConfigFlag) +func newAES(c *cli.Command, s store.Store) types.EncryptionServiceBuilder { + key := c.String(rawKeyConfigFlag) return &aesConfiguration{key, s, nil} } diff --git a/server/services/encryption/encryption.go b/server/services/encryption/encryption.go index 4548aa8a3d..4312a5ae5c 100644 --- a/server/services/encryption/encryption.go +++ b/server/services/encryption/encryption.go @@ -17,7 +17,7 @@ package encryption import ( "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server/services/encryption/types" "go.woodpecker-ci.org/woodpecker/v2/server/store" @@ -25,12 +25,12 @@ import ( type builder struct { store store.Store - ctx *cli.Context + c *cli.Command clients []types.EncryptionClient } -func Encryption(ctx *cli.Context, s store.Store) types.EncryptionBuilder { - return &builder{store: s, ctx: ctx} +func Encryption(c *cli.Command, s store.Store) types.EncryptionBuilder { + return &builder{store: s, c: c} } func (b builder) WithClient(client types.EncryptionClient) types.EncryptionBuilder { @@ -44,7 +44,7 @@ func (b builder) Build() error { return err } - disableFlag := b.ctx.Bool(disableEncryptionConfigFlag) + disableFlag := b.c.Bool(disableEncryptionConfigFlag) keyType, err := b.detectKeyType() if err != nil { diff --git a/server/services/encryption/encryption_builder.go b/server/services/encryption/encryption_builder.go index 700fbdb77e..b59606360d 100644 --- a/server/services/encryption/encryption_builder.go +++ b/server/services/encryption/encryption_builder.go @@ -48,8 +48,8 @@ func (b builder) isEnabled() (bool, error) { } func (b builder) detectKeyType() (string, error) { - rawKeyPresent := b.ctx.IsSet(rawKeyConfigFlag) - tinkKeysetPresent := b.ctx.IsSet(tinkKeysetFilepathConfigFlag) + rawKeyPresent := b.c.IsSet(rawKeyConfigFlag) + tinkKeysetPresent := b.c.IsSet(tinkKeysetFilepathConfigFlag) switch { case rawKeyPresent && tinkKeysetPresent: return "", errors.New(errMessageCantUseBothServices) @@ -64,9 +64,9 @@ func (b builder) detectKeyType() (string, error) { func (b builder) serviceBuilder(keyType string) (types.EncryptionServiceBuilder, error) { switch { case keyType == keyTypeTink: - return newTink(b.ctx, b.store), nil + return newTink(b.c, b.store), nil case keyType == keyTypeRaw: - return newAES(b.ctx, b.store), nil + return newAES(b.c, b.store), nil case keyType == keyTypeNone: return &noEncryptionBuilder{}, nil } diff --git a/server/services/encryption/tink_builder.go b/server/services/encryption/tink_builder.go index 9dd1ddd799..ccb10cb53f 100644 --- a/server/services/encryption/tink_builder.go +++ b/server/services/encryption/tink_builder.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server/services/encryption/types" "go.woodpecker-ci.org/woodpecker/v2/server/store" @@ -30,8 +30,8 @@ type tinkConfiguration struct { clients []types.EncryptionClient } -func newTink(ctx *cli.Context, s store.Store) types.EncryptionServiceBuilder { - filepath := ctx.String(tinkKeysetFilepathConfigFlag) +func newTink(c *cli.Command, s store.Store) types.EncryptionServiceBuilder { + filepath := c.String(tinkKeysetFilepathConfigFlag) return &tinkConfiguration{filepath, s, nil} } diff --git a/server/services/manager.go b/server/services/manager.go index 3107f827de..e38b140e9f 100644 --- a/server/services/manager.go +++ b/server/services/manager.go @@ -19,7 +19,7 @@ import ( "time" "github.com/jellydator/ttlcache/v3" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server/forge" "go.woodpecker-ci.org/woodpecker/v2/server/model" @@ -61,7 +61,7 @@ type manager struct { setupForge SetupForge } -func NewManager(c *cli.Context, store store.Store, setupForge SetupForge) (Manager, error) { +func NewManager(c *cli.Command, store store.Store, setupForge SetupForge) (Manager, error) { signaturePrivateKey, signaturePublicKey, err := setupSignatureKeys(store) if err != nil { return nil, err diff --git a/server/services/setup.go b/server/services/setup.go index 305541c02b..8260159aed 100644 --- a/server/services/setup.go +++ b/server/services/setup.go @@ -24,7 +24,7 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v2/server/model" "go.woodpecker-ci.org/woodpecker/v2/server/services/config" @@ -57,13 +57,13 @@ func setupSecretService(store store.Store) secret.Service { return secret.NewDB(store) } -func setupConfigService(c *cli.Context, privateSignatureKey crypto.PrivateKey) (config.Service, error) { +func setupConfigService(c *cli.Command, privateSignatureKey crypto.PrivateKey) (config.Service, error) { timeout := c.Duration("forge-timeout") retries := c.Uint("forge-retry") if retries == 0 { return nil, fmt.Errorf("WOODPECKER_FORGE_RETRY can not be 0") } - configFetcher := config.NewForge(timeout, retries) + configFetcher := config.NewForge(timeout, uint(retries)) if endpoint := c.String("config-service-endpoint"); endpoint != "" { httpFetcher := config.NewHTTP(endpoint, privateSignatureKey) @@ -100,7 +100,7 @@ func setupSignatureKeys(_store store.Store) (crypto.PrivateKey, crypto.PublicKey return privateKey, privateKey.Public(), nil } -func setupForgeService(c *cli.Context, _store store.Store) error { +func setupForgeService(c *cli.Command, _store store.Store) error { _forge, err := _store.ForgeGet(1) if err != nil && !errors.Is(err, types.RecordNotExist) { return err diff --git a/shared/logger/logger.go b/shared/logger/logger.go index 916ec1b01e..2667772654 100644 --- a/shared/logger/logger.go +++ b/shared/logger/logger.go @@ -15,6 +15,7 @@ package logger import ( + "context" "fmt" "io" "os" @@ -22,37 +23,37 @@ import ( "github.com/6543/logfile-open" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var GlobalLoggerFlags = []cli.Flag{ &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LOG_LEVEL"}, + Sources: cli.EnvVars("WOODPECKER_LOG_LEVEL"), Name: "log-level", Usage: "set logging level", Value: "info", }, &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_LOG_FILE"}, + Sources: cli.EnvVars("WOODPECKER_LOG_FILE"), Name: "log-file", Usage: "Output destination for logs. 'stdout' and 'stderr' can be used as special keywords.", Value: "stderr", }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_DEBUG_PRETTY"}, + Sources: cli.EnvVars("WOODPECKER_DEBUG_PRETTY"), Name: "pretty", Usage: "enable pretty-printed debug output", Value: isInteractiveTerminal(), // make pretty on interactive terminal by default }, &cli.BoolFlag{ - EnvVars: []string{"WOODPECKER_DEBUG_NOCOLOR"}, + Sources: cli.EnvVars("WOODPECKER_DEBUG_NOCOLOR"), Name: "nocolor", Usage: "disable colored debug output, only has effect if pretty output is set too", Value: !isInteractiveTerminal(), // do color on interactive terminal by default }, } -func SetupGlobalLogger(c *cli.Context, outputLvl bool) error { +func SetupGlobalLogger(ctx context.Context, c *cli.Command, outputLvl bool) error { logLevel := c.String("log-level") pretty := c.Bool("pretty") noColor := c.Bool("nocolor") @@ -65,7 +66,7 @@ func SetupGlobalLogger(c *cli.Context, outputLvl bool) error { case "stdout": file = os.Stdout default: // a file was set - openFile, err := logfile.OpenFileWithContext(c.Context, logFile, 0o660) + openFile, err := logfile.OpenFileWithContext(ctx, logFile, 0o660) if err != nil { return fmt.Errorf("could not open log file '%s': %w", logFile, err) }