Extend approval options (#3348)

This commit is contained in:
Anbraten
2024-11-18 14:49:12 +01:00
committed by GitHub
parent 2a445a6663
commit 5e2fa8164b
27 changed files with 431 additions and 93 deletions

View File

@@ -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."
}
}

View File

@@ -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">

View File

@@ -1,18 +1,19 @@
<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="desc" class="text-sm text-wp-text-alt-100">{{ desc }}</p>
<div v-if="$slots.titleActions">
<slot name="titleActions" />
</div>
</div>
<Warning v-if="warning" class="text-sm mt-1" :text="warning" />
<Warning v-if="warning" class="text-sm mt-4" :text="warning" />
</div>
<slot />

View File

@@ -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,

View File

@@ -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'