You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-06-03 16:35:37 +02:00
Add config to change default pipeline config paths and extensions (#6580)
Signed-off-by: jolheiser <git@jolheiser.com>
This commit is contained in:
@@ -291,6 +291,24 @@ var flags = append([]cli.Flag{
|
||||
Name: "config-extension-netrc",
|
||||
Usage: "whether global configuration extension should receive netrc data",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_PIPELINE_CONFIGS"),
|
||||
Name: "default-pipeline-configs",
|
||||
Usage: "default pipeline config paths to check",
|
||||
Value: constant.DefaultConfigOrder,
|
||||
Config: cli.StringConfig{
|
||||
TrimSpace: true,
|
||||
},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_PIPELINE_CONFIG_EXTENSIONS"),
|
||||
Name: "default-pipeline-config-extensions",
|
||||
Usage: "default pipeline config extensions when scanning a pipeline config directory",
|
||||
Value: []string{".yaml", ".yml"},
|
||||
Config: cli.StringConfig{
|
||||
TrimSpace: true,
|
||||
},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_REGISTRY_EXTENSION_ENDPOINT"),
|
||||
Name: "registry-extension-endpoint",
|
||||
|
||||
@@ -980,6 +980,24 @@ Specify a configuration extension endpoint, see [Configuration Extension](../../
|
||||
|
||||
---
|
||||
|
||||
### DEFAULT_PIPELINE_CONFIGS
|
||||
|
||||
- Name: `WOODPECKER_DEFAULT_PIPELINE_CONFIGS`
|
||||
- Default: `.woodpecker/`, `.woodpecker.yaml`, `.woodpecker.yml`
|
||||
|
||||
Specify the default pipeline config paths.
|
||||
|
||||
---
|
||||
|
||||
### DEFAULT_PIPELINE_CONFIG_EXTENSIONS
|
||||
|
||||
- Name: `WOODPECKER_DEFAULT_PIPELINE_CONFIG_EXTENSIONS`
|
||||
- Default: `.yaml`, `.yml`
|
||||
|
||||
Specify the default pipeline config extensions when scanning a pipeline config directory.
|
||||
|
||||
---
|
||||
|
||||
### CONFIG_EXTENSION_EXCLUSIVE
|
||||
|
||||
- Name: `CONFIG_EXTENSION_EXCLUSIVE`
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/services"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/services/permissions"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/store"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/constant"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -151,6 +152,8 @@ func newTestManager(s store.Store, mockForge *forge_mocks.MockForge) (services.M
|
||||
// Forge flags — gitea=true satisfies setupForgeService's type switch.
|
||||
&cli.BoolFlag{Name: string(TestForgeType), Value: true},
|
||||
&cli.StringFlag{Name: "forge-url", Value: "https://forge.example.test"},
|
||||
&cli.StringSliceFlag{Name: "default-pipeline-configs", Value: constant.DefaultConfigOrder},
|
||||
&cli.StringSliceFlag{Name: "default-pipeline-config-extensions", Value: []string{".yaml", ".yml"}},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/services/config"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/services/utils"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/constant"
|
||||
)
|
||||
|
||||
func TestFetchFromConfigService(t *testing.T) {
|
||||
@@ -220,7 +221,7 @@ func TestFetchFromConfigService(t *testing.T) {
|
||||
|
||||
f.On("Netrc", mock.Anything, mock.Anything).Return(&model.Netrc{Machine: "mock", Login: "mock", Password: "mock"}, nil)
|
||||
|
||||
forgeFetcher := config.NewForge(time.Second*3, 3)
|
||||
forgeFetcher := config.NewForge(time.Second*3, 3, constant.DefaultConfigOrder, []string{".yaml", ".yml"})
|
||||
configFetcher := config.NewCombined(forgeFetcher, httpFetcher)
|
||||
files, err := configFetcher.Fetch(
|
||||
t.Context(),
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -26,18 +28,21 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/constant"
|
||||
)
|
||||
|
||||
type forgeFetcher struct {
|
||||
timeout time.Duration
|
||||
retryCount uint
|
||||
timeout time.Duration
|
||||
retryCount uint
|
||||
configPaths []string
|
||||
configExtensions []string
|
||||
}
|
||||
|
||||
func NewForge(timeout time.Duration, retries uint) Service {
|
||||
func NewForge(timeout time.Duration, retries uint, configPaths, configExtensions []string) Service {
|
||||
return &forgeFetcher{
|
||||
timeout: timeout,
|
||||
retryCount: retries,
|
||||
timeout: timeout,
|
||||
retryCount: retries,
|
||||
configPaths: configPaths,
|
||||
configExtensions: configExtensions,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +53,13 @@ func (f *forgeFetcher) Fetch(ctx context.Context, forge forge.Forge, user *model
|
||||
}
|
||||
|
||||
ffc := &forgeFetcherContext{
|
||||
forge: forge,
|
||||
user: user,
|
||||
repo: repo,
|
||||
pipeline: pipeline,
|
||||
timeout: f.timeout,
|
||||
forge: forge,
|
||||
user: user,
|
||||
repo: repo,
|
||||
pipeline: pipeline,
|
||||
timeout: f.timeout,
|
||||
configPaths: f.configPaths,
|
||||
configExtensions: f.configExtensions,
|
||||
}
|
||||
|
||||
// try to fetch multiple times
|
||||
@@ -69,11 +76,13 @@ func (f *forgeFetcher) Fetch(ctx context.Context, forge forge.Forge, user *model
|
||||
}
|
||||
|
||||
type forgeFetcherContext struct {
|
||||
forge forge.Forge
|
||||
user *model.User
|
||||
repo *model.Repo
|
||||
pipeline *model.Pipeline
|
||||
timeout time.Duration
|
||||
forge forge.Forge
|
||||
user *model.User
|
||||
repo *model.Repo
|
||||
pipeline *model.Pipeline
|
||||
timeout time.Duration
|
||||
configPaths []string
|
||||
configExtensions []string
|
||||
}
|
||||
|
||||
// fetch attempts to fetch the configuration file(s) for the given config string.
|
||||
@@ -97,7 +106,7 @@ func (f *forgeFetcherContext) fetch(c context.Context, config string) ([]*types.
|
||||
|
||||
log.Trace().Msgf("configFetcher[%s]: user did not define own config, following default procedure", f.repo.FullName)
|
||||
// for the order see shared/constants/constants.go
|
||||
fileMetas, err := f.getFirstAvailableConfig(ctx, constant.DefaultConfigOrder[:])
|
||||
fileMetas, err := f.getFirstAvailableConfig(ctx, f.configPaths)
|
||||
if err == nil {
|
||||
return fileMetas, nil
|
||||
}
|
||||
@@ -110,11 +119,11 @@ func (f *forgeFetcherContext) fetch(c context.Context, config string) ([]*types.
|
||||
}
|
||||
}
|
||||
|
||||
func filterPipelineFiles(files []*types.FileMeta) []*types.FileMeta {
|
||||
func (f *forgeFetcherContext) filterPipelineFiles(files []*types.FileMeta) []*types.FileMeta {
|
||||
var res []*types.FileMeta
|
||||
|
||||
for _, file := range files {
|
||||
if strings.HasSuffix(file.Name, ".yml") || strings.HasSuffix(file.Name, ".yaml") {
|
||||
if slices.Contains(f.configExtensions, filepath.Ext(file.Name)) {
|
||||
res = append(res, file)
|
||||
}
|
||||
}
|
||||
@@ -154,7 +163,7 @@ func (f *forgeFetcherContext) getFirstAvailableConfig(c context.Context, configs
|
||||
}
|
||||
continue
|
||||
}
|
||||
files = filterPipelineFiles(files)
|
||||
files = f.filterPipelineFiles(files)
|
||||
if len(files) != 0 {
|
||||
log.Trace().Msgf("configFetcher[%s]: found %d files in '%s'", f.repo.FullName, len(files), fileOrFolder)
|
||||
return files, nil
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
forge_types "go.woodpecker-ci.org/woodpecker/v3/server/forge/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/services/config"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/constant"
|
||||
)
|
||||
|
||||
func TestFetch(t *testing.T) {
|
||||
@@ -307,6 +308,8 @@ func TestFetch(t *testing.T) {
|
||||
configFetcher := config.NewForge(
|
||||
time.Second*3,
|
||||
3,
|
||||
constant.DefaultConfigOrder,
|
||||
[]string{".yaml", ".yml"},
|
||||
)
|
||||
files, err := configFetcher.Fetch(
|
||||
t.Context(),
|
||||
|
||||
@@ -76,7 +76,7 @@ func setupConfigService(c *cli.Command, client *utils.Client) (config.Service, e
|
||||
if retries == 0 {
|
||||
return nil, fmt.Errorf("WOODPECKER_FORGE_RETRY can not be 0")
|
||||
}
|
||||
configFetcher := config.NewForge(timeout, retries)
|
||||
configFetcher := config.NewForge(timeout, retries, c.StringSlice("default-pipeline-configs"), c.StringSlice("default-pipeline-config-extensions"))
|
||||
|
||||
if endpoint := c.String("config-extension-endpoint"); endpoint != "" {
|
||||
httpFetcher := config.NewHTTP(endpoint, client, c.Bool("config-extension-netrc"))
|
||||
|
||||
@@ -16,9 +16,9 @@ package constant
|
||||
|
||||
import "time"
|
||||
|
||||
// DefaultConfigOrder represent the priority in witch woodpecker search for a pipeline config by default
|
||||
// DefaultConfigOrder represent the priority in which woodpecker searches for a pipeline config by default
|
||||
// folders are indicated by supplying a trailing slash.
|
||||
var DefaultConfigOrder = [...]string{
|
||||
var DefaultConfigOrder = []string{
|
||||
".woodpecker/",
|
||||
".woodpecker.yaml",
|
||||
".woodpecker.yml",
|
||||
|
||||
Reference in New Issue
Block a user