From f7f0a9b5617886298561d9e5973879731b2a6ef9 Mon Sep 17 00:00:00 2001
From: qwerty287 <80460567+qwerty287@users.noreply.github.com>
Date: Thu, 28 May 2026 14:08:36 +0200
Subject: [PATCH] Show correct default paths in UI (#6665)
---
cmd/server/setup.go | 4 ++++
server/config.go | 2 ++
server/web/config.go | 21 +++++++++++++++++++++
web/src/assets/locales/en.json | 2 +-
web/src/compositions/useConfig.ts | 2 ++
web/src/views/repo/settings/General.vue | 6 +++++-
6 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/cmd/server/setup.go b/cmd/server/setup.go
index 6e8bb194c1..0726e2b703 100644
--- a/cmd/server/setup.go
+++ b/cmd/server/setup.go
@@ -227,6 +227,10 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) (err e
server.Config.Pipeline.Proxy.HTTP = c.String("backend-http-proxy")
server.Config.Pipeline.Proxy.HTTPS = c.String("backend-https-proxy")
+ // pipeline config paths
+ server.Config.Pipeline.ConfigPaths = c.StringSlice("default-pipeline-configs")
+ server.Config.Pipeline.ConfigExtensions = c.StringSlice("default-pipeline-config-extensions")
+
// server configuration
server.Config.Server.JWTSecret, err = setupJWTSecret(s)
if err != nil {
diff --git a/server/config.go b/server/config.go
index e6e05099a4..72e44ee22f 100644
--- a/server/config.go
+++ b/server/config.go
@@ -81,6 +81,8 @@ var Config = struct {
HTTP string
HTTPS string
}
+ ConfigPaths []string
+ ConfigExtensions []string
// TODO: remove with version 4.x
ForceIgnoreServiceFailure bool
}
diff --git a/server/web/config.go b/server/web/config.go
index 2265491bed..3831309e16 100644
--- a/server/web/config.go
+++ b/server/web/config.go
@@ -16,8 +16,10 @@ package web
import (
"encoding/json"
+ "fmt"
"net/http"
"strconv"
+ "strings"
"text/template"
"github.com/gin-gonic/gin"
@@ -39,6 +41,23 @@ func Config(c *gin.Context) {
csrf, _ = t.Sign(user.Hash)
}
+ var configPaths []string
+
+ extensionsClean := make([]string, len(server.Config.Pipeline.ConfigExtensions))
+ for i, e := range server.Config.Pipeline.ConfigExtensions {
+ extensionsClean[i] = strings.TrimPrefix(e, ".")
+ }
+
+ extensions := strings.Join(extensionsClean, ",")
+ for _, p := range server.Config.Pipeline.ConfigPaths {
+ if strings.HasSuffix(p, "/") {
+ // it's a directory -> add extensions
+ configPaths = append(configPaths, fmt.Sprintf("%s*.{%s}", p, extensions))
+ } else {
+ configPaths = append(configPaths, p)
+ }
+ }
+
configData := map[string]any{
"user": user,
"csrf": csrf,
@@ -48,6 +67,7 @@ func Config(c *gin.Context) {
"enable_swagger": server.Config.WebUI.EnableSwagger,
"user_registered_agents": !server.Config.Agent.DisableUserRegisteredAgentRegistration,
"max_pipeline_log_line_count": server.Config.WebUI.MaxPipelineLogLineCount,
+ "default_config_paths": configPaths,
}
// default func map with json parser.
@@ -83,4 +103,5 @@ window.WOODPECKER_ENABLE_SWAGGER = {{ .enable_swagger }};
window.WOODPECKER_SKIP_VERSION_CHECK = {{ .skip_version_check }}
window.WOODPECKER_USER_REGISTERED_AGENTS = {{ .user_registered_agents }}
window.WOODPECKER_MAX_PIPELINE_LOG_LINE_COUNT = {{ .max_pipeline_log_line_count }}
+window.WOODPECKER_DEFAULT_CONFIG_PATHS = {{ json .default_config_paths }}
`
diff --git a/web/src/assets/locales/en.json b/web/src/assets/locales/en.json
index fd9384d2ce..e2d880c77b 100644
--- a/web/src/assets/locales/en.json
+++ b/web/src/assets/locales/en.json
@@ -106,7 +106,7 @@
"success": "Project settings updated",
"pipeline_path": {
"path": "Pipeline path",
- "default": "By default: .woodpecker/*.{'{yaml,yml}'} -> .woodpecker.yaml -> .woodpecker.yml",
+ "by_default": "By default: {paths}",
"desc": "Path to your pipeline config (for example {0}). Folders should end with a {1}.",
"desc_path_example": "my/path/"
},
diff --git a/web/src/compositions/useConfig.ts b/web/src/compositions/useConfig.ts
index 5c340f5408..060cf2f2e1 100644
--- a/web/src/compositions/useConfig.ts
+++ b/web/src/compositions/useConfig.ts
@@ -10,6 +10,7 @@ declare global {
WOODPECKER_ENABLE_SWAGGER: boolean | undefined;
WOODPECKER_USER_REGISTERED_AGENTS: boolean | undefined;
WOODPECKER_MAX_PIPELINE_LOG_LINE_COUNT: number | undefined;
+ WOODPECKER_DEFAULT_CONFIG_PATHS: string[] | undefined;
}
}
@@ -22,4 +23,5 @@ export default () => ({
enableSwagger: window.WOODPECKER_ENABLE_SWAGGER === true || false,
userRegisteredAgents: window.WOODPECKER_USER_REGISTERED_AGENTS || false,
maxPipelineLogLineCount: window.WOODPECKER_MAX_PIPELINE_LOG_LINE_COUNT ?? 5000,
+ defaultConfigPaths: window.WOODPECKER_DEFAULT_CONFIG_PATHS || [],
});
diff --git a/web/src/views/repo/settings/General.vue b/web/src/views/repo/settings/General.vue
index e80a121767..17c6ca527d 100644
--- a/web/src/views/repo/settings/General.vue
+++ b/web/src/views/repo/settings/General.vue
@@ -142,7 +142,9 @@
@@ -196,6 +198,7 @@ import Settings from '~/components/layout/Settings.vue';
import useApiClient from '~/compositions/useApiClient';
import { useAsyncAction } from '~/compositions/useAsyncAction';
import useAuthentication from '~/compositions/useAuthentication';
+import useConfig from '~/compositions/useConfig';
import { requiredInject } from '~/compositions/useInjectProvide';
import useNotifications from '~/compositions/useNotifications';
import { useWPTitle } from '~/compositions/useWPTitle';
@@ -208,6 +211,7 @@ const notifications = useNotifications();
const { user } = useAuthentication();
const repoStore = useRepoStore();
const i18n = useI18n();
+const { defaultConfigPaths } = useConfig();
const repo = requiredInject('repo');
const repoSettings = ref();