From 16b86a64a99926aabef5fbae7e47d87322968da5 Mon Sep 17 00:00:00 2001 From: Bengt Brodersen Date: Fri, 23 May 2025 10:05:42 +0200 Subject: [PATCH] feat: add cli option to set concurrent jobs count (#2762) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- cmd/input.go | 1 + cmd/root.go | 2 ++ pkg/runner/runner.go | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/cmd/input.go b/cmd/input.go index a7ccae8..36c7f7a 100644 --- a/cmd/input.go +++ b/cmd/input.go @@ -62,6 +62,7 @@ type Input struct { useNewActionCache bool localRepository []string listOptions bool + concurrentJobs int } func (i *Input) resolve(path string) string { diff --git a/cmd/root.go b/cmd/root.go index 50a2155..87f59ea 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -127,6 +127,7 @@ func createRootCommand(ctx context.Context, input *Input, version string) *cobra rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally") rootCmd.PersistentFlags().StringArrayVarP(&input.localRepository, "local-repository", "", []string{}, "Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)") rootCmd.PersistentFlags().BoolVar(&input.listOptions, "list-options", false, "Print a json structure of compatible options") + rootCmd.PersistentFlags().IntVar(&input.concurrentJobs, "concurrent-jobs", 0, "Maximum number of concurrent jobs to run. Default is the number of CPUs available.") rootCmd.SetArgs(args()) return rootCmd } @@ -635,6 +636,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str ReplaceGheActionTokenWithGithubCom: input.replaceGheActionTokenWithGithubCom, Matrix: matrixes, ContainerNetworkMode: docker_container.NetworkMode(input.networkName), + ConcurrentJobs: input.concurrentJobs, } if input.useNewActionCache || len(input.localRepository) > 0 { if input.actionOfflineMode { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 59b92a5..078657e 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -61,6 +61,20 @@ type Config struct { Matrix map[string]map[string]bool // Matrix config to run ContainerNetworkMode docker_container.NetworkMode // the network mode of job containers (the value of --network) ActionCache ActionCache // Use a custom ActionCache Implementation + ConcurrentJobs int // Number of max concurrent jobs +} + +func (config *Config) GetConcurrentJobs() int { + if config.ConcurrentJobs >= 1 { + return config.ConcurrentJobs + } + + ncpu := runtime.NumCPU() + log.Debugf("Detected CPUs: %d", ncpu) + if ncpu > 1 { + return ncpu + } + return 1 } type caller struct { @@ -195,12 +209,9 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor { } pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...)) } - ncpu := runtime.NumCPU() - if 1 > ncpu { - ncpu = 1 - } - log.Debugf("Detected CPUs: %d", ncpu) - return common.NewParallelExecutor(ncpu, pipeline...)(ctx) + + log.Debugf("PlanExecutor concurrency: %d", runner.config.GetConcurrentJobs()) + return common.NewParallelExecutor(runner.config.GetConcurrentJobs(), pipeline...)(ctx) }) }