mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-24 10:07:21 +02:00
Merge branch 'main' into service-use
This commit is contained in:
commit
6086932671
@ -59,7 +59,7 @@ steps:
|
|||||||
- event: manual
|
- event: manual
|
||||||
|
|
||||||
deploy-preview:
|
deploy-preview:
|
||||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.2
|
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.3
|
||||||
settings:
|
settings:
|
||||||
path: 'docs/build/'
|
path: 'docs/build/'
|
||||||
surge_token:
|
surge_token:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
steps:
|
steps:
|
||||||
- name: release-helper
|
- name: release-helper
|
||||||
image: docker.io/woodpeckerci/plugin-ready-release-go:2.1.1
|
image: docker.io/woodpeckerci/plugin-ready-release-go:3.0.0
|
||||||
settings:
|
settings:
|
||||||
release_branch: ${CI_COMMIT_BRANCH}
|
release_branch: ${CI_COMMIT_BRANCH}
|
||||||
forge_type: github
|
forge_type: github
|
||||||
|
@ -28,9 +28,9 @@ var Command = &cli.Command{
|
|||||||
Name: "admin",
|
Name: "admin",
|
||||||
Usage: "manage server settings",
|
Usage: "manage server settings",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
secret.Command,
|
|
||||||
registry.Command,
|
|
||||||
user.Command,
|
|
||||||
loglevel.Command,
|
loglevel.Command,
|
||||||
|
registry.Command,
|
||||||
|
secret.Command,
|
||||||
|
user.Command,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
var Command = &cli.Command{
|
var Command = &cli.Command{
|
||||||
Name: "log-level",
|
Name: "log-level",
|
||||||
ArgsUsage: "[level]",
|
ArgsUsage: "[level]",
|
||||||
Usage: "get the logging level of the server, or set it with [level]",
|
Usage: "retrieve log level from server, or set it with [level]",
|
||||||
Action: logLevel,
|
Action: logLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +59,6 @@ func logLevel(ctx context.Context, c *cli.Command) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msgf("logging level: %s", ll.Level)
|
log.Info().Msgf("log level: %s", ll.Level)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
registryCreateCmd,
|
registryCreateCmd,
|
||||||
registryDeleteCmd,
|
registryDeleteCmd,
|
||||||
registryUpdateCmd,
|
|
||||||
registryInfoCmd,
|
|
||||||
registryListCmd,
|
registryListCmd,
|
||||||
|
registryShowCmd,
|
||||||
|
registryUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
|
|
||||||
var registryCreateCmd = &cli.Command{
|
var registryCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a registry",
|
Usage: "add a registry",
|
||||||
Action: registryCreate,
|
Action: registryCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
|
@ -25,10 +25,10 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var registryInfoCmd = &cli.Command{
|
var registryShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display registry info",
|
Usage: "show registry information",
|
||||||
Action: registryInfo,
|
Action: registryShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "hostname",
|
Name: "hostname",
|
||||||
@ -39,7 +39,7 @@ var registryInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
hostname = c.String("hostname")
|
hostname = c.String("hostname")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -25,8 +25,8 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
secretCreateCmd,
|
secretCreateCmd,
|
||||||
secretDeleteCmd,
|
secretDeleteCmd,
|
||||||
secretUpdateCmd,
|
|
||||||
secretInfoCmd,
|
|
||||||
secretListCmd,
|
secretListCmd,
|
||||||
|
secretShowCmd,
|
||||||
|
secretUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
|
|
||||||
var secretCreateCmd = &cli.Command{
|
var secretCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a secret",
|
Usage: "add a secret",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretCreate,
|
Action: secretCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
@ -26,11 +26,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var secretInfoCmd = &cli.Command{
|
var secretShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display secret info",
|
Usage: "show secret information",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretInfo,
|
Action: secretShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
@ -40,7 +40,7 @@ var secretInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
secretName = c.String("name")
|
secretName = c.String("name")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -23,9 +23,9 @@ var Command = &cli.Command{
|
|||||||
Name: "user",
|
Name: "user",
|
||||||
Usage: "manage users",
|
Usage: "manage users",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
userListCmd,
|
|
||||||
userInfoCmd,
|
|
||||||
userAddCmd,
|
userAddCmd,
|
||||||
|
userListCmd,
|
||||||
userRemoveCmd,
|
userRemoveCmd,
|
||||||
|
userShowCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
|
|
||||||
var userAddCmd = &cli.Command{
|
var userAddCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a user",
|
Usage: "add a user",
|
||||||
ArgsUsage: "<username>",
|
ArgsUsage: "<username>",
|
||||||
Action: userAdd,
|
Action: userAdd,
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,15 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var userInfoCmd = &cli.Command{
|
var userShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "show user details",
|
Usage: "show user information",
|
||||||
ArgsUsage: "<username>",
|
ArgsUsage: "<username>",
|
||||||
Action: userInfo,
|
Action: userShow,
|
||||||
Flags: []cli.Flag{common.FormatFlag(tmplUserInfo)},
|
Flags: []cli.Flag{common.FormatFlag(tmplUserInfo)},
|
||||||
}
|
}
|
||||||
|
|
||||||
func userInfo(ctx context.Context, c *cli.Command) error {
|
func userShow(ctx context.Context, c *cli.Command) error {
|
||||||
client, err := internal.NewClient(ctx, c)
|
client, err := internal.NewClient(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
@ -35,18 +35,18 @@ func Before(ctx context.Context, c *cli.Command) (context.Context, error) {
|
|||||||
waitForUpdateCheck, cancelWaitForUpdate = context.WithCancelCause(context.Background())
|
waitForUpdateCheck, cancelWaitForUpdate = context.WithCancelCause(context.Background())
|
||||||
defer cancelWaitForUpdate(errors.New("update check finished"))
|
defer cancelWaitForUpdate(errors.New("update check finished"))
|
||||||
|
|
||||||
log.Debug().Msg("Checking for updates ...")
|
log.Debug().Msg("checking for updates ...")
|
||||||
|
|
||||||
newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) //nolint:contextcheck
|
newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) //nolint:contextcheck
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("Failed to check for updates")
|
log.Error().Err(err).Msgf("failed to check for updates")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if newVersion != nil {
|
if newVersion != nil {
|
||||||
log.Warn().Msgf("A new version of woodpecker-cli is available: %s. Update by running: %s update", newVersion.Version, c.Root().Name)
|
log.Warn().Msgf("new version of woodpecker-cli is available: %s, update with: %s update", newVersion.Version, c.Root().Name)
|
||||||
} else {
|
} else {
|
||||||
log.Debug().Msgf("No update required")
|
log.Debug().Msgf("no update required")
|
||||||
}
|
}
|
||||||
}(ctx)
|
}(ctx)
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ func After(_ context.Context, _ *cli.Command) error {
|
|||||||
case <-waitForUpdateCheck.Done():
|
case <-waitForUpdateCheck.Done():
|
||||||
// When the actual command already finished, we still wait 500ms for the update check to finish
|
// When the actual command already finished, we still wait 500ms for the update check to finish
|
||||||
case <-time.After(time.Millisecond * 500):
|
case <-time.After(time.Millisecond * 500):
|
||||||
log.Debug().Msg("Update check stopped due to timeout")
|
log.Debug().Msg("update check stopped due to timeout")
|
||||||
cancelWaitForUpdate(errors.New("update check timeout"))
|
cancelWaitForUpdate(errors.New("update check timeout"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func Load(ctx context.Context, c *cli.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.ServerURL == "" || config.Token == "" {
|
if config.ServerURL == "" || config.Token == "" {
|
||||||
log.Info().Msg("The woodpecker-cli is not yet set up. Please run `woodpecker-cli setup` or provide the required environment variables / flags.")
|
log.Info().Msg("woodpecker-cli is not set up, run `woodpecker-cli setup` or provide required environment variables/flags")
|
||||||
return errors.New("woodpecker-cli is not configured")
|
return errors.New("woodpecker-cli is not configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ func Load(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Any("config", config).Msg("Loaded config")
|
log.Debug().Any("config", config).Msg("loaded config")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -93,16 +93,16 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Str("configPath", configPath).Msg("Checking for config file")
|
log.Debug().Str("configPath", configPath).Msg("checking for config file")
|
||||||
|
|
||||||
content, err := os.ReadFile(configPath)
|
content, err := os.ReadFile(configPath)
|
||||||
switch {
|
switch {
|
||||||
case err != nil && !os.IsNotExist(err):
|
case err != nil && !os.IsNotExist(err):
|
||||||
log.Debug().Err(err).Msg("Failed to read the config file")
|
log.Debug().Err(err).Msg("failed to read the config file")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
||||||
case err != nil && os.IsNotExist(err):
|
case err != nil && os.IsNotExist(err):
|
||||||
log.Debug().Msg("The config file does not exist")
|
log.Debug().Msg("config file does not exist")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
configFromFile := &Config{}
|
configFromFile := &Config{}
|
||||||
@ -111,7 +111,7 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conf.MergeIfNotSet(configFromFile)
|
conf.MergeIfNotSet(configFromFile)
|
||||||
log.Debug().Msg("Loaded config from file")
|
log.Debug().Msg("loaded config from file")
|
||||||
}
|
}
|
||||||
|
|
||||||
// if server or token are explicitly set, use them
|
// if server or token are explicitly set, use them
|
||||||
@ -123,11 +123,11 @@ func Get(_ context.Context, c *cli.Command, _configPath string) (*Config, error)
|
|||||||
service := c.Root().Name
|
service := c.Root().Name
|
||||||
secret, err := keyring.Get(service, conf.ServerURL)
|
secret, err := keyring.Get(service, conf.ServerURL)
|
||||||
if errors.Is(err, keyring.ErrUnsupportedPlatform) {
|
if errors.Is(err, keyring.ErrUnsupportedPlatform) {
|
||||||
log.Warn().Msg("Keyring is not supported on this platform")
|
log.Warn().Msg("keyring is not supported on this platform")
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
if errors.Is(err, keyring.ErrNotFound) {
|
if errors.Is(err, keyring.ErrNotFound) {
|
||||||
log.Warn().Msg("Token not found in keyring")
|
log.Warn().Msg("token not found in keyring")
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
conf.Token = secret
|
conf.Token = secret
|
||||||
|
@ -40,12 +40,12 @@ var Command = &cli.Command{
|
|||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
||||||
Name: "plugins-privileged",
|
Name: "plugins-privileged",
|
||||||
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
Usage: "allow plugins to run in privileged mode, if set empty, there is no",
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_TRUSTED_CLONE"),
|
Sources: cli.EnvVars("WOODPECKER_PLUGINS_TRUSTED_CLONE"),
|
||||||
Name: "plugins-trusted-clone",
|
Name: "plugins-trusted-clone",
|
||||||
Usage: "Plugins which are trusted to handle Git credentials in clone steps",
|
Usage: "plugins that are trusted to handle Git credentials in cloning steps",
|
||||||
Value: constant.TrustedClonePlugins,
|
Value: constant.TrustedClonePlugins,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
|
@ -29,9 +29,9 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
registryCreateCmd,
|
registryCreateCmd,
|
||||||
registryDeleteCmd,
|
registryDeleteCmd,
|
||||||
registryUpdateCmd,
|
|
||||||
registryInfoCmd,
|
|
||||||
registryListCmd,
|
registryListCmd,
|
||||||
|
registryShowCmd,
|
||||||
|
registryUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
var registryCreateCmd = &cli.Command{
|
var registryCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a registry",
|
Usage: "add a registry",
|
||||||
ArgsUsage: "[org-id|org-full-name]",
|
ArgsUsage: "[org-id|org-full-name]",
|
||||||
Action: registryCreate,
|
Action: registryCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
@ -25,11 +25,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var registryInfoCmd = &cli.Command{
|
var registryShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display registry info",
|
Usage: "show registry information",
|
||||||
ArgsUsage: "[org-id|org-full-name]",
|
ArgsUsage: "[org-id|org-full-name]",
|
||||||
Action: registryInfo,
|
Action: registryShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
common.OrgFlag,
|
common.OrgFlag,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -41,7 +41,7 @@ var registryInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
hostname = c.String("hostname")
|
hostname = c.String("hostname")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -29,9 +29,9 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
secretCreateCmd,
|
secretCreateCmd,
|
||||||
secretDeleteCmd,
|
secretDeleteCmd,
|
||||||
secretUpdateCmd,
|
|
||||||
secretInfoCmd,
|
|
||||||
secretListCmd,
|
secretListCmd,
|
||||||
|
secretShowCmd,
|
||||||
|
secretUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
var secretCreateCmd = &cli.Command{
|
var secretCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a secret",
|
Usage: "add a secret",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretCreate,
|
Action: secretCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
@ -43,11 +43,11 @@ var secretUpdateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "event",
|
Name: "event",
|
||||||
Usage: "secret limited to these events",
|
Usage: "limit secret to these event",
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "image",
|
Name: "image",
|
||||||
Usage: "secret limited to these images",
|
Usage: "limit secret to these image",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var secretInfoCmd = &cli.Command{
|
var secretShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display secret info",
|
Usage: "show secret information",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretInfo,
|
Action: secretShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
common.OrgFlag,
|
common.OrgFlag,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -41,7 +41,7 @@ var secretInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
secretName = c.String("name")
|
secretName = c.String("name")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -74,5 +74,5 @@ func pipelineCreate(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ var Command = &cli.Command{
|
|||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "param",
|
Name: "param",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Usage: "custom parameters to be injected into the step environment. Format: KEY=value",
|
Usage: "custom parameters to inject into the step environment. Format: KEY=value",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func pipelineKill(ctx context.Context, c *cli.Command) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.PipelineKill(repoID, number)
|
err = client.PipelineDelete(repoID, number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
|
|
||||||
var pipelineLastCmd = &cli.Command{
|
var pipelineLastCmd = &cli.Command{
|
||||||
Name: "last",
|
Name: "last",
|
||||||
Usage: "show latest pipeline details",
|
Usage: "show latest pipeline information",
|
||||||
ArgsUsage: "<repo-id|repo-full-name>",
|
ArgsUsage: "<repo-id|repo-full-name>",
|
||||||
Action: pipelineLast,
|
Action: pipelineLast,
|
||||||
Flags: append(common.OutputFlags("table"), []cli.Flag{
|
Flags: append(common.OutputFlags("table"), []cli.Flag{
|
||||||
@ -58,5 +58,5 @@ func pipelineLast(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/common"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/common"
|
||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
|
shared_utils "go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ func buildPipelineListCmd() *cli.Command {
|
|||||||
},
|
},
|
||||||
&cli.TimestampFlag{
|
&cli.TimestampFlag{
|
||||||
Name: "before",
|
Name: "before",
|
||||||
Usage: "only return pipelines before this RFC3339 date",
|
Usage: "only return pipelines before this date (RFC3339)",
|
||||||
Config: cli.TimestampConfig{
|
Config: cli.TimestampConfig{
|
||||||
Layouts: []string{
|
Layouts: []string{
|
||||||
time.RFC3339,
|
time.RFC3339,
|
||||||
@ -61,7 +62,7 @@ func buildPipelineListCmd() *cli.Command {
|
|||||||
},
|
},
|
||||||
&cli.TimestampFlag{
|
&cli.TimestampFlag{
|
||||||
Name: "after",
|
Name: "after",
|
||||||
Usage: "only return pipelines after this RFC3339 date",
|
Usage: "only return pipelines after this date (RFC3339)",
|
||||||
Config: cli.TimestampConfig{
|
Config: cli.TimestampConfig{
|
||||||
Layouts: []string{
|
Layouts: []string{
|
||||||
time.RFC3339,
|
time.RFC3339,
|
||||||
@ -77,60 +78,51 @@ func List(ctx context.Context, c *cli.Command) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resources, err := pipelineList(ctx, c, client)
|
pipelines, err := pipelineList(c, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return pipelineOutput(c, resources)
|
return pipelineOutput(c, pipelines)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipelineList(_ context.Context, c *cli.Command, client woodpecker.Client) ([]woodpecker.Pipeline, error) {
|
func pipelineList(c *cli.Command, client woodpecker.Client) ([]*woodpecker.Pipeline, error) {
|
||||||
resources := make([]woodpecker.Pipeline, 0)
|
|
||||||
|
|
||||||
repoIDOrFullName := c.Args().First()
|
repoIDOrFullName := c.Args().First()
|
||||||
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resources, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := woodpecker.PipelineListOptions{}
|
opt := woodpecker.PipelineListOptions{}
|
||||||
before := c.Timestamp("before")
|
|
||||||
after := c.Timestamp("after")
|
|
||||||
|
|
||||||
if !before.IsZero() {
|
if before := c.Timestamp("before"); !before.IsZero() {
|
||||||
opt.Before = before
|
opt.Before = before
|
||||||
}
|
}
|
||||||
if !after.IsZero() {
|
if after := c.Timestamp("after"); !after.IsZero() {
|
||||||
opt.After = after
|
opt.After = after
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelines, err := client.PipelineList(repoID, opt)
|
|
||||||
if err != nil {
|
|
||||||
return resources, err
|
|
||||||
}
|
|
||||||
|
|
||||||
branch := c.String("branch")
|
branch := c.String("branch")
|
||||||
event := c.String("event")
|
event := c.String("event")
|
||||||
status := c.String("status")
|
status := c.String("status")
|
||||||
limit := int(c.Int("limit"))
|
limit := int(c.Int("limit"))
|
||||||
|
|
||||||
var count int
|
pipelines, err := shared_utils.Paginate(func(page int) ([]*woodpecker.Pipeline, error) {
|
||||||
for _, pipeline := range pipelines {
|
return client.PipelineList(repoID,
|
||||||
if count >= limit {
|
woodpecker.PipelineListOptions{
|
||||||
break
|
ListOptions: woodpecker.ListOptions{
|
||||||
}
|
Page: page,
|
||||||
if branch != "" && pipeline.Branch != branch {
|
},
|
||||||
continue
|
Before: opt.Before,
|
||||||
}
|
After: opt.After,
|
||||||
if event != "" && pipeline.Event != event {
|
Branch: branch,
|
||||||
continue
|
Events: []string{event},
|
||||||
}
|
Status: status,
|
||||||
if status != "" && pipeline.Status != status {
|
},
|
||||||
continue
|
)
|
||||||
}
|
}, limit)
|
||||||
resources = append(resources, *pipeline)
|
if err != nil {
|
||||||
count++
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resources, nil
|
return pipelines, nil
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func TestPipelineList(t *testing.T) {
|
|||||||
pipelines []*woodpecker.Pipeline
|
pipelines []*woodpecker.Pipeline
|
||||||
pipelineErr error
|
pipelineErr error
|
||||||
args []string
|
args []string
|
||||||
expected []woodpecker.Pipeline
|
expected []*woodpecker.Pipeline
|
||||||
wantErr error
|
wantErr error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -34,53 +34,12 @@ func TestPipelineList(t *testing.T) {
|
|||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||||
},
|
},
|
||||||
args: []string{"ls", "repo/name"},
|
args: []string{"ls", "repo/name"},
|
||||||
expected: []woodpecker.Pipeline{
|
expected: []*woodpecker.Pipeline{
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "filter by branch",
|
|
||||||
repoID: 1,
|
|
||||||
pipelines: []*woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
|
||||||
},
|
|
||||||
args: []string{"ls", "--branch", "main", "repo/name"},
|
|
||||||
expected: []woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "filter by event",
|
|
||||||
repoID: 1,
|
|
||||||
pipelines: []*woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
|
||||||
},
|
|
||||||
args: []string{"ls", "--event", "push", "repo/name"},
|
|
||||||
expected: []woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "filter by status",
|
|
||||||
repoID: 1,
|
|
||||||
pipelines: []*woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
|
||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
|
||||||
},
|
|
||||||
args: []string{"ls", "--status", "success", "repo/name"},
|
|
||||||
expected: []woodpecker.Pipeline{
|
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "limit results",
|
name: "limit results",
|
||||||
repoID: 1,
|
repoID: 1,
|
||||||
@ -90,7 +49,7 @@ func TestPipelineList(t *testing.T) {
|
|||||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||||
},
|
},
|
||||||
args: []string{"ls", "--limit", "2", "repo/name"},
|
args: []string{"ls", "--limit", "2", "repo/name"},
|
||||||
expected: []woodpecker.Pipeline{
|
expected: []*woodpecker.Pipeline{
|
||||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||||
},
|
},
|
||||||
@ -107,13 +66,21 @@ func TestPipelineList(t *testing.T) {
|
|||||||
for _, tt := range testtases {
|
for _, tt := range testtases {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
mockClient := mocks.NewClient(t)
|
mockClient := mocks.NewClient(t)
|
||||||
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(tt.pipelines, tt.pipelineErr)
|
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(func(_ int64, opt woodpecker.PipelineListOptions) ([]*woodpecker.Pipeline, error) {
|
||||||
|
if tt.pipelineErr != nil {
|
||||||
|
return nil, tt.pipelineErr
|
||||||
|
}
|
||||||
|
if opt.Page == 1 {
|
||||||
|
return tt.pipelines, nil
|
||||||
|
}
|
||||||
|
return []*woodpecker.Pipeline{}, nil
|
||||||
|
}).Maybe()
|
||||||
mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil)
|
mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil)
|
||||||
|
|
||||||
command := buildPipelineListCmd()
|
command := buildPipelineListCmd()
|
||||||
command.Writer = io.Discard
|
command.Writer = io.Discard
|
||||||
command.Action = func(ctx context.Context, c *cli.Command) error {
|
command.Action = func(_ context.Context, c *cli.Command) error {
|
||||||
pipelines, err := pipelineList(ctx, c, mockClient)
|
pipelines, err := pipelineList(c, mockClient)
|
||||||
if tt.wantErr != nil {
|
if tt.wantErr != nil {
|
||||||
assert.EqualError(t, err, tt.wantErr.Error())
|
assert.EqualError(t, err, tt.wantErr.Error())
|
||||||
return nil
|
return nil
|
||||||
|
@ -24,5 +24,6 @@ var Command = &cli.Command{
|
|||||||
Usage: "manage logs",
|
Usage: "manage logs",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
logPurgeCmd,
|
logPurgeCmd,
|
||||||
|
logShowCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package pipeline
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -27,14 +27,14 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pipelineLogsCmd = &cli.Command{
|
var logShowCmd = &cli.Command{
|
||||||
Name: "logs",
|
Name: "show",
|
||||||
Usage: "show pipeline logs",
|
Usage: "show pipeline logs",
|
||||||
ArgsUsage: "<repo-id|repo-full-name> <pipeline> [step-number|step-name]",
|
ArgsUsage: "<repo-id|repo-full-name> <pipeline> [step-number|step-name]",
|
||||||
Action: pipelineLogs,
|
Action: logShow,
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipelineLogs(ctx context.Context, c *cli.Command) error {
|
func logShow(ctx context.Context, c *cli.Command) error {
|
||||||
repoIDOrFullName := c.Args().First()
|
repoIDOrFullName := c.Args().First()
|
||||||
client, err := internal.NewClient(ctx, c)
|
client, err := internal.NewClient(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,17 +59,17 @@ func pipelineLogs(ctx context.Context, c *cli.Command) error {
|
|||||||
|
|
||||||
stepArg := c.Args().Get(2) //nolint:mnd
|
stepArg := c.Args().Get(2) //nolint:mnd
|
||||||
if len(stepArg) == 0 {
|
if len(stepArg) == 0 {
|
||||||
return showPipelineLog(client, repoID, number)
|
return pipelineLog(client, repoID, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
step, err := internal.ParseStep(client, repoID, number, stepArg)
|
step, err := internal.ParseStep(client, repoID, number, stepArg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid step '%s': %w", stepArg, err)
|
return fmt.Errorf("invalid step '%s': %w", stepArg, err)
|
||||||
}
|
}
|
||||||
return showStepLog(client, repoID, number, step)
|
return stepLog(client, repoID, number, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func showPipelineLog(client woodpecker.Client, repoID, number int64) error {
|
func pipelineLog(client woodpecker.Client, repoID, number int64) error {
|
||||||
pipeline, err := client.Pipeline(repoID, number)
|
pipeline, err := client.Pipeline(repoID, number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -85,7 +85,7 @@ func showPipelineLog(client woodpecker.Client, repoID, number int64) error {
|
|||||||
if err := tmpl.Execute(os.Stdout, map[string]any{"workflow": workflow, "step": step}); err != nil {
|
if err := tmpl.Execute(os.Stdout, map[string]any{"workflow": workflow, "step": step}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err := showStepLog(client, repoID, number, step.ID)
|
err := stepLog(client, repoID, number, step.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ func showPipelineLog(client woodpecker.Client, repoID, number int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func showStepLog(client woodpecker.Client, repoID, number, step int64) error {
|
func stepLog(client woodpecker.Client, repoID, number, step int64) error {
|
||||||
logs, err := client.StepLogEntries(repoID, number, step)
|
logs, err := client.StepLogEntries(repoID, number, step)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
@ -33,24 +33,24 @@ var Command = &cli.Command{
|
|||||||
Name: "pipeline",
|
Name: "pipeline",
|
||||||
Usage: "manage pipelines",
|
Usage: "manage pipelines",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
buildPipelineListCmd(),
|
|
||||||
pipelineLastCmd,
|
|
||||||
pipelineLogsCmd,
|
|
||||||
pipelineInfoCmd,
|
|
||||||
pipelineStopCmd,
|
|
||||||
pipelineStartCmd,
|
|
||||||
pipelineApproveCmd,
|
pipelineApproveCmd,
|
||||||
pipelineDeclineCmd,
|
|
||||||
pipelineQueueCmd,
|
|
||||||
pipelineKillCmd,
|
|
||||||
pipelinePsCmd,
|
|
||||||
pipelineCreateCmd,
|
pipelineCreateCmd,
|
||||||
log.Command,
|
pipelineDeclineCmd,
|
||||||
deploy.Command,
|
deploy.Command,
|
||||||
|
pipelineKillCmd,
|
||||||
|
pipelineLastCmd,
|
||||||
|
buildPipelineListCmd(),
|
||||||
|
log.Command,
|
||||||
|
pipelinePsCmd,
|
||||||
|
pipelinePurgeCmd,
|
||||||
|
pipelineQueueCmd,
|
||||||
|
pipelineShowCmd,
|
||||||
|
pipelineStartCmd,
|
||||||
|
pipelineStopCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Writer) error {
|
func pipelineOutput(c *cli.Command, pipelines []*woodpecker.Pipeline, fd ...io.Writer) error {
|
||||||
outFmt, outOpt := output.ParseOutputOptions(c.String("output"))
|
outFmt, outOpt := output.ParseOutputOptions(c.String("output"))
|
||||||
noHeader := c.Bool("output-no-headers")
|
noHeader := c.Bool("output-no-headers")
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tmpl.Execute(out, resources); err != nil {
|
if err := tmpl.Execute(out, pipelines); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "table":
|
case "table":
|
||||||
@ -89,7 +89,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
|
|||||||
if !noHeader {
|
if !noHeader {
|
||||||
table.WriteHeader(cols)
|
table.WriteHeader(cols)
|
||||||
}
|
}
|
||||||
for _, resource := range resources {
|
for _, resource := range pipelines {
|
||||||
if err := table.Write(cols, resource); err != nil {
|
if err := table.Write(cols, resource); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func TestPipelineOutput(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelines := []woodpecker.Pipeline{
|
pipelines := []*woodpecker.Pipeline{
|
||||||
{
|
{
|
||||||
Number: 1,
|
Number: 1,
|
||||||
Status: "success",
|
Status: "success",
|
||||||
|
157
cli/pipeline/purge.go
Normal file
157
cli/pipeline/purge.go
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
// Copyright 2022 Woodpecker Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package pipeline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
|
shared_utils "go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:mnd
|
||||||
|
var pipelinePurgeCmd = &cli.Command{
|
||||||
|
Name: "purge",
|
||||||
|
Usage: "purge pipelines",
|
||||||
|
ArgsUsage: "<repo-id|repo-full-name>",
|
||||||
|
Action: Purge,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "older-than",
|
||||||
|
Usage: "remove pipelines older than the specified time limit",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "keep-min",
|
||||||
|
Usage: "minimum number of pipelines to keep",
|
||||||
|
Value: 10,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "dry-run",
|
||||||
|
Usage: "disable non-read api calls",
|
||||||
|
Value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Purge(ctx context.Context, c *cli.Command) error {
|
||||||
|
client, err := internal.NewClient(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return pipelinePurge(c, client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pipelinePurge(c *cli.Command, client woodpecker.Client) (err error) {
|
||||||
|
repoIDOrFullName := c.Args().First()
|
||||||
|
if len(repoIDOrFullName) == 0 {
|
||||||
|
return fmt.Errorf("missing required argument repo-id / repo-full-name")
|
||||||
|
}
|
||||||
|
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid repo '%s': %w", repoIDOrFullName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
olderThan := c.String("older-than")
|
||||||
|
keepMin := c.Int("keep-min")
|
||||||
|
dryRun := c.Bool("dry-run")
|
||||||
|
|
||||||
|
duration, err := time.ParseDuration(olderThan)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pipelinesKeep []*woodpecker.Pipeline
|
||||||
|
|
||||||
|
if keepMin > 0 {
|
||||||
|
pipelinesKeep, err = fetchPipelinesToKeep(client, repoID, int(keepMin))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pipelines, err := fetchPipelines(client, repoID, duration)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a map of pipeline IDs to keep
|
||||||
|
keepMap := make(map[int64]struct{})
|
||||||
|
for _, p := range pipelinesKeep {
|
||||||
|
keepMap[p.ID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter pipelines to only include those not in keepMap
|
||||||
|
var pipelinesToPurge []*woodpecker.Pipeline
|
||||||
|
for _, p := range pipelines {
|
||||||
|
if _, exists := keepMap[p.ID]; !exists {
|
||||||
|
pipelinesToPurge = append(pipelinesToPurge, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msgPrefix := ""
|
||||||
|
if dryRun {
|
||||||
|
msgPrefix = "DRY-RUN: "
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, p := range pipelinesToPurge {
|
||||||
|
// cspell:words spurge
|
||||||
|
log.Debug().Msgf("%spurge %v/%v pipelines from repo '%v'", msgPrefix, i+1, len(pipelinesToPurge), repoIDOrFullName)
|
||||||
|
if dryRun {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.PipelineDelete(repoID, p.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchPipelinesToKeep(client woodpecker.Client, repoID int64, keepMin int) ([]*woodpecker.Pipeline, error) {
|
||||||
|
if keepMin <= 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return shared_utils.Paginate(func(page int) ([]*woodpecker.Pipeline, error) {
|
||||||
|
return client.PipelineList(repoID,
|
||||||
|
woodpecker.PipelineListOptions{
|
||||||
|
ListOptions: woodpecker.ListOptions{
|
||||||
|
Page: page,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, keepMin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchPipelines(client woodpecker.Client, repoID int64, duration time.Duration) ([]*woodpecker.Pipeline, error) {
|
||||||
|
return shared_utils.Paginate(func(page int) ([]*woodpecker.Pipeline, error) {
|
||||||
|
return client.PipelineList(repoID,
|
||||||
|
woodpecker.PipelineListOptions{
|
||||||
|
ListOptions: woodpecker.ListOptions{
|
||||||
|
Page: page,
|
||||||
|
},
|
||||||
|
After: time.Now().Add(-duration),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, -1)
|
||||||
|
}
|
105
cli/pipeline/purge_test.go
Normal file
105
cli/pipeline/purge_test.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package pipeline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||||
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker/mocks"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPipelinePurge(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
repoID int64
|
||||||
|
args []string
|
||||||
|
pipelinesKeep []*woodpecker.Pipeline
|
||||||
|
pipelines []*woodpecker.Pipeline
|
||||||
|
wantDelete int
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "success with no pipelines to purge",
|
||||||
|
repoID: 1,
|
||||||
|
args: []string{"purge", "--older-than", "1h", "repo/name"},
|
||||||
|
pipelinesKeep: []*woodpecker.Pipeline{
|
||||||
|
{ID: 1},
|
||||||
|
},
|
||||||
|
pipelines: []*woodpecker.Pipeline{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "success with pipelines to purge",
|
||||||
|
repoID: 1,
|
||||||
|
args: []string{"purge", "--older-than", "1h", "repo/name"},
|
||||||
|
pipelinesKeep: []*woodpecker.Pipeline{
|
||||||
|
{ID: 1},
|
||||||
|
},
|
||||||
|
pipelines: []*woodpecker.Pipeline{
|
||||||
|
{ID: 1},
|
||||||
|
{ID: 2},
|
||||||
|
{ID: 3},
|
||||||
|
},
|
||||||
|
wantDelete: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error on invalid duration",
|
||||||
|
repoID: 1,
|
||||||
|
args: []string{"purge", "--older-than", "invalid", "repo/name"},
|
||||||
|
wantErr: errors.New("time: invalid duration \"invalid\""),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
mockClient := mocks.NewClient(t)
|
||||||
|
mockClient.On("RepoLookup", mock.Anything).Maybe().Return(&woodpecker.Repo{ID: tt.repoID}, nil)
|
||||||
|
|
||||||
|
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(func(_ int64, opt woodpecker.PipelineListOptions) ([]*woodpecker.Pipeline, error) {
|
||||||
|
// Return keep pipelines for first call
|
||||||
|
if opt.After.IsZero() {
|
||||||
|
if opt.Page == 1 {
|
||||||
|
return tt.pipelinesKeep, nil
|
||||||
|
}
|
||||||
|
return []*woodpecker.Pipeline{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return pipelines to purge for calls with After filter
|
||||||
|
if !opt.After.IsZero() {
|
||||||
|
if opt.Page == 1 {
|
||||||
|
return tt.pipelines, nil
|
||||||
|
}
|
||||||
|
return []*woodpecker.Pipeline{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return []*woodpecker.Pipeline{}, nil
|
||||||
|
}).Maybe()
|
||||||
|
|
||||||
|
if tt.wantDelete > 0 {
|
||||||
|
mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(nil).Times(tt.wantDelete)
|
||||||
|
}
|
||||||
|
|
||||||
|
command := pipelinePurgeCmd
|
||||||
|
command.Writer = io.Discard
|
||||||
|
command.Action = func(_ context.Context, c *cli.Command) error {
|
||||||
|
err := pipelinePurge(c, mockClient)
|
||||||
|
|
||||||
|
if tt.wantErr != nil {
|
||||||
|
assert.EqualError(t, err, tt.wantErr.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = command.Run(context.Background(), tt.args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -25,15 +25,15 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pipelineInfoCmd = &cli.Command{
|
var pipelineShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "show pipeline details",
|
Usage: "show pipeline information",
|
||||||
ArgsUsage: "<repo-id|repo-full-name> [pipeline]",
|
ArgsUsage: "<repo-id|repo-full-name> [pipeline]",
|
||||||
Action: pipelineInfo,
|
Action: pipelineShow,
|
||||||
Flags: common.OutputFlags("table"),
|
Flags: common.OutputFlags("table"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipelineInfo(ctx context.Context, c *cli.Command) error {
|
func pipelineShow(ctx context.Context, c *cli.Command) error {
|
||||||
repoIDOrFullName := c.Args().First()
|
repoIDOrFullName := c.Args().First()
|
||||||
client, err := internal.NewClient(ctx, c)
|
client, err := internal.NewClient(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -65,5 +65,5 @@ func pipelineInfo(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ var pipelineStartCmd = &cli.Command{
|
|||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "param",
|
Name: "param",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Usage: "custom parameters to be injected into the step environment. Format: KEY=value",
|
Usage: "custom parameters to inject into the step environment. Format: KEY=value",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
cronCreateCmd,
|
cronCreateCmd,
|
||||||
cronDeleteCmd,
|
cronDeleteCmd,
|
||||||
cronUpdateCmd,
|
|
||||||
cronInfoCmd,
|
|
||||||
cronListCmd,
|
cronListCmd,
|
||||||
|
cronShowCmd,
|
||||||
|
cronUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cronInfoCmd = &cli.Command{
|
var cronShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display info about a cron job",
|
Usage: "show cron job information",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: cronInfo,
|
Action: cronShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
common.RepoFlag,
|
common.RepoFlag,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -41,7 +41,7 @@ var cronInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cronInfo(ctx context.Context, c *cli.Command) error {
|
func cronShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
cronID = c.Int("id")
|
cronID = c.Int("id")
|
||||||
repoIDOrFullName = c.String("repository")
|
repoIDOrFullName = c.String("repository")
|
@ -28,9 +28,9 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
registryCreateCmd,
|
registryCreateCmd,
|
||||||
registryDeleteCmd,
|
registryDeleteCmd,
|
||||||
registryUpdateCmd,
|
|
||||||
registryInfoCmd,
|
|
||||||
registryListCmd,
|
registryListCmd,
|
||||||
|
registryShowCmd,
|
||||||
|
registryUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
var registryCreateCmd = &cli.Command{
|
var registryCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a registry",
|
Usage: "add a registry",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: registryCreate,
|
Action: registryCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
@ -25,11 +25,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var registryInfoCmd = &cli.Command{
|
var registryShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display registry info",
|
Usage: "show registry information",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: registryInfo,
|
Action: registryShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
common.RepoFlag,
|
common.RepoFlag,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -41,7 +41,7 @@ var registryInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func registryInfo(ctx context.Context, c *cli.Command) error {
|
func registryShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
hostname = c.String("hostname")
|
hostname = c.String("hostname")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -27,16 +27,16 @@ var Command = &cli.Command{
|
|||||||
Name: "repo",
|
Name: "repo",
|
||||||
Usage: "manage repositories",
|
Usage: "manage repositories",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
repoListCmd,
|
|
||||||
repoInfoCmd,
|
|
||||||
repoAddCmd,
|
repoAddCmd,
|
||||||
repoUpdateCmd,
|
repoChownCmd,
|
||||||
|
cron.Command,
|
||||||
|
repoListCmd,
|
||||||
|
registry.Command,
|
||||||
repoRemoveCmd,
|
repoRemoveCmd,
|
||||||
repoRepairCmd,
|
repoRepairCmd,
|
||||||
repoChownCmd,
|
|
||||||
repoSyncCmd,
|
|
||||||
registry.Command,
|
|
||||||
secret.Command,
|
secret.Command,
|
||||||
cron.Command,
|
repoShowCmd,
|
||||||
|
repoSyncCmd,
|
||||||
|
repoUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -25,15 +25,15 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var repoInfoCmd = &cli.Command{
|
var repoShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "show repository details",
|
Usage: "show repository information",
|
||||||
ArgsUsage: "<repo-id|repo-full-name>",
|
ArgsUsage: "<repo-id|repo-full-name>",
|
||||||
Action: repoInfo,
|
Action: repoShow,
|
||||||
Flags: []cli.Flag{common.FormatFlag(tmplRepoInfo)},
|
Flags: []cli.Flag{common.FormatFlag(tmplRepoInfo)},
|
||||||
}
|
}
|
||||||
|
|
||||||
func repoInfo(ctx context.Context, c *cli.Command) error {
|
func repoShow(ctx context.Context, c *cli.Command) error {
|
||||||
repoIDOrFullName := c.Args().First()
|
repoIDOrFullName := c.Args().First()
|
||||||
client, err := internal.NewClient(ctx, c)
|
client, err := internal.NewClient(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
@ -53,7 +53,7 @@ var repoUpdateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "config",
|
Name: "config",
|
||||||
Usage: "repository configuration path (e.g. .woodpecker.yml)",
|
Usage: "repository configuration path. Example: .woodpecker.yml",
|
||||||
},
|
},
|
||||||
&cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "pipeline-counter",
|
Name: "pipeline-counter",
|
||||||
@ -61,7 +61,7 @@ var repoUpdateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "unsafe",
|
Name: "unsafe",
|
||||||
Usage: "validate updating the pipeline-counter is unsafe",
|
Usage: "allow unsafe operations",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ var Command = &cli.Command{
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
secretCreateCmd,
|
secretCreateCmd,
|
||||||
secretDeleteCmd,
|
secretDeleteCmd,
|
||||||
secretUpdateCmd,
|
|
||||||
secretInfoCmd,
|
|
||||||
secretListCmd,
|
secretListCmd,
|
||||||
|
secretShowCmd,
|
||||||
|
secretUpdateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
|
|
||||||
var secretCreateCmd = &cli.Command{
|
var secretCreateCmd = &cli.Command{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Usage: "adds a secret",
|
Usage: "add a secret",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretCreate,
|
Action: secretCreate,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
@ -43,11 +43,11 @@ var secretCreateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "event",
|
Name: "event",
|
||||||
Usage: "secret limited to these events",
|
Usage: "limit secret to these events",
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "image",
|
Name: "image",
|
||||||
Usage: "secret limited to these images",
|
Usage: "limit secret to these images",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,11 @@ var secretUpdateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "event",
|
Name: "event",
|
||||||
Usage: "secret limited to these events",
|
Usage: "limit secret to these events",
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "image",
|
Name: "image",
|
||||||
Usage: "secret limited to these images",
|
Usage: "limit secret to these images",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@ import (
|
|||||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var secretInfoCmd = &cli.Command{
|
var secretShowCmd = &cli.Command{
|
||||||
Name: "info",
|
Name: "show",
|
||||||
Usage: "display secret info",
|
Usage: "show secret information",
|
||||||
ArgsUsage: "[repo-id|repo-full-name]",
|
ArgsUsage: "[repo-id|repo-full-name]",
|
||||||
Action: secretInfo,
|
Action: secretShow,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
common.RepoFlag,
|
common.RepoFlag,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -41,7 +41,7 @@ var secretInfoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func secretInfo(ctx context.Context, c *cli.Command) error {
|
func secretShow(ctx context.Context, c *cli.Command) error {
|
||||||
var (
|
var (
|
||||||
secretName = c.String("name")
|
secretName = c.String("name")
|
||||||
format = c.String("format") + "\n"
|
format = c.String("format") + "\n"
|
@ -20,11 +20,11 @@ var Command = &cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "server",
|
Name: "server",
|
||||||
Usage: "The URL of the woodpecker server",
|
Usage: "URL of the woodpecker server",
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "token",
|
Name: "token",
|
||||||
Usage: "The token to authenticate with the woodpecker server",
|
Usage: "token to authenticate with the woodpecker server",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: setup,
|
Action: setup,
|
||||||
@ -41,7 +41,7 @@ func setup(ctx context.Context, c *cli.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !setupAgain {
|
if !setupAgain {
|
||||||
log.Info().Msg("Configuration skipped")
|
log.Info().Msg("configuration skipped")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ func setup(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msg("The woodpecker-cli has been successfully setup")
|
log.Info().Msg("woodpecker-cli has been successfully setup")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ func receiveTokenFromUI(c context.Context, serverURL string) (string, error) {
|
|||||||
srv.Handler = setupRouter(tokenReceived)
|
srv.Handler = setupRouter(tokenReceived)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Debug().Msgf("Listening for token response on :%d", port)
|
log.Debug().Msgf("listening for token response on :%d", port)
|
||||||
_ = srv.ListenAndServe()
|
_ = srv.ListenAndServe()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
log.Debug().Msg("Shutting down server")
|
log.Debug().Msg("shutting down server")
|
||||||
_ = srv.Shutdown(c)
|
_ = srv.Shutdown(c)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ func setupRouter(tokenReceived chan string) *gin.Engine {
|
|||||||
|
|
||||||
err := c.BindJSON(&data)
|
err := c.BindJSON(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug().Err(err).Msg("Failed to bind JSON")
|
log.Debug().Err(err).Msg("failed to bind JSON")
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid request",
|
"error": "invalid request",
|
||||||
})
|
})
|
||||||
@ -110,7 +110,7 @@ func setupRouter(tokenReceived chan string) *gin.Engine {
|
|||||||
func openBrowser(url string) error {
|
func openBrowser(url string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
log.Debug().Msgf("Opening browser with URL: %s", url)
|
log.Debug().Msgf("opening browser with URL: %s", url)
|
||||||
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux":
|
case "linux":
|
||||||
|
@ -24,7 +24,7 @@ var Command = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(ctx context.Context, c *cli.Command) error {
|
func update(ctx context.Context, c *cli.Command) error {
|
||||||
log.Info().Msg("Checking for updates ...")
|
log.Info().Msg("checking for updates ...")
|
||||||
|
|
||||||
newVersion, err := CheckForUpdate(ctx, c.Bool("force"))
|
newVersion, err := CheckForUpdate(ctx, c.Bool("force"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -32,11 +32,11 @@ func update(ctx context.Context, c *cli.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if newVersion == nil {
|
if newVersion == nil {
|
||||||
fmt.Println("You are using the latest version of woodpecker-cli")
|
fmt.Println("you are using the latest version of woodpecker-cli")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msgf("New version %s is available! Updating ...", newVersion.Version)
|
log.Info().Msgf("new version %s is available! Updating ...", newVersion.Version)
|
||||||
|
|
||||||
var tarFilePath string
|
var tarFilePath string
|
||||||
tarFilePath, err = downloadNewVersion(ctx, newVersion.AssetURL)
|
tarFilePath, err = downloadNewVersion(ctx, newVersion.AssetURL)
|
||||||
@ -44,14 +44,14 @@ func update(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("New version %s has been downloaded successfully! Installing ...", newVersion.Version)
|
log.Debug().Msgf("new version %s has been downloaded successfully! Installing ...", newVersion.Version)
|
||||||
|
|
||||||
binFile, err := extractNewVersion(tarFilePath)
|
binFile, err := extractNewVersion(tarFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("New version %s has been extracted to %s", newVersion.Version, binFile)
|
log.Debug().Msgf("new version %s has been extracted to %s", newVersion.Version, binFile)
|
||||||
|
|
||||||
executablePathOrSymlink, err := os.Executable()
|
executablePathOrSymlink, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,10 +22,10 @@ func CheckForUpdate(ctx context.Context, force bool) (*NewVersion, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVersion, error) {
|
func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVersion, error) {
|
||||||
log.Debug().Msgf("Current version: %s", version.String())
|
log.Debug().Msgf("current version: %s", version.String())
|
||||||
|
|
||||||
if (version.String() == "dev" || strings.HasPrefix(version.String(), "next-")) && !force {
|
if (version.String() == "dev" || strings.HasPrefix(version.String(), "next-")) && !force {
|
||||||
log.Debug().Msgf("Skipping update check for development & next versions")
|
log.Debug().Msgf("skipping update check for development/next versions")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +61,11 @@ func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVer
|
|||||||
|
|
||||||
// using the latest release
|
// using the latest release
|
||||||
if installedVersion == upstreamVersion && !force {
|
if installedVersion == upstreamVersion && !force {
|
||||||
log.Debug().Msgf("No new version available")
|
log.Debug().Msgf("no new version available")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("New version available: %s", upstreamVersion)
|
log.Debug().Msgf("new version available: %s", upstreamVersion)
|
||||||
|
|
||||||
assetURL := fmt.Sprintf(githubBinaryURL, upstreamVersion, runtime.GOOS, runtime.GOARCH)
|
assetURL := fmt.Sprintf(githubBinaryURL, upstreamVersion, runtime.GOOS, runtime.GOARCH)
|
||||||
return &NewVersion{
|
return &NewVersion{
|
||||||
@ -75,7 +75,7 @@ func checkForUpdate(ctx context.Context, versionURL string, force bool) (*NewVer
|
|||||||
}
|
}
|
||||||
|
|
||||||
func downloadNewVersion(ctx context.Context, downloadURL string) (string, error) {
|
func downloadNewVersion(ctx context.Context, downloadURL string) (string, error) {
|
||||||
log.Debug().Msgf("Downloading new version from %s ...", downloadURL)
|
log.Debug().Msgf("downloading new version from %s ...", downloadURL)
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -102,13 +102,13 @@ func downloadNewVersion(ctx context.Context, downloadURL string) (string, error)
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("New version downloaded to %s", file.Name())
|
log.Debug().Msgf("new version downloaded to %s", file.Name())
|
||||||
|
|
||||||
return file.Name(), nil
|
return file.Name(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractNewVersion(tarFilePath string) (string, error) {
|
func extractNewVersion(tarFilePath string) (string, error) {
|
||||||
log.Debug().Msgf("Extracting new version from %s ...", tarFilePath)
|
log.Debug().Msgf("extracting new version from %s ...", tarFilePath)
|
||||||
|
|
||||||
tarFile, err := os.Open(tarFilePath)
|
tarFile, err := os.Open(tarFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -132,7 +132,7 @@ func extractNewVersion(tarFilePath string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("New version extracted to %s", tmpDir)
|
log.Debug().Msgf("new version extracted to %s", tmpDir)
|
||||||
|
|
||||||
return path.Join(tmpDir, "woodpecker-cli"), nil
|
return path.Join(tmpDir, "woodpecker-cli"), nil
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,12 @@ func newApp() *cli.Command {
|
|||||||
app.Suggest = true
|
app.Suggest = true
|
||||||
app.Commands = []*cli.Command{
|
app.Commands = []*cli.Command{
|
||||||
admin.Command,
|
admin.Command,
|
||||||
org.Command,
|
|
||||||
repo.Command,
|
|
||||||
pipeline.Command,
|
|
||||||
exec.Command,
|
exec.Command,
|
||||||
info.Command,
|
info.Command,
|
||||||
lint.Command,
|
lint.Command,
|
||||||
|
org.Command,
|
||||||
|
pipeline.Command,
|
||||||
|
repo.Command,
|
||||||
setup.Command,
|
setup.Command,
|
||||||
update.Command,
|
update.Command,
|
||||||
}
|
}
|
||||||
|
@ -2984,6 +2984,12 @@ const docTemplate = `{
|
|||||||
"description": "filter pipelines by strings contained in ref",
|
"description": "filter pipelines by strings contained in ref",
|
||||||
"name": "ref",
|
"name": "ref",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "filter pipelines by status",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
@ -70,11 +70,11 @@ This is the reference list of all environment variables available to your pipeli
|
|||||||
| `CI_COMMIT_REF` | commit ref | `refs/heads/main` |
|
| `CI_COMMIT_REF` | commit ref | `refs/heads/main` |
|
||||||
| `CI_COMMIT_REFSPEC` | commit ref spec | `issue-branch:main` |
|
| `CI_COMMIT_REFSPEC` | commit ref spec | `issue-branch:main` |
|
||||||
| `CI_COMMIT_BRANCH` | commit branch (equals target branch for pull requests) | `main` |
|
| `CI_COMMIT_BRANCH` | commit branch (equals target branch for pull requests) | `main` |
|
||||||
| `CI_COMMIT_SOURCE_BRANCH` | commit source branch (empty if event is not `pull_request` or `pull_request_closed`) | `issue-branch` |
|
| `CI_COMMIT_SOURCE_BRANCH` | commit source branch (set only for `pull_request` and `pull_request_closed` events) | `issue-branch` |
|
||||||
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (empty if event is not `pull_request` or `pull_request_closed`) | `main` |
|
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (set only for `pull_request` and `pull_request_closed` events) | `main` |
|
||||||
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) | `v1.10.3` |
|
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) | `v1.10.3` |
|
||||||
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (empty if event is not `pull_request` or `pull_request_closed`) | `1` |
|
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (set only for `pull_request` and `pull_request_closed` events) | `1` |
|
||||||
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (empty if event is not `pull_request` or `pull_request_closed`) | `server` |
|
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (set only for `pull_request` and `pull_request_closed` events) | `server` |
|
||||||
| `CI_COMMIT_MESSAGE` | commit message | `Initial commit` |
|
| `CI_COMMIT_MESSAGE` | commit message | `Initial commit` |
|
||||||
| `CI_COMMIT_AUTHOR` | commit author username | `john-doe` |
|
| `CI_COMMIT_AUTHOR` | commit author username | `john-doe` |
|
||||||
| `CI_COMMIT_AUTHOR_EMAIL` | commit author email address | `john-doe@example.com` |
|
| `CI_COMMIT_AUTHOR_EMAIL` | commit author email address | `john-doe@example.com` |
|
||||||
@ -103,8 +103,8 @@ This is the reference list of all environment variables available to your pipeli
|
|||||||
| `CI_PREV_COMMIT_REF` | previous commit ref | `refs/heads/main` |
|
| `CI_PREV_COMMIT_REF` | previous commit ref | `refs/heads/main` |
|
||||||
| `CI_PREV_COMMIT_REFSPEC` | previous commit ref spec | `issue-branch:main` |
|
| `CI_PREV_COMMIT_REFSPEC` | previous commit ref spec | `issue-branch:main` |
|
||||||
| `CI_PREV_COMMIT_BRANCH` | previous commit branch | `main` |
|
| `CI_PREV_COMMIT_BRANCH` | previous commit branch | `main` |
|
||||||
| `CI_PREV_COMMIT_SOURCE_BRANCH` | previous commit source branch | `issue-branch` |
|
| `CI_PREV_COMMIT_SOURCE_BRANCH` | previous commit source branch (set only for `pull_request` and `pull_request_closed` events) | `issue-branch` |
|
||||||
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch | `main` |
|
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch (set only for `pull_request` and `pull_request_closed` events) | `main` |
|
||||||
| `CI_PREV_COMMIT_URL` | previous commit link in forge | `https://git.example.com/john-doe/my-repo/commit/15784117e4e103f36cba75a9e29da48046eb82c4` |
|
| `CI_PREV_COMMIT_URL` | previous commit link in forge | `https://git.example.com/john-doe/my-repo/commit/15784117e4e103f36cba75a9e29da48046eb82c4` |
|
||||||
| `CI_PREV_COMMIT_MESSAGE` | previous commit message | `test` |
|
| `CI_PREV_COMMIT_MESSAGE` | previous commit message | `test` |
|
||||||
| `CI_PREV_COMMIT_AUTHOR` | previous commit author username | `john-doe` |
|
| `CI_PREV_COMMIT_AUTHOR` | previous commit author username | `john-doe` |
|
||||||
|
185
docs/pnpm-lock.yaml
generated
185
docs/pnpm-lock.yaml
generated
@ -119,7 +119,7 @@ importers:
|
|||||||
version: 9.1.0
|
version: 9.1.0
|
||||||
isomorphic-dompurify:
|
isomorphic-dompurify:
|
||||||
specifier: ^2.16.0
|
specifier: ^2.16.0
|
||||||
version: 2.17.0
|
version: 2.18.0
|
||||||
marked:
|
marked:
|
||||||
specifier: ^15.0.2
|
specifier: ^15.0.2
|
||||||
version: 15.0.3
|
version: 15.0.3
|
||||||
@ -2753,8 +2753,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
dompurify@3.2.1:
|
dompurify@3.2.2:
|
||||||
resolution: {integrity: sha512-NBHEsc0/kzRYQd+AY6HR6B/IgsqzBABrqJbpCDQII/OK6h7B7LXzweZTDsqSW2LkTRpoxf18YUP+YjGySk6B3w==}
|
resolution: {integrity: sha512-YMM+erhdZ2nkZ4fTNRTSI94mb7VG7uVF5vj5Zde7tImgnhZE3R6YW/IACGIHb2ux+QkEXMhe591N+5jWOmL4Zw==}
|
||||||
|
|
||||||
domutils@2.8.0:
|
domutils@2.8.0:
|
||||||
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
|
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
|
||||||
@ -2778,8 +2778,8 @@ packages:
|
|||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||||
|
|
||||||
electron-to-chromium@1.5.64:
|
electron-to-chromium@1.5.67:
|
||||||
resolution: {integrity: sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==}
|
resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==}
|
||||||
|
|
||||||
emoji-regex@8.0.0:
|
emoji-regex@8.0.0:
|
||||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||||
@ -2857,8 +2857,8 @@ packages:
|
|||||||
es-shim-unscopables@1.0.2:
|
es-shim-unscopables@1.0.2:
|
||||||
resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
|
resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
|
||||||
|
|
||||||
es-to-primitive@1.2.1:
|
es-to-primitive@1.3.0:
|
||||||
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
|
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
es6-promise@3.3.1:
|
es6-promise@3.3.1:
|
||||||
@ -3230,8 +3230,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
|
resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
gopd@1.0.1:
|
gopd@1.1.0:
|
||||||
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
resolution: {integrity: sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
got@14.4.5:
|
got@14.4.5:
|
||||||
resolution: {integrity: sha512-sq+uET8TnNKRNnjEOPJzMcxeI0irT8BBNmf+GtZcJpmhYsQM1DSKmCROUjPWKsXZ5HzwD5Cf5/RV+QD9BSTxJg==}
|
resolution: {integrity: sha512-sq+uET8TnNKRNnjEOPJzMcxeI0irT8BBNmf+GtZcJpmhYsQM1DSKmCROUjPWKsXZ5HzwD5Cf5/RV+QD9BSTxJg==}
|
||||||
@ -3264,8 +3265,8 @@ packages:
|
|||||||
has-property-descriptors@1.0.2:
|
has-property-descriptors@1.0.2:
|
||||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||||
|
|
||||||
has-proto@1.0.3:
|
has-proto@1.1.0:
|
||||||
resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
|
resolution: {integrity: sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
has-symbols@1.0.3:
|
has-symbols@1.0.3:
|
||||||
@ -3615,8 +3616,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==}
|
resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
is-number-object@1.0.7:
|
is-number-object@1.1.0:
|
||||||
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
|
resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-number@7.0.0:
|
is-number@7.0.0:
|
||||||
@ -3654,8 +3655,8 @@ packages:
|
|||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||||
|
|
||||||
is-regex@1.1.4:
|
is-regex@1.2.0:
|
||||||
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
|
resolution: {integrity: sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-regexp@1.0.0:
|
is-regexp@1.0.0:
|
||||||
@ -3732,8 +3733,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
|
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
isomorphic-dompurify@2.17.0:
|
isomorphic-dompurify@2.18.0:
|
||||||
resolution: {integrity: sha512-W9RC9aPgEAFF55VMo/9AUQ+GYkQ68gTRMLqS8fP9rw1VoYCsI7RdrRMAePhhqyCLfZS3JNjA4ahFi1L4aczUUg==}
|
resolution: {integrity: sha512-e0AaROtWPy6ofSTCnUuBvXFidt1eFmrwEbi+Acpz0du6v2H+fq+3svPBn0g/AfBXz24FTWA9ccle7HSFT3HG7A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
jest-util@29.7.0:
|
jest-util@29.7.0:
|
||||||
@ -4241,8 +4242,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==}
|
resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
nanoid@3.3.7:
|
nanoid@3.3.8:
|
||||||
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
|
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@ -4319,8 +4320,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
webpack: ^4.0.0 || ^5.0.0
|
webpack: ^4.0.0 || ^5.0.0
|
||||||
|
|
||||||
nwsapi@2.2.13:
|
nwsapi@2.2.16:
|
||||||
resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==}
|
resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==}
|
||||||
|
|
||||||
oas-kit-common@1.0.8:
|
oas-kit-common@1.0.8:
|
||||||
resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==}
|
resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==}
|
||||||
@ -4388,8 +4389,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
openapi-sampler@1.6.0:
|
openapi-sampler@1.6.1:
|
||||||
resolution: {integrity: sha512-0PKhql1Ms38xSngEztcNQ7EXgssR2jAyVX7RckEln4reynIr/HHwuwM29cDEpiNkk4OkrHoc+7Li9V7WTAPYmw==}
|
resolution: {integrity: sha512-s1cIatOqrrhSj2tmJ4abFYZQK6l5v+V4toO5q1Pa0DyN8mtyqy2I+Qrj5W9vOELEtybIMQs/TBZGVO/DtTFK8w==}
|
||||||
|
|
||||||
opener@1.5.2:
|
opener@1.5.2:
|
||||||
resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
|
resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
|
||||||
@ -5191,8 +5192,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==}
|
resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
registry-auth-token@5.0.2:
|
registry-auth-token@5.0.3:
|
||||||
resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==}
|
resolution: {integrity: sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
registry-url@6.0.1:
|
registry-url@6.0.1:
|
||||||
@ -5433,8 +5434,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
shell-quote@1.8.1:
|
shell-quote@1.8.2:
|
||||||
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
shelljs@0.8.5:
|
shelljs@0.8.5:
|
||||||
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
||||||
@ -5702,11 +5704,11 @@ packages:
|
|||||||
tiny-warning@1.0.3:
|
tiny-warning@1.0.3:
|
||||||
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||||
|
|
||||||
tldts-core@6.1.64:
|
tldts-core@6.1.65:
|
||||||
resolution: {integrity: sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==}
|
resolution: {integrity: sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==}
|
||||||
|
|
||||||
tldts@6.1.64:
|
tldts@6.1.65:
|
||||||
resolution: {integrity: sha512-ph4AE5BXWIOsSy9stpoeo7bYe/Cy7VfpciIH4RhVZUPItCJmhqWCN0EVzxd8BOHiyNb42vuJc6NWTjJkg91Tuw==}
|
resolution: {integrity: sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
@ -5760,8 +5762,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
|
|
||||||
type-fest@4.28.0:
|
type-fest@4.29.1:
|
||||||
resolution: {integrity: sha512-jXMwges/FVbFRe5lTMJZVEZCrO9kI9c8k0PA/z7nF3bo0JSCCLysvokFjNPIUK/itEMas10MQM+AiHoHt/T/XA==}
|
resolution: {integrity: sha512-Y1zUveI92UYM/vo1EFlQSsNf74+hfKH+7saZJslF0Fw92FRaiTAnHPIvo9d7SLxXt/gAYqA4RXyDTioMQCCp0A==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
type-is@1.6.18:
|
type-is@1.6.18:
|
||||||
@ -6033,8 +6035,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
which-typed-array@1.1.15:
|
which-typed-array@1.1.16:
|
||||||
resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
|
resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
which@1.3.1:
|
which@1.3.1:
|
||||||
@ -9162,7 +9164,7 @@ snapshots:
|
|||||||
browserslist@4.24.2:
|
browserslist@4.24.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001684
|
caniuse-lite: 1.0.30001684
|
||||||
electron-to-chromium: 1.5.64
|
electron-to-chromium: 1.5.67
|
||||||
node-releases: 2.0.18
|
node-releases: 2.0.18
|
||||||
update-browserslist-db: 1.1.1(browserslist@4.24.2)
|
update-browserslist-db: 1.1.1(browserslist@4.24.2)
|
||||||
|
|
||||||
@ -9375,7 +9377,7 @@ snapshots:
|
|||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
rxjs: 7.8.1
|
rxjs: 7.8.1
|
||||||
shell-quote: 1.8.1
|
shell-quote: 1.8.2
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
tree-kill: 1.2.2
|
tree-kill: 1.2.2
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
@ -9669,7 +9671,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
es-define-property: 1.0.0
|
es-define-property: 1.0.0
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
|
|
||||||
define-lazy-prop@2.0.0: {}
|
define-lazy-prop@2.0.0: {}
|
||||||
|
|
||||||
@ -9793,7 +9795,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
|
|
||||||
dompurify@3.2.1:
|
dompurify@3.2.2:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/trusted-types': 2.0.7
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
||||||
@ -9824,7 +9826,7 @@ snapshots:
|
|||||||
|
|
||||||
ee-first@1.1.1: {}
|
ee-first@1.1.1: {}
|
||||||
|
|
||||||
electron-to-chromium@1.5.64: {}
|
electron-to-chromium@1.5.67: {}
|
||||||
|
|
||||||
emoji-regex@8.0.0: {}
|
emoji-regex@8.0.0: {}
|
||||||
|
|
||||||
@ -9869,8 +9871,8 @@ snapshots:
|
|||||||
html-element-map: 1.3.1
|
html-element-map: 1.3.1
|
||||||
is-boolean-object: 1.1.2
|
is-boolean-object: 1.1.2
|
||||||
is-callable: 1.2.7
|
is-callable: 1.2.7
|
||||||
is-number-object: 1.0.7
|
is-number-object: 1.1.0
|
||||||
is-regex: 1.1.4
|
is-regex: 1.2.0
|
||||||
is-string: 1.0.7
|
is-string: 1.0.7
|
||||||
is-subset: 0.1.1
|
is-subset: 0.1.1
|
||||||
lodash.escape: 4.0.1
|
lodash.escape: 4.0.1
|
||||||
@ -9901,14 +9903,14 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
es-object-atoms: 1.0.0
|
es-object-atoms: 1.0.0
|
||||||
es-set-tostringtag: 2.0.3
|
es-set-tostringtag: 2.0.3
|
||||||
es-to-primitive: 1.2.1
|
es-to-primitive: 1.3.0
|
||||||
function.prototype.name: 1.1.6
|
function.prototype.name: 1.1.6
|
||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
get-symbol-description: 1.0.2
|
get-symbol-description: 1.0.2
|
||||||
globalthis: 1.0.4
|
globalthis: 1.0.4
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
has-proto: 1.0.3
|
has-proto: 1.1.0
|
||||||
has-symbols: 1.0.3
|
has-symbols: 1.0.3
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
internal-slot: 1.0.7
|
internal-slot: 1.0.7
|
||||||
@ -9916,7 +9918,7 @@ snapshots:
|
|||||||
is-callable: 1.2.7
|
is-callable: 1.2.7
|
||||||
is-data-view: 1.0.1
|
is-data-view: 1.0.1
|
||||||
is-negative-zero: 2.0.3
|
is-negative-zero: 2.0.3
|
||||||
is-regex: 1.1.4
|
is-regex: 1.2.0
|
||||||
is-shared-array-buffer: 1.0.3
|
is-shared-array-buffer: 1.0.3
|
||||||
is-string: 1.0.7
|
is-string: 1.0.7
|
||||||
is-typed-array: 1.1.13
|
is-typed-array: 1.1.13
|
||||||
@ -9935,7 +9937,7 @@ snapshots:
|
|||||||
typed-array-byte-offset: 1.0.3
|
typed-array-byte-offset: 1.0.3
|
||||||
typed-array-length: 1.0.7
|
typed-array-length: 1.0.7
|
||||||
unbox-primitive: 1.0.2
|
unbox-primitive: 1.0.2
|
||||||
which-typed-array: 1.1.15
|
which-typed-array: 1.1.16
|
||||||
|
|
||||||
es-array-method-boxes-properly@1.0.0: {}
|
es-array-method-boxes-properly@1.0.0: {}
|
||||||
|
|
||||||
@ -9961,7 +9963,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
|
|
||||||
es-to-primitive@1.2.1:
|
es-to-primitive@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-callable: 1.2.7
|
is-callable: 1.2.7
|
||||||
is-date-object: 1.0.5
|
is-date-object: 1.0.5
|
||||||
@ -10328,7 +10330,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
has-proto: 1.0.3
|
has-proto: 1.1.0
|
||||||
has-symbols: 1.0.3
|
has-symbols: 1.0.3
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
|
|
||||||
@ -10391,7 +10393,7 @@ snapshots:
|
|||||||
globalthis@1.0.4:
|
globalthis@1.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
define-properties: 1.2.1
|
define-properties: 1.2.1
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
|
|
||||||
globby@11.1.0:
|
globby@11.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10410,7 +10412,7 @@ snapshots:
|
|||||||
merge2: 1.4.1
|
merge2: 1.4.1
|
||||||
slash: 4.0.0
|
slash: 4.0.0
|
||||||
|
|
||||||
gopd@1.0.1:
|
gopd@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
|
|
||||||
@ -10426,7 +10428,7 @@ snapshots:
|
|||||||
lowercase-keys: 3.0.0
|
lowercase-keys: 3.0.0
|
||||||
p-cancelable: 4.0.1
|
p-cancelable: 4.0.1
|
||||||
responselike: 3.0.0
|
responselike: 3.0.0
|
||||||
type-fest: 4.28.0
|
type-fest: 4.29.1
|
||||||
|
|
||||||
graceful-fs@4.2.10: {}
|
graceful-fs@4.2.10: {}
|
||||||
|
|
||||||
@ -10453,7 +10455,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
es-define-property: 1.0.0
|
es-define-property: 1.0.0
|
||||||
|
|
||||||
has-proto@1.0.3: {}
|
has-proto@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.7
|
||||||
|
|
||||||
has-symbols@1.0.3: {}
|
has-symbols@1.0.3: {}
|
||||||
|
|
||||||
@ -10869,8 +10873,9 @@ snapshots:
|
|||||||
|
|
||||||
is-npm@6.0.0: {}
|
is-npm@6.0.0: {}
|
||||||
|
|
||||||
is-number-object@1.0.7:
|
is-number-object@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
call-bind: 1.0.7
|
||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
is-number@7.0.0: {}
|
is-number@7.0.0: {}
|
||||||
@ -10893,10 +10898,12 @@ snapshots:
|
|||||||
|
|
||||||
is-potential-custom-element-name@1.0.1: {}
|
is-potential-custom-element-name@1.0.1: {}
|
||||||
|
|
||||||
is-regex@1.1.4:
|
is-regex@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
|
gopd: 1.1.0
|
||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
|
hasown: 2.0.2
|
||||||
|
|
||||||
is-regexp@1.0.0: {}
|
is-regexp@1.0.0: {}
|
||||||
|
|
||||||
@ -10924,7 +10931,7 @@ snapshots:
|
|||||||
|
|
||||||
is-typed-array@1.1.13:
|
is-typed-array@1.1.13:
|
||||||
dependencies:
|
dependencies:
|
||||||
which-typed-array: 1.1.15
|
which-typed-array: 1.1.16
|
||||||
|
|
||||||
is-typedarray@1.0.0: {}
|
is-typedarray@1.0.0: {}
|
||||||
|
|
||||||
@ -10953,9 +10960,9 @@ snapshots:
|
|||||||
|
|
||||||
isobject@3.0.1: {}
|
isobject@3.0.1: {}
|
||||||
|
|
||||||
isomorphic-dompurify@2.17.0:
|
isomorphic-dompurify@2.18.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
dompurify: 3.2.1
|
dompurify: 3.2.2
|
||||||
jsdom: 25.0.1
|
jsdom: 25.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
@ -11018,7 +11025,7 @@ snapshots:
|
|||||||
http-proxy-agent: 7.0.2
|
http-proxy-agent: 7.0.2
|
||||||
https-proxy-agent: 7.0.5
|
https-proxy-agent: 7.0.5
|
||||||
is-potential-custom-element-name: 1.0.1
|
is-potential-custom-element-name: 1.0.1
|
||||||
nwsapi: 2.2.13
|
nwsapi: 2.2.16
|
||||||
parse5: 7.2.1
|
parse5: 7.2.1
|
||||||
rrweb-cssom: 0.7.1
|
rrweb-cssom: 0.7.1
|
||||||
saxes: 6.0.0
|
saxes: 6.0.0
|
||||||
@ -11077,7 +11084,7 @@ snapshots:
|
|||||||
launch-editor@2.9.1:
|
launch-editor@2.9.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
shell-quote: 1.8.1
|
shell-quote: 1.8.2
|
||||||
|
|
||||||
leven@3.1.0: {}
|
leven@3.1.0: {}
|
||||||
|
|
||||||
@ -11734,7 +11741,7 @@ snapshots:
|
|||||||
dns-packet: 5.6.1
|
dns-packet: 5.6.1
|
||||||
thunky: 1.1.0
|
thunky: 1.1.0
|
||||||
|
|
||||||
nanoid@3.3.7: {}
|
nanoid@3.3.8: {}
|
||||||
|
|
||||||
nearley@2.20.1:
|
nearley@2.20.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11799,7 +11806,7 @@ snapshots:
|
|||||||
schema-utils: 3.3.0
|
schema-utils: 3.3.0
|
||||||
webpack: 5.96.1
|
webpack: 5.96.1
|
||||||
|
|
||||||
nwsapi@2.2.13: {}
|
nwsapi@2.2.16: {}
|
||||||
|
|
||||||
oas-kit-common@1.0.8:
|
oas-kit-common@1.0.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11884,7 +11891,7 @@ snapshots:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
|
|
||||||
openapi-sampler@1.6.0:
|
openapi-sampler@1.6.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/json-schema': 7.0.15
|
'@types/json-schema': 7.0.15
|
||||||
fast-xml-parser: 4.5.0
|
fast-xml-parser: 4.5.0
|
||||||
@ -11932,7 +11939,7 @@ snapshots:
|
|||||||
package-json@8.1.1:
|
package-json@8.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
got: 14.4.5
|
got: 14.4.5
|
||||||
registry-auth-token: 5.0.2
|
registry-auth-token: 5.0.3
|
||||||
registry-url: 6.0.1
|
registry-url: 6.0.1
|
||||||
semver: 7.6.3
|
semver: 7.6.3
|
||||||
|
|
||||||
@ -12462,13 +12469,13 @@ snapshots:
|
|||||||
|
|
||||||
postcss@8.4.38:
|
postcss@8.4.38:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.7
|
nanoid: 3.3.8
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
postcss@8.4.49:
|
postcss@8.4.49:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.7
|
nanoid: 3.3.8
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
@ -12585,7 +12592,7 @@ snapshots:
|
|||||||
prompts: 2.4.2
|
prompts: 2.4.2
|
||||||
react-error-overlay: 6.0.11
|
react-error-overlay: 6.0.11
|
||||||
recursive-readdir: 2.2.3
|
recursive-readdir: 2.2.3
|
||||||
shell-quote: 1.8.1
|
shell-quote: 1.8.2
|
||||||
strip-ansi: 6.0.1
|
strip-ansi: 6.0.1
|
||||||
text-table: 0.2.0
|
text-table: 0.2.0
|
||||||
webpack: 5.96.1
|
webpack: 5.96.1
|
||||||
@ -12750,7 +12757,7 @@ snapshots:
|
|||||||
classnames: 2.5.1
|
classnames: 2.5.1
|
||||||
core-js: 3.39.0
|
core-js: 3.39.0
|
||||||
decko: 1.2.0
|
decko: 1.2.0
|
||||||
dompurify: 3.2.1
|
dompurify: 3.2.2
|
||||||
eventemitter3: 5.0.1
|
eventemitter3: 5.0.1
|
||||||
json-pointer: 0.6.2
|
json-pointer: 0.6.2
|
||||||
lunr: 2.3.9
|
lunr: 2.3.9
|
||||||
@ -12758,7 +12765,7 @@ snapshots:
|
|||||||
marked: 4.3.0
|
marked: 4.3.0
|
||||||
mobx: 6.13.5
|
mobx: 6.13.5
|
||||||
mobx-react: 9.1.1(mobx@6.13.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
mobx-react: 9.1.1(mobx@6.13.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
openapi-sampler: 1.6.0
|
openapi-sampler: 1.6.1
|
||||||
path-browserify: 1.0.1
|
path-browserify: 1.0.1
|
||||||
perfect-scrollbar: 1.5.6
|
perfect-scrollbar: 1.5.6
|
||||||
polished: 4.3.1
|
polished: 4.3.1
|
||||||
@ -12803,7 +12810,7 @@ snapshots:
|
|||||||
es-abstract: 1.23.5
|
es-abstract: 1.23.5
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
which-builtin-type: 1.2.0
|
which-builtin-type: 1.2.0
|
||||||
|
|
||||||
reftools@1.1.9: {}
|
reftools@1.1.9: {}
|
||||||
@ -12836,7 +12843,7 @@ snapshots:
|
|||||||
unicode-match-property-ecmascript: 2.0.0
|
unicode-match-property-ecmascript: 2.0.0
|
||||||
unicode-match-property-value-ecmascript: 2.2.0
|
unicode-match-property-value-ecmascript: 2.2.0
|
||||||
|
|
||||||
registry-auth-token@5.0.2:
|
registry-auth-token@5.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@pnpm/npm-conf': 2.3.1
|
'@pnpm/npm-conf': 2.3.1
|
||||||
|
|
||||||
@ -13018,7 +13025,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
is-regex: 1.1.4
|
is-regex: 1.2.0
|
||||||
|
|
||||||
safer-buffer@2.1.2: {}
|
safer-buffer@2.1.2: {}
|
||||||
|
|
||||||
@ -13132,7 +13139,7 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
|
|
||||||
set-function-name@2.0.2:
|
set-function-name@2.0.2:
|
||||||
@ -13158,7 +13165,7 @@ snapshots:
|
|||||||
|
|
||||||
shebang-regex@3.0.0: {}
|
shebang-regex@3.0.0: {}
|
||||||
|
|
||||||
shell-quote@1.8.1: {}
|
shell-quote@1.8.2: {}
|
||||||
|
|
||||||
shelljs@0.8.5:
|
shelljs@0.8.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13453,11 +13460,11 @@ snapshots:
|
|||||||
|
|
||||||
tiny-warning@1.0.3: {}
|
tiny-warning@1.0.3: {}
|
||||||
|
|
||||||
tldts-core@6.1.64: {}
|
tldts-core@6.1.65: {}
|
||||||
|
|
||||||
tldts@6.1.64:
|
tldts@6.1.65:
|
||||||
dependencies:
|
dependencies:
|
||||||
tldts-core: 6.1.64
|
tldts-core: 6.1.65
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13469,7 +13476,7 @@ snapshots:
|
|||||||
|
|
||||||
tough-cookie@5.0.0:
|
tough-cookie@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tldts: 6.1.64
|
tldts: 6.1.65
|
||||||
|
|
||||||
tr46@0.0.3: {}
|
tr46@0.0.3: {}
|
||||||
|
|
||||||
@ -13493,7 +13500,7 @@ snapshots:
|
|||||||
|
|
||||||
type-fest@2.19.0: {}
|
type-fest@2.19.0: {}
|
||||||
|
|
||||||
type-fest@4.28.0: {}
|
type-fest@4.29.1: {}
|
||||||
|
|
||||||
type-is@1.6.18:
|
type-is@1.6.18:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13510,8 +13517,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
for-each: 0.3.3
|
for-each: 0.3.3
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
has-proto: 1.0.3
|
has-proto: 1.1.0
|
||||||
is-typed-array: 1.1.13
|
is-typed-array: 1.1.13
|
||||||
|
|
||||||
typed-array-byte-offset@1.0.3:
|
typed-array-byte-offset@1.0.3:
|
||||||
@ -13519,8 +13526,8 @@ snapshots:
|
|||||||
available-typed-arrays: 1.0.7
|
available-typed-arrays: 1.0.7
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
for-each: 0.3.3
|
for-each: 0.3.3
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
has-proto: 1.0.3
|
has-proto: 1.1.0
|
||||||
is-typed-array: 1.1.13
|
is-typed-array: 1.1.13
|
||||||
reflect.getprototypeof: 1.0.7
|
reflect.getprototypeof: 1.0.7
|
||||||
|
|
||||||
@ -13528,7 +13535,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
for-each: 0.3.3
|
for-each: 0.3.3
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
is-typed-array: 1.1.13
|
is-typed-array: 1.1.13
|
||||||
possible-typed-array-names: 1.0.0
|
possible-typed-array-names: 1.0.0
|
||||||
reflect.getprototypeof: 1.0.7
|
reflect.getprototypeof: 1.0.7
|
||||||
@ -13856,7 +13863,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-bigint: 1.0.4
|
is-bigint: 1.0.4
|
||||||
is-boolean-object: 1.1.2
|
is-boolean-object: 1.1.2
|
||||||
is-number-object: 1.0.7
|
is-number-object: 1.1.0
|
||||||
is-string: 1.0.7
|
is-string: 1.0.7
|
||||||
is-symbol: 1.0.4
|
is-symbol: 1.0.4
|
||||||
|
|
||||||
@ -13869,12 +13876,12 @@ snapshots:
|
|||||||
is-date-object: 1.0.5
|
is-date-object: 1.0.5
|
||||||
is-finalizationregistry: 1.1.0
|
is-finalizationregistry: 1.1.0
|
||||||
is-generator-function: 1.0.10
|
is-generator-function: 1.0.10
|
||||||
is-regex: 1.1.4
|
is-regex: 1.2.0
|
||||||
is-weakref: 1.0.2
|
is-weakref: 1.0.2
|
||||||
isarray: 2.0.5
|
isarray: 2.0.5
|
||||||
which-boxed-primitive: 1.0.2
|
which-boxed-primitive: 1.0.2
|
||||||
which-collection: 1.0.2
|
which-collection: 1.0.2
|
||||||
which-typed-array: 1.1.15
|
which-typed-array: 1.1.16
|
||||||
|
|
||||||
which-collection@1.0.2:
|
which-collection@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13883,12 +13890,12 @@ snapshots:
|
|||||||
is-weakmap: 2.0.2
|
is-weakmap: 2.0.2
|
||||||
is-weakset: 2.0.3
|
is-weakset: 2.0.3
|
||||||
|
|
||||||
which-typed-array@1.1.15:
|
which-typed-array@1.1.16:
|
||||||
dependencies:
|
dependencies:
|
||||||
available-typed-arrays: 1.0.7
|
available-typed-arrays: 1.0.7
|
||||||
call-bind: 1.0.7
|
call-bind: 1.0.7
|
||||||
for-each: 0.3.3
|
for-each: 0.3.3
|
||||||
gopd: 1.0.1
|
gopd: 1.1.0
|
||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
which@1.3.1:
|
which@1.3.1:
|
||||||
|
@ -33,6 +33,7 @@ This will be the next version of Woodpecker.
|
|||||||
- Removed old API routes: `registry/` -> `registries`, `/authorize/token`
|
- Removed old API routes: `registry/` -> `registries`, `/authorize/token`
|
||||||
- Replaced `registry` command with `repo registry` in cli
|
- Replaced `registry` command with `repo registry` in cli
|
||||||
- Deprecated `secrets`, use `environment` with `from_secret`
|
- Deprecated `secrets`, use `environment` with `from_secret`
|
||||||
|
- Empty string environment variables are not set
|
||||||
- CLI commands got restructured to provide a simplified structure:
|
- CLI commands got restructured to provide a simplified structure:
|
||||||
- `woodpecker-cli secret [add|rm|...] --global` is now `woodpecker-cli admin secret [add|rm|...]`
|
- `woodpecker-cli secret [add|rm|...] --global` is now `woodpecker-cli admin secret [add|rm|...]`
|
||||||
- `woodpecker-cli user` is now `woodpecker-cli admin user`
|
- `woodpecker-cli user` is now `woodpecker-cli admin user`
|
||||||
@ -42,6 +43,8 @@ This will be the next version of Woodpecker.
|
|||||||
- `woodpecker-cli log` is now `woodpecker-cli pipeline log`
|
- `woodpecker-cli log` is now `woodpecker-cli pipeline log`
|
||||||
- `woodpecker-cli cron` is now `woodpecker-cli repo cron`
|
- `woodpecker-cli cron` is now `woodpecker-cli repo cron`
|
||||||
- `woodpecker-cli secret [add|rm|...] --repository` is now `woodpecker-cli repo secret [add|rm|...]`
|
- `woodpecker-cli secret [add|rm|...] --repository` is now `woodpecker-cli repo secret [add|rm|...]`
|
||||||
|
- `woodpecker-cli pipeline logs` is now `woodpecker-cli pipeline log show`
|
||||||
|
- `woodpecker-cli [registry|secret|...] info` is now `woodpecker-cli [registry|secret|...] show`
|
||||||
- Deprecated `detached` in favor of services
|
- Deprecated `detached` in favor of services
|
||||||
|
|
||||||
## Admin migrations
|
## Admin migrations
|
||||||
|
2
go.mod
2
go.mod
@ -56,7 +56,7 @@ require (
|
|||||||
github.com/swaggo/gin-swagger v1.6.0
|
github.com/swaggo/gin-swagger v1.6.0
|
||||||
github.com/swaggo/swag v1.16.4
|
github.com/swaggo/swag v1.16.4
|
||||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
||||||
github.com/urfave/cli/v3 v3.0.0-alpha9.6
|
github.com/urfave/cli/v3 v3.0.0-alpha9.10
|
||||||
github.com/xanzy/go-gitlab v0.114.0
|
github.com/xanzy/go-gitlab v0.114.0
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0
|
github.com/xeipuuv/gojsonschema v1.2.0
|
||||||
github.com/yaronf/httpsign v0.3.1
|
github.com/yaronf/httpsign v0.3.1
|
||||||
|
4
go.sum
4
go.sum
@ -545,8 +545,8 @@ github.com/urfave/cli-docs/v3 v3.0.0-alpha6 h1:w/l/N0xw1rO/aHRIGXJ0lDwwYFOzilup1
|
|||||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6/go.mod h1:p7Z4lg8FSTrPB9GTaNyTrK3ygffHZcK3w0cU2VE+mzU=
|
github.com/urfave/cli-docs/v3 v3.0.0-alpha6/go.mod h1:p7Z4lg8FSTrPB9GTaNyTrK3ygffHZcK3w0cU2VE+mzU=
|
||||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
github.com/urfave/cli/v3 v3.0.0-alpha9.6 h1:MvGvMfcbnEBNBDkH7melypUZ9Rc1RYnQuLvNRTZFsbs=
|
github.com/urfave/cli/v3 v3.0.0-alpha9.10 h1:whPwidq9cUh18NBqzSR8N3tts8NiQDsTmt9s7AyX85c=
|
||||||
github.com/urfave/cli/v3 v3.0.0-alpha9.6/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
github.com/urfave/cli/v3 v3.0.0-alpha9.10/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xanzy/go-gitlab v0.114.0 h1:0wQr/KBckwrZPfEMjRqpUz0HmsKKON9UhCYv9KDy19M=
|
github.com/xanzy/go-gitlab v0.114.0 h1:0wQr/KBckwrZPfEMjRqpUz0HmsKKON9UhCYv9KDy19M=
|
||||||
|
@ -25,11 +25,143 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
const (
|
||||||
pullRegexp = regexp.MustCompile(`\d+`)
|
initialEnvMapSize = 100
|
||||||
maxChangedFiles = 500
|
maxChangedFiles = 500
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var pullRegexp = regexp.MustCompile(`\d+`)
|
||||||
|
|
||||||
|
// Environ returns the metadata as a map of environment variables.
|
||||||
|
func (m *Metadata) Environ() map[string]string {
|
||||||
|
params := make(map[string]string, initialEnvMapSize)
|
||||||
|
|
||||||
|
system := m.Sys
|
||||||
|
setNonEmptyEnvVar(params, "CI", system.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_SYSTEM_NAME", system.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_SYSTEM_URL", system.URL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_SYSTEM_HOST", system.Host)
|
||||||
|
setNonEmptyEnvVar(params, "CI_SYSTEM_PLATFORM", system.Platform) // will be set by pipeline platform option or by agent
|
||||||
|
setNonEmptyEnvVar(params, "CI_SYSTEM_VERSION", system.Version)
|
||||||
|
|
||||||
|
forge := m.Forge
|
||||||
|
setNonEmptyEnvVar(params, "CI_FORGE_TYPE", forge.Type)
|
||||||
|
setNonEmptyEnvVar(params, "CI_FORGE_URL", forge.URL)
|
||||||
|
|
||||||
|
repo := m.Repo
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO", path.Join(repo.Owner, repo.Name))
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_NAME", repo.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_OWNER", repo.Owner)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_REMOTE_ID", repo.RemoteID)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_SCM", repo.SCM)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_URL", repo.ForgeURL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_CLONE_URL", repo.CloneURL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_CLONE_SSH_URL", repo.CloneSSHURL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_DEFAULT_BRANCH", repo.Branch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_PRIVATE", strconv.FormatBool(repo.Private))
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_NETWORK", strconv.FormatBool(repo.Trusted.Network))
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_VOLUMES", strconv.FormatBool(repo.Trusted.Volumes))
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_SECURITY", strconv.FormatBool(repo.Trusted.Security))
|
||||||
|
// Deprecated remove in 4.x
|
||||||
|
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED", strconv.FormatBool(m.Repo.Trusted.Security && m.Repo.Trusted.Network && m.Repo.Trusted.Volumes))
|
||||||
|
|
||||||
|
pipeline := m.Curr
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_NUMBER", strconv.FormatInt(pipeline.Number, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_PARENT", strconv.FormatInt(pipeline.Parent, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_EVENT", pipeline.Event)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_URL", m.getPipelineWebURL(pipeline, 0))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_FORGE_URL", pipeline.ForgeURL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_DEPLOY_TARGET", pipeline.DeployTo)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_DEPLOY_TASK", pipeline.DeployTask)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_CREATED", strconv.FormatInt(pipeline.Created, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PIPELINE_STARTED", strconv.FormatInt(pipeline.Started, 10))
|
||||||
|
|
||||||
|
workflow := m.Workflow
|
||||||
|
setNonEmptyEnvVar(params, "CI_WORKFLOW_NAME", workflow.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_WORKFLOW_NUMBER", strconv.Itoa(workflow.Number))
|
||||||
|
|
||||||
|
step := m.Step
|
||||||
|
setNonEmptyEnvVar(params, "CI_STEP_NAME", step.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_STEP_NUMBER", strconv.Itoa(step.Number))
|
||||||
|
setNonEmptyEnvVar(params, "CI_STEP_URL", m.getPipelineWebURL(pipeline, step.Number))
|
||||||
|
// CI_STEP_STARTED will be set by agent
|
||||||
|
|
||||||
|
commit := pipeline.Commit
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_SHA", commit.Sha)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_REF", commit.Ref)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_REFSPEC", commit.Refspec)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_MESSAGE", commit.Message)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_BRANCH", commit.Branch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR", commit.Author.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR_EMAIL", commit.Author.Email)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR_AVATAR", commit.Author.Avatar)
|
||||||
|
if pipeline.Event == EventTag || pipeline.Event == EventRelease || strings.HasPrefix(pipeline.Commit.Ref, "refs/tags/") {
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_TAG", strings.TrimPrefix(pipeline.Commit.Ref, "refs/tags/"))
|
||||||
|
}
|
||||||
|
if pipeline.Event == EventRelease {
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_PRERELEASE", strconv.FormatBool(pipeline.Commit.IsPrerelease))
|
||||||
|
}
|
||||||
|
if pipeline.Event == EventPull || pipeline.Event == EventPullClosed {
|
||||||
|
sourceBranch, targetBranch := getSourceTargetBranches(commit.Refspec)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_SOURCE_BRANCH", sourceBranch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_TARGET_BRANCH", targetBranch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_PULL_REQUEST", pullRegexp.FindString(pipeline.Commit.Ref))
|
||||||
|
setNonEmptyEnvVar(params, "CI_COMMIT_PULL_REQUEST_LABELS", strings.Join(pipeline.Commit.PullRequestLabels, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only export changed files if maxChangedFiles is not exceeded
|
||||||
|
changedFiles := commit.ChangedFiles
|
||||||
|
if len(changedFiles) == 0 {
|
||||||
|
params["CI_PIPELINE_FILES"] = "[]"
|
||||||
|
} else if len(changedFiles) <= maxChangedFiles {
|
||||||
|
// we have to use json, as other separators like ;, or space are valid filename chars
|
||||||
|
changedFiles, err := json.Marshal(changedFiles)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("marshal changed files")
|
||||||
|
}
|
||||||
|
params["CI_PIPELINE_FILES"] = string(changedFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
prevPipeline := m.Prev
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_NUMBER", strconv.FormatInt(prevPipeline.Number, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_PARENT", strconv.FormatInt(prevPipeline.Parent, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_EVENT", prevPipeline.Event)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_URL", m.getPipelineWebURL(prevPipeline, 0))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_FORGE_URL", prevPipeline.ForgeURL)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_URL", prevPipeline.ForgeURL) // why commit url?
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_DEPLOY_TARGET", prevPipeline.DeployTo)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_DEPLOY_TASK", prevPipeline.DeployTask)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_STATUS", prevPipeline.Status)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_CREATED", strconv.FormatInt(prevPipeline.Created, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_STARTED", strconv.FormatInt(prevPipeline.Started, 10))
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_FINISHED", strconv.FormatInt(prevPipeline.Finished, 10))
|
||||||
|
|
||||||
|
prevCommit := prevPipeline.Commit
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_SHA", prevCommit.Sha)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_REF", prevCommit.Ref)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_REFSPEC", prevCommit.Refspec)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_MESSAGE", prevCommit.Message)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_BRANCH", prevCommit.Branch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR", prevCommit.Author.Name)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR_EMAIL", prevCommit.Author.Email)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR_AVATAR", prevCommit.Author.Avatar)
|
||||||
|
if prevPipeline.Event == EventPull || prevPipeline.Event == EventPullClosed {
|
||||||
|
prevSourceBranch, prevTargetBranch := getSourceTargetBranches(prevCommit.Refspec)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_SOURCE_BRANCH", prevSourceBranch)
|
||||||
|
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_TARGET_BRANCH", prevTargetBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Metadata) getPipelineWebURL(pipeline Pipeline, stepNumber int) string {
|
||||||
|
if stepNumber == 0 {
|
||||||
|
return fmt.Sprintf("%s/repos/%d/pipeline/%d", m.Sys.URL, m.Repo.ID, pipeline.Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s/repos/%d/pipeline/%d/%d", m.Sys.URL, m.Repo.ID, pipeline.Number, stepNumber)
|
||||||
|
}
|
||||||
|
|
||||||
func getSourceTargetBranches(refspec string) (string, string) {
|
func getSourceTargetBranches(refspec string) (string, string) {
|
||||||
var (
|
var (
|
||||||
sourceBranch string
|
sourceBranch string
|
||||||
@ -45,124 +177,10 @@ func getSourceTargetBranches(refspec string) (string, string) {
|
|||||||
return sourceBranch, targetBranch
|
return sourceBranch, targetBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Environ returns the metadata as a map of environment variables.
|
func setNonEmptyEnvVar(env map[string]string, key, value string) {
|
||||||
func (m *Metadata) Environ() map[string]string {
|
if len(value) > 0 {
|
||||||
sourceBranch, targetBranch := getSourceTargetBranches(m.Curr.Commit.Refspec)
|
env[key] = value
|
||||||
prevSourceBranch, prevTargetBranch := getSourceTargetBranches(m.Prev.Commit.Refspec)
|
} else {
|
||||||
|
log.Trace().Str("variable", key).Msg("env var is filtered as it's empty")
|
||||||
params := map[string]string{
|
|
||||||
"CI": m.Sys.Name,
|
|
||||||
"CI_REPO": path.Join(m.Repo.Owner, m.Repo.Name),
|
|
||||||
"CI_REPO_NAME": m.Repo.Name,
|
|
||||||
"CI_REPO_OWNER": m.Repo.Owner,
|
|
||||||
"CI_REPO_REMOTE_ID": m.Repo.RemoteID,
|
|
||||||
"CI_REPO_SCM": m.Repo.SCM,
|
|
||||||
"CI_REPO_URL": m.Repo.ForgeURL,
|
|
||||||
"CI_REPO_CLONE_URL": m.Repo.CloneURL,
|
|
||||||
"CI_REPO_CLONE_SSH_URL": m.Repo.CloneSSHURL,
|
|
||||||
"CI_REPO_DEFAULT_BRANCH": m.Repo.Branch,
|
|
||||||
"CI_REPO_PRIVATE": strconv.FormatBool(m.Repo.Private),
|
|
||||||
"CI_REPO_TRUSTED_NETWORK": strconv.FormatBool(m.Repo.Trusted.Network),
|
|
||||||
"CI_REPO_TRUSTED_VOLUMES": strconv.FormatBool(m.Repo.Trusted.Volumes),
|
|
||||||
"CI_REPO_TRUSTED_SECURITY": strconv.FormatBool(m.Repo.Trusted.Security),
|
|
||||||
// Deprecated remove in 4.x
|
|
||||||
"CI_REPO_TRUSTED": strconv.FormatBool(m.Repo.Trusted.Security && m.Repo.Trusted.Network && m.Repo.Trusted.Volumes),
|
|
||||||
|
|
||||||
"CI_COMMIT_SHA": m.Curr.Commit.Sha,
|
|
||||||
"CI_COMMIT_REF": m.Curr.Commit.Ref,
|
|
||||||
"CI_COMMIT_REFSPEC": m.Curr.Commit.Refspec,
|
|
||||||
"CI_COMMIT_BRANCH": m.Curr.Commit.Branch,
|
|
||||||
"CI_COMMIT_SOURCE_BRANCH": sourceBranch,
|
|
||||||
"CI_COMMIT_TARGET_BRANCH": targetBranch,
|
|
||||||
"CI_COMMIT_MESSAGE": m.Curr.Commit.Message,
|
|
||||||
"CI_COMMIT_AUTHOR": m.Curr.Commit.Author.Name,
|
|
||||||
"CI_COMMIT_AUTHOR_EMAIL": m.Curr.Commit.Author.Email,
|
|
||||||
"CI_COMMIT_AUTHOR_AVATAR": m.Curr.Commit.Author.Avatar,
|
|
||||||
"CI_COMMIT_TAG": "", // will be set if event is tag
|
|
||||||
"CI_COMMIT_PULL_REQUEST": "", // will be set if event is pull_request or pull_request_closed
|
|
||||||
"CI_COMMIT_PULL_REQUEST_LABELS": "", // will be set if event is pull_request or pull_request_closed
|
|
||||||
|
|
||||||
"CI_PIPELINE_NUMBER": strconv.FormatInt(m.Curr.Number, 10),
|
|
||||||
"CI_PIPELINE_PARENT": strconv.FormatInt(m.Curr.Parent, 10),
|
|
||||||
"CI_PIPELINE_EVENT": m.Curr.Event,
|
|
||||||
"CI_PIPELINE_URL": m.getPipelineWebURL(m.Curr, 0),
|
|
||||||
"CI_PIPELINE_FORGE_URL": m.Curr.ForgeURL,
|
|
||||||
"CI_PIPELINE_DEPLOY_TARGET": m.Curr.DeployTo,
|
|
||||||
"CI_PIPELINE_DEPLOY_TASK": m.Curr.DeployTask,
|
|
||||||
"CI_PIPELINE_CREATED": strconv.FormatInt(m.Curr.Created, 10),
|
|
||||||
"CI_PIPELINE_STARTED": strconv.FormatInt(m.Curr.Started, 10),
|
|
||||||
|
|
||||||
"CI_WORKFLOW_NAME": m.Workflow.Name,
|
|
||||||
"CI_WORKFLOW_NUMBER": strconv.Itoa(m.Workflow.Number),
|
|
||||||
|
|
||||||
"CI_STEP_NAME": m.Step.Name,
|
|
||||||
"CI_STEP_NUMBER": strconv.Itoa(m.Step.Number),
|
|
||||||
"CI_STEP_STARTED": "", // will be set by agent
|
|
||||||
"CI_STEP_URL": m.getPipelineWebURL(m.Curr, m.Step.Number),
|
|
||||||
|
|
||||||
"CI_PREV_COMMIT_SHA": m.Prev.Commit.Sha,
|
|
||||||
"CI_PREV_COMMIT_REF": m.Prev.Commit.Ref,
|
|
||||||
"CI_PREV_COMMIT_REFSPEC": m.Prev.Commit.Refspec,
|
|
||||||
"CI_PREV_COMMIT_BRANCH": m.Prev.Commit.Branch,
|
|
||||||
"CI_PREV_COMMIT_URL": m.Prev.ForgeURL,
|
|
||||||
"CI_PREV_COMMIT_MESSAGE": m.Prev.Commit.Message,
|
|
||||||
"CI_PREV_COMMIT_AUTHOR": m.Prev.Commit.Author.Name,
|
|
||||||
"CI_PREV_COMMIT_AUTHOR_EMAIL": m.Prev.Commit.Author.Email,
|
|
||||||
"CI_PREV_COMMIT_AUTHOR_AVATAR": m.Prev.Commit.Author.Avatar,
|
|
||||||
"CI_PREV_COMMIT_SOURCE_BRANCH": prevSourceBranch,
|
|
||||||
"CI_PREV_COMMIT_TARGET_BRANCH": prevTargetBranch,
|
|
||||||
|
|
||||||
"CI_PREV_PIPELINE_NUMBER": strconv.FormatInt(m.Prev.Number, 10),
|
|
||||||
"CI_PREV_PIPELINE_PARENT": strconv.FormatInt(m.Prev.Parent, 10),
|
|
||||||
"CI_PREV_PIPELINE_EVENT": m.Prev.Event,
|
|
||||||
"CI_PREV_PIPELINE_URL": m.getPipelineWebURL(m.Prev, 0),
|
|
||||||
"CI_PREV_PIPELINE_FORGE_URL": m.Prev.ForgeURL,
|
|
||||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": m.Prev.DeployTo,
|
|
||||||
"CI_PREV_PIPELINE_DEPLOY_TASK": m.Prev.DeployTask,
|
|
||||||
"CI_PREV_PIPELINE_STATUS": m.Prev.Status,
|
|
||||||
"CI_PREV_PIPELINE_CREATED": strconv.FormatInt(m.Prev.Created, 10),
|
|
||||||
"CI_PREV_PIPELINE_STARTED": strconv.FormatInt(m.Prev.Started, 10),
|
|
||||||
"CI_PREV_PIPELINE_FINISHED": strconv.FormatInt(m.Prev.Finished, 10),
|
|
||||||
|
|
||||||
"CI_SYSTEM_NAME": m.Sys.Name,
|
|
||||||
"CI_SYSTEM_URL": m.Sys.URL,
|
|
||||||
"CI_SYSTEM_HOST": m.Sys.Host,
|
|
||||||
"CI_SYSTEM_PLATFORM": m.Sys.Platform, // will be set by pipeline platform option or by agent
|
|
||||||
"CI_SYSTEM_VERSION": m.Sys.Version,
|
|
||||||
|
|
||||||
"CI_FORGE_TYPE": m.Forge.Type,
|
|
||||||
"CI_FORGE_URL": m.Forge.URL,
|
|
||||||
}
|
}
|
||||||
if m.Curr.Event == EventTag || m.Curr.Event == EventRelease || strings.HasPrefix(m.Curr.Commit.Ref, "refs/tags/") {
|
|
||||||
params["CI_COMMIT_TAG"] = strings.TrimPrefix(m.Curr.Commit.Ref, "refs/tags/")
|
|
||||||
}
|
|
||||||
if m.Curr.Event == EventRelease {
|
|
||||||
params["CI_COMMIT_PRERELEASE"] = strconv.FormatBool(m.Curr.Commit.IsPrerelease)
|
|
||||||
}
|
|
||||||
if m.Curr.Event == EventPull || m.Curr.Event == EventPullClosed {
|
|
||||||
params["CI_COMMIT_PULL_REQUEST"] = pullRegexp.FindString(m.Curr.Commit.Ref)
|
|
||||||
params["CI_COMMIT_PULL_REQUEST_LABELS"] = strings.Join(m.Curr.Commit.PullRequestLabels, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only export changed files if maxChangedFiles is not exceeded
|
|
||||||
if len(m.Curr.Commit.ChangedFiles) == 0 {
|
|
||||||
params["CI_PIPELINE_FILES"] = "[]"
|
|
||||||
} else if len(m.Curr.Commit.ChangedFiles) <= maxChangedFiles {
|
|
||||||
// we have to use json, as other separators like ;, or space are valid filename chars
|
|
||||||
changedFiles, err := json.Marshal(m.Curr.Commit.ChangedFiles)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("marshal changed files")
|
|
||||||
}
|
|
||||||
params["CI_PIPELINE_FILES"] = string(changedFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Metadata) getPipelineWebURL(pipeline Pipeline, stepNumber int) string {
|
|
||||||
if stepNumber == 0 {
|
|
||||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d", m.Sys.URL, m.Repo.ID, pipeline.Number)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d/%d", m.Sys.URL, m.Repo.ID, pipeline.Number, stepNumber)
|
|
||||||
}
|
}
|
||||||
|
@ -391,8 +391,8 @@ func TestCompilerCompile(t *testing.T) {
|
|||||||
for _, st := range backConf.Stages {
|
for _, st := range backConf.Stages {
|
||||||
for _, s := range st.Steps {
|
for _, s := range st.Steps {
|
||||||
s.UUID = ""
|
s.UUID = ""
|
||||||
assert.Truef(t, s.Environment["VERBOSE"] == "true", "expect to get value of global set environment")
|
assert.Truef(t, s.Environment["VERBOSE"] == "true", "expected to get value of global set environment")
|
||||||
assert.Truef(t, len(s.Environment) > 50, "expect to have a lot of build in variables")
|
assert.Truef(t, len(s.Environment) > 10, "expected to have a lot of built-in variables")
|
||||||
s.Environment = nil
|
s.Environment = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,7 @@ func createTmpPipeline(event model.WebhookEvent, commit *model.Commit, user *mod
|
|||||||
// @Param branch query string false "filter pipelines by branch"
|
// @Param branch query string false "filter pipelines by branch"
|
||||||
// @Param event query string false "filter pipelines by webhook events (comma separated)"
|
// @Param event query string false "filter pipelines by webhook events (comma separated)"
|
||||||
// @Param ref query string false "filter pipelines by strings contained in ref"
|
// @Param ref query string false "filter pipelines by strings contained in ref"
|
||||||
|
// @Param status query string false "filter pipelines by status"
|
||||||
func GetPipelines(c *gin.Context) {
|
func GetPipelines(c *gin.Context) {
|
||||||
repo := session.Repo(c)
|
repo := session.Repo(c)
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ func GetPipelines(c *gin.Context) {
|
|||||||
if events := c.Query("event"); events != "" {
|
if events := c.Query("event"); events != "" {
|
||||||
eventList := strings.Split(events, ",")
|
eventList := strings.Split(events, ",")
|
||||||
wel := make(model.WebhookEventList, 0, len(eventList))
|
wel := make(model.WebhookEventList, 0, len(eventList))
|
||||||
for _, event := range events {
|
for _, event := range eventList {
|
||||||
we := model.WebhookEvent(event)
|
we := model.WebhookEvent(event)
|
||||||
if err := we.Validate(); err != nil {
|
if err := we.Validate(); err != nil {
|
||||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||||
@ -142,6 +143,15 @@ func GetPipelines(c *gin.Context) {
|
|||||||
filter.Events = wel
|
filter.Events = wel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if status := c.Query("status"); status != "" {
|
||||||
|
ps := model.StatusValue(status)
|
||||||
|
if err := ps.Validate(); err != nil {
|
||||||
|
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filter.Status = ps
|
||||||
|
}
|
||||||
|
|
||||||
if before := c.Query("before"); before != "" {
|
if before := c.Query("before"); before != "" {
|
||||||
beforeDt, err := time.Parse(time.RFC3339, before)
|
beforeDt, err := time.Parse(time.RFC3339, before)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,6 +96,24 @@ func TestGetPipelines(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, http.StatusOK, c.Writer.Status())
|
assert.Equal(t, http.StatusOK, c.Writer.Status())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("should filter pipelines by events", func(t *testing.T) {
|
||||||
|
pipelines := []*model.Pipeline{fakePipeline}
|
||||||
|
mockStore := store_mocks.NewStore(t)
|
||||||
|
mockStore.On("GetPipelineList", mock.Anything, mock.Anything, mock.Anything).Return(pipelines, nil)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
c, _ := gin.CreateTestContext(w)
|
||||||
|
c.Set("store", mockStore)
|
||||||
|
c.Request, _ = http.NewRequest(http.MethodGet, "/?event=push,pull_request", nil)
|
||||||
|
|
||||||
|
GetPipelines(c)
|
||||||
|
|
||||||
|
mockStore.AssertCalled(t, "GetPipelineList", mock.Anything, mock.Anything, &model.PipelineFilter{
|
||||||
|
Events: model.WebhookEventList{model.EventPush, model.EventPull},
|
||||||
|
})
|
||||||
|
assert.Equal(t, http.StatusOK, c.Writer.Status())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeletePipeline(t *testing.T) {
|
func TestDeletePipeline(t *testing.T) {
|
||||||
|
@ -66,6 +66,17 @@ const (
|
|||||||
StatusCreated StatusValue = "created" // created / internal use only
|
StatusCreated StatusValue = "created" // created / internal use only
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrInvalidStatusValue = errors.New("invalid status value")
|
||||||
|
|
||||||
|
func (s StatusValue) Validate() error {
|
||||||
|
switch s {
|
||||||
|
case StatusSkipped, StatusPending, StatusRunning, StatusSuccess, StatusFailure, StatusKilled, StatusError, StatusBlocked, StatusDeclined, StatusCreated:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("%w: %s", ErrInvalidStatusValue, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SCMKind represent different version control systems.
|
// SCMKind represent different version control systems.
|
||||||
type SCMKind string // @name SCMKind
|
type SCMKind string // @name SCMKind
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ type PipelineFilter struct {
|
|||||||
Branch string
|
Branch string
|
||||||
Events []WebhookEvent
|
Events []WebhookEvent
|
||||||
RefContains string
|
RefContains string
|
||||||
|
Status StatusValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMultiPipeline checks if step list contain more than one parent step.
|
// IsMultiPipeline checks if step list contain more than one parent step.
|
||||||
|
@ -43,20 +43,15 @@ func TestMetadataFromStruct(t *testing.T) {
|
|||||||
name: "Test with empty info",
|
name: "Test with empty info",
|
||||||
expectedMetadata: metadata.Metadata{Sys: metadata.System{Name: "woodpecker"}},
|
expectedMetadata: metadata.Metadata{Sys: metadata.System{Name: "woodpecker"}},
|
||||||
expectedEnviron: map[string]string{
|
expectedEnviron: map[string]string{
|
||||||
"CI": "woodpecker",
|
"CI": "woodpecker",
|
||||||
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
|
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
|
||||||
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
|
"CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "/repos/0/pipeline/0",
|
||||||
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_FORGE_TYPE": "", "CI_FORGE_URL": "",
|
"CI_PREV_PIPELINE_CREATED": "0",
|
||||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
|
"CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
|
||||||
"CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PIPELINE_FORGE_URL": "",
|
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_URL": "/repos/0/pipeline/0",
|
||||||
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "", "CI_PREV_COMMIT_SOURCE_BRANCH": "", "CI_PREV_COMMIT_TARGET_BRANCH": "",
|
"CI_REPO_PRIVATE": "false", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_TRUSTED_VOLUMES": "false",
|
||||||
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
|
"CI_STEP_NUMBER": "0", "CI_STEP_URL": "/repos/0/pipeline/0", "CI_SYSTEM_NAME": "woodpecker",
|
||||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
|
"CI_WORKFLOW_NUMBER": "0",
|
||||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "", "CI_REPO_CLONE_URL": "", "CI_REPO_CLONE_SSH_URL": "", "CI_REPO_DEFAULT_BRANCH": "", "CI_REPO_REMOTE_ID": "",
|
|
||||||
"CI_REPO_NAME": "", "CI_REPO_OWNER": "", "CI_REPO_PRIVATE": "false", "CI_REPO_SCM": "", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false",
|
|
||||||
"CI_REPO_TRUSTED_VOLUMES": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_URL": "",
|
|
||||||
"CI_STEP_NAME": "", "CI_STEP_NUMBER": "0", "CI_STEP_STARTED": "", "CI_STEP_URL": "/repos/0/pipeline/0", "CI_SYSTEM_HOST": "", "CI_SYSTEM_NAME": "woodpecker",
|
|
||||||
"CI_SYSTEM_PLATFORM": "", "CI_SYSTEM_URL": "", "CI_SYSTEM_VERSION": "", "CI_WORKFLOW_NAME": "", "CI_WORKFLOW_NUMBER": "0",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -79,22 +74,17 @@ func TestMetadataFromStruct(t *testing.T) {
|
|||||||
Workflow: metadata.Workflow{Name: "hello"},
|
Workflow: metadata.Workflow{Name: "hello"},
|
||||||
},
|
},
|
||||||
expectedEnviron: map[string]string{
|
expectedEnviron: map[string]string{
|
||||||
"CI": "woodpecker",
|
"CI": "woodpecker",
|
||||||
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
|
"CI_FORGE_TYPE": "gitea", "CI_FORGE_URL": "https://gitea.com",
|
||||||
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
|
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
|
||||||
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_FORGE_TYPE": "gitea", "CI_FORGE_URL": "https://gitea.com",
|
"CI_PIPELINE_NUMBER": "3", "CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "https://example.com/repos/0/pipeline/3",
|
||||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
|
"CI_PREV_PIPELINE_CREATED": "0",
|
||||||
"CI_PIPELINE_NUMBER": "3", "CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "https://example.com/repos/0/pipeline/3", "CI_PIPELINE_FORGE_URL": "",
|
"CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
|
||||||
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "", "CI_PREV_COMMIT_SOURCE_BRANCH": "", "CI_PREV_COMMIT_TARGET_BRANCH": "",
|
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_URL": "https://example.com/repos/0/pipeline/2", "CI_REPO": "testUser/testRepo", "CI_REPO_CLONE_URL": "https://gitea.com/testUser/testRepo.git", "CI_REPO_CLONE_SSH_URL": "git@gitea.com:testUser/testRepo.git",
|
||||||
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
|
"CI_REPO_DEFAULT_BRANCH": "main", "CI_REPO_NAME": "testRepo", "CI_REPO_OWNER": "testUser", "CI_REPO_PRIVATE": "true",
|
||||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
|
"CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_TRUSTED_VOLUMES": "false",
|
||||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "https://example.com/repos/0/pipeline/2", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "testUser/testRepo", "CI_REPO_CLONE_URL": "https://gitea.com/testUser/testRepo.git", "CI_REPO_CLONE_SSH_URL": "git@gitea.com:testUser/testRepo.git",
|
"CI_REPO_URL": "https://gitea.com/testUser/testRepo", "CI_STEP_NUMBER": "0", "CI_STEP_URL": "https://example.com/repos/0/pipeline/3", "CI_SYSTEM_HOST": "example.com",
|
||||||
"CI_REPO_DEFAULT_BRANCH": "main", "CI_REPO_NAME": "testRepo", "CI_REPO_OWNER": "testUser", "CI_REPO_PRIVATE": "true", "CI_REPO_REMOTE_ID": "",
|
"CI_SYSTEM_NAME": "woodpecker", "CI_SYSTEM_URL": "https://example.com", "CI_WORKFLOW_NAME": "hello", "CI_WORKFLOW_NUMBER": "0",
|
||||||
"CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false",
|
|
||||||
"CI_REPO_TRUSTED_VOLUMES": "false", "CI_REPO_TRUSTED_SECURITY": "false",
|
|
||||||
"CI_REPO_URL": "https://gitea.com/testUser/testRepo",
|
|
||||||
"CI_STEP_NAME": "", "CI_STEP_NUMBER": "0", "CI_STEP_STARTED": "", "CI_STEP_URL": "https://example.com/repos/0/pipeline/3", "CI_SYSTEM_HOST": "example.com",
|
|
||||||
"CI_SYSTEM_NAME": "woodpecker", "CI_SYSTEM_PLATFORM": "", "CI_SYSTEM_URL": "https://example.com", "CI_SYSTEM_VERSION": "", "CI_WORKFLOW_NAME": "hello", "CI_WORKFLOW_NUMBER": "0",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,10 @@ func (s storage) GetPipelineList(repo *model.Repo, p *model.ListOptions, f *mode
|
|||||||
cond = cond.And(builder.Eq{"branch": f.Branch})
|
cond = cond.And(builder.Eq{"branch": f.Branch})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.Status != "" {
|
||||||
|
cond = cond.And(builder.Eq{"status": f.Status})
|
||||||
|
}
|
||||||
|
|
||||||
if len(f.Events) != 0 {
|
if len(f.Events) != 0 {
|
||||||
cond = cond.And(builder.In("event", f.Events))
|
cond = cond.And(builder.In("event", f.Events))
|
||||||
}
|
}
|
||||||
|
@ -277,6 +277,35 @@ func TestPipelines(t *testing.T) {
|
|||||||
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
||||||
g.Assert(pipelines[0].RepoID).Equal(pipeline1.RepoID)
|
g.Assert(pipelines[0].RepoID).Equal(pipeline1.RepoID)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
g.It("Should get pipelines filtered by status", func() {
|
||||||
|
pipeline1 := &model.Pipeline{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Status: model.StatusSuccess,
|
||||||
|
}
|
||||||
|
pipeline2 := &model.Pipeline{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Status: model.StatusFailure,
|
||||||
|
}
|
||||||
|
pipeline3 := &model.Pipeline{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Status: model.StatusRunning,
|
||||||
|
}
|
||||||
|
err1 := store.CreatePipeline(pipeline1, []*model.Step{}...)
|
||||||
|
g.Assert(err1).IsNil()
|
||||||
|
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
|
||||||
|
g.Assert(err2).IsNil()
|
||||||
|
err3 := store.CreatePipeline(pipeline3, []*model.Step{}...)
|
||||||
|
g.Assert(err3).IsNil()
|
||||||
|
|
||||||
|
pipelines, err := store.GetPipelineList(&model.Repo{ID: 1}, nil, &model.PipelineFilter{
|
||||||
|
Status: model.StatusSuccess,
|
||||||
|
})
|
||||||
|
g.Assert(err).IsNil()
|
||||||
|
g.Assert(len(pipelines)).Equal(1)
|
||||||
|
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
||||||
|
g.Assert(pipelines[0].Status).Equal(model.StatusSuccess)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
web/.gitignore
vendored
1
web/.gitignore
vendored
@ -3,4 +3,3 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
src/assets/dayjsLocales
|
|
||||||
|
@ -4,5 +4,4 @@ coverage/
|
|||||||
LICENSE
|
LICENSE
|
||||||
components.d.ts
|
components.d.ts
|
||||||
src/assets/locales/*.json
|
src/assets/locales/*.json
|
||||||
src/assets/dayjsLocales/
|
|
||||||
!src/assets/locales/en.json
|
!src/assets/locales/en.json
|
||||||
|
@ -106,7 +106,6 @@ export default antfu(
|
|||||||
'tsconfig.json',
|
'tsconfig.json',
|
||||||
'src/assets/locales/**/*',
|
'src/assets/locales/**/*',
|
||||||
'!src/assets/locales/en.json',
|
'!src/assets/locales/en.json',
|
||||||
'src/assets/dayjsLocales/',
|
|
||||||
'components.d.ts',
|
'components.d.ts',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
"@mdi/js": "^7.4.47",
|
"@mdi/js": "^7.4.47",
|
||||||
"@vueuse/core": "^12.0.0",
|
"@vueuse/core": "^12.0.0",
|
||||||
"ansi_up": "^6.0.2",
|
"ansi_up": "^6.0.2",
|
||||||
"dayjs": "^1.11.12",
|
|
||||||
"dompurify": "^3.2.0",
|
"dompurify": "^3.2.0",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
@ -57,10 +56,9 @@
|
|||||||
"eslint-plugin-vue-scoped-css": "^2.8.1",
|
"eslint-plugin-vue-scoped-css": "^2.8.1",
|
||||||
"jsdom": "^25.0.0",
|
"jsdom": "^25.0.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"replace-in-file": "^8.1.0",
|
|
||||||
"tinycolor2": "^1.6.0",
|
"tinycolor2": "^1.6.0",
|
||||||
"typescript": "5.6.3",
|
"typescript": "5.6.3",
|
||||||
"vite": "^5.4.1",
|
"vite": "^6.0.0",
|
||||||
"vite-plugin-prismjs": "^0.0.11",
|
"vite-plugin-prismjs": "^0.0.11",
|
||||||
"vite-plugin-windicss": "^1.9.3",
|
"vite-plugin-windicss": "^1.9.3",
|
||||||
"vite-svg-loader": "^5.1.0",
|
"vite-svg-loader": "^5.1.0",
|
||||||
|
1280
web/pnpm-lock.yaml
generated
1280
web/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
|||||||
"delete_agent": "Odstranit agent",
|
"delete_agent": "Odstranit agent",
|
||||||
"delete_confirm": "Opravdu chcete tohoto agenta odstranit? Už se nebude moci připojit k serveru.",
|
"delete_confirm": "Opravdu chcete tohoto agenta odstranit? Už se nebude moci připojit k serveru.",
|
||||||
"deleted": "Agent smazán",
|
"deleted": "Agent smazán",
|
||||||
"desc": "Agenti registrovaní pro tento server",
|
"desc": "Agenti registrovaní na tomto serveru.",
|
||||||
"edit_agent": "Upravit agent",
|
"edit_agent": "Upravit agent",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"last_contact": "Poslední kontakt",
|
"last_contact": "Poslední kontakt",
|
||||||
@ -41,12 +41,12 @@
|
|||||||
"token": "Tokeny",
|
"token": "Tokeny",
|
||||||
"version": "Verze"
|
"version": "Verze"
|
||||||
},
|
},
|
||||||
"not_allowed": "Nemáte povolen přístup k nastavení serveru",
|
"not_allowed": "K nastavení serveru nemáte přístup.",
|
||||||
"orgs": {
|
"orgs": {
|
||||||
"delete_confirm": "Opravdu chcete tuto organizaci smazat? Tím se odstraní také všechna úložiště vlastněná touto organizací.",
|
"delete_confirm": "Opravdu chcete tuto organizaci smazat? Tím se odstraní také všechna úložiště vlastněná touto organizací.",
|
||||||
"delete_org": "Odstranit organizaci",
|
"delete_org": "Odstranit organizaci",
|
||||||
"deleted": "Organizace vymazána",
|
"deleted": "Organizace vymazána",
|
||||||
"desc": "Organizace vlastnící úložiště na tomto serveru",
|
"desc": "Organizace vlastnící repozitáře na tomto serveru.",
|
||||||
"none": "Zatím neexistují žádné organizace.",
|
"none": "Zatím neexistují žádné organizace.",
|
||||||
"org_settings": "Organizační nastavení",
|
"org_settings": "Organizační nastavení",
|
||||||
"orgs": "Organizace",
|
"orgs": "Organizace",
|
||||||
@ -74,7 +74,7 @@
|
|||||||
"waiting_for": "čekání na"
|
"waiting_for": "čekání na"
|
||||||
},
|
},
|
||||||
"repos": {
|
"repos": {
|
||||||
"desc": "Úložiště, která jsou nebo byla na tomto serveru povolena",
|
"desc": "Repozitáře, které jsou nebo byly na tomto serveru povoleny.",
|
||||||
"disabled": "Bezbariérový",
|
"disabled": "Bezbariérový",
|
||||||
"none": "Zatím neexistují žádná úložiště.",
|
"none": "Zatím neexistují žádná úložiště.",
|
||||||
"repos": "Repozitáře",
|
"repos": "Repozitáře",
|
||||||
@ -198,7 +198,7 @@
|
|||||||
"success": "Repozitář povoleno"
|
"success": "Repozitář povoleno"
|
||||||
},
|
},
|
||||||
"manual_pipeline": {
|
"manual_pipeline": {
|
||||||
"select_branch": "Vyberte pobočku",
|
"select_branch": "Vyberte větev",
|
||||||
"title": "Spuštění ručního spuštění potrubí",
|
"title": "Spuštění ručního spuštění potrubí",
|
||||||
"trigger": "Spustit potrubí",
|
"trigger": "Spustit potrubí",
|
||||||
"variables": {
|
"variables": {
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
"not_found": "Server could not find requested object"
|
"not_found": "Server could not find requested object"
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"template": "MMM D, YYYY, HH:mm z",
|
"not_started": "not started yet",
|
||||||
"not_started": "not started yet"
|
"just_now": "just now"
|
||||||
},
|
},
|
||||||
"repo": {
|
"repo": {
|
||||||
"manual_pipeline": {
|
"manual_pipeline": {
|
||||||
|
@ -193,8 +193,8 @@
|
|||||||
"add": "Ajouter un dépôt",
|
"add": "Ajouter un dépôt",
|
||||||
"branches": "Branches",
|
"branches": "Branches",
|
||||||
"deploy_pipeline": {
|
"deploy_pipeline": {
|
||||||
"enter_target": "Environnement de déploiement ciblé",
|
"enter_target": "Environnement de 'déploiement' ciblé",
|
||||||
"title": "Déclenchement d'un événement de déploiement pour le pipeline courant #{pipelineId}",
|
"title": "Déclenchement d'un événement de 'déploiement' pour le pipeline courant #{pipelineId}",
|
||||||
"trigger": "Déployer",
|
"trigger": "Déployer",
|
||||||
"variables": {
|
"variables": {
|
||||||
"add": "Ajouter une variable",
|
"add": "Ajouter une variable",
|
||||||
@ -365,7 +365,7 @@
|
|||||||
"general": {
|
"general": {
|
||||||
"allow_pr": {
|
"allow_pr": {
|
||||||
"allow": "Autoriser les demandes de fusions",
|
"allow": "Autoriser les demandes de fusions",
|
||||||
"desc": "Les pipelines peuvent se déclencher sur les pull requests."
|
"desc": "Permettre aux pipelines de se déclencher sur les pull requests."
|
||||||
},
|
},
|
||||||
"cancel_prev": {
|
"cancel_prev": {
|
||||||
"cancel": "Annuler les pipelines précédents",
|
"cancel": "Annuler les pipelines précédents",
|
||||||
@ -373,8 +373,8 @@
|
|||||||
},
|
},
|
||||||
"general": "Général",
|
"general": "Général",
|
||||||
"netrc_only_trusted": {
|
"netrc_only_trusted": {
|
||||||
"desc": "Injecter les identifiants netrc uniquement dans des conteneurs de confiance (recommandé).",
|
"desc": "Les plugins listés ici auront accès aux identifiants netrc qui peuvent être utiliser pour cloner des dépôts depuis la forge, ou pour pousser vers celle-ci.",
|
||||||
"netrc_only_trusted": "Injecter les identifiants netrc uniquement dans des conteneurs de confiance"
|
"netrc_only_trusted": "Plugins de clonage personnalisés de confiance"
|
||||||
},
|
},
|
||||||
"pipeline_path": {
|
"pipeline_path": {
|
||||||
"default": "Par défaut : .woodpecker/*.{'{yaml,yml}'} -> .woodpecker.yaml -> .woodpecker.yml",
|
"default": "Par défaut : .woodpecker/*.{'{yaml,yml}'} -> .woodpecker.yaml -> .woodpecker.yml",
|
||||||
@ -388,14 +388,23 @@
|
|||||||
"protected": "Protégé"
|
"protected": "Protégé"
|
||||||
},
|
},
|
||||||
"save": "Enregistrer les paramètres",
|
"save": "Enregistrer les paramètres",
|
||||||
"success": "Paramètres du dépôt mis à jour",
|
"success": "Paramètres du projet mis à jour",
|
||||||
"timeout": {
|
"timeout": {
|
||||||
"minutes": "minutes",
|
"minutes": "minutes",
|
||||||
"timeout": "Délai d’inactivité"
|
"timeout": "Délai d’inactivité"
|
||||||
},
|
},
|
||||||
"trusted": {
|
"trusted": {
|
||||||
"desc": "Les conteneurs du pipeline ont accès à des capacités privilégiées (comme le montage de volumes).",
|
"desc": "Les conteneurs du pipeline ont accès à des capacités privilégiées (comme le montage de volumes).",
|
||||||
"trusted": "Vérifié"
|
"trusted": "Vérifié",
|
||||||
|
"network": {
|
||||||
|
"network": "Réseau"
|
||||||
|
},
|
||||||
|
"volumes": {
|
||||||
|
"volumes": "Volumes"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"security": "Sécurité"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"internal": {
|
"internal": {
|
||||||
@ -413,8 +422,8 @@
|
|||||||
"visibility": "Visibilité du projet"
|
"visibility": "Visibilité du projet"
|
||||||
},
|
},
|
||||||
"allow_deploy": {
|
"allow_deploy": {
|
||||||
"allow": "Autoriser les déploiements",
|
"allow": "Autoriser les événements de 'déploiement'.",
|
||||||
"desc": "Autoriser les déploiements depuis les pipelines ayant réussis. À utiliser que si vous avez confiance dans les utilisateurs ayant un accès en écriture."
|
"desc": "Permettre les déploiements depuis les pipelines ayant réussis. À utiliser que si vous avez confiance dans les utilisateurs ayant un accès en écriture."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"not_allowed": "Vous n'êtes pas autorisé à accéder aux paramètres de ce dépôt",
|
"not_allowed": "Vous n'êtes pas autorisé à accéder aux paramètres de ce dépôt",
|
||||||
@ -463,7 +472,22 @@
|
|||||||
},
|
},
|
||||||
"settings": "Paramètres"
|
"settings": "Paramètres"
|
||||||
},
|
},
|
||||||
"user_none": "Cet(te) organisation / utilisateur n'a pas encore de projets."
|
"user_none": "Cet(te) organisation / utilisateur n'a pas encore de projets.",
|
||||||
|
"visibility": {
|
||||||
|
"visibility": "Visibilité du projet",
|
||||||
|
"public": {
|
||||||
|
"public": "Publique",
|
||||||
|
"desc": "Tout le monde peut voir le projet sans être connecté."
|
||||||
|
},
|
||||||
|
"private": {
|
||||||
|
"private": "Privé",
|
||||||
|
"desc": "Seul vous et les propriétaires de ce dépôt peuvent le voir."
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"internal": "Interne",
|
||||||
|
"desc": "Seuls les comptes identifiés sur cet instance de Woodpecker peuvent voir ce projet."
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"repos": "Dépôt",
|
"repos": "Dépôt",
|
||||||
"repositories": "Dépôts",
|
"repositories": "Dépôts",
|
||||||
@ -476,7 +500,8 @@
|
|||||||
"not_started": "pas encore démarré",
|
"not_started": "pas encore démarré",
|
||||||
"sec_short": "sec",
|
"sec_short": "sec",
|
||||||
"template": "D MMM, YYYY, HH:mm z",
|
"template": "D MMM, YYYY, HH:mm z",
|
||||||
"weeks_short": "s"
|
"weeks_short": "s",
|
||||||
|
"just_now": "il y a peu de temps"
|
||||||
},
|
},
|
||||||
"unknown_error": "Une erreur inconnue est survenue",
|
"unknown_error": "Une erreur inconnue est survenue",
|
||||||
"update_woodpecker": "Merci de mettre à jour votre instance Woodpecker vers la version {0}",
|
"update_woodpecker": "Merci de mettre à jour votre instance Woodpecker vers la version {0}",
|
||||||
|
@ -1 +1,67 @@
|
|||||||
{}
|
{
|
||||||
|
"back": "Vissza",
|
||||||
|
"logout": "Kijelentkezés",
|
||||||
|
"search": "Keresés…",
|
||||||
|
"username": "Felhasználónév",
|
||||||
|
"unknown_error": "Ismeretlen hiba történt",
|
||||||
|
"password": "Jelszó",
|
||||||
|
"repo": {
|
||||||
|
"visibility": {
|
||||||
|
"public": {
|
||||||
|
"public": "Nyilvános"
|
||||||
|
},
|
||||||
|
"private": {
|
||||||
|
"private": "Privát",
|
||||||
|
"desc": "Csak te és a többi tulajdonos láthatjátok ezt a projektet a tárolóban."
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"internal": "Belső"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"general": {
|
||||||
|
"timeout": {
|
||||||
|
"minutes": "percek"
|
||||||
|
},
|
||||||
|
"save": "Beállítások mentése",
|
||||||
|
"project": "Projekt beállítások",
|
||||||
|
"success": "Projekt beállítások frissítve"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"disable": {
|
||||||
|
"disable": "Tároló inaktiválása"
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"delete": "Tároló törlése"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pipeline": {
|
||||||
|
"loading": "Betöltés…"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"settings": {
|
||||||
|
"users": {
|
||||||
|
"show": "Mutasd a felhasználokat",
|
||||||
|
"cancel": "Mégse",
|
||||||
|
"save": "Felhasználó mentése",
|
||||||
|
"add": "Felhasználó hozzáadása",
|
||||||
|
"deleted": "Felhasználó törölve",
|
||||||
|
"created": "Felhasználó létrehozva",
|
||||||
|
"saved": "Felhasználó mentve",
|
||||||
|
"delete_user": "Felhasználó törlése",
|
||||||
|
"edit_user": "Felhasználó szerkesztése"
|
||||||
|
},
|
||||||
|
"orgs": {
|
||||||
|
"orgs": "Szervezetek",
|
||||||
|
"delete_org": "Szervezet törlése"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cancel": "Mégse",
|
||||||
|
"login": "Bejelentkezés",
|
||||||
|
"internal_error": "Valamilyen belső hiba történt",
|
||||||
|
"info": "Információ",
|
||||||
|
"registration_closed": "A regisztráció zárva"
|
||||||
|
}
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="text-xs font-medium inline-flex">
|
<span class="text-xs font-medium inline-flex">
|
||||||
<span
|
<span
|
||||||
class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full"
|
class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full flex items-center"
|
||||||
:class="{
|
:class="{
|
||||||
'rounded-r-full pr-2': value === undefined,
|
'rounded-r-full pr-2': value === undefined,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="value !== undefined" class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full">
|
<span
|
||||||
|
v-if="value !== undefined"
|
||||||
|
class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full flex items-center"
|
||||||
|
>
|
||||||
{{ value }}
|
{{ value }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<Panel>
|
<Panel>
|
||||||
<div class="flex flex-col border-b mb-4 pb-4 justify-center dark:border-wp-background-100">
|
<div class="flex flex-col border-b mb-4 pb-4 justify-center dark:border-wp-background-100">
|
||||||
<h1 class="text-xl text-wp-text-100 flex items-center gap-1">
|
<div class="flex items-center justify-between">
|
||||||
{{ title }}
|
<h1 class="text-xl text-wp-text-100 flex items-center gap-1">
|
||||||
<DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" />
|
{{ title }}
|
||||||
</h1>
|
<DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" />
|
||||||
|
</h1>
|
||||||
|
<slot v-if="$slots.titleActions" name="titleActions" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-x-4 gap-y-2 items-center justify-between">
|
<div class="flex flex-wrap gap-x-4 gap-y-2 items-center justify-between">
|
||||||
<p v-if="description" class="text-sm text-wp-text-alt-100">{{ description }}</p>
|
<p v-if="description" class="text-sm text-wp-text-alt-100">{{ description }}</p>
|
||||||
|
@ -1,44 +1,94 @@
|
|||||||
import dayjs from 'dayjs';
|
|
||||||
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|
||||||
import duration from 'dayjs/plugin/duration';
|
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
||||||
import timezone from 'dayjs/plugin/timezone';
|
|
||||||
import utc from 'dayjs/plugin/utc';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
dayjs.extend(timezone);
|
let currentLocale = 'en';
|
||||||
dayjs.extend(utc);
|
|
||||||
dayjs.extend(advancedFormat);
|
|
||||||
dayjs.extend(relativeTime);
|
|
||||||
dayjs.extend(duration);
|
|
||||||
|
|
||||||
function toLocaleString(date: Date) {
|
function splitDuration(durationMs: number) {
|
||||||
return dayjs(date).format(useI18n().t('time.template'));
|
const totalSeconds = durationMs / 1000;
|
||||||
|
const totalMinutes = totalSeconds / 60;
|
||||||
|
const totalHours = totalMinutes / 60;
|
||||||
|
|
||||||
|
const seconds = Math.floor(totalSeconds) % 60;
|
||||||
|
const minutes = Math.floor(totalMinutes) % 60;
|
||||||
|
const hours = Math.floor(totalHours) % 24;
|
||||||
|
|
||||||
|
return {
|
||||||
|
seconds,
|
||||||
|
minutes,
|
||||||
|
hours,
|
||||||
|
totalHours,
|
||||||
|
totalMinutes,
|
||||||
|
totalSeconds,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function timeAgo(date: Date | string | number) {
|
function toLocaleString(date: Date) {
|
||||||
return dayjs().to(dayjs(date));
|
return date.toLocaleString(currentLocale, {
|
||||||
|
dateStyle: 'short',
|
||||||
|
timeStyle: 'short',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeAgo(date: number) {
|
||||||
|
const seconds = Math.floor((new Date().getTime() - date) / 1000);
|
||||||
|
|
||||||
|
const formatter = new Intl.RelativeTimeFormat(currentLocale);
|
||||||
|
|
||||||
|
let interval = seconds / 31536000;
|
||||||
|
if (interval > 1) {
|
||||||
|
return formatter.format(-Math.round(interval), 'year');
|
||||||
|
}
|
||||||
|
interval = seconds / 2592000;
|
||||||
|
if (interval > 1) {
|
||||||
|
return formatter.format(-Math.round(interval), 'month');
|
||||||
|
}
|
||||||
|
interval = seconds / 86400;
|
||||||
|
if (interval > 1) {
|
||||||
|
return formatter.format(-Math.round(interval), 'day');
|
||||||
|
}
|
||||||
|
interval = seconds / 3600;
|
||||||
|
if (interval > 1) {
|
||||||
|
return formatter.format(-Math.round(interval), 'hour');
|
||||||
|
}
|
||||||
|
interval = seconds / 60;
|
||||||
|
if (interval > 0.5) {
|
||||||
|
return formatter.format(-Math.round(interval), 'minute');
|
||||||
|
}
|
||||||
|
return useI18n().t('time.just_now');
|
||||||
}
|
}
|
||||||
|
|
||||||
function prettyDuration(durationMs: number) {
|
function prettyDuration(durationMs: number) {
|
||||||
return dayjs.duration(durationMs).humanize();
|
const t = splitDuration(durationMs);
|
||||||
|
|
||||||
|
if (t.totalHours > 1) {
|
||||||
|
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'hour', unitDisplay: 'long' }).format(
|
||||||
|
Math.round(t.totalHours),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (t.totalMinutes > 1) {
|
||||||
|
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'minute', unitDisplay: 'long' }).format(
|
||||||
|
Math.round(t.totalMinutes),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Intl.NumberFormat(currentLocale, { style: 'unit', unit: 'second', unitDisplay: 'long' }).format(
|
||||||
|
Math.round(t.totalSeconds),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function durationAsNumber(durationMs: number): string {
|
function durationAsNumber(durationMs: number): string {
|
||||||
const dur = dayjs.duration(durationMs);
|
const { seconds, minutes, hours } = splitDuration(durationMs);
|
||||||
return dur.format(dur.hours() > 1 ? 'HH:mm:ss' : 'mm:ss');
|
|
||||||
|
const minSecFormat = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours.toString().padStart(2, '0')}:${minSecFormat}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return minSecFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useDate() {
|
export function useDate() {
|
||||||
const addedLocales = ['en'];
|
|
||||||
|
|
||||||
async function setDayjsLocale(locale: string) {
|
async function setDayjsLocale(locale: string) {
|
||||||
if (!addedLocales.includes(locale)) {
|
currentLocale = locale;
|
||||||
const l = (await import(`~/assets/dayjsLocales/${locale}.js`)) as { default: string };
|
|
||||||
dayjs.locale(l.default);
|
|
||||||
} else {
|
|
||||||
dayjs.locale(locale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
<Scaffold v-if="org" enable-tabs :go-back="goBack">
|
<Scaffold v-if="org" enable-tabs :go-back="goBack">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span>
|
<span>
|
||||||
<router-link :to="{ name: 'org' }" class="hover:underline">
|
<router-link :to="{ name: 'org' }" class="hover:underline">{{
|
||||||
{{ org.name }}
|
org.name
|
||||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
|
/* eslint-disable-next-line @intlify/vue-i18n/no-raw-text */
|
||||||
</router-link>
|
}}</router-link>
|
||||||
/
|
/
|
||||||
{{ $t('settings') }}
|
{{ $t('settings') }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<Settings :title="$t('repo.settings.badge.badge')">
|
<Settings :title="$t('repo.settings.badge.badge')">
|
||||||
<template #headerActions>
|
<template #titleActions>
|
||||||
<a v-if="badgeUrl" :href="badgeUrl" target="_blank">
|
<a v-if="badgeUrl" :href="badgeUrl" target="_blank">
|
||||||
<img :src="badgeUrl" />
|
<img :src="badgeUrl" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</InputField>
|
</InputField>
|
||||||
|
|
||||||
<InputField :label="$t('user.settings.cli_and_api.token')">
|
<InputField :label="$t('user.settings.cli_and_api.token')">
|
||||||
<template #headerActions>
|
<template #titleActions>
|
||||||
<Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" />
|
<Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" />
|
||||||
</template>
|
</template>
|
||||||
<pre class="code-box">{{ token }}</pre>
|
<pre class="code-box">{{ token }}</pre>
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { copyFile, existsSync, mkdirSync, readdirSync } from 'node:fs';
|
import { readdirSync } from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import { replaceInFileSync } from 'replace-in-file';
|
|
||||||
import type { Plugin } from 'vite';
|
import type { Plugin } from 'vite';
|
||||||
import prismjs from 'vite-plugin-prismjs';
|
import prismjs from 'vite-plugin-prismjs';
|
||||||
import WindiCSS from 'vite-plugin-windicss';
|
import WindiCSS from 'vite-plugin-windicss';
|
||||||
@ -54,44 +53,6 @@ export default defineConfig({
|
|||||||
|
|
||||||
const filenames = readdirSync('src/assets/locales/').map((filename) => filename.replace('.json', ''));
|
const filenames = readdirSync('src/assets/locales/').map((filename) => filename.replace('.json', ''));
|
||||||
|
|
||||||
if (!existsSync('src/assets/dayjsLocales')) {
|
|
||||||
mkdirSync('src/assets/dayjsLocales');
|
|
||||||
}
|
|
||||||
|
|
||||||
filenames.forEach((name) => {
|
|
||||||
// English is always directly loaded (compiled by Vite) and thus not copied
|
|
||||||
if (name === 'en') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let langName = name;
|
|
||||||
|
|
||||||
// copy dayjs language
|
|
||||||
if (name === 'zh-Hans') {
|
|
||||||
// zh-Hans is called zh in dayjs
|
|
||||||
langName = 'zh';
|
|
||||||
} else if (name === 'zh-Hant') {
|
|
||||||
// zh-Hant is called zh-cn in dayjs
|
|
||||||
langName = 'zh-cn';
|
|
||||||
}
|
|
||||||
|
|
||||||
copyFile(
|
|
||||||
`node_modules/dayjs/esm/locale/${langName}.js`,
|
|
||||||
`src/assets/dayjsLocales/${name}.js`,
|
|
||||||
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
||||||
(err) => {
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
replaceInFileSync({
|
|
||||||
files: 'src/assets/dayjsLocales/*.js',
|
|
||||||
// remove any dayjs import and any dayjs.locale call
|
|
||||||
from: /(?:import dayjs.*'|dayjs\.locale.*);/g,
|
|
||||||
to: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'vue-i18n-supported-locales',
|
name: 'vue-i18n-supported-locales',
|
||||||
|
|
||||||
|
@ -84,6 +84,8 @@ type Client interface {
|
|||||||
// the specified repository.
|
// the specified repository.
|
||||||
PipelineList(repoID int64, opt PipelineListOptions) ([]*Pipeline, error)
|
PipelineList(repoID int64, opt PipelineListOptions) ([]*Pipeline, error)
|
||||||
|
|
||||||
|
PipelineDelete(repoID, pipeline int64) error
|
||||||
|
|
||||||
// PipelineQueue returns a list of enqueued pipelines.
|
// PipelineQueue returns a list of enqueued pipelines.
|
||||||
PipelineQueue() ([]*Feed, error)
|
PipelineQueue() ([]*Feed, error)
|
||||||
|
|
||||||
@ -102,9 +104,6 @@ type Client interface {
|
|||||||
// PipelineDecline declines a blocked pipeline.
|
// PipelineDecline declines a blocked pipeline.
|
||||||
PipelineDecline(repoID, pipeline int64) (*Pipeline, error)
|
PipelineDecline(repoID, pipeline int64) (*Pipeline, error)
|
||||||
|
|
||||||
// PipelineKill force kills the running pipeline.
|
|
||||||
PipelineKill(repoID, pipeline int64) error
|
|
||||||
|
|
||||||
// PipelineMetadata returns metadata for a pipeline.
|
// PipelineMetadata returns metadata for a pipeline.
|
||||||
PipelineMetadata(repoID int64, pipelineNumber int) ([]byte, error)
|
PipelineMetadata(repoID int64, pipelineNumber int) ([]byte, error)
|
||||||
|
|
||||||
|
@ -1133,12 +1133,12 @@ func (_m *Client) PipelineDecline(repoID int64, pipeline int64) (*woodpecker.Pip
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipelineKill provides a mock function with given fields: repoID, pipeline
|
// PipelineDelete provides a mock function with given fields: repoID, pipeline
|
||||||
func (_m *Client) PipelineKill(repoID int64, pipeline int64) error {
|
func (_m *Client) PipelineDelete(repoID int64, pipeline int64) error {
|
||||||
ret := _m.Called(repoID, pipeline)
|
ret := _m.Called(repoID, pipeline)
|
||||||
|
|
||||||
if len(ret) == 0 {
|
if len(ret) == 0 {
|
||||||
panic("no return value specified for PipelineKill")
|
panic("no return value specified for PipelineDelete")
|
||||||
}
|
}
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,8 +32,12 @@ const (
|
|||||||
|
|
||||||
type PipelineListOptions struct {
|
type PipelineListOptions struct {
|
||||||
ListOptions
|
ListOptions
|
||||||
Before time.Time
|
Before time.Time
|
||||||
After time.Time
|
After time.Time
|
||||||
|
Branch string
|
||||||
|
Events []string
|
||||||
|
RefContains string
|
||||||
|
Status string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronListOptions struct {
|
type CronListOptions struct {
|
||||||
@ -77,6 +82,18 @@ func (opt *PipelineListOptions) QueryEncode() string {
|
|||||||
if !opt.After.IsZero() {
|
if !opt.After.IsZero() {
|
||||||
query.Add("after", opt.After.Format(time.RFC3339))
|
query.Add("after", opt.After.Format(time.RFC3339))
|
||||||
}
|
}
|
||||||
|
if opt.Branch != "" {
|
||||||
|
query.Add("branch", opt.Branch)
|
||||||
|
}
|
||||||
|
if len(opt.Events) > 0 {
|
||||||
|
query.Add("event", strings.Join(opt.Events, ","))
|
||||||
|
}
|
||||||
|
if opt.RefContains != "" {
|
||||||
|
query.Add("ref", opt.RefContains)
|
||||||
|
}
|
||||||
|
if opt.Status != "" {
|
||||||
|
query.Add("status", opt.Status)
|
||||||
|
}
|
||||||
return query.Encode()
|
return query.Encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +338,13 @@ func (c *client) PipelineList(repoID int64, opt PipelineListOptions) ([]*Pipelin
|
|||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PipelineDelete deletes a pipeline by the specified repository ID and pipeline ID.
|
||||||
|
func (c *client) PipelineDelete(repoID, pipeline int64) error {
|
||||||
|
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
||||||
|
err := c.delete(uri)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// PipelineCreate creates a new pipeline for the specified repository.
|
// PipelineCreate creates a new pipeline for the specified repository.
|
||||||
func (c *client) PipelineCreate(repoID int64, options *PipelineOptions) (*Pipeline, error) {
|
func (c *client) PipelineCreate(repoID int64, options *PipelineOptions) (*Pipeline, error) {
|
||||||
var out *Pipeline
|
var out *Pipeline
|
||||||
@ -361,13 +385,6 @@ func (c *client) PipelineDecline(repoID, pipeline int64) (*Pipeline, error) {
|
|||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipelineKill force kills the running pipeline.
|
|
||||||
func (c *client) PipelineKill(repoID, pipeline int64) error {
|
|
||||||
uri := fmt.Sprintf(pathPipeline, c.addr, repoID, pipeline)
|
|
||||||
err := c.delete(uri)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogsPurge purges the pipeline all steps logs for the specified pipeline.
|
// LogsPurge purges the pipeline all steps logs for the specified pipeline.
|
||||||
func (c *client) LogsPurge(repoID, pipeline int64) error {
|
func (c *client) LogsPurge(repoID, pipeline int64) error {
|
||||||
uri := fmt.Sprintf(pathPipelineLogs, c.addr, repoID, pipeline)
|
uri := fmt.Sprintf(pathPipelineLogs, c.addr, repoID, pipeline)
|
||||||
|
Loading…
Reference in New Issue
Block a user