mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-25 11:21:02 +00:00
Merge branch 'main' into git-only
This commit is contained in:
commit
9ad32b6941
61 changed files with 755 additions and 518 deletions
|
@ -65,6 +65,7 @@ Visibility: {{ .Visibility }}
|
|||
Private: {{ .IsSCMPrivate }}
|
||||
Trusted: {{ .IsTrusted }}
|
||||
Gated: {{ .IsGated }}
|
||||
Require approval for: {{ .RequireApproval }}
|
||||
Clone url: {{ .Clone }}
|
||||
Allow pull-requests: {{ .AllowPullRequests }}
|
||||
`
|
||||
|
|
|
@ -39,6 +39,10 @@ var repoUpdateCmd = &cli.Command{
|
|||
Name: "gated",
|
||||
Usage: "repository is gated",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "require-approval",
|
||||
Usage: "repository requires approval for",
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "timeout",
|
||||
Usage: "repository timeout",
|
||||
|
@ -79,6 +83,7 @@ func repoUpdate(ctx context.Context, c *cli.Command) error {
|
|||
timeout = c.Duration("timeout")
|
||||
trusted = c.Bool("trusted")
|
||||
gated = c.Bool("gated")
|
||||
requireApproval = c.String("require-approval")
|
||||
pipelineCounter = int(c.Int("pipeline-counter"))
|
||||
unsafe = c.Bool("unsafe")
|
||||
)
|
||||
|
@ -87,8 +92,29 @@ func repoUpdate(ctx context.Context, c *cli.Command) error {
|
|||
if c.IsSet("trusted") {
|
||||
patch.IsTrusted = &trusted
|
||||
}
|
||||
// TODO: remove isGated in next major release
|
||||
if c.IsSet("gated") {
|
||||
patch.IsGated = &gated
|
||||
if gated {
|
||||
patch.RequireApproval = &woodpecker.RequireApprovalAllEvents
|
||||
} else {
|
||||
patch.RequireApproval = &woodpecker.RequireApprovalNone
|
||||
}
|
||||
}
|
||||
if c.IsSet("require-approval") {
|
||||
if mode := woodpecker.ApprovalMode(requireApproval); mode.Valid() {
|
||||
patch.RequireApproval = &mode
|
||||
} else {
|
||||
return fmt.Errorf("update approval mode failed: '%s' is no valid mode", mode)
|
||||
}
|
||||
|
||||
// TODO: remove isGated in next major release
|
||||
if requireApproval == string(woodpecker.RequireApprovalAllEvents) {
|
||||
trueBool := true
|
||||
patch.IsGated = &trueBool
|
||||
} else if requireApproval == string(woodpecker.RequireApprovalNone) {
|
||||
falseBool := false
|
||||
patch.IsGated = &falseBool
|
||||
}
|
||||
}
|
||||
if c.IsSet("timeout") {
|
||||
v := int64(timeout / time.Minute)
|
||||
|
|
|
@ -4905,6 +4905,9 @@ const docTemplate = `{
|
|||
"forge_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"from_fork": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -5068,9 +5071,6 @@ const docTemplate = `{
|
|||
"full_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"gated": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -5092,6 +5092,9 @@ const docTemplate = `{
|
|||
"private": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"require_approval": {
|
||||
"$ref": "#/definitions/model.ApprovalMode"
|
||||
},
|
||||
"scm": {
|
||||
"$ref": "#/definitions/SCMKind"
|
||||
},
|
||||
|
@ -5125,11 +5128,15 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"gated": {
|
||||
"description": "TODO: deprecated in favor of RequireApproval =\u003e Remove in next major release",
|
||||
"type": "boolean"
|
||||
},
|
||||
"netrc_only_trusted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"require_approval": {
|
||||
"type": "string"
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -5621,6 +5628,27 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"model.ApprovalMode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"forks",
|
||||
"pull_requests",
|
||||
"all_events"
|
||||
],
|
||||
"x-enum-comments": {
|
||||
"RequireApprovalAllEvents": "require approval for all external events",
|
||||
"RequireApprovalForks": "require approval for PRs from forks (default)",
|
||||
"RequireApprovalNone": "require approval for no events",
|
||||
"RequireApprovalPullRequests": "require approval for all PRs"
|
||||
},
|
||||
"x-enum-varnames": [
|
||||
"RequireApprovalNone",
|
||||
"RequireApprovalForks",
|
||||
"RequireApprovalPullRequests",
|
||||
"RequireApprovalAllEvents"
|
||||
]
|
||||
},
|
||||
"model.ForgeType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
|
@ -25,10 +25,9 @@ Only activate this option if you trust all users who have push access to your re
|
|||
Otherwise, these users will be able to steal secrets that are only available for `deploy` events.
|
||||
:::
|
||||
|
||||
## Protected
|
||||
## Require approval for
|
||||
|
||||
Every pipeline initiated by an webhook event needs to be approved by a project members with push permissions before being executed.
|
||||
The protected option can be used as an additional review process before running potentially harmful pipelines. Especially if pipelines can be executed by third-parties through pull-requests.
|
||||
To prevent malicious pipelines from extracting secrets or running harmful commands or to prevent accidental pipeline runs, you can require approval for an additional review process. Depending on the enabled option, a pipeline will be put on hold after creation and will only continue after approval. The default restrictive setting is `Approvals for forked repositories`.
|
||||
|
||||
## Trusted
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 353 KiB |
|
@ -224,6 +224,11 @@
|
|||
"name": "EditorConfig Checker",
|
||||
"docs": "https://codeberg.org/woodpecker-plugins/editorconfig-checker/raw/branch/main/docs.md",
|
||||
"verified": true
|
||||
},
|
||||
{
|
||||
"name": "Microsoft Teams Notify",
|
||||
"docs": "https://raw.githubusercontent.com/GECO-IT/woodpecker-plugin-teams-notify/refs/heads/main/docs.md",
|
||||
"verified": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6864,7 +6864,7 @@ snapshots:
|
|||
'@docusaurus/core': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/logger': 3.6.1
|
||||
'@docusaurus/mdx-loader': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/theme-common': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/types': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
|
@ -6904,48 +6904,6 @@ snapshots:
|
|||
- webpack-cli
|
||||
|
||||
'@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@docusaurus/core': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/logger': 3.6.1
|
||||
'@docusaurus/mdx-loader': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/module-type-aliases': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/theme-common': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/types': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/utils-common': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/utils-validation': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@types/react-router-config': 5.0.11
|
||||
combine-promises: 1.2.0
|
||||
fs-extra: 11.2.0
|
||||
js-yaml: 4.1.0
|
||||
lodash: 4.17.21
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
tslib: 2.8.1
|
||||
utility-types: 3.11.0
|
||||
webpack: 5.96.1
|
||||
transitivePeerDependencies:
|
||||
- '@docusaurus/faster'
|
||||
- '@mdx-js/react'
|
||||
- '@parcel/css'
|
||||
- '@rspack/core'
|
||||
- '@swc/core'
|
||||
- '@swc/css'
|
||||
- acorn
|
||||
- bufferutil
|
||||
- csso
|
||||
- debug
|
||||
- esbuild
|
||||
- eslint
|
||||
- lightningcss
|
||||
- supports-color
|
||||
- typescript
|
||||
- uglify-js
|
||||
- utf-8-validate
|
||||
- vue-template-compiler
|
||||
- webpack-cli
|
||||
|
||||
'@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@docusaurus/core': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/logger': 3.6.1
|
||||
|
@ -7177,7 +7135,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@docusaurus/core': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-blog': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-pages': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-debug': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-google-analytics': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
|
@ -7226,7 +7184,7 @@ snapshots:
|
|||
'@docusaurus/mdx-loader': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/module-type-aliases': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/plugin-content-blog': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-pages': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/theme-common': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/theme-translations': 3.6.1
|
||||
|
@ -7270,37 +7228,11 @@ snapshots:
|
|||
- vue-template-compiler
|
||||
- webpack-cli
|
||||
|
||||
'@docusaurus/theme-common@3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@docusaurus/mdx-loader': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/module-type-aliases': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/utils-common': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@types/history': 4.7.11
|
||||
'@types/react': 18.3.12
|
||||
'@types/react-router-config': 5.0.11
|
||||
clsx: 2.1.1
|
||||
parse-numeric-range: 1.3.0
|
||||
prism-react-renderer: 2.4.0(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
tslib: 2.8.1
|
||||
utility-types: 3.11.0
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- acorn
|
||||
- esbuild
|
||||
- supports-color
|
||||
- typescript
|
||||
- uglify-js
|
||||
- webpack-cli
|
||||
|
||||
'@docusaurus/theme-common@3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@docusaurus/mdx-loader': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/module-type-aliases': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/utils-common': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@types/history': 4.7.11
|
||||
|
@ -7327,7 +7259,7 @@ snapshots:
|
|||
'@docsearch/react': 3.8.0(@algolia/client-search@5.14.2)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)
|
||||
'@docusaurus/core': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/logger': 3.6.1
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/plugin-content-docs': 3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(debug@4.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/theme-common': 3.6.1(@docusaurus/plugin-content-docs@3.6.1(@mdx-js/react@3.1.0(@types/react@18.3.12)(react@18.3.1))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
'@docusaurus/theme-translations': 3.6.1
|
||||
'@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
addlicense
|
||||
protoc-gen-go
|
||||
protoc-gen-go-grpc
|
||||
gcc
|
||||
];
|
||||
CFLAGS = "-I${pkgs.glibc.dev}/include";
|
||||
LDFLAGS = "-L${pkgs.glibc}/lib";
|
||||
|
|
|
@ -91,6 +91,7 @@ func PostRepo(c *gin.Context) {
|
|||
repo.Update(from)
|
||||
} else {
|
||||
repo = from
|
||||
repo.RequireApproval = model.RequireApprovalForks
|
||||
repo.AllowPull = true
|
||||
repo.AllowDeploy = false
|
||||
repo.NetrcOnlyTrusted = true
|
||||
|
@ -250,8 +251,20 @@ func PatchRepo(c *gin.Context) {
|
|||
if in.AllowDeploy != nil {
|
||||
repo.AllowDeploy = *in.AllowDeploy
|
||||
}
|
||||
if in.IsGated != nil {
|
||||
repo.IsGated = *in.IsGated
|
||||
|
||||
if in.RequireApproval != nil {
|
||||
if mode := model.ApprovalMode(*in.RequireApproval); mode.Valid() {
|
||||
repo.RequireApproval = mode
|
||||
} else {
|
||||
c.String(http.StatusBadRequest, "Invalid require-approval setting")
|
||||
return
|
||||
}
|
||||
} else if in.IsGated != nil { // TODO: remove isGated in next major release
|
||||
if *in.IsGated {
|
||||
repo.RequireApproval = model.RequireApprovalAllEvents
|
||||
} else {
|
||||
repo.RequireApproval = model.RequireApprovalForks
|
||||
}
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
repo.Timeout = *in.Timeout
|
||||
|
|
|
@ -179,6 +179,7 @@ func convertPullHook(from *internal.PullRequestHook) *model.Pipeline {
|
|||
Author: from.Actor.Login,
|
||||
Sender: from.Actor.Login,
|
||||
Timestamp: from.PullRequest.Updated.UTC().Unix(),
|
||||
FromFork: from.PullRequest.Source.Repo.UUID != from.PullRequest.Dest.Repo.UUID,
|
||||
}
|
||||
|
||||
if from.PullRequest.State == stateClosed {
|
||||
|
|
|
@ -122,6 +122,7 @@ func convertPullRequestEvent(ev *bb.PullRequestEvent, baseURL string) *model.Pip
|
|||
Ref: fmt.Sprintf("refs/pull-requests/%d/from", ev.PullRequest.ID),
|
||||
ForgeURL: fmt.Sprintf("%s/projects/%s/repos/%s/commits/%s", baseURL, ev.PullRequest.Source.Repository.Project.Key, ev.PullRequest.Source.Repository.Slug, ev.PullRequest.Source.Latest),
|
||||
Refspec: fmt.Sprintf("%s:%s", ev.PullRequest.Source.DisplayID, ev.PullRequest.Target.DisplayID),
|
||||
FromFork: ev.PullRequest.Source.Repository.ID != ev.PullRequest.Target.Repository.ID,
|
||||
}
|
||||
|
||||
if ev.EventKey == bb.EventKeyPullRequestMerged || ev.EventKey == bb.EventKeyPullRequestDeclined || ev.EventKey == bb.EventKeyPullRequestDeleted {
|
||||
|
|
|
@ -170,6 +170,7 @@ func pipelineFromPullRequest(hook *pullRequestHook) *model.Pipeline {
|
|||
hook.PullRequest.Base.Ref,
|
||||
),
|
||||
PullRequestLabels: convertLabels(hook.PullRequest.Labels),
|
||||
FromFork: hook.PullRequest.Head.RepoID != hook.PullRequest.Base.RepoID,
|
||||
}
|
||||
|
||||
return pipeline
|
||||
|
|
|
@ -171,6 +171,7 @@ func pipelineFromPullRequest(hook *pullRequestHook) *model.Pipeline {
|
|||
hook.PullRequest.Base.Ref,
|
||||
),
|
||||
PullRequestLabels: convertLabels(hook.PullRequest.Labels),
|
||||
FromFork: hook.PullRequest.Head.RepoID != hook.PullRequest.Base.RepoID,
|
||||
}
|
||||
|
||||
return pipeline
|
||||
|
|
|
@ -157,6 +157,8 @@ func parsePullHook(hook *github.PullRequestEvent, merge bool) (*github.PullReque
|
|||
event = model.EventPullClosed
|
||||
}
|
||||
|
||||
fromFork := hook.GetPullRequest().GetHead().GetRepo().GetID() != hook.GetPullRequest().GetBase().GetRepo().GetID()
|
||||
|
||||
pipeline := &model.Pipeline{
|
||||
Event: event,
|
||||
Commit: hook.GetPullRequest().GetHead().GetSHA(),
|
||||
|
@ -173,6 +175,7 @@ func parsePullHook(hook *github.PullRequestEvent, merge bool) (*github.PullReque
|
|||
hook.GetPullRequest().GetBase().GetRef(),
|
||||
),
|
||||
PullRequestLabels: convertLabels(hook.GetPullRequest().Labels),
|
||||
FromFork: fromFork,
|
||||
}
|
||||
if merge {
|
||||
pipeline.Ref = fmt.Sprintf(mergeRefs, hook.GetPullRequest().GetNumber())
|
||||
|
|
|
@ -138,6 +138,7 @@ func convertMergeRequestHook(hook *gitlab.MergeEvent, req *http.Request) (int, *
|
|||
pipeline.Title = obj.Title
|
||||
pipeline.ForgeURL = obj.URL
|
||||
pipeline.PullRequestLabels = convertLabels(hook.Labels)
|
||||
pipeline.FromFork = target.PathWithNamespace != source.PathWithNamespace
|
||||
|
||||
return obj.IID, repo, pipeline, nil
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ type Pipeline struct {
|
|||
AdditionalVariables map[string]string `json:"variables,omitempty" xorm:"json 'additional_variables'"`
|
||||
PullRequestLabels []string `json:"pr_labels,omitempty" xorm:"json 'pr_labels'"`
|
||||
IsPrerelease bool `json:"is_prerelease,omitempty" xorm:"is_prerelease"`
|
||||
FromFork bool `json:"from_fork,omitempty" xorm:"from_fork"`
|
||||
} // @name Pipeline
|
||||
|
||||
// TableName return database table name for xorm.
|
||||
|
|
|
@ -20,6 +20,27 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type ApprovalMode string
|
||||
|
||||
const (
|
||||
RequireApprovalNone ApprovalMode = "none" // require approval for no events
|
||||
RequireApprovalForks ApprovalMode = "forks" // require approval for PRs from forks (default)
|
||||
RequireApprovalPullRequests ApprovalMode = "pull_requests" // require approval for all PRs
|
||||
RequireApprovalAllEvents ApprovalMode = "all_events" // require approval for all external events
|
||||
)
|
||||
|
||||
func (mode ApprovalMode) Valid() bool {
|
||||
switch mode {
|
||||
case RequireApprovalNone,
|
||||
RequireApprovalForks,
|
||||
RequireApprovalPullRequests,
|
||||
RequireApprovalAllEvents:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Repo represents a repository.
|
||||
type Repo struct {
|
||||
ID int64 `json:"id,omitempty" xorm:"pk autoincr 'id'"`
|
||||
|
@ -41,7 +62,7 @@ type Repo struct {
|
|||
Visibility RepoVisibility `json:"visibility" xorm:"varchar(10) 'visibility'"`
|
||||
IsSCMPrivate bool `json:"private" xorm:"private"`
|
||||
Trusted TrustedConfiguration `json:"trusted" xorm:"json 'trusted'"`
|
||||
IsGated bool `json:"gated" xorm:"gated"`
|
||||
RequireApproval ApprovalMode `json:"require_approval" xorm:"varchar(50) require_approval"`
|
||||
IsActive bool `json:"active" xorm:"active"`
|
||||
AllowPull bool `json:"allow_pr" xorm:"allow_pr"`
|
||||
AllowDeploy bool `json:"allow_deploy" xorm:"allow_deploy"`
|
||||
|
@ -107,7 +128,8 @@ func (r *Repo) Update(from *Repo) {
|
|||
// RepoPatch represents a repository patch object.
|
||||
type RepoPatch struct {
|
||||
Config *string `json:"config_file,omitempty"`
|
||||
IsGated *bool `json:"gated,omitempty"`
|
||||
IsGated *bool `json:"gated,omitempty"` // TODO: deprecated in favor of RequireApproval => Remove in next major release
|
||||
RequireApproval *string `json:"require_approval,omitempty"`
|
||||
Timeout *int64 `json:"timeout,omitempty"`
|
||||
Visibility *string `json:"visibility,omitempty"`
|
||||
AllowPull *bool `json:"allow_pr,omitempty"`
|
||||
|
|
|
@ -27,8 +27,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/store"
|
||||
)
|
||||
|
||||
// Approve update the status to pending for a blocked pipeline because of a gated repo
|
||||
// and start them afterward.
|
||||
// Approve update the status to pending for a blocked pipeline so it can be executed.
|
||||
func Approve(ctx context.Context, store store.Store, currentPipeline *model.Pipeline, user *model.User, repo *model.Repo) (*model.Pipeline, error) {
|
||||
if currentPipeline.Status != model.StatusBlocked {
|
||||
return nil, ErrBadRequest{Msg: fmt.Sprintf("cannot approve a pipeline with status %s", currentPipeline.Status)}
|
||||
|
|
|
@ -68,7 +68,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline
|
|||
// update some pipeline fields
|
||||
pipeline.RepoID = repo.ID
|
||||
pipeline.Status = model.StatusCreated
|
||||
setGatedState(repo, pipeline)
|
||||
setApprovalState(repo, pipeline)
|
||||
err = _store.CreatePipeline(pipeline)
|
||||
if err != nil {
|
||||
msg := fmt.Errorf("failed to save pipeline for %s", repo.FullName)
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/store"
|
||||
)
|
||||
|
||||
// Decline updates the status to declined for blocked pipelines because of a gated repo.
|
||||
// Decline updates the status to declined for blocked pipelines.
|
||||
func Decline(ctx context.Context, store store.Store, pipeline *model.Pipeline, user *model.User, repo *model.Repo) (*model.Pipeline, error) {
|
||||
forge, err := server.Config.Services.Manager.ForgeFromRepo(repo)
|
||||
if err != nil {
|
||||
|
|
|
@ -16,11 +16,40 @@ package pipeline
|
|||
|
||||
import "go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
|
||||
func setGatedState(repo *model.Repo, pipeline *model.Pipeline) {
|
||||
// TODO(336): extend gated feature with an allow/block List
|
||||
if repo.IsGated &&
|
||||
// events created by woodpecker itself should run right away
|
||||
pipeline.Event != model.EventCron && pipeline.Event != model.EventManual {
|
||||
pipeline.Status = model.StatusBlocked
|
||||
func setApprovalState(repo *model.Repo, pipeline *model.Pipeline) {
|
||||
if !needsApproval(repo, pipeline) {
|
||||
return
|
||||
}
|
||||
|
||||
// set pipeline status to blocked and require approval
|
||||
pipeline.Status = model.StatusBlocked
|
||||
}
|
||||
|
||||
func needsApproval(repo *model.Repo, pipeline *model.Pipeline) bool {
|
||||
// skip events created by woodpecker itself
|
||||
if pipeline.Event == model.EventCron || pipeline.Event == model.EventManual {
|
||||
return false
|
||||
}
|
||||
|
||||
// repository allows all events without approval
|
||||
if repo.RequireApproval == model.RequireApprovalNone {
|
||||
return false
|
||||
}
|
||||
|
||||
// repository requires approval for pull requests from forks
|
||||
if pipeline.Event == model.EventPull && pipeline.FromFork {
|
||||
return true
|
||||
}
|
||||
|
||||
// repository requires approval for pull requests
|
||||
if pipeline.Event == model.EventPull && repo.RequireApproval == model.RequireApprovalPullRequests {
|
||||
return true
|
||||
}
|
||||
|
||||
// repository requires approval for all events
|
||||
if repo.RequireApproval == model.RequireApprovalAllEvents {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
78
server/pipeline/gated_test.go
Normal file
78
server/pipeline/gated_test.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package pipeline
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
||||
func TestSetGatedState(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
repo *model.Repo
|
||||
pipeline *model.Pipeline
|
||||
expectBlocked bool
|
||||
}{
|
||||
{
|
||||
name: "by-pass for cron",
|
||||
repo: &model.Repo{
|
||||
RequireApproval: model.RequireApprovalAllEvents,
|
||||
},
|
||||
pipeline: &model.Pipeline{
|
||||
Event: model.EventCron,
|
||||
},
|
||||
expectBlocked: false,
|
||||
},
|
||||
{
|
||||
name: "by-pass for manual pipeline",
|
||||
repo: &model.Repo{
|
||||
RequireApproval: model.RequireApprovalAllEvents,
|
||||
},
|
||||
pipeline: &model.Pipeline{
|
||||
Event: model.EventManual,
|
||||
},
|
||||
expectBlocked: false,
|
||||
},
|
||||
{
|
||||
name: "require approval for fork PRs",
|
||||
repo: &model.Repo{
|
||||
RequireApproval: model.RequireApprovalForks,
|
||||
},
|
||||
pipeline: &model.Pipeline{
|
||||
Event: model.EventPull,
|
||||
FromFork: true,
|
||||
},
|
||||
expectBlocked: true,
|
||||
},
|
||||
{
|
||||
name: "require approval for PRs",
|
||||
repo: &model.Repo{
|
||||
RequireApproval: model.RequireApprovalPullRequests,
|
||||
},
|
||||
pipeline: &model.Pipeline{
|
||||
Event: model.EventPull,
|
||||
FromFork: false,
|
||||
},
|
||||
expectBlocked: true,
|
||||
},
|
||||
{
|
||||
name: "require approval for everything",
|
||||
repo: &model.Repo{
|
||||
RequireApproval: model.RequireApprovalAllEvents,
|
||||
},
|
||||
pipeline: &model.Pipeline{
|
||||
Event: model.EventPush,
|
||||
},
|
||||
expectBlocked: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
setApprovalState(tc.repo, tc.pipeline)
|
||||
assert.Equal(t, tc.expectBlocked, tc.pipeline.Status == model.StatusBlocked)
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ package queue
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
|
@ -26,64 +27,85 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
||||
var filterFnTrue = func(*model.Task) (bool, int) { return true, 1 }
|
||||
var (
|
||||
filterFnTrue = func(*model.Task) (bool, int) { return true, 1 }
|
||||
genDummyTask = func() *model.Task {
|
||||
return &model.Task{
|
||||
ID: "1",
|
||||
Data: []byte("{}"),
|
||||
}
|
||||
}
|
||||
waitForProcess = func() { time.Sleep(processTimeInterval + 10*time.Millisecond) }
|
||||
)
|
||||
|
||||
func TestFifo(t *testing.T) {
|
||||
want := &model.Task{ID: "1"}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q := NewMemoryQueue(ctx)
|
||||
assert.NoError(t, q.Push(ctx, want))
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
waitForProcess()
|
||||
info := q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 1, "expect task in pending queue")
|
||||
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, want, got)
|
||||
assert.Equal(t, dummyTask, got)
|
||||
|
||||
waitForProcess()
|
||||
info = q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 0, "expect task removed from pending queue")
|
||||
assert.Len(t, info.Running, 1, "expect task in running queue")
|
||||
|
||||
assert.NoError(t, q.Done(ctx, got.ID, model.StatusSuccess))
|
||||
|
||||
waitForProcess()
|
||||
info = q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 0, "expect task removed from pending queue")
|
||||
assert.Len(t, info.Running, 0, "expect task removed from running queue")
|
||||
}
|
||||
|
||||
func TestFifoExpire(t *testing.T) {
|
||||
want := &model.Task{ID: "1"}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
q.extension = 0
|
||||
assert.NoError(t, q.Push(ctx, want))
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
waitForProcess()
|
||||
info := q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 1, "expect task in pending queue")
|
||||
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
waitForProcess()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, want, got)
|
||||
assert.Equal(t, dummyTask, got)
|
||||
|
||||
// cancel the context to let the process func end
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond)
|
||||
cancel(nil)
|
||||
}()
|
||||
q.process()
|
||||
info = q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 1, "expect task re-added to pending queue")
|
||||
}
|
||||
|
||||
func TestFifoWait(t *testing.T) {
|
||||
want := &model.Task{ID: "1"}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NoError(t, q.Push(ctx, want))
|
||||
assert.NotNil(t, q)
|
||||
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, want, got)
|
||||
assert.Equal(t, dummyTask, got)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
@ -98,27 +120,34 @@ func TestFifoWait(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoEvict(t *testing.T) {
|
||||
t1 := &model.Task{ID: "1"}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q := NewMemoryQueue(ctx)
|
||||
assert.NoError(t, q.Push(ctx, t1))
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
|
||||
waitForProcess()
|
||||
info := q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 1, "expect task in pending queue")
|
||||
err := q.Evict(ctx, t1.ID)
|
||||
|
||||
err := q.Evict(ctx, dummyTask.ID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
waitForProcess()
|
||||
info = q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 0)
|
||||
err = q.Evict(ctx, t1.ID)
|
||||
|
||||
err = q.Evict(ctx, dummyTask.ID)
|
||||
assert.ErrorIs(t, err, ErrNotFound)
|
||||
}
|
||||
|
||||
func TestFifoDependencies(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
|
@ -126,31 +155,34 @@ func TestFifoDependencies(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task1}))
|
||||
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task1, got)
|
||||
|
||||
waitForProcess()
|
||||
assert.NoError(t, q.Done(ctx, got.ID, model.StatusSuccess))
|
||||
|
||||
waitForProcess()
|
||||
got, err = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task2, got)
|
||||
}
|
||||
|
||||
func TestFifoErrors(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
DepStatus: make(map[string]model.StatusValue),
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"1"},
|
||||
|
@ -159,19 +191,24 @@ func TestFifoErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task1, got)
|
||||
|
||||
assert.NoError(t, q.Error(ctx, got.ID, fmt.Errorf("exit code 1, there was an error")))
|
||||
|
||||
waitForProcess()
|
||||
got, err = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task2, got)
|
||||
assert.False(t, got.ShouldRun())
|
||||
|
||||
waitForProcess()
|
||||
got, err = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task3, got)
|
||||
|
@ -179,15 +216,13 @@ func TestFifoErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoErrors2(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"1", "2"},
|
||||
|
@ -195,9 +230,12 @@ func TestFifoErrors2(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, got != task1 && got != task2, "expect task1 or task2 returned from queue as task3 depends on them")
|
||||
|
@ -210,6 +248,7 @@ func TestFifoErrors2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task3, got)
|
||||
|
@ -217,17 +256,15 @@ func TestFifoErrors2(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoErrorsMultiThread(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
DepStatus: make(map[string]model.StatusValue),
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"1", "2"},
|
||||
|
@ -235,15 +272,21 @@ func TestFifoErrorsMultiThread(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
obtainedWorkCh := make(chan *model.Task)
|
||||
defer func() { close(obtainedWorkCh) }()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func(i int) {
|
||||
for {
|
||||
fmt.Printf("Worker %d started\n", i)
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
if err != nil && errors.Is(err, context.Canceled) {
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
obtainedWorkCh <- got
|
||||
}
|
||||
|
@ -266,7 +309,11 @@ func TestFifoErrorsMultiThread(t *testing.T) {
|
|||
go func() {
|
||||
for {
|
||||
fmt.Printf("Worker spawned\n")
|
||||
got, _ := q.Poll(ctx, 1, filterFnTrue)
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
if err != nil && errors.Is(err, context.Canceled) {
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
obtainedWorkCh <- got
|
||||
}
|
||||
}()
|
||||
|
@ -277,7 +324,11 @@ func TestFifoErrorsMultiThread(t *testing.T) {
|
|||
go func() {
|
||||
for {
|
||||
fmt.Printf("Worker spawned\n")
|
||||
got, _ := q.Poll(ctx, 1, filterFnTrue)
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
if err != nil && errors.Is(err, context.Canceled) {
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
obtainedWorkCh <- got
|
||||
}
|
||||
}()
|
||||
|
@ -297,17 +348,15 @@ func TestFifoErrorsMultiThread(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoTransitiveErrors(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
DepStatus: make(map[string]model.StatusValue),
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"2"},
|
||||
|
@ -315,19 +364,24 @@ func TestFifoTransitiveErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
waitForProcess()
|
||||
got, err := q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task1, got)
|
||||
assert.NoError(t, q.Error(ctx, got.ID, fmt.Errorf("exit code 1, there was an error")))
|
||||
|
||||
waitForProcess()
|
||||
got, err = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task2, got)
|
||||
assert.False(t, got.ShouldRun(), "expect task2 should not run, since task1 failed")
|
||||
assert.NoError(t, q.Done(ctx, got.ID, model.StatusSkipped))
|
||||
|
||||
waitForProcess()
|
||||
got, err = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, task3, got)
|
||||
|
@ -335,17 +389,15 @@ func TestFifoTransitiveErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoCancel(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
DepStatus: make(map[string]model.StatusValue),
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"1"},
|
||||
|
@ -354,24 +406,33 @@ func TestFifoCancel(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
_, _ = q.Poll(ctx, 1, filterFnTrue)
|
||||
assert.NoError(t, q.Error(ctx, task1.ID, fmt.Errorf("canceled")))
|
||||
assert.NoError(t, q.Error(ctx, task2.ID, fmt.Errorf("canceled")))
|
||||
assert.NoError(t, q.Error(ctx, task3.ID, fmt.Errorf("canceled")))
|
||||
|
||||
info := q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 0, "all pipelines should be canceled")
|
||||
|
||||
time.Sleep(processTimeInterval * 2)
|
||||
info = q.Info(ctx)
|
||||
assert.Len(t, info.Pending, 2, "canceled are rescheduled")
|
||||
assert.Len(t, info.Running, 0, "canceled are rescheduled")
|
||||
assert.Len(t, info.WaitingOnDeps, 0, "canceled are rescheduled")
|
||||
}
|
||||
|
||||
func TestFifoPause(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
|
@ -381,8 +442,8 @@ func TestFifoPause(t *testing.T) {
|
|||
|
||||
q.Pause()
|
||||
t0 := time.Now()
|
||||
assert.NoError(t, q.Push(ctx, task1))
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
waitForProcess()
|
||||
q.Resume()
|
||||
|
||||
wg.Wait()
|
||||
|
@ -391,37 +452,37 @@ func TestFifoPause(t *testing.T) {
|
|||
assert.Greater(t, t1.Sub(t0), 20*time.Millisecond, "should have waited til resume")
|
||||
|
||||
q.Pause()
|
||||
assert.NoError(t, q.Push(ctx, task1))
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
q.Resume()
|
||||
_, _ = q.Poll(ctx, 1, filterFnTrue)
|
||||
}
|
||||
|
||||
func TestFifoPauseResume(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
dummyTask := genDummyTask()
|
||||
|
||||
q.Pause()
|
||||
assert.NoError(t, q.Push(ctx, task1))
|
||||
assert.NoError(t, q.Push(ctx, dummyTask))
|
||||
q.Resume()
|
||||
|
||||
_, _ = q.Poll(ctx, 1, filterFnTrue)
|
||||
}
|
||||
|
||||
func TestWaitingVsPending(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
task1 := &model.Task{
|
||||
ID: "1",
|
||||
}
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
task1 := genDummyTask()
|
||||
task2 := &model.Task{
|
||||
ID: "2",
|
||||
Dependencies: []string{"1"},
|
||||
DepStatus: make(map[string]model.StatusValue),
|
||||
}
|
||||
|
||||
task3 := &model.Task{
|
||||
ID: "3",
|
||||
Dependencies: []string{"1"},
|
||||
|
@ -430,10 +491,13 @@ func TestWaitingVsPending(t *testing.T) {
|
|||
}
|
||||
|
||||
q, _ := NewMemoryQueue(ctx).(*fifo)
|
||||
assert.NotNil(t, q)
|
||||
|
||||
assert.NoError(t, q.PushAtOnce(ctx, []*model.Task{task2, task3, task1}))
|
||||
|
||||
got, _ := q.Poll(ctx, 1, filterFnTrue)
|
||||
|
||||
waitForProcess()
|
||||
info := q.Info(ctx)
|
||||
assert.Equal(t, 2, info.Stats.WaitingOnDeps)
|
||||
|
||||
|
@ -442,6 +506,7 @@ func TestWaitingVsPending(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, task2, got)
|
||||
|
||||
waitForProcess()
|
||||
info = q.Info(ctx)
|
||||
assert.Equal(t, 0, info.Stats.WaitingOnDeps)
|
||||
assert.Equal(t, 1, info.Stats.Pending)
|
||||
|
@ -518,7 +583,9 @@ func TestShouldRun(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFifoWithScoring(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
t.Cleanup(func() { cancel(nil) })
|
||||
|
||||
q := NewMemoryQueue(ctx)
|
||||
|
||||
// Create tasks with different labels
|
||||
|
@ -530,9 +597,7 @@ func TestFifoWithScoring(t *testing.T) {
|
|||
{ID: "5", Labels: map[string]string{"org-id": "*", "platform": "linux"}},
|
||||
}
|
||||
|
||||
for _, task := range tasks {
|
||||
assert.NoError(t, q.Push(ctx, task))
|
||||
}
|
||||
assert.NoError(t, q.PushAtOnce(ctx, tasks))
|
||||
|
||||
// Create filter functions for different workers
|
||||
filters := map[int]FilterFn{
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2024 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 migration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var gatedToRequireApproval = xormigrate.Migration{
|
||||
ID: "gated-to-require-approval",
|
||||
MigrateSession: func(sess *xorm.Session) (err error) {
|
||||
const (
|
||||
RequireApprovalNone string = "none"
|
||||
RequireApprovalForks string = "forks"
|
||||
RequireApprovalPullRequests string = "pull_requests"
|
||||
RequireApprovalAllEvents string = "all_events"
|
||||
)
|
||||
|
||||
type repos struct {
|
||||
ID int64 `xorm:"pk autoincr 'id'"`
|
||||
IsGated bool `xorm:"gated"`
|
||||
RequireApproval string `xorm:"require_approval"`
|
||||
Visibility string `xorm:"varchar(10) 'visibility'"`
|
||||
}
|
||||
|
||||
if err := sess.Sync(new(repos)); err != nil {
|
||||
return fmt.Errorf("sync new models failed: %w", err)
|
||||
}
|
||||
|
||||
// migrate gated repos
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalAllEvents}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": true})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// migrate public repos to new default require approval
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalForks}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": false, "visibility": "public"})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// migrate private repos to new default require approval
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalNone}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": false}.And(builder.Neq{"visibility": "public"}))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dropTableColumns(sess, "repos", "gated")
|
||||
},
|
||||
}
|
|
@ -47,6 +47,7 @@ var migrationTasks = []*xormigrate.Migration{
|
|||
&addCustomLabelsToAgent,
|
||||
&splitTrusted,
|
||||
&correctPotentialCorruptOrgsUsersRelation,
|
||||
&gatedToRequireApproval,
|
||||
&removeRepoScm,
|
||||
}
|
||||
|
||||
|
|
|
@ -216,36 +216,32 @@ packages:
|
|||
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/compat-data@7.25.7':
|
||||
resolution: {integrity: sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==}
|
||||
'@babel/compat-data@7.26.2':
|
||||
resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/core@7.25.7':
|
||||
resolution: {integrity: sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==}
|
||||
'@babel/core@7.26.0':
|
||||
resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/generator@7.26.2':
|
||||
resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-compilation-targets@7.25.7':
|
||||
resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==}
|
||||
'@babel/helper-compilation-targets@7.25.9':
|
||||
resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-module-imports@7.25.7':
|
||||
resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==}
|
||||
'@babel/helper-module-imports@7.25.9':
|
||||
resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-module-transforms@7.25.7':
|
||||
resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==}
|
||||
'@babel/helper-module-transforms@7.26.0':
|
||||
resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-simple-access@7.25.7':
|
||||
resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.25.9':
|
||||
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
@ -254,12 +250,12 @@ packages:
|
|||
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-option@7.25.7':
|
||||
resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==}
|
||||
'@babel/helper-validator-option@7.25.9':
|
||||
resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helpers@7.25.7':
|
||||
resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==}
|
||||
'@babel/helpers@7.26.0':
|
||||
resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/parser@7.26.2':
|
||||
|
@ -267,8 +263,8 @@ packages:
|
|||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/runtime@7.25.7':
|
||||
resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==}
|
||||
'@babel/runtime@7.26.0':
|
||||
resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.25.9':
|
||||
|
@ -443,12 +439,6 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0':
|
||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.1':
|
||||
resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
@ -476,10 +466,6 @@ packages:
|
|||
resolution: {integrity: sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/eslintrc@3.1.0':
|
||||
resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/eslintrc@3.2.0':
|
||||
resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -559,8 +545,8 @@ packages:
|
|||
resolution: {integrity: sha512-AFbhEo10DP095/45EauinQJ5hJ3rJUmuuqltGguvc3WsvezZN+g8qNHLGWKu60FHQVizMrQY7VJ+zVlBXlQQkQ==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/message-compiler@11.0.0-beta.0':
|
||||
resolution: {integrity: sha512-HWHv6jj7wJmHY5I73k80lBffDfnpqjx5vvn965YJB4lLvo0zkP3H15WGkwrLa/OR6fyYoP0DJVUKj9g2q7QJCA==}
|
||||
'@intlify/message-compiler@11.0.0-beta.1':
|
||||
resolution: {integrity: sha512-yMXfN4hg/EeSdtWfmoMrwB9X4TXwkBoZlTIpNydQaW9y0tSJHGnUPRoahtkbsyACCm9leSJINLY4jQ0rK6BK0Q==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/message-compiler@9.14.1':
|
||||
|
@ -571,8 +557,8 @@ packages:
|
|||
resolution: {integrity: sha512-ukFn0I01HsSgr3VYhYcvkTCLS7rGa0gw4A4AMpcy/A9xx/zRJy7PS2BElMXLwUazVFMAr5zuiTk3MQeoeGXaJg==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/shared@11.0.0-beta.0':
|
||||
resolution: {integrity: sha512-v/IAS+BBeaWIKPI4CgSKsil2vJ64naIUUENha3e7jfhq1CxinXQquQYUM2GcCC86USxzTGgu67nafbaYzHS3vA==}
|
||||
'@intlify/shared@11.0.0-beta.1':
|
||||
resolution: {integrity: sha512-Md/4T/QOx7wZ7zqVzSsMx2M/9Mx/1nsgsjXS5SFIowFKydqUhMz7K+y7pMFh781aNYz+rGXYwad8E9/+InK9SA==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/shared@9.14.1':
|
||||
|
@ -663,8 +649,8 @@ packages:
|
|||
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
|
||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
|
||||
'@rollup/pluginutils@5.1.2':
|
||||
resolution: {integrity: sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==}
|
||||
'@rollup/pluginutils@5.1.3':
|
||||
resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
|
@ -1080,11 +1066,6 @@ packages:
|
|||
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
browserslist@4.24.0:
|
||||
resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
|
||||
browserslist@4.24.2:
|
||||
resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
|
@ -1102,9 +1083,6 @@ packages:
|
|||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
caniuse-lite@1.0.30001667:
|
||||
resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==}
|
||||
|
||||
caniuse-lite@1.0.30001680:
|
||||
resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==}
|
||||
|
||||
|
@ -1305,9 +1283,6 @@ packages:
|
|||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
electron-to-chromium@1.5.32:
|
||||
resolution: {integrity: sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==}
|
||||
|
||||
electron-to-chromium@1.5.62:
|
||||
resolution: {integrity: sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==}
|
||||
|
||||
|
@ -1366,8 +1341,8 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: '>=6.0.0'
|
||||
|
||||
eslint-compat-utils@0.6.0:
|
||||
resolution: {integrity: sha512-1vVBdI/HLS6HTHVQCJGlN+LOF0w1Rs/WB9se23mQr84cRM0iMM8PulMFFhQdQ1BvS0cGwjpis4xziI91Rk0l6g==}
|
||||
eslint-compat-utils@0.6.3:
|
||||
resolution: {integrity: sha512-9IDdksh5pUYP2ZLi7mOdROxVjLY8gY2qKxprmrJ/5Dyqud7M/IFKxF3o0VLlRhITm1pK6Fk7NiBxE39M/VlUcw==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
eslint: '>=6.0.0'
|
||||
|
@ -1635,8 +1610,8 @@ packages:
|
|||
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
form-data@4.0.1:
|
||||
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
fs.realpath@1.0.0:
|
||||
|
@ -1693,10 +1668,6 @@ packages:
|
|||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globals@15.10.0:
|
||||
resolution: {integrity: sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globals@15.12.0:
|
||||
resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
@ -2174,8 +2145,8 @@ packages:
|
|||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
parse5@7.1.2:
|
||||
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
|
||||
parse5@7.2.1:
|
||||
resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==}
|
||||
|
||||
path-browserify@1.0.1:
|
||||
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
|
||||
|
@ -2206,9 +2177,6 @@ packages:
|
|||
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
|
||||
engines: {node: '>= 14.16'}
|
||||
|
||||
picocolors@1.1.0:
|
||||
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
|
@ -2259,10 +2227,6 @@ packages:
|
|||
resolution: {integrity: sha512-8I7Cd8sxiEITIp32xBK4K/Aj1ukX6vuWnx8oY/oAH35NfQI4OZaY5nd68Yx8HeN5S49uhQ6DL0rNk0ZBu/TaLg==}
|
||||
engines: {node: ^8.10.0 || ^10.13.0 || ^11.10.1 || >=12.13.0}
|
||||
|
||||
postcss@8.4.47:
|
||||
resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
postcss@8.4.49:
|
||||
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
@ -2488,10 +2452,6 @@ packages:
|
|||
resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
synckit@0.9.1:
|
||||
resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
|
||||
synckit@0.9.2:
|
||||
resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
|
@ -2521,11 +2481,11 @@ packages:
|
|||
resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
tldts-core@6.1.50:
|
||||
resolution: {integrity: sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw==}
|
||||
tldts-core@6.1.61:
|
||||
resolution: {integrity: sha512-In7VffkDWUPgwa+c9picLUxvb0RltVwTkSgMNFgvlGSWveCzGBemBqTsgJCL4EDFWZ6WH0fKTsot6yNhzy3ZzQ==}
|
||||
|
||||
tldts@6.1.50:
|
||||
resolution: {integrity: sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==}
|
||||
tldts@6.1.61:
|
||||
resolution: {integrity: sha512-rv8LUyez4Ygkopqn+M6OLItAOT9FF3REpPQDkdMx5ix8w4qkuE7Vo2o/vw1nxKQYmJDV8JpAMJQr1b+lTKf0FA==}
|
||||
hasBin: true
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
|
@ -2544,21 +2504,12 @@ packages:
|
|||
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
ts-api-utils@1.3.0:
|
||||
resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
|
||||
ts-api-utils@1.4.0:
|
||||
resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
|
||||
tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
|
@ -2605,14 +2556,9 @@ packages:
|
|||
unist-util-visit@5.0.0:
|
||||
resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
|
||||
|
||||
unplugin@1.14.1:
|
||||
resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==}
|
||||
unplugin@1.16.0:
|
||||
resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
webpack-sources: ^3
|
||||
peerDependenciesMeta:
|
||||
webpack-sources:
|
||||
optional: true
|
||||
|
||||
update-browserslist-db@1.1.1:
|
||||
resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
|
||||
|
@ -2707,8 +2653,8 @@ packages:
|
|||
vscode-uri@3.0.8:
|
||||
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
|
||||
|
||||
vue-component-type-helpers@2.1.6:
|
||||
resolution: {integrity: sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==}
|
||||
vue-component-type-helpers@2.1.10:
|
||||
resolution: {integrity: sha512-lfgdSLQKrUmADiSV6PbBvYgQ33KF3Ztv6gP85MfGaGaSGMTXORVaHT1EHfsqCgzRNBstPKYDmvAV9Do5CmJ07A==}
|
||||
|
||||
vue-demi@0.14.10:
|
||||
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
|
||||
|
@ -2926,16 +2872,16 @@ snapshots:
|
|||
js-tokens: 4.0.0
|
||||
picocolors: 1.1.1
|
||||
|
||||
'@babel/compat-data@7.25.7': {}
|
||||
'@babel/compat-data@7.26.2': {}
|
||||
|
||||
'@babel/core@7.25.7':
|
||||
'@babel/core@7.26.0':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@babel/code-frame': 7.26.2
|
||||
'@babel/generator': 7.26.2
|
||||
'@babel/helper-compilation-targets': 7.25.7
|
||||
'@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7)
|
||||
'@babel/helpers': 7.25.7
|
||||
'@babel/helper-compilation-targets': 7.25.9
|
||||
'@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0)
|
||||
'@babel/helpers': 7.26.0
|
||||
'@babel/parser': 7.26.2
|
||||
'@babel/template': 7.25.9
|
||||
'@babel/traverse': 7.25.9
|
||||
|
@ -2956,45 +2902,37 @@ snapshots:
|
|||
'@jridgewell/trace-mapping': 0.3.25
|
||||
jsesc: 3.0.2
|
||||
|
||||
'@babel/helper-compilation-targets@7.25.7':
|
||||
'@babel/helper-compilation-targets@7.25.9':
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.25.7
|
||||
'@babel/helper-validator-option': 7.25.7
|
||||
browserslist: 4.24.0
|
||||
'@babel/compat-data': 7.26.2
|
||||
'@babel/helper-validator-option': 7.25.9
|
||||
browserslist: 4.24.2
|
||||
lru-cache: 5.1.1
|
||||
semver: 7.6.3
|
||||
|
||||
'@babel/helper-module-imports@7.25.7':
|
||||
'@babel/helper-module-imports@7.25.9':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.25.9
|
||||
'@babel/types': 7.26.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-module-transforms@7.25.7(@babel/core@7.25.7)':
|
||||
'@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)':
|
||||
dependencies:
|
||||
'@babel/core': 7.25.7
|
||||
'@babel/helper-module-imports': 7.25.7
|
||||
'@babel/helper-simple-access': 7.25.7
|
||||
'@babel/core': 7.26.0
|
||||
'@babel/helper-module-imports': 7.25.9
|
||||
'@babel/helper-validator-identifier': 7.25.9
|
||||
'@babel/traverse': 7.25.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-simple-access@7.25.7':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.25.9
|
||||
'@babel/types': 7.26.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-string-parser@7.25.9': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.25.9': {}
|
||||
|
||||
'@babel/helper-validator-option@7.25.7': {}
|
||||
'@babel/helper-validator-option@7.25.9': {}
|
||||
|
||||
'@babel/helpers@7.25.7':
|
||||
'@babel/helpers@7.26.0':
|
||||
dependencies:
|
||||
'@babel/template': 7.25.9
|
||||
'@babel/types': 7.26.0
|
||||
|
@ -3003,7 +2941,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@babel/types': 7.26.0
|
||||
|
||||
'@babel/runtime@7.25.7':
|
||||
'@babel/runtime@7.26.0':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
|
@ -3128,11 +3066,6 @@ snapshots:
|
|||
eslint: 9.15.0(jiti@1.21.6)
|
||||
ignore: 5.3.2
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0(eslint@9.15.0(jiti@1.21.6))':
|
||||
dependencies:
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.1(eslint@9.15.0(jiti@1.21.6))':
|
||||
dependencies:
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
|
@ -3154,20 +3087,6 @@ snapshots:
|
|||
|
||||
'@eslint/core@0.9.0': {}
|
||||
|
||||
'@eslint/eslintrc@3.1.0':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.3.7
|
||||
espree: 10.3.0
|
||||
globals: 14.0.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.1.0
|
||||
minimatch: 3.1.2
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/eslintrc@3.2.0':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
|
@ -3227,8 +3146,8 @@ snapshots:
|
|||
|
||||
'@intlify/bundle-utils@10.0.0(vue-i18n@10.0.4(vue@3.5.13(typescript@5.6.3)))':
|
||||
dependencies:
|
||||
'@intlify/message-compiler': 11.0.0-beta.0
|
||||
'@intlify/shared': 11.0.0-beta.0
|
||||
'@intlify/message-compiler': 11.0.0-beta.1
|
||||
'@intlify/shared': 11.0.0-beta.1
|
||||
acorn: 8.14.0
|
||||
escodegen: 2.1.0
|
||||
estree-walker: 2.0.2
|
||||
|
@ -3251,14 +3170,14 @@ snapshots:
|
|||
|
||||
'@intlify/eslint-plugin-vue-i18n@3.0.0(eslint@9.15.0(jiti@1.21.6))':
|
||||
dependencies:
|
||||
'@eslint/eslintrc': 3.1.0
|
||||
'@eslint/eslintrc': 3.2.0
|
||||
'@intlify/core-base': 9.14.1
|
||||
'@intlify/message-compiler': 9.14.1
|
||||
debug: 4.3.7
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
eslint-compat-utils: 0.5.1(eslint@9.15.0(jiti@1.21.6))
|
||||
glob: 10.4.5
|
||||
globals: 15.10.0
|
||||
globals: 15.12.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.0
|
||||
is-language-code: 3.1.0
|
||||
|
@ -3266,9 +3185,9 @@ snapshots:
|
|||
json5: 2.2.3
|
||||
jsonc-eslint-parser: 2.4.0
|
||||
lodash: 4.17.21
|
||||
parse5: 7.1.2
|
||||
parse5: 7.2.1
|
||||
semver: 7.6.3
|
||||
synckit: 0.9.1
|
||||
synckit: 0.9.2
|
||||
vue-eslint-parser: 9.4.3(eslint@9.15.0(jiti@1.21.6))
|
||||
yaml-eslint-parser: 1.2.3
|
||||
transitivePeerDependencies:
|
||||
|
@ -3279,9 +3198,9 @@ snapshots:
|
|||
'@intlify/shared': 10.0.4
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@intlify/message-compiler@11.0.0-beta.0':
|
||||
'@intlify/message-compiler@11.0.0-beta.1':
|
||||
dependencies:
|
||||
'@intlify/shared': 11.0.0-beta.0
|
||||
'@intlify/shared': 11.0.0-beta.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@intlify/message-compiler@9.14.1':
|
||||
|
@ -3291,17 +3210,17 @@ snapshots:
|
|||
|
||||
'@intlify/shared@10.0.4': {}
|
||||
|
||||
'@intlify/shared@11.0.0-beta.0': {}
|
||||
'@intlify/shared@11.0.0-beta.1': {}
|
||||
|
||||
'@intlify/shared@9.14.1': {}
|
||||
|
||||
'@intlify/unplugin-vue-i18n@6.0.0(@vue/compiler-dom@3.5.13)(eslint@9.15.0(jiti@1.21.6))(rollup@4.27.2)(typescript@5.6.3)(vue-i18n@10.0.4(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@9.15.0(jiti@1.21.6))
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@1.21.6))
|
||||
'@intlify/bundle-utils': 10.0.0(vue-i18n@10.0.4(vue@3.5.13(typescript@5.6.3)))
|
||||
'@intlify/shared': 10.0.4
|
||||
'@intlify/vue-i18n-extensions': 7.0.0(@intlify/shared@10.0.4)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.4(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))
|
||||
'@rollup/pluginutils': 5.1.2(rollup@4.27.2)
|
||||
'@rollup/pluginutils': 5.1.3(rollup@4.27.2)
|
||||
'@typescript-eslint/scope-manager': 8.14.0
|
||||
'@typescript-eslint/typescript-estree': 8.14.0(typescript@5.6.3)
|
||||
debug: 4.3.7
|
||||
|
@ -3311,7 +3230,7 @@ snapshots:
|
|||
pathe: 1.1.2
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
unplugin: 1.14.1
|
||||
unplugin: 1.16.0
|
||||
vue: 3.5.13(typescript@5.6.3)
|
||||
optionalDependencies:
|
||||
vue-i18n: 10.0.4(vue@3.5.13(typescript@5.6.3))
|
||||
|
@ -3321,7 +3240,6 @@ snapshots:
|
|||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
- webpack-sources
|
||||
|
||||
'@intlify/vue-i18n-extensions@7.0.0(@intlify/shared@10.0.4)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.4(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))':
|
||||
dependencies:
|
||||
|
@ -3383,11 +3301,11 @@ snapshots:
|
|||
|
||||
'@pkgr/core@0.1.1': {}
|
||||
|
||||
'@rollup/pluginutils@5.1.2(rollup@4.27.2)':
|
||||
'@rollup/pluginutils@5.1.3(rollup@4.27.2)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 2.3.1
|
||||
picomatch: 4.0.2
|
||||
optionalDependencies:
|
||||
rollup: 4.27.2
|
||||
|
||||
|
@ -3561,7 +3479,7 @@ snapshots:
|
|||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.6.3
|
||||
ts-api-utils: 1.3.0(typescript@5.6.3)
|
||||
ts-api-utils: 1.4.0(typescript@5.6.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.6.3
|
||||
transitivePeerDependencies:
|
||||
|
@ -3725,7 +3643,7 @@ snapshots:
|
|||
'@vue/test-utils@2.4.6':
|
||||
dependencies:
|
||||
js-beautify: 1.15.1
|
||||
vue-component-type-helpers: 2.1.6
|
||||
vue-component-type-helpers: 2.1.10
|
||||
|
||||
'@vueuse/core@11.2.0(vue@3.5.13(typescript@5.6.3))':
|
||||
dependencies:
|
||||
|
@ -3832,13 +3750,6 @@ snapshots:
|
|||
dependencies:
|
||||
fill-range: 7.1.1
|
||||
|
||||
browserslist@4.24.0:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001667
|
||||
electron-to-chromium: 1.5.32
|
||||
node-releases: 2.0.18
|
||||
update-browserslist-db: 1.1.1(browserslist@4.24.0)
|
||||
|
||||
browserslist@4.24.2:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001680
|
||||
|
@ -3852,8 +3763,6 @@ snapshots:
|
|||
|
||||
callsites@3.1.0: {}
|
||||
|
||||
caniuse-lite@1.0.30001667: {}
|
||||
|
||||
caniuse-lite@1.0.30001680: {}
|
||||
|
||||
ccount@2.0.1: {}
|
||||
|
@ -4036,8 +3945,6 @@ snapshots:
|
|||
minimatch: 9.0.1
|
||||
semver: 7.6.3
|
||||
|
||||
electron-to-chromium@1.5.32: {}
|
||||
|
||||
electron-to-chromium@1.5.62: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
@ -4106,7 +4013,7 @@ snapshots:
|
|||
eslint: 9.15.0(jiti@1.21.6)
|
||||
semver: 7.6.3
|
||||
|
||||
eslint-compat-utils@0.6.0(eslint@9.15.0(jiti@1.21.6)):
|
||||
eslint-compat-utils@0.6.3(eslint@9.15.0(jiti@1.21.6)):
|
||||
dependencies:
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
semver: 7.6.3
|
||||
|
@ -4194,7 +4101,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@1.21.6))
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
eslint-compat-utils: 0.6.0(eslint@9.15.0(jiti@1.21.6))
|
||||
eslint-compat-utils: 0.6.3(eslint@9.15.0(jiti@1.21.6))
|
||||
eslint-json-compat-utils: 0.2.1(eslint@9.15.0(jiti@1.21.6))(jsonc-eslint-parser@2.4.0)
|
||||
espree: 9.6.1
|
||||
graphemer: 1.4.0
|
||||
|
@ -4284,13 +4191,13 @@ snapshots:
|
|||
|
||||
eslint-plugin-vue-scoped-css@2.8.1(eslint@9.15.0(jiti@1.21.6))(vue-eslint-parser@9.4.3(eslint@9.15.0(jiti@1.21.6))):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@9.15.0(jiti@1.21.6))
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0(jiti@1.21.6))
|
||||
eslint: 9.15.0(jiti@1.21.6)
|
||||
eslint-compat-utils: 0.5.1(eslint@9.15.0(jiti@1.21.6))
|
||||
lodash: 4.17.21
|
||||
postcss: 8.4.47
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.47)
|
||||
postcss-scss: 4.0.9(postcss@8.4.47)
|
||||
postcss: 8.4.49
|
||||
postcss-safe-parser: 6.0.0(postcss@8.4.49)
|
||||
postcss-scss: 4.0.9(postcss@8.4.49)
|
||||
postcss-selector-parser: 6.1.2
|
||||
postcss-styl: 0.12.3
|
||||
vue-eslint-parser: 9.4.3(eslint@9.15.0(jiti@1.21.6))
|
||||
|
@ -4468,7 +4375,7 @@ snapshots:
|
|||
cross-spawn: 7.0.5
|
||||
signal-exit: 4.1.0
|
||||
|
||||
form-data@4.0.0:
|
||||
form-data@4.0.1:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
|
@ -4525,8 +4432,6 @@ snapshots:
|
|||
|
||||
globals@14.0.0: {}
|
||||
|
||||
globals@15.10.0: {}
|
||||
|
||||
globals@15.12.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
@ -4605,7 +4510,7 @@ snapshots:
|
|||
|
||||
is-language-code@3.1.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.25.7
|
||||
'@babel/runtime': 7.26.0
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
|
@ -4646,13 +4551,13 @@ snapshots:
|
|||
cssstyle: 4.1.0
|
||||
data-urls: 5.0.0
|
||||
decimal.js: 10.4.3
|
||||
form-data: 4.0.0
|
||||
form-data: 4.0.1
|
||||
html-encoding-sniffer: 4.0.0
|
||||
http-proxy-agent: 7.0.2
|
||||
https-proxy-agent: 7.0.5
|
||||
is-potential-custom-element-name: 1.0.1
|
||||
nwsapi: 2.2.13
|
||||
parse5: 7.1.2
|
||||
parse5: 7.2.1
|
||||
rrweb-cssom: 0.7.1
|
||||
saxes: 6.0.0
|
||||
symbol-tree: 3.2.4
|
||||
|
@ -5162,7 +5067,7 @@ snapshots:
|
|||
json-parse-even-better-errors: 2.3.1
|
||||
lines-and-columns: 1.2.4
|
||||
|
||||
parse5@7.1.2:
|
||||
parse5@7.2.1:
|
||||
dependencies:
|
||||
entities: 4.5.0
|
||||
|
||||
|
@ -5185,8 +5090,6 @@ snapshots:
|
|||
|
||||
pathval@2.0.0: {}
|
||||
|
||||
picocolors@1.1.0: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
@ -5209,13 +5112,13 @@ snapshots:
|
|||
|
||||
pluralize@8.0.0: {}
|
||||
|
||||
postcss-safe-parser@6.0.0(postcss@8.4.47):
|
||||
postcss-safe-parser@6.0.0(postcss@8.4.49):
|
||||
dependencies:
|
||||
postcss: 8.4.47
|
||||
postcss: 8.4.49
|
||||
|
||||
postcss-scss@4.0.9(postcss@8.4.47):
|
||||
postcss-scss@4.0.9(postcss@8.4.49):
|
||||
dependencies:
|
||||
postcss: 8.4.47
|
||||
postcss: 8.4.49
|
||||
|
||||
postcss-selector-parser@6.1.2:
|
||||
dependencies:
|
||||
|
@ -5227,17 +5130,11 @@ snapshots:
|
|||
debug: 4.3.7
|
||||
fast-diff: 1.3.0
|
||||
lodash.sortedlastindex: 4.1.0
|
||||
postcss: 8.4.47
|
||||
postcss: 8.4.49
|
||||
stylus: 0.57.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
postcss@8.4.47:
|
||||
dependencies:
|
||||
nanoid: 3.3.7
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
postcss@8.4.49:
|
||||
dependencies:
|
||||
nanoid: 3.3.7
|
||||
|
@ -5459,7 +5356,7 @@ snapshots:
|
|||
css-tree: 2.3.1
|
||||
css-what: 6.1.0
|
||||
csso: 5.0.5
|
||||
picocolors: 1.1.0
|
||||
picocolors: 1.1.1
|
||||
|
||||
symbol-tree@3.2.4: {}
|
||||
|
||||
|
@ -5467,11 +5364,6 @@ snapshots:
|
|||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
synckit@0.9.1:
|
||||
dependencies:
|
||||
'@pkgr/core': 0.1.1
|
||||
tslib: 2.7.0
|
||||
|
||||
synckit@0.9.2:
|
||||
dependencies:
|
||||
'@pkgr/core': 0.1.1
|
||||
|
@ -5491,11 +5383,11 @@ snapshots:
|
|||
|
||||
tinyspy@3.0.2: {}
|
||||
|
||||
tldts-core@6.1.50: {}
|
||||
tldts-core@6.1.61: {}
|
||||
|
||||
tldts@6.1.50:
|
||||
tldts@6.1.61:
|
||||
dependencies:
|
||||
tldts-core: 6.1.50
|
||||
tldts-core: 6.1.61
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
dependencies:
|
||||
|
@ -5507,22 +5399,16 @@ snapshots:
|
|||
|
||||
tough-cookie@5.0.0:
|
||||
dependencies:
|
||||
tldts: 6.1.50
|
||||
tldts: 6.1.61
|
||||
|
||||
tr46@5.0.0:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
ts-api-utils@1.3.0(typescript@5.6.3):
|
||||
dependencies:
|
||||
typescript: 5.6.3
|
||||
|
||||
ts-api-utils@1.4.0(typescript@5.6.3):
|
||||
dependencies:
|
||||
typescript: 5.6.3
|
||||
|
||||
tslib@2.7.0: {}
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
type-check@0.4.0:
|
||||
|
@ -5562,17 +5448,11 @@ snapshots:
|
|||
unist-util-is: 6.0.0
|
||||
unist-util-visit-parents: 6.0.1
|
||||
|
||||
unplugin@1.14.1:
|
||||
unplugin@1.16.0:
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
webpack-virtual-modules: 0.6.2
|
||||
|
||||
update-browserslist-db@1.1.1(browserslist@4.24.0):
|
||||
dependencies:
|
||||
browserslist: 4.24.0
|
||||
escalade: 3.2.0
|
||||
picocolors: 1.1.1
|
||||
|
||||
update-browserslist-db@1.1.1(browserslist@4.24.2):
|
||||
dependencies:
|
||||
browserslist: 4.24.2
|
||||
|
@ -5610,7 +5490,7 @@ snapshots:
|
|||
|
||||
vite-plugin-prismjs@0.0.11(prismjs@1.29.0):
|
||||
dependencies:
|
||||
'@babel/core': 7.25.7
|
||||
'@babel/core': 7.26.0
|
||||
babel-plugin-prismjs: 2.1.0(prismjs@1.29.0)
|
||||
transitivePeerDependencies:
|
||||
- prismjs
|
||||
|
@ -5679,7 +5559,7 @@ snapshots:
|
|||
|
||||
vscode-uri@3.0.8: {}
|
||||
|
||||
vue-component-type-helpers@2.1.6: {}
|
||||
vue-component-type-helpers@2.1.10: {}
|
||||
|
||||
vue-demi@0.14.10(vue@3.5.13(typescript@5.6.3)):
|
||||
dependencies:
|
||||
|
|
|
@ -88,10 +88,6 @@
|
|||
"allow": "Allow deployments",
|
||||
"desc": "Allow deployments from successful pipelines. Only use if you trust all users with push access."
|
||||
},
|
||||
"protected": {
|
||||
"protected": "Protected",
|
||||
"desc": "Every pipeline needs to be approved before being executed."
|
||||
},
|
||||
"netrc_only_trusted": {
|
||||
"netrc_only_trusted": "Only inject netrc credentials into trusted clone plugins",
|
||||
"desc": "If enabled, git netrc credentials are only available for trusted clone plugins set in `WOODPECKER_PLUGINS_TRUSTED_CLONE`. Otherwise, all clone plugins can use the netrc credentials. This option has no effect on non-clone steps."
|
||||
|
@ -504,5 +500,14 @@
|
|||
"internal_error": "Some internal error occurred",
|
||||
"registration_closed": "The registration is closed",
|
||||
"access_denied": "You are not allowed to access this instance",
|
||||
"invalid_state": "The OAuth state is invalid"
|
||||
"invalid_state": "The OAuth state is invalid",
|
||||
"require_approval": {
|
||||
"require_approval_for": "Require approval for",
|
||||
"none": "No approval required",
|
||||
"none_desc": "This setting can be dangerous and should only be used on private forges where all users are trusted.",
|
||||
"forks": "Pull request from forked repositories",
|
||||
"pull_requests": "All pull requests",
|
||||
"all_events": "All events from forge",
|
||||
"desc": "Prevent malicious pipelines from exposing secrets or running harmful tasks by approving them before execution."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<AgentManager
|
||||
:desc="$t('admin.settings.agents.desc')"
|
||||
:description="$t('admin.settings.agents.desc')"
|
||||
:load-agents="loadAgents"
|
||||
:create-agent="createAgent"
|
||||
:update-agent="updateAgent"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Settings :title="$t('admin.settings.orgs.orgs')" :desc="$t('admin.settings.orgs.desc')">
|
||||
<Settings :title="$t('admin.settings.orgs.orgs')" :description="$t('admin.settings.orgs.desc')">
|
||||
<div class="space-y-4 text-wp-text-100">
|
||||
<ListItem
|
||||
v-for="org in orgs"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('admin.settings.queue.queue')" :desc="$t('admin.settings.queue.desc')">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('admin.settings.queue.queue')" :description="$t('admin.settings.queue.desc')">
|
||||
<template #headerActions>
|
||||
<div v-if="queueInfo">
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<template>
|
||||
<Settings
|
||||
:title="$t('registries.registries')"
|
||||
:desc="$t('admin.settings.registries.desc')"
|
||||
:description="$t('admin.settings.registries.desc')"
|
||||
docs-url="docs/usage/registries"
|
||||
:warning="$t('admin.settings.registries.warning')"
|
||||
>
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedRegistry"
|
||||
:text="$t('registries.show')"
|
||||
|
@ -15,6 +14,10 @@
|
|||
<Button v-else :text="$t('registries.add')" start-icon="plus" @click="showAddRegistry" />
|
||||
</template>
|
||||
|
||||
<template #headerEnd>
|
||||
<Warning class="text-sm mt-4" :text="$t('admin.settings.registries.warning')" />
|
||||
</template>
|
||||
|
||||
<RegistryList
|
||||
v-if="!selectedRegistry"
|
||||
v-model="registries"
|
||||
|
@ -39,6 +42,7 @@ import { computed, ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import Button from '~/components/atomic/Button.vue';
|
||||
import Warning from '~/components/atomic/Warning.vue';
|
||||
import Settings from '~/components/layout/Settings.vue';
|
||||
import RegistryEdit from '~/components/registry/RegistryEdit.vue';
|
||||
import RegistryList from '~/components/registry/RegistryList.vue';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('admin.settings.repos.repos')" :desc="$t('admin.settings.repos.desc')">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('admin.settings.repos.repos')" :description="$t('admin.settings.repos.desc')">
|
||||
<template #headerActions>
|
||||
<Button
|
||||
start-icon="heal"
|
||||
:is-loading="isRepairingRepos"
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<template>
|
||||
<Settings
|
||||
:title="$t('secrets.secrets')"
|
||||
:desc="$t('admin.settings.secrets.desc')"
|
||||
:description="$t('admin.settings.secrets.desc')"
|
||||
docs-url="docs/usage/secrets"
|
||||
:warning="$t('admin.settings.secrets.warning')"
|
||||
>
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
|
||||
<Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
|
||||
</template>
|
||||
|
||||
<template #headerEnd>
|
||||
<Warning class="text-sm mt-4" :text="$t('admin.settings.secrets.warning')" />
|
||||
</template>
|
||||
|
||||
<SecretList
|
||||
v-if="!selectedSecret"
|
||||
v-model="secrets"
|
||||
|
@ -34,6 +37,7 @@ import { computed, ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import Button from '~/components/atomic/Button.vue';
|
||||
import Warning from '~/components/atomic/Warning.vue';
|
||||
import Settings from '~/components/layout/Settings.vue';
|
||||
import SecretEdit from '~/components/secrets/SecretEdit.vue';
|
||||
import SecretList from '~/components/secrets/SecretList.vue';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('admin.settings.users.users')" :desc="$t('admin.settings.users.desc')">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('admin.settings.users.users')" :description="$t('admin.settings.users.desc')">
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedUser"
|
||||
:text="$t('admin.settings.users.show')"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('admin.settings.agents.agents')" :desc="desc">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('admin.settings.agents.agents')" :description>
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedAgent"
|
||||
:text="$t('admin.settings.agents.show')"
|
||||
|
@ -46,7 +46,7 @@ import AgentForm from './AgentForm.vue';
|
|||
import AgentList from './AgentList.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
desc: string;
|
||||
description: string;
|
||||
loadAgents: (page: number) => Promise<Agent[] | null>;
|
||||
createAgent: (agent: Partial<Agent>) => Promise<Agent>;
|
||||
updateAgent: (agent: Agent) => Promise<Agent | void>;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
type="radio"
|
||||
class="radio relative flex-shrink-0 border bg-wp-control-neutral-100 border-wp-control-neutral-200 cursor-pointer rounded-full w-5 h-5 checked:bg-wp-control-ok-200 checked:border-wp-control-ok-200 focus-visible:border-wp-control-neutral-300 checked:focus-visible:border-wp-control-ok-300"
|
||||
:value="option.value"
|
||||
:checked="innerValue.includes(option.value)"
|
||||
:checked="innerValue?.includes(option.value)"
|
||||
@click="innerValue = option.value"
|
||||
/>
|
||||
<div class="flex flex-col ml-4">
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<template>
|
||||
<Panel>
|
||||
<h1 class="text-xl text-wp-text-100">{{ title }}</h1>
|
||||
<div class="flex flex-col gap-4 border-b mb-4 pb-4">
|
||||
<div class="flex flex-col sm:flex-row gap-4 sm:gap-12 md:justify-between dark:border-wp-background-100">
|
||||
<div v-if="desc" class="flex items-center gap-x-2 text-sm text-wp-text-alt-100">
|
||||
<span class="flex flex-grow-0">{{ desc }}</span>
|
||||
<DocsLink v-if="docsUrl" class="flex flex-grow-0" :topic="title" :url="docsUrl" />
|
||||
</div>
|
||||
<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">
|
||||
{{ title }}
|
||||
<DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" />
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
<slot v-if="$slots.titleActions" name="titleActions" />
|
||||
<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>
|
||||
<div v-if="$slots.headerActions">
|
||||
<slot name="headerActions" />
|
||||
</div>
|
||||
</div>
|
||||
<Warning v-if="warning" class="text-sm mt-1" :text="warning" />
|
||||
<slot name="headerEnd" />
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
|
@ -21,13 +21,11 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import DocsLink from '~/components/atomic/DocsLink.vue';
|
||||
import Warning from '~/components/atomic/Warning.vue';
|
||||
import Panel from '~/components/layout/Panel.vue';
|
||||
|
||||
defineProps<{
|
||||
title: string;
|
||||
desc?: string;
|
||||
description?: string;
|
||||
docsUrl?: string;
|
||||
warning?: string;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
>
|
||||
<div v-if="pipelineCount > 0" class="spinner" />
|
||||
<div
|
||||
class="z-1 flex items-center justify-center h-full w-full font-bold bg-white bg-opacity-15 dark:bg-black dark:bg-opacity-10 rounded-md"
|
||||
class="z-0 flex items-center justify-center h-full w-full font-bold bg-white bg-opacity-15 dark:bg-black dark:bg-opacity-10 rounded-md"
|
||||
>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
|
||||
{{ pipelineCount > 9 ? '9+' : pipelineCount }}
|
||||
|
@ -31,17 +31,17 @@ onMounted(async () => {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
@keyframes spinner-rotate {
|
||||
@keyframes rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
.spinner {
|
||||
@apply absolute z-0 inset-1.5 rounded-md;
|
||||
@apply absolute inset-1.5 rounded-md;
|
||||
overflow: hidden;
|
||||
}
|
||||
.spinner::before {
|
||||
@apply absolute -z-2 bg-wp-primary-200 dark:bg-wp-primary-300;
|
||||
@apply absolute bg-wp-primary-200 dark:bg-wp-primary-300;
|
||||
content: '';
|
||||
left: -50%;
|
||||
top: -50%;
|
||||
|
@ -51,11 +51,16 @@ onMounted(async () => {
|
|||
background-size:
|
||||
50% 50%,
|
||||
50% 50%;
|
||||
background-image: linear-gradient(#fff, transparent);
|
||||
animation: spinner-rotate 1.5s linear infinite;
|
||||
background-image: linear-gradient(#fff, #fff);
|
||||
animation: rotate 1.5s linear infinite;
|
||||
}
|
||||
.spinner::after {
|
||||
@apply absolute inset-0.5 rounded-md bg-blend-darken bg-wp-primary-200 dark:bg-wp-primary-300;
|
||||
@apply absolute inset-0.5 bg-wp-primary-200 dark:bg-wp-primary-300;
|
||||
/*
|
||||
The nested border radius needs to be calculated correctly to look right:
|
||||
https://www.30secondsofcode.org/css/s/nested-border-radius/
|
||||
*/
|
||||
border-radius: calc(0.375rem - 0.125rem);
|
||||
content: '';
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -24,26 +24,26 @@
|
|||
</div>
|
||||
<TextField
|
||||
v-if="searchBoxPresent"
|
||||
class="w-auto <md:w-full <md:order-3"
|
||||
class="w-auto <md:w-full flex-grow <md:order-3"
|
||||
:aria-label="$t('search')"
|
||||
:placeholder="$t('search')"
|
||||
:model-value="search"
|
||||
@update:model-value="(value: string) => $emit('update:search', value)"
|
||||
/>
|
||||
<div
|
||||
v-if="$slots.titleActions"
|
||||
v-if="$slots.headerActions"
|
||||
class="flex items-center md:justify-end gap-x-2 min-w-0"
|
||||
:class="{
|
||||
'md:flex-1': searchBoxPresent,
|
||||
}"
|
||||
>
|
||||
<slot name="titleActions" />
|
||||
<slot name="headerActions" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="enableTabs" class="flex md:items-center flex-col py-2 md:flex-row md:justify-between md:py-0">
|
||||
<Tabs class="<md:order-2" />
|
||||
<div v-if="$slots.titleActions" class="flex content-start md:justify-end">
|
||||
<div v-if="$slots.headerActions" class="flex content-start md:justify-end">
|
||||
<slot name="tabActions" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,6 +52,8 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import IconButton from '~/components/atomic/IconButton.vue';
|
||||
import TextField from '~/components/form/TextField.vue';
|
||||
import Container from '~/components/layout/Container.vue';
|
||||
|
@ -69,5 +71,5 @@ defineEmits<{
|
|||
(event: 'update:search', query: string): void;
|
||||
}>();
|
||||
|
||||
const searchBoxPresent = props.search !== undefined;
|
||||
const searchBoxPresent = computed(() => props.search !== undefined);
|
||||
</script>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
@update:search="(value) => $emit('update:search', value)"
|
||||
>
|
||||
<template #title><slot name="title" /></template>
|
||||
<template v-if="$slots.titleActions" #titleActions><slot name="titleActions" /></template>
|
||||
<template v-if="$slots.headerActions" #headerActions><slot name="headerActions" /></template>
|
||||
<template v-if="$slots.tabActions" #tabActions><slot name="tabActions" /></template>
|
||||
</Header>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<AgentManager
|
||||
:desc="$t('org.settings.agents.desc')"
|
||||
:description="$t('org.settings.agents.desc')"
|
||||
:load-agents="loadAgents"
|
||||
:create-agent="createAgent"
|
||||
:update-agent="updateAgent"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<Settings
|
||||
:title="$t('registries.registries')"
|
||||
:desc="$t('org.settings.registries.desc')"
|
||||
:description="$t('org.settings.registries.desc')"
|
||||
docs-url="docs/usage/registries"
|
||||
>
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedRegistry"
|
||||
:text="$t('registries.show')"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('secrets.secrets')" :desc="$t('org.settings.secrets.desc')" docs-url="docs/usage/secrets">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('secrets.secrets')" :description="$t('org.settings.secrets.desc')" docs-url="docs/usage/secrets">
|
||||
<template #headerActions>
|
||||
<Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
|
||||
<Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('repo.settings.badge.badge')">
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<a v-if="badgeUrl" :href="badgeUrl" target="_blank">
|
||||
<img :src="badgeUrl" />
|
||||
</a>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<Settings :title="$t('repo.settings.crons.crons')" :desc="$t('repo.settings.crons.desc')" docs-url="docs/usage/cron">
|
||||
<template #titleActions>
|
||||
<Settings
|
||||
:title="$t('repo.settings.crons.crons')"
|
||||
:description="$t('repo.settings.crons.desc')"
|
||||
docs-url="docs/usage/cron"
|
||||
>
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedCron"
|
||||
start-icon="back"
|
||||
|
|
|
@ -1,26 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('repo.settings.general.general')">
|
||||
<form v-if="repoSettings" class="flex flex-col" @submit.prevent="saveRepoSettings">
|
||||
<InputField
|
||||
docs-url="docs/usage/project-settings#pipeline-path"
|
||||
:label="$t('repo.settings.general.pipeline_path.path')"
|
||||
>
|
||||
<template #default="{ id }">
|
||||
<TextField
|
||||
:id="id"
|
||||
v-model="repoSettings.config_file"
|
||||
:placeholder="$t('repo.settings.general.pipeline_path.default')"
|
||||
/>
|
||||
</template>
|
||||
<template #description>
|
||||
<i18n-t keypath="repo.settings.general.pipeline_path.desc" tag="p" class="text-sm text-wp-text-alt-100">
|
||||
<span class="code-box-inline">{{ $t('repo.settings.general.pipeline_path.desc_path_example') }}</span>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
|
||||
<span class="code-box-inline">/</span>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</InputField>
|
||||
|
||||
<InputField
|
||||
docs-url="docs/usage/project-settings#project-settings-1"
|
||||
:label="$t('repo.settings.general.project')"
|
||||
|
@ -35,11 +15,6 @@
|
|||
:label="$t('repo.settings.general.allow_deploy.allow')"
|
||||
:description="$t('repo.settings.general.allow_deploy.desc')"
|
||||
/>
|
||||
<Checkbox
|
||||
v-model="repoSettings.gated"
|
||||
:label="$t('repo.settings.general.protected.protected')"
|
||||
:description="$t('repo.settings.general.protected.desc')"
|
||||
/>
|
||||
<Checkbox
|
||||
v-model="repoSettings.netrc_only_trusted"
|
||||
:label="$t('repo.settings.general.netrc_only_trusted.netrc_only_trusted')"
|
||||
|
@ -69,6 +44,36 @@
|
|||
/>
|
||||
</InputField>
|
||||
|
||||
<InputField :label="$t('require_approval.require_approval_for')">
|
||||
<RadioField
|
||||
v-model="repoSettings.require_approval"
|
||||
:options="[
|
||||
{
|
||||
value: RepoRequireApproval.None,
|
||||
text: $t('require_approval.none'),
|
||||
description: $t('require_approval.none_desc'),
|
||||
},
|
||||
{
|
||||
value: RepoRequireApproval.Forks,
|
||||
text: $t('require_approval.forks'),
|
||||
},
|
||||
{
|
||||
value: RepoRequireApproval.PullRequests,
|
||||
text: $t('require_approval.pull_requests'),
|
||||
},
|
||||
{
|
||||
value: RepoRequireApproval.AllEvents,
|
||||
text: $t('require_approval.all_events'),
|
||||
},
|
||||
]"
|
||||
/>
|
||||
<template #description>
|
||||
<p class="text-sm">
|
||||
{{ $t('require_approval.desc') }}
|
||||
</p>
|
||||
</template>
|
||||
</InputField>
|
||||
|
||||
<InputField
|
||||
docs-url="docs/usage/project-settings#project-visibility"
|
||||
:label="$t('repo.settings.general.visibility.visibility')"
|
||||
|
@ -87,6 +92,26 @@
|
|||
</div>
|
||||
</InputField>
|
||||
|
||||
<InputField
|
||||
docs-url="docs/usage/project-settings#pipeline-path"
|
||||
:label="$t('repo.settings.general.pipeline_path.path')"
|
||||
>
|
||||
<template #default="{ id }">
|
||||
<TextField
|
||||
:id="id"
|
||||
v-model="repoSettings.config_file"
|
||||
:placeholder="$t('repo.settings.general.pipeline_path.default')"
|
||||
/>
|
||||
</template>
|
||||
<template #description>
|
||||
<i18n-t keypath="repo.settings.general.pipeline_path.desc" tag="p" class="text-sm text-wp-text-alt-100">
|
||||
<span class="code-box-inline">{{ $t('repo.settings.general.pipeline_path.desc_path_example') }}</span>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
|
||||
<span class="code-box-inline">/</span>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</InputField>
|
||||
|
||||
<InputField
|
||||
docs-url="docs/usage/project-settings#cancel-previous-pipelines"
|
||||
:label="$t('repo.settings.general.cancel_prev.cancel')"
|
||||
|
@ -130,7 +155,7 @@ import useApiClient from '~/compositions/useApiClient';
|
|||
import { useAsyncAction } from '~/compositions/useAsyncAction';
|
||||
import useAuthentication from '~/compositions/useAuthentication';
|
||||
import useNotifications from '~/compositions/useNotifications';
|
||||
import { RepoVisibility, WebhookEvents, type Repo, type RepoSettings } from '~/lib/api/types';
|
||||
import { RepoRequireApproval, RepoVisibility, WebhookEvents, type Repo, type RepoSettings } from '~/lib/api/types';
|
||||
import { useRepoStore } from '~/store/repos';
|
||||
|
||||
const apiClient = useApiClient();
|
||||
|
@ -151,7 +176,7 @@ function loadRepoSettings() {
|
|||
config_file: repo.value.config_file,
|
||||
timeout: repo.value.timeout,
|
||||
visibility: repo.value.visibility,
|
||||
gated: repo.value.gated,
|
||||
require_approval: repo.value.require_approval,
|
||||
trusted: repo.value.trusted,
|
||||
allow_pr: repo.value.allow_pr,
|
||||
allow_deploy: repo.value.allow_deploy,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('registries.credentials')" :desc="$t('registries.desc')" docs-url="docs/usage/registries">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('registries.credentials')" :description="$t('registries.desc')" docs-url="docs/usage/registries">
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedRegistry"
|
||||
:text="$t('registries.show')"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('secrets.secrets')" :desc="$t('secrets.desc')" docs-url="docs/usage/secrets">
|
||||
<template #titleActions>
|
||||
<Settings :title="$t('secrets.secrets')" :description="$t('secrets.desc')" docs-url="docs/usage/secrets">
|
||||
<template #headerActions>
|
||||
<Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
|
||||
<Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<AgentManager
|
||||
:desc="$t('user.settings.agents.desc')"
|
||||
:description="$t('user.settings.agents.desc')"
|
||||
:load-agents="loadAgents"
|
||||
:create-agent="createAgent"
|
||||
:update-agent="updateAgent"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<Settings :title="$t('user.settings.cli_and_api.cli_and_api')" :desc="$t('user.settings.cli_and_api.desc')">
|
||||
<Settings :title="$t('user.settings.cli_and_api.cli_and_api')" :description="$t('user.settings.cli_and_api.desc')">
|
||||
<InputField :label="$t('user.settings.cli_and_api.cli_usage')">
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<a :href="cliDownload" target="_blank" class="ml-4 text-wp-link-100 hover:text-wp-link-200">{{
|
||||
$t('user.settings.cli_and_api.download_cli')
|
||||
}}</a>
|
||||
|
@ -10,14 +10,14 @@
|
|||
</InputField>
|
||||
|
||||
<InputField :label="$t('user.settings.cli_and_api.token')">
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" />
|
||||
</template>
|
||||
<pre class="code-box">{{ token }}</pre>
|
||||
</InputField>
|
||||
|
||||
<InputField :label="$t('user.settings.cli_and_api.api_usage')">
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<a
|
||||
v-if="enableSwagger"
|
||||
:href="`${address}/swagger/index.html`"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<Settings
|
||||
:title="$t('registries.registries')"
|
||||
:desc="$t('user.settings.registries.desc')"
|
||||
:description="$t('user.settings.registries.desc')"
|
||||
docs-url="docs/usage/registries"
|
||||
>
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button
|
||||
v-if="selectedRegistry"
|
||||
:text="$t('registries.show')"
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<Settings :title="$t('secrets.secrets')" :desc="$t('user.settings.secrets.desc')" docs-url="docs/usage/secrets">
|
||||
<template #titleActions>
|
||||
<Settings
|
||||
:title="$t('secrets.secrets')"
|
||||
:description="$t('user.settings.secrets.desc')"
|
||||
docs-url="docs/usage/secrets"
|
||||
>
|
||||
<template #headerActions>
|
||||
<Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
|
||||
<Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
|
||||
</template>
|
||||
|
|
|
@ -67,7 +67,7 @@ export interface Repo {
|
|||
|
||||
last_pipeline: number;
|
||||
|
||||
gated: boolean;
|
||||
require_approval: RepoRequireApproval;
|
||||
|
||||
// Events that will cancel running pipelines before starting a new one
|
||||
cancel_previous_pipeline_events: string[];
|
||||
|
@ -81,6 +81,13 @@ export enum RepoVisibility {
|
|||
Private = 'private',
|
||||
Internal = 'internal',
|
||||
}
|
||||
|
||||
export enum RepoRequireApproval {
|
||||
None = 'none',
|
||||
Forks = 'forks',
|
||||
PullRequests = 'pull_requests',
|
||||
AllEvents = 'all_events',
|
||||
}
|
||||
/* eslint-enable */
|
||||
|
||||
export type RepoSettings = Pick<
|
||||
|
@ -89,7 +96,7 @@ export type RepoSettings = Pick<
|
|||
| 'timeout'
|
||||
| 'visibility'
|
||||
| 'trusted'
|
||||
| 'gated'
|
||||
| 'require_approval'
|
||||
| 'allow_pr'
|
||||
| 'allow_deploy'
|
||||
| 'cancel_previous_pipeline_events'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{ $t('repositories') }}
|
||||
</template>
|
||||
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<Button :to="{ name: 'repo-add' }" start-icon="plus" :text="$t('repo.add')" />
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<Scaffold enable-tabs>
|
||||
<template #title>{{ $t('user.settings.settings') }}</template>
|
||||
<template #titleActions><Button :text="$t('logout')" :to="`${address}/logout`" /></template>
|
||||
<template #headerActions><Button :text="$t('logout')" :to="`${address}/logout`" /></template>
|
||||
<Tab id="general" :title="$t('user.settings.general.general')">
|
||||
<UserGeneralTab />
|
||||
</Tab>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{ org.name }}
|
||||
</template>
|
||||
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<IconButton
|
||||
v-if="orgPermissions.admin"
|
||||
icon="settings"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{ org.name }}
|
||||
</template>
|
||||
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<IconButton
|
||||
v-if="orgPermissions.admin"
|
||||
:to="{ name: org.is_user ? 'user' : 'repo-settings' }"
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
v-model:active-tab="activeTab"
|
||||
enable-tabs
|
||||
disable-tab-url-hash-mode
|
||||
:go-back="goBack"
|
||||
>
|
||||
<template #title>
|
||||
<span class="flex">
|
||||
|
@ -16,7 +15,7 @@
|
|||
{{ repo.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<a v-if="badgeUrl" :href="badgeUrl" target="_blank">
|
||||
<img :src="badgeUrl" />
|
||||
</a>
|
||||
|
@ -68,7 +67,6 @@ import useAuthentication from '~/compositions/useAuthentication';
|
|||
import useConfig from '~/compositions/useConfig';
|
||||
import { useForgeStore } from '~/compositions/useForgeStore';
|
||||
import useNotifications from '~/compositions/useNotifications';
|
||||
import { useRouteBack } from '~/compositions/useRouteBack';
|
||||
import type { Forge, RepoPermissions } from '~/lib/api/types';
|
||||
import { usePipelineStore } from '~/store/pipelines';
|
||||
import { useRepoStore } from '~/store/repos';
|
||||
|
@ -155,6 +153,4 @@ const activeTab = computed({
|
|||
}
|
||||
},
|
||||
});
|
||||
|
||||
const goBack = useRouteBack({ name: 'repos' });
|
||||
</script>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</span>
|
||||
</template>
|
||||
|
||||
<template #titleActions>
|
||||
<template #headerActions>
|
||||
<div class="flex md:items-center flex-col gap-2 md:flex-row md:justify-between min-w-0">
|
||||
<div class="flex content-start gap-2 min-w-0">
|
||||
<PipelineStatusIcon :status="pipeline.status" class="flex flex-shrink-0" />
|
||||
|
|
|
@ -14,6 +14,27 @@
|
|||
|
||||
package woodpecker
|
||||
|
||||
type ApprovalMode string
|
||||
|
||||
var (
|
||||
RequireApprovalNone ApprovalMode = "none" // require approval for no events
|
||||
RequireApprovalForks ApprovalMode = "forks" // require approval for PRs from forks
|
||||
RequireApprovalPullRequests ApprovalMode = "pull_requests" // require approval for all PRs (default)
|
||||
RequireApprovalAllEvents ApprovalMode = "all_events" // require approval for all events
|
||||
)
|
||||
|
||||
func (mode ApprovalMode) Valid() bool {
|
||||
switch mode {
|
||||
case RequireApprovalNone,
|
||||
RequireApprovalForks,
|
||||
RequireApprovalPullRequests,
|
||||
RequireApprovalAllEvents:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// User represents a user account.
|
||||
User struct {
|
||||
|
@ -27,37 +48,39 @@ type (
|
|||
|
||||
// Repo represents a repository.
|
||||
Repo struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
ForgeRemoteID string `json:"forge_remote_id"`
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Avatar string `json:"avatar_url,omitempty"`
|
||||
ForgeURL string `json:"forge_url,omitempty"`
|
||||
Clone string `json:"clone_url,omitempty"`
|
||||
DefaultBranch string `json:"default_branch,omitempty"`
|
||||
SCMKind string `json:"scm,omitempty"`
|
||||
Timeout int64 `json:"timeout,omitempty"`
|
||||
Visibility string `json:"visibility"`
|
||||
IsSCMPrivate bool `json:"private"`
|
||||
IsTrusted bool `json:"trusted"`
|
||||
IsGated bool `json:"gated"`
|
||||
IsActive bool `json:"active"`
|
||||
AllowPullRequests bool `json:"allow_pr"`
|
||||
Config string `json:"config_file"`
|
||||
CancelPreviousPipelineEvents []string `json:"cancel_previous_pipeline_events"`
|
||||
NetrcOnlyTrusted bool `json:"netrc_only_trusted"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
ForgeRemoteID string `json:"forge_remote_id"`
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Avatar string `json:"avatar_url,omitempty"`
|
||||
ForgeURL string `json:"forge_url,omitempty"`
|
||||
Clone string `json:"clone_url,omitempty"`
|
||||
DefaultBranch string `json:"default_branch,omitempty"`
|
||||
SCMKind string `json:"scm,omitempty"`
|
||||
Timeout int64 `json:"timeout,omitempty"`
|
||||
Visibility string `json:"visibility"`
|
||||
IsSCMPrivate bool `json:"private"`
|
||||
IsTrusted bool `json:"trusted"`
|
||||
IsGated bool `json:"gated,omitempty"` // TODO: remove in next major release
|
||||
RequireApproval ApprovalMode `json:"require_approval"`
|
||||
IsActive bool `json:"active"`
|
||||
AllowPullRequests bool `json:"allow_pr"`
|
||||
Config string `json:"config_file"`
|
||||
CancelPreviousPipelineEvents []string `json:"cancel_previous_pipeline_events"`
|
||||
NetrcOnlyTrusted bool `json:"netrc_only_trusted"`
|
||||
}
|
||||
|
||||
// RepoPatch defines a repository patch request.
|
||||
RepoPatch struct {
|
||||
Config *string `json:"config_file,omitempty"`
|
||||
IsTrusted *bool `json:"trusted,omitempty"`
|
||||
IsGated *bool `json:"gated,omitempty"`
|
||||
Timeout *int64 `json:"timeout,omitempty"`
|
||||
Visibility *string `json:"visibility"`
|
||||
AllowPull *bool `json:"allow_pr,omitempty"`
|
||||
PipelineCounter *int `json:"pipeline_counter,omitempty"`
|
||||
Config *string `json:"config_file,omitempty"`
|
||||
IsTrusted *bool `json:"trusted,omitempty"`
|
||||
IsGated *bool `json:"gated,omitempty"` // TODO: remove in next major release
|
||||
RequireApproval *ApprovalMode `json:"require_approval,omitempty"`
|
||||
Timeout *int64 `json:"timeout,omitempty"`
|
||||
Visibility *string `json:"visibility"`
|
||||
AllowPull *bool `json:"allow_pr,omitempty"`
|
||||
PipelineCounter *int `json:"pipeline_counter,omitempty"`
|
||||
}
|
||||
|
||||
PipelineError struct {
|
||||
|
|
Loading…
Reference in a new issue