Skip to content

Commit

Permalink
Allow to disable deployments (#3570)
Browse files Browse the repository at this point in the history
…but if they're enabled, allow for all events. Also add warning that you
should only enable it if you trust the users with push access.

closes #3559

---------

Co-authored-by: Robert Kaussow <xoxys@rknet.org>
  • Loading branch information
qwerty287 and xoxys authored Apr 2, 2024
1 parent a6e054f commit eaf1061
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 12 deletions.
6 changes: 6 additions & 0 deletions cmd/server/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4048,6 +4048,9 @@ const docTemplate = `{
"active": {
"type": "boolean"
},
"allow_deploy": {
"type": "boolean"
},
"allow_pr": {
"type": "boolean"
},
Expand Down Expand Up @@ -4123,6 +4126,9 @@ const docTemplate = `{
"RepoPatch": {
"type": "object",
"properties": {
"allow_deploy": {
"type": "boolean"
},
"allow_pr": {
"type": "boolean"
},
Expand Down
9 changes: 9 additions & 0 deletions docs/docs/20-usage/71-project-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ Your Version-Control-System will notify Woodpecker about events via webhooks. If

Enables handling webhook's pull request event. If disabled, then pipeline won't run for pull requests.

## Allow deployments

Enables a pipeline to be started with the `deploy` event from a successful pipeline.

:::danger
Only activate this option if you trust all users who have push access to your repository.
Otherwise, these users will be able to steal secrets that are only available for `deploy` events.
:::

## Protected

Every pipeline initiated by an webhook event needs to be approved by a project members with push permissions before being executed.
Expand Down
15 changes: 7 additions & 8 deletions server/api/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,23 +407,22 @@ func PostPipeline(c *gin.Context) {
refreshUserToken(c, user)

// make Deploy overridable
pl.Deploy = c.DefaultQuery("deploy_to", pl.Deploy)

// make Event overridable to deploy
// TODO refactor to use own proper API for deploy
if event, ok := c.GetQuery("event"); ok {
// only allow deploy from push, tag and release
if pl.Event != model.EventPush && pl.Event != model.EventTag && pl.Event != model.EventRelease {
_ = c.AbortWithError(http.StatusBadRequest, fmt.Errorf("can only deploy push, tag and release pipelines"))
return
}

pl.Event = model.WebhookEvent(event)

if pl.Event != model.EventDeploy {
_ = c.AbortWithError(http.StatusBadRequest, model.ErrInvalidWebhookEvent)
return
}

if !repo.AllowDeploy {
_ = c.AbortWithError(http.StatusForbidden, fmt.Errorf("repo does not allow deployments"))
return
}

pl.Deploy = c.DefaultQuery("deploy_to", pl.Deploy)
}

// Read query string parameters into pipelineParams, exclude reserved params
Expand Down
4 changes: 4 additions & 0 deletions server/api/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func PostRepo(c *gin.Context) {
} else {
repo = from
repo.AllowPull = true
repo.AllowDeploy = false
repo.NetrcOnlyTrusted = true
repo.CancelPreviousPipelineEvents = server.Config.Pipeline.DefaultCancelPreviousPipelineEvents
}
Expand Down Expand Up @@ -223,6 +224,9 @@ func PatchRepo(c *gin.Context) {
if in.AllowPull != nil {
repo.AllowPull = *in.AllowPull
}
if in.AllowDeploy != nil {
repo.AllowDeploy = *in.AllowDeploy
}
if in.IsGated != nil {
repo.IsGated = *in.IsGated
}
Expand Down
2 changes: 2 additions & 0 deletions server/model/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Repo struct {
IsGated bool `json:"gated" xorm:"repo_gated"`
IsActive bool `json:"active" xorm:"repo_active"`
AllowPull bool `json:"allow_pr" xorm:"repo_allow_pr"`
AllowDeploy bool `json:"allow_deploy" xorm:"repo_allow_deploy"`
Config string `json:"config_file" xorm:"varchar(500) 'repo_config_path'"`
Hash string `json:"-" xorm:"varchar(500) 'repo_hash'"`
Perm *Perm `json:"-" xorm:"-"`
Expand Down Expand Up @@ -112,6 +113,7 @@ type RepoPatch struct {
Timeout *int64 `json:"timeout,omitempty"`
Visibility *string `json:"visibility,omitempty"`
AllowPull *bool `json:"allow_pr,omitempty"`
AllowDeploy *bool `json:"allow_deploy,omitempty"`
CancelPreviousPipelineEvents *[]WebhookEvent `json:"cancel_previous_pipeline_events"`
NetrcOnlyTrusted *bool `json:"netrc_only_trusted"`
} // @name RepoPatch
Expand Down
4 changes: 4 additions & 0 deletions web/src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
"allow": "Allow Pull Requests",
"desc": "Pipelines can run on pull requests."
},
"allow_deploy": {
"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."
Expand Down
6 changes: 6 additions & 0 deletions web/src/components/repo/settings/GeneralTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
:label="$t('repo.settings.general.allow_pr.allow')"
:description="$t('repo.settings.general.allow_pr.desc')"
/>
<Checkbox
v-model="repoSettings.allow_deploy"
: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')"
Expand Down Expand Up @@ -132,6 +137,7 @@ function loadRepoSettings() {
gated: repo.value.gated,
trusted: repo.value.trusted,
allow_pr: repo.value.allow_pr,
allow_deploy: repo.value.allow_deploy,
cancel_previous_pipeline_events: repo.value.cancel_previous_pipeline_events || [],
netrc_only_trusted: repo.value.netrc_only_trusted,
};
Expand Down
3 changes: 3 additions & 0 deletions web/src/lib/api/types/repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export type Repo = {
// Whether pull requests should trigger a pipeline.
allow_pr: boolean;

allow_deploy: boolean;

config_file: string;

visibility: RepoVisibility;
Expand Down Expand Up @@ -84,6 +86,7 @@ export type RepoSettings = Pick<
| 'trusted'
| 'gated'
| 'allow_pr'
| 'allow_deploy'
| 'cancel_previous_pipeline_events'
| 'netrc_only_trusted'
>;
Expand Down
5 changes: 1 addition & 4 deletions web/src/views/repo/pipeline/PipelineWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@
@click="restartPipeline"
/>
<Button
v-if="
pipeline.status === 'success' &&
(pipeline.event === 'push' || pipeline.event === 'tag' || pipeline.event === 'release')
"
v-if="pipeline.status === 'success' && repo.allow_deploy"
class="flex-shrink-0"
:text="$t('repo.pipeline.actions.deploy')"
@click="showDeployPipelinePopup = true"
Expand Down

0 comments on commit eaf1061

Please sign in to comment.