diff --git a/DEV.md b/DEV.md new file mode 100644 index 00000000000..e8c8d3366b3 --- /dev/null +++ b/DEV.md @@ -0,0 +1,2 @@ +go mod vendor +make release-agent CI_COMMIT_TAG=v2.7.0-single-workflow-0 diff --git a/cmd/agent/core/agent.go b/cmd/agent/core/agent.go index dea39a8a5ce..d413b6639ce 100644 --- a/cmd/agent/core/agent.go +++ b/cmd/agent/core/agent.go @@ -86,7 +86,14 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error { hostname, _ = os.Hostname() } - counter.Polling = int(c.Int("max-workflows")) + maxWorkflows := int(c.Int("max-workflows")) + singleWorkflow := c.Bool("single-workflow") + if singleWorkflow && maxWorkflows > 1 { + log.Warn().Msgf("max-workflows forced from %d to 1 due to agent running single workflow mode.", maxWorkflows) + maxWorkflows = 1 + } + + counter.Polling = maxWorkflows counter.Running = 0 if c.Bool("healthcheck") { @@ -197,7 +204,6 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error { } log.Debug().Msgf("loaded %s backend engine", backendEngine.Name()) - 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 @@ -275,15 +281,30 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error { log.Debug().Msg("polling new steps") if err := runner.Run(agentCtx, shutdownCtx); err != nil { log.Error().Err(err).Msg("runner done with error") + if singleWorkflow { + ctxCancel(nil) + } return err } + + if singleWorkflow { + log.Info().Msg("shutdown single workflow runner") + ctxCancel(nil) + return nil + } } }) } - log.Info().Msgf( - "starting Woodpecker agent with version '%s' and backend '%s' using platform '%s' running up to %d pipelines in parallel", - version.String(), backendEngine.Name(), engInfo.Platform, maxWorkflows) + if singleWorkflow { + log.Info().Msgf( + "starting Woodpecker agent with version '%s' and backend '%s' using platform '%s' running up in single workflow mode", + version.String(), backendEngine.Name(), engInfo.Platform) + } else { + log.Info().Msgf( + "starting Woodpecker agent with version '%s' and backend '%s' using platform '%s' running up to %d pipelines in parallel", + version.String(), backendEngine.Name(), engInfo.Platform, maxWorkflows) + } return serviceWaitingGroup.Wait() } diff --git a/cmd/agent/core/flags.go b/cmd/agent/core/flags.go index 6770e36bd54..721a8abb2bb 100644 --- a/cmd/agent/core/flags.go +++ b/cmd/agent/core/flags.go @@ -70,6 +70,12 @@ var flags = []cli.Flag{ Usage: "agent parallel workflows", Value: 1, }, + &cli.BoolFlag{ + Sources: cli.EnvVars("WOODPECKER_AGENT_SINGLE_WORKFLOW"), + Name: "single-workflow", + Usage: "exit the agent after first workflow", + Value: false, + }, &cli.BoolFlag{ Sources: cli.EnvVars("WOODPECKER_HEALTHCHECK"), Name: "healthcheck", diff --git a/docs/docs/30-administration/15-agent-config.md b/docs/docs/30-administration/15-agent-config.md index 15792b38bdc..908d3cc49f5 100644 --- a/docs/docs/30-administration/15-agent-config.md +++ b/docs/docs/30-administration/15-agent-config.md @@ -120,6 +120,11 @@ Configures the path of the agent config file. Configures the number of parallel workflows. +### `WOODPECKER_AGENT_SINGLE_WORKFLOW` +> Default: `false` + +Configures the agent to exit(shutdown) after first workflow. When configured, `WOODPECKER_MAX_WORKFLOWS` is forced to 1. + ### `WOODPECKER_FILTER_LABELS` > Default: empty