Merge branch 'main' into pr/anbraten/3849
@ -25,6 +25,7 @@
|
||||
"backports",
|
||||
"binutils",
|
||||
"bitbucketdatacenter",
|
||||
"Bluesky",
|
||||
"Boguslawski",
|
||||
"bradrydzewski",
|
||||
"BUILDPLATFORM",
|
||||
@ -201,6 +202,7 @@
|
||||
"typecheck",
|
||||
"Typeflag",
|
||||
"unplugin",
|
||||
"unsanitize",
|
||||
"Upsert",
|
||||
"urfave",
|
||||
"usecase",
|
||||
|
4
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -80,11 +80,9 @@ body:
|
||||
label: Validations
|
||||
description: Before submitting the issue, please make sure you do the following
|
||||
options:
|
||||
# - label: Follow our [Code of Conduct](https://github.com/woodpecker-ci/woodpecker/blob/main/CODE_OF_CONDUCT.md)
|
||||
# required: true
|
||||
- label: Read the [docs](https://woodpecker-ci.org/docs/intro).
|
||||
required: true
|
||||
- label: Check that there isn't [already an issue](https://github.com/woodpecker-ci/woodpecker/issues) that reports the same bug to avoid creating a duplicate.
|
||||
required: true
|
||||
- label: Checked that the bug isn't fixed in the `next` version already [https://woodpecker-ci.org/faq#which-version-of-woodpecker-should-i-use]
|
||||
- label: Checked that the bug isn't fixed in the `next` version already [https://woodpecker-ci.org/versions]
|
||||
required: true
|
||||
|
4
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -37,9 +37,7 @@ body:
|
||||
label: Validations
|
||||
description: Before submitting the issue, please make sure you do the following
|
||||
options:
|
||||
# - label: Follow our [Code of Conduct](https://github.com/woodpecker-ci/woodpecker/blob/main/CODE_OF_CONDUCT.md)
|
||||
# required: true
|
||||
- label: Checked that the feature isn't part of the `next` version already [https://woodpecker-ci.org/faq#which-version-of-woodpecker-should-i-use]
|
||||
- label: Checked that the feature isn't part of the `next` version already [https://woodpecker-ci.org/versions]
|
||||
required: true
|
||||
- label: Read the [docs](https://woodpecker-ci.org/docs/intro).
|
||||
required: true
|
||||
|
@ -162,7 +162,7 @@ linters:
|
||||
- makezero
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- tenv
|
||||
- usetesting
|
||||
- unconvert
|
||||
- unparam
|
||||
- wastedassign
|
||||
|
@ -10,11 +10,11 @@ repos:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.63.4
|
||||
rev: v1.64.7
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.43.0
|
||||
rev: v0.44.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
exclude: '^(docs/versioned_docs/.*|CHANGELOG.md)$'
|
||||
@ -28,11 +28,11 @@ repos:
|
||||
hooks:
|
||||
- id: hadolint
|
||||
- repo: https://github.com/rbubley/mirrors-prettier
|
||||
rev: v3.4.2
|
||||
rev: v3.5.3
|
||||
hooks:
|
||||
- id: prettier
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.35.1
|
||||
rev: v1.36.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args: [--strict, -c=.yamllint.yaml]
|
||||
|
@ -7,9 +7,9 @@ when:
|
||||
- .woodpecker/binaries.yaml
|
||||
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &golang_image 'docker.io/golang:1.24'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.23.x'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.24.x'
|
||||
|
||||
# cspell:words bindata netgo
|
||||
|
||||
@ -99,7 +99,7 @@ steps:
|
||||
release:
|
||||
depends_on:
|
||||
- checksums
|
||||
image: woodpeckerci/plugin-release:0.2.3
|
||||
image: woodpeckerci/plugin-release:0.2.4
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: github_token
|
||||
|
@ -1,8 +1,8 @@
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &golang_image 'docker.io/golang:1.24'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.23.x'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:5.1.0'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.24.x'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:5.2.1'
|
||||
- &platforms_release 'linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/386,linux/amd64,linux/ppc64le,linux/riscv64,linux/s390x,freebsd/arm64,freebsd/amd64,openbsd/arm64,openbsd/amd64'
|
||||
- &platforms_server 'linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le,linux/riscv64'
|
||||
- &platforms_preview 'linux/amd64'
|
||||
|
@ -1,5 +1,5 @@
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &golang_image 'docker.io/golang:1.24'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.21'
|
||||
- path: &when_path
|
||||
@ -69,7 +69,7 @@ steps:
|
||||
- event: manual
|
||||
|
||||
deploy-preview:
|
||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.4
|
||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.5
|
||||
settings:
|
||||
path: 'docs/build/'
|
||||
surge_token:
|
||||
|
@ -6,7 +6,7 @@ when:
|
||||
|
||||
steps:
|
||||
- name: release-helper
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:3.1.1
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:3.1.3
|
||||
settings:
|
||||
release_branch: ${CI_COMMIT_BRANCH}
|
||||
forge_type: github
|
||||
|
@ -5,7 +5,7 @@ when:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
|
||||
variables:
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.3.0
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.4.0
|
||||
|
||||
steps:
|
||||
backend:
|
||||
|
@ -3,7 +3,7 @@ when:
|
||||
|
||||
steps:
|
||||
- name: lint-editorconfig
|
||||
image: docker.io/woodpeckerci/plugin-editorconfig-checker:0.2.0
|
||||
image: docker.io/woodpeckerci/plugin-editorconfig-checker:0.3.0
|
||||
depends_on: []
|
||||
when:
|
||||
- event: pull_request
|
||||
|
@ -1,5 +1,5 @@
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &golang_image 'docker.io/golang:1.24'
|
||||
- &when
|
||||
- path: &when_path # related config files
|
||||
- '.woodpecker/test.yaml'
|
||||
@ -149,7 +149,7 @@ services:
|
||||
when: *when
|
||||
|
||||
mysql:
|
||||
image: docker.io/mysql:9.1.0
|
||||
image: docker.io/mysql:9.2.0
|
||||
ports: ['3306']
|
||||
environment:
|
||||
MYSQL_DATABASE: test
|
||||
|
214
CHANGELOG.md
@ -1,5 +1,219 @@
|
||||
# Changelog
|
||||
|
||||
## [3.3.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.3.0) - 2025-03-04
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@Levy-Tal, @qwerty287, @xoxys
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Refactor admin docs [[#4899](https://github.com/woodpecker-ci/woodpecker/pull/4899)]
|
||||
- chore(deps): lock file maintenance [[#4928](https://github.com/woodpecker-ci/woodpecker/pull/4928)]
|
||||
- chore(deps): update dependency @types/node to v22.13.9 [[#4925](https://github.com/woodpecker-ci/woodpecker/pull/4925)]
|
||||
- chore(deps): lock file maintenance [[#4922](https://github.com/woodpecker-ci/woodpecker/pull/4922)]
|
||||
- Add some blog posts [[#4921](https://github.com/woodpecker-ci/woodpecker/pull/4921)]
|
||||
- chore(deps): update dependency @types/node to v22.13.8 [[#4915](https://github.com/woodpecker-ci/woodpecker/pull/4915)]
|
||||
- Remove Slack plugin from examples [[#4914](https://github.com/woodpecker-ci/woodpecker/pull/4914)]
|
||||
- chore(deps): update docs npm deps non-major [[#4911](https://github.com/woodpecker-ci/woodpecker/pull/4911)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Add migration to fix zero forge_id in orgs table [[#4924](https://github.com/woodpecker-ci/woodpecker/pull/4924)]
|
||||
- Fix unique constraint for orgs [[#4923](https://github.com/woodpecker-ci/woodpecker/pull/4923)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- BitbucketDC: optimize repository search [[#4919](https://github.com/woodpecker-ci/woodpecker/pull/4919)]
|
||||
- Include forge type in netrc [[#4908](https://github.com/woodpecker-ci/woodpecker/pull/4908)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- chore(deps): update dependency @types/node to v22.13.9 [[#4926](https://github.com/woodpecker-ci/woodpecker/pull/4926)]
|
||||
- chore(deps): update pre-commit non-major [[#4927](https://github.com/woodpecker-ci/woodpecker/pull/4927)]
|
||||
- chore(deps): update dependency @antfu/eslint-config to v4.4.0 [[#4917](https://github.com/woodpecker-ci/woodpecker/pull/4917)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.124.0 [[#4920](https://github.com/woodpecker-ci/woodpecker/pull/4920)]
|
||||
- chore(deps): update dependency @types/node to v22.13.8 [[#4916](https://github.com/woodpecker-ci/woodpecker/pull/4916)]
|
||||
- chore(deps): update dependency @types/lodash to v4.17.16 [[#4913](https://github.com/woodpecker-ci/woodpecker/pull/4913)]
|
||||
- chore(deps): update web npm deps non-major [[#4912](https://github.com/woodpecker-ci/woodpecker/pull/4912)]
|
||||
|
||||
## [3.2.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.2.0) - 2025-02-26
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@DHandspikerWade, @anbraten, @arthurpro, @hhomar, @jenrik, @jpgleeson, @mark-pitblado, @maurerle, @qwerty287, @xoxys
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- Fix approval requirement if PR is closed [[#4902](https://github.com/woodpecker-ci/woodpecker/pull/4902)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- chore(deps): lock file maintenance [[#4906](https://github.com/woodpecker-ci/woodpecker/pull/4906)]
|
||||
- chore(deps): update dependency axios to v1.8.1 [[#4905](https://github.com/woodpecker-ci/woodpecker/pull/4905)]
|
||||
- Fix typo on forgejo/gitea documentation [[#4898](https://github.com/woodpecker-ci/woodpecker/pull/4898)]
|
||||
- chore(deps): update docs npm deps non-major [[#4878](https://github.com/woodpecker-ci/woodpecker/pull/4878)]
|
||||
- plugins: add Hugo plugin for woodpecker [[#4870](https://github.com/woodpecker-ci/woodpecker/pull/4870)]
|
||||
- Add Microsoft Teams Notification (Advanced) plugin [[#4868](https://github.com/woodpecker-ci/woodpecker/pull/4868)]
|
||||
- chore(deps): update dependency @types/react to v19.0.9 [[#4864](https://github.com/woodpecker-ci/woodpecker/pull/4864)]
|
||||
- Drop versioned docs for v1 [[#4844](https://github.com/woodpecker-ci/woodpecker/pull/4844)]
|
||||
- Add a Home Assistant notification plugin [[#4841](https://github.com/woodpecker-ci/woodpecker/pull/4841)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Use forge IDs for hook tokens [[#4897](https://github.com/woodpecker-ci/woodpecker/pull/4897)]
|
||||
- Fix nil dereference in Bitbucket webhook handling [[#4896](https://github.com/woodpecker-ci/woodpecker/pull/4896)]
|
||||
- Fix org assign on login [[#4817](https://github.com/woodpecker-ci/woodpecker/pull/4817)]
|
||||
- Directly fetch directory contents [[#4842](https://github.com/woodpecker-ci/woodpecker/pull/4842)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- Remove eslint types [[#4893](https://github.com/woodpecker-ci/woodpecker/pull/4893)]
|
||||
- Add default option for allowing pull requests on repositories [[#4873](https://github.com/woodpecker-ci/woodpecker/pull/4873)]
|
||||
- Replace deprecated linter [[#4843](https://github.com/woodpecker-ci/woodpecker/pull/4843)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- chore(deps): update woodpeckerci/plugin-git docker tag to v2.6.2 [[#4903](https://github.com/woodpecker-ci/woodpecker/pull/4903)]
|
||||
- fix(deps): update web npm deps non-major [[#4904](https://github.com/woodpecker-ci/woodpecker/pull/4904)]
|
||||
- fix(deps): update golang-packages [[#4900](https://github.com/woodpecker-ci/woodpecker/pull/4900)]
|
||||
- chore(deps): lock file maintenance [[#4895](https://github.com/woodpecker-ci/woodpecker/pull/4895)]
|
||||
- chore(deps): update dependency vue-tsc to v2.2.4 [[#4894](https://github.com/woodpecker-ci/woodpecker/pull/4894)]
|
||||
- fix(deps): update dependency simple-icons to v14.8.0 [[#4891](https://github.com/woodpecker-ci/woodpecker/pull/4891)]
|
||||
- fix(deps): update golang-packages [[#4890](https://github.com/woodpecker-ci/woodpecker/pull/4890)]
|
||||
- chore(deps): update dependency @types/eslint__js to v9 [[#4884](https://github.com/woodpecker-ci/woodpecker/pull/4884)]
|
||||
- chore(deps): update pre-commit hook rbubley/mirrors-prettier to v3.5.2 [[#4883](https://github.com/woodpecker-ci/woodpecker/pull/4883)]
|
||||
- fix(deps): update module codeberg.org/mvdkleijn/forgejo-sdk/forgejo to v2 [[#4858](https://github.com/woodpecker-ci/woodpecker/pull/4858)]
|
||||
- fix(deps): update web npm deps non-major [[#4882](https://github.com/woodpecker-ci/woodpecker/pull/4882)]
|
||||
- chore(deps): update postgres docker tag to v17.4 [[#4881](https://github.com/woodpecker-ci/woodpecker/pull/4881)]
|
||||
- chore(deps): update woodpeckerci/plugin-git docker tag to v2.6.1 [[#4879](https://github.com/woodpecker-ci/woodpecker/pull/4879)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-editorconfig-checker docker tag to v0.3.0 [[#4880](https://github.com/woodpecker-ci/woodpecker/pull/4880)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-surge-preview docker tag to v1.3.5 [[#4877](https://github.com/woodpecker-ci/woodpecker/pull/4877)]
|
||||
- fix(deps): update module github.com/prometheus/client_golang to v1.21.0 [[#4874](https://github.com/woodpecker-ci/woodpecker/pull/4874)]
|
||||
- fix(deps): update module github.com/go-sql-driver/mysql to v1.9.0 [[#4872](https://github.com/woodpecker-ci/woodpecker/pull/4872)]
|
||||
- fix(deps): update module github.com/google/go-github/v69 to v69.2.0 [[#4869](https://github.com/woodpecker-ci/woodpecker/pull/4869)]
|
||||
- chore(deps): lock file maintenance [[#4866](https://github.com/woodpecker-ci/woodpecker/pull/4866)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-trivy docker tag to v1.4.0 [[#4865](https://github.com/woodpecker-ci/woodpecker/pull/4865)]
|
||||
- fix(deps): update dependency simple-icons to v14.7.0 [[#4862](https://github.com/woodpecker-ci/woodpecker/pull/4862)]
|
||||
- fix(deps): update dependency pinia to v3 [[#4856](https://github.com/woodpecker-ci/woodpecker/pull/4856)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.123.0 [[#4860](https://github.com/woodpecker-ci/woodpecker/pull/4860)]
|
||||
- chore(deps): update dependency vue-tsc to v2.2.2 [[#4859](https://github.com/woodpecker-ci/woodpecker/pull/4859)]
|
||||
- fix(deps): update web npm deps non-major [[#4857](https://github.com/woodpecker-ci/woodpecker/pull/4857)]
|
||||
- chore(deps): update pre-commit non-major [[#4855](https://github.com/woodpecker-ci/woodpecker/pull/4855)]
|
||||
- chore(deps): update postgres docker tag to v17.3 [[#4854](https://github.com/woodpecker-ci/woodpecker/pull/4854)]
|
||||
- chore(deps): update docker.io/techknowlogick/xgo docker tag to go-1.24.x [[#4853](https://github.com/woodpecker-ci/woodpecker/pull/4853)]
|
||||
- chore(deps): update docker.io/golang docker tag to v1.24 [[#4852](https://github.com/woodpecker-ci/woodpecker/pull/4852)]
|
||||
- chore(deps): update woodpeckerci/plugin-release docker tag to v0.2.4 [[#4851](https://github.com/woodpecker-ci/woodpecker/pull/4851)]
|
||||
- fix(deps): update dependency @tailwindcss/vite to v4.0.6 [[#4846](https://github.com/woodpecker-ci/woodpecker/pull/4846)]
|
||||
- chore(deps): lock file maintenance [[#4845](https://github.com/woodpecker-ci/woodpecker/pull/4845)]
|
||||
- fix(deps): update dependency tailwindcss to v4 [[#4778](https://github.com/woodpecker-ci/woodpecker/pull/4778)]
|
||||
- fix(deps): update golang-packages [[#4839](https://github.com/woodpecker-ci/woodpecker/pull/4839)]
|
||||
|
||||
### Misc
|
||||
|
||||
- kubernetes: create service for detached steps [[#4892](https://github.com/woodpecker-ci/woodpecker/pull/4892)]
|
||||
- docs: remove latest from docker compose example [[#4849](https://github.com/woodpecker-ci/woodpecker/pull/4849)]
|
||||
|
||||
## [3.1.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.1.0) - 2025-02-12
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@Levy-Tal, @anbraten, @cduchenoy, @damuzhi0810, @lafriks, @mzampetakis, @pat-s, @qwerty287, @xoxys
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- Add allow list for approvals [[#4768](https://github.com/woodpecker-ci/woodpecker/pull/4768)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Unsanitize user and org names in DB [[#4762](https://github.com/woodpecker-ci/woodpecker/pull/4762)]
|
||||
- Store/delete repos after forge communication [[#4827](https://github.com/woodpecker-ci/woodpecker/pull/4827)]
|
||||
- Fix k8s secret schema [[#4819](https://github.com/woodpecker-ci/woodpecker/pull/4819)]
|
||||
- Move section description to the top [[#4773](https://github.com/woodpecker-ci/woodpecker/pull/4773)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Docs: Add Radicle forge addon [[#4833](https://github.com/woodpecker-ci/woodpecker/pull/4833)]
|
||||
- fix(deps): update docs npm deps non-major [[#4823](https://github.com/woodpecker-ci/woodpecker/pull/4823)]
|
||||
- chore(deps): update dependency isomorphic-dompurify to v2.21.0 [[#4805](https://github.com/woodpecker-ci/woodpecker/pull/4805)]
|
||||
- chore(deps): update dependency @types/node to v22.13.0 [[#4799](https://github.com/woodpecker-ci/woodpecker/pull/4799)]
|
||||
- Add bluesky post plugin [[#4549](https://github.com/woodpecker-ci/woodpecker/pull/4549)]
|
||||
- Various docs improvements [[#4772](https://github.com/woodpecker-ci/woodpecker/pull/4772)]
|
||||
- fix(deps): update docs npm deps non-major [[#4774](https://github.com/woodpecker-ci/woodpecker/pull/4774)]
|
||||
- Add git basic changelog [[#4755](https://github.com/woodpecker-ci/woodpecker/pull/4755)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- Optimize repository list loading to return also latest pipeline info [[#4814](https://github.com/woodpecker-ci/woodpecker/pull/4814)]
|
||||
- Add Git Ref To Build Status in BitbucketDatacenter [[#4724](https://github.com/woodpecker-ci/woodpecker/pull/4724)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- fix(deps): update golang-packages [[#4834](https://github.com/woodpecker-ci/woodpecker/pull/4834)]
|
||||
- fix(deps): update web npm deps non-major [[#4831](https://github.com/woodpecker-ci/woodpecker/pull/4831)]
|
||||
- fix(deps): update dependency simple-icons to v14.6.0 [[#4830](https://github.com/woodpecker-ci/woodpecker/pull/4830)]
|
||||
- fix(deps): update golang-packages [[#4829](https://github.com/woodpecker-ci/woodpecker/pull/4829)]
|
||||
- fix(deps): update web npm deps non-major to v4.0.5 [[#4828](https://github.com/woodpecker-ci/woodpecker/pull/4828)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-docker-buildx docker tag to v5.2.1 [[#4822](https://github.com/woodpecker-ci/woodpecker/pull/4822)]
|
||||
- fix(deps): update module github.com/google/go-github/v68 to v69 [[#4826](https://github.com/woodpecker-ci/woodpecker/pull/4826)]
|
||||
- fix(deps): update web npm deps non-major [[#4825](https://github.com/woodpecker-ci/woodpecker/pull/4825)]
|
||||
- fix(deps): update golang-packages [[#4812](https://github.com/woodpecker-ci/woodpecker/pull/4812)]
|
||||
- chore(deps): update dependency vitest to v3.0.5 [security] [[#4810](https://github.com/woodpecker-ci/woodpecker/pull/4810)]
|
||||
- chore(deps): lock file maintenance [[#4808](https://github.com/woodpecker-ci/woodpecker/pull/4808)]
|
||||
- chore(deps): update dependency @antfu/eslint-config to v4.1.1 [[#4806](https://github.com/woodpecker-ci/woodpecker/pull/4806)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.121.0 [[#4804](https://github.com/woodpecker-ci/woodpecker/pull/4804)]
|
||||
- fix(deps): update dependency simple-icons to v14.5.0 [[#4803](https://github.com/woodpecker-ci/woodpecker/pull/4803)]
|
||||
- fix(deps): update web npm deps non-major to v4.0.3 [[#4802](https://github.com/woodpecker-ci/woodpecker/pull/4802)]
|
||||
- fix(deps): update web npm deps non-major [[#4798](https://github.com/woodpecker-ci/woodpecker/pull/4798)]
|
||||
- fix(deps): update module github.com/getkin/kin-openapi to v0.129.0 [[#4790](https://github.com/woodpecker-ci/woodpecker/pull/4790)]
|
||||
- chore(deps): lock file maintenance [[#4783](https://github.com/woodpecker-ci/woodpecker/pull/4783)]
|
||||
- chore(deps): update dependency @antfu/eslint-config to v4.1.0 [[#4780](https://github.com/woodpecker-ci/woodpecker/pull/4780)]
|
||||
- fix(deps): update module github.com/bmatcuk/doublestar/v4 to v4.8.1 [[#4781](https://github.com/woodpecker-ci/woodpecker/pull/4781)]
|
||||
- chore(deps): update dependency @antfu/eslint-config to v4 [[#4779](https://github.com/woodpecker-ci/woodpecker/pull/4779)]
|
||||
- fix(deps): update web npm deps non-major [[#4777](https://github.com/woodpecker-ci/woodpecker/pull/4777)]
|
||||
- chore(deps): update pre-commit hook igorshubovych/markdownlint-cli to v0.44.0 [[#4776](https://github.com/woodpecker-ci/woodpecker/pull/4776)]
|
||||
- fix(deps): update module google.golang.org/protobuf to v1.36.4 [[#4775](https://github.com/woodpecker-ci/woodpecker/pull/4775)]
|
||||
- fix(deps): update module google.golang.org/grpc to v1.70.0 [[#4770](https://github.com/woodpecker-ci/woodpecker/pull/4770)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-docker-buildx docker tag to v5.2.0 [[#4767](https://github.com/woodpecker-ci/woodpecker/pull/4767)]
|
||||
- chore(deps): update docker.io/mysql docker tag to v9.2.0 [[#4766](https://github.com/woodpecker-ci/woodpecker/pull/4766)]
|
||||
- fix(deps): update module github.com/hashicorp/go-plugin to v1.6.3 [[#4765](https://github.com/woodpecker-ci/woodpecker/pull/4765)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-ready-release-go docker tag to v3.1.3 [[#4764](https://github.com/woodpecker-ci/woodpecker/pull/4764)]
|
||||
- fix(deps): update docker to v27.5.1+incompatible [[#4761](https://github.com/woodpecker-ci/woodpecker/pull/4761)]
|
||||
- chore(deps): update dependency vite to v6.0.9 [security] [[#4757](https://github.com/woodpecker-ci/woodpecker/pull/4757)]
|
||||
|
||||
### Misc
|
||||
|
||||
- chore: fix some function names in comment [[#4769](https://github.com/woodpecker-ci/woodpecker/pull/4769)]
|
||||
|
||||
## [3.0.1](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.0.1) - 2025-01-20
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@pat-s, @qwerty287, @xoxys
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Only show visited repos and hide at all if less than 4 repos [[#4753](https://github.com/woodpecker-ci/woodpecker/pull/4753)]
|
||||
- Fix sql identifier escaping in datastore feed [[#4746](https://github.com/woodpecker-ci/woodpecker/pull/4746)]
|
||||
- Fix log folder permissions [[#4749](https://github.com/woodpecker-ci/woodpecker/pull/4749)]
|
||||
- Add missing error message for org_access_denied [[#4744](https://github.com/woodpecker-ci/woodpecker/pull/4744)]
|
||||
- Fix package configs [[#4741](https://github.com/woodpecker-ci/woodpecker/pull/4741)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- chore(deps): lock file maintenance [[#4751](https://github.com/woodpecker-ci/woodpecker/pull/4751)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- fix(deps): update golang-packages [[#4750](https://github.com/woodpecker-ci/woodpecker/pull/4750)]
|
||||
- fix(deps): update dependency simple-icons to v14.3.0 [[#4739](https://github.com/woodpecker-ci/woodpecker/pull/4739)]
|
||||
- chore(deps): update dependency vitest to v3 [[#4736](https://github.com/woodpecker-ci/woodpecker/pull/4736)]
|
||||
|
||||
### Misc
|
||||
|
||||
- fix minor tag creation for server scratch image [[#4748](https://github.com/woodpecker-ci/woodpecker/pull/4748)]
|
||||
- use v3 woodpecker libs [[#4742](https://github.com/woodpecker-ci/woodpecker/pull/4742)]
|
||||
|
||||
## [3.0.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.0.0) - 2025-01-18
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
2
Makefile
@ -40,7 +40,7 @@ CGO_ENABLED ?= 1 # only used to compile server
|
||||
HAS_GO = $(shell hash go > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||
ifeq ($(HAS_GO),GO)
|
||||
# renovate: datasource=docker depName=docker.io/techknowlogick/xgo
|
||||
XGO_VERSION ?= go-1.23.x
|
||||
XGO_VERSION ?= go-1.24.x
|
||||
CGO_CFLAGS ?= $(shell go env CGO_CFLAGS)
|
||||
endif
|
||||
CGO_CFLAGS ?=
|
||||
|
@ -31,7 +31,7 @@ var userListCmd = &cli.Command{
|
||||
Usage: "list all users",
|
||||
ArgsUsage: " ",
|
||||
Action: userList,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplUserList)},
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplUserList, false)},
|
||||
}
|
||||
|
||||
func userList(ctx context.Context, c *cli.Command) error {
|
||||
|
@ -31,7 +31,7 @@ var userShowCmd = &cli.Command{
|
||||
Usage: "show user information",
|
||||
ArgsUsage: "<username>",
|
||||
Action: userShow,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplUserInfo)},
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplUserInfo, false)},
|
||||
}
|
||||
|
||||
func userShow(ctx context.Context, c *cli.Command) error {
|
||||
|
@ -15,6 +15,8 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/logger"
|
||||
@ -63,10 +65,15 @@ var GlobalFlags = append([]cli.Flag{
|
||||
|
||||
// FormatFlag return format flag with value set based on template
|
||||
// if hidden value is set, flag will be hidden.
|
||||
func FormatFlag(tmpl string, hidden ...bool) *cli.StringFlag {
|
||||
func FormatFlag(tmpl string, deprecated bool, hidden ...bool) *cli.StringFlag {
|
||||
usage := "format output"
|
||||
if deprecated {
|
||||
usage = fmt.Sprintf("%s (deprecated)", usage)
|
||||
}
|
||||
|
||||
return &cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "format output",
|
||||
Usage: usage,
|
||||
Value: tmpl,
|
||||
Hidden: len(hidden) != 0,
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ func TestMetadataFromContext(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("InvalidFile", func(t *testing.T) {
|
||||
tempFile, err := os.CreateTemp("", "invalid.json")
|
||||
tempFile, err := os.CreateTemp(t.TempDir(), "invalid.json")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.Remove(tempFile.Name()) })
|
||||
|
||||
@ -132,7 +132,7 @@ func TestMetadataFromContext(t *testing.T) {
|
||||
|
||||
func createTempFile(t *testing.T, content any) string {
|
||||
t.Helper()
|
||||
tempFile, err := os.CreateTemp("", "metadata.json")
|
||||
tempFile, err := os.CreateTemp(t.TempDir(), "metadata.json")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.Remove(tempFile.Name()) })
|
||||
|
||||
|
@ -52,15 +52,15 @@ func (o *Table) Columns() (cols []string) {
|
||||
|
||||
// AddFieldAlias overrides the field name to allow custom column headers.
|
||||
func (o *Table) AddFieldAlias(field, alias string) *Table {
|
||||
o.fieldAlias[field] = alias
|
||||
o.fieldAlias[strings.ToLower(alias)] = field
|
||||
return o
|
||||
}
|
||||
|
||||
// AddFieldFn adds a function which handles the output of the specified field.
|
||||
func (o *Table) AddFieldFn(field string, fn FieldFn) *Table {
|
||||
o.fieldMapping[field] = fn
|
||||
o.allowedFields[field] = true
|
||||
o.columns[field] = true
|
||||
o.fieldMapping[strings.ToLower(field)] = fn
|
||||
o.allowedFields[strings.ToLower(field)] = true
|
||||
o.columns[strings.ToLower(field)] = true
|
||||
return o
|
||||
}
|
||||
|
||||
@ -117,9 +117,6 @@ func (o *Table) ValidateColumns(cols []string) error {
|
||||
func (o *Table) WriteHeader(columns []string) {
|
||||
var header []string
|
||||
for _, col := range columns {
|
||||
if alias, ok := o.fieldAlias[col]; ok {
|
||||
col = alias
|
||||
}
|
||||
header = append(header, strings.ReplaceAll(strings.ToUpper(col), "_", " "))
|
||||
}
|
||||
_, _ = fmt.Fprintln(o.w, strings.Join(header, "\t"))
|
||||
@ -146,12 +143,9 @@ func (o *Table) Write(columns []string, obj any) error {
|
||||
for _, col := range columns {
|
||||
colName := strings.ToLower(col)
|
||||
if alias, ok := o.fieldAlias[colName]; ok {
|
||||
if fn, ok := o.fieldMapping[alias]; ok {
|
||||
out = append(out, sanitizeString(fn(obj)))
|
||||
continue
|
||||
}
|
||||
colName = strings.ToLower(alias)
|
||||
}
|
||||
if fn, ok := o.fieldMapping[colName]; ok {
|
||||
if fn, ok := o.fieldMapping[strings.ReplaceAll(colName, "_", "")]; ok {
|
||||
out = append(out, sanitizeString(fn(obj)))
|
||||
continue
|
||||
}
|
||||
|
@ -32,17 +32,17 @@ func TestTableOutput(t *testing.T) {
|
||||
}
|
||||
})
|
||||
t.Run("AddFieldAlias", func(t *testing.T) {
|
||||
to.AddFieldAlias("woodpecker_ci", "woodpecker ci")
|
||||
if alias, ok := to.fieldAlias["woodpecker_ci"]; !ok || alias != "woodpecker ci" {
|
||||
t.Errorf("woodpecker_ci alias should be 'woodpecker ci', is: %v", alias)
|
||||
to.AddFieldAlias("WoodpeckerCI", "wp")
|
||||
if alias, ok := to.fieldAlias["wp"]; !ok || alias != "WoodpeckerCI" {
|
||||
t.Errorf("'wp' alias should resolve to 'WoodpeckerCI', is: %v", alias)
|
||||
}
|
||||
})
|
||||
t.Run("AddFieldOutputFn", func(t *testing.T) {
|
||||
to.AddFieldFn("woodpecker ci", FieldFn(func(_ any) string {
|
||||
to.AddFieldFn("WoodpeckerCI", FieldFn(func(_ any) string {
|
||||
return "WOODPECKER CI!!!"
|
||||
}))
|
||||
if _, ok := to.fieldMapping["woodpecker ci"]; !ok {
|
||||
t.Errorf("'woodpecker ci' field output fn should be set")
|
||||
if _, ok := to.fieldMapping["woodpeckerci"]; !ok {
|
||||
t.Errorf("'WoodpeckerCI' field output fn should be set")
|
||||
}
|
||||
})
|
||||
t.Run("ValidateColumns", func(t *testing.T) {
|
||||
@ -54,14 +54,14 @@ func TestTableOutput(t *testing.T) {
|
||||
}
|
||||
})
|
||||
t.Run("WriteHeader", func(t *testing.T) {
|
||||
to.WriteHeader([]string{"woodpecker_ci", "name"})
|
||||
if wfs.String() != "WOODPECKER CI\tNAME\n" {
|
||||
to.WriteHeader([]string{"wp", "name"})
|
||||
if wfs.String() != "WP\tNAME\n" {
|
||||
t.Errorf("written header should be 'WOODPECKER CI\\tNAME\\n', is: %q", wfs.String())
|
||||
}
|
||||
wfs.Reset()
|
||||
})
|
||||
t.Run("WriteLine", func(t *testing.T) {
|
||||
_ = to.Write([]string{"woodpecker_ci", "name", "number"}, &testFieldsStruct{"test123", 1000000000})
|
||||
_ = to.Write([]string{"wp", "name", "number"}, &testFieldsStruct{"test123", 1000000000})
|
||||
if wfs.String() != "WOODPECKER CI!!!\ttest123\t1000000000\n" {
|
||||
t.Errorf("written line should be 'WOODPECKER CI!!!\\ttest123\\t1000000000\\n', is: %q", wfs.String())
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ var Command = &cli.Command{
|
||||
ArgsUsage: "<repo-id|repo-full-name> <pipeline> <environment>",
|
||||
Action: deploy,
|
||||
Flags: []cli.Flag{
|
||||
common.FormatFlag(tmplDeployInfo),
|
||||
common.FormatFlag(tmplDeployInfo, false),
|
||||
&cli.StringFlag{
|
||||
Name: "branch",
|
||||
Usage: "branch filter",
|
||||
|
@ -55,13 +55,9 @@ func pipelineOutput(c *cli.Command, pipelines []*woodpecker.Pipeline, fd ...io.W
|
||||
noHeader := c.Bool("output-no-headers")
|
||||
|
||||
var out io.Writer
|
||||
switch len(fd) {
|
||||
case 0:
|
||||
out = os.Stdout
|
||||
case 1:
|
||||
out = os.Stdout
|
||||
if len(fd) > 0 {
|
||||
out = fd[0]
|
||||
default:
|
||||
out = os.Stdout
|
||||
}
|
||||
|
||||
switch outFmt {
|
||||
|
@ -33,7 +33,7 @@ var pipelinePsCmd = &cli.Command{
|
||||
Usage: "show pipeline steps",
|
||||
ArgsUsage: "<repo-id|repo-full-name> <pipeline>",
|
||||
Action: pipelinePs,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplPipelinePs)},
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplPipelinePs, false)},
|
||||
}
|
||||
|
||||
func pipelinePs(ctx context.Context, c *cli.Command) error {
|
||||
|
@ -31,7 +31,7 @@ var pipelineQueueCmd = &cli.Command{
|
||||
Usage: "show pipeline queue",
|
||||
ArgsUsage: " ",
|
||||
Action: pipelineQueue,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplPipelineQueue)},
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplPipelineQueue, false)},
|
||||
}
|
||||
|
||||
func pipelineQueue(ctx context.Context, c *cli.Command) error {
|
||||
|
@ -15,11 +15,19 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/output"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/repo/cron"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/repo/registry"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/repo/secret"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
// Command exports the repository command.
|
||||
@ -40,3 +48,84 @@ var Command = &cli.Command{
|
||||
repoUpdateCmd,
|
||||
},
|
||||
}
|
||||
|
||||
func repoOutput(c *cli.Command, repos []*woodpecker.Repo, fd ...io.Writer) error {
|
||||
outFmt, outOpt := output.ParseOutputOptions(c.String("output"))
|
||||
noHeader := c.Bool("output-no-headers")
|
||||
|
||||
legacyFmt := c.String("format")
|
||||
if legacyFmt != "" {
|
||||
log.Warn().Msgf("the --format flag is deprecated, please use --output instead")
|
||||
|
||||
outFmt = "go-template"
|
||||
outOpt = []string{legacyFmt}
|
||||
}
|
||||
|
||||
var out io.Writer
|
||||
out = os.Stdout
|
||||
if len(fd) > 0 {
|
||||
out = fd[0]
|
||||
}
|
||||
|
||||
switch outFmt {
|
||||
case "go-template":
|
||||
if len(outOpt) < 1 {
|
||||
return fmt.Errorf("%w: missing template", output.ErrOutputOptionRequired)
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(outOpt[0] + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tmpl.Execute(out, repos); err != nil {
|
||||
return err
|
||||
}
|
||||
case "table":
|
||||
fallthrough
|
||||
default:
|
||||
table := output.NewTable(out)
|
||||
|
||||
// Add custom field mapping for nested Trusted fields
|
||||
table.AddFieldFn("TrustedNetwork", func(obj any) string {
|
||||
repo, ok := obj.(*woodpecker.Repo)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return output.YesNo(repo.Trusted.Network)
|
||||
})
|
||||
table.AddFieldFn("TrustedSecurity", func(obj any) string {
|
||||
repo, ok := obj.(*woodpecker.Repo)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return output.YesNo(repo.Trusted.Security)
|
||||
})
|
||||
table.AddFieldFn("TrustedVolume", func(obj any) string {
|
||||
repo, ok := obj.(*woodpecker.Repo)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return output.YesNo(repo.Trusted.Volumes)
|
||||
})
|
||||
|
||||
table.AddFieldAlias("Is_Active", "Active")
|
||||
table.AddFieldAlias("Is_SCM_Private", "SCM_Private")
|
||||
|
||||
cols := []string{"Full_Name", "Branch", "Forge_URL", "Visibility", "SCM_Private", "Active", "Allow_Pull"}
|
||||
|
||||
if len(outOpt) > 0 {
|
||||
cols = outOpt
|
||||
}
|
||||
if !noHeader {
|
||||
table.WriteHeader(cols)
|
||||
}
|
||||
for _, resource := range repos {
|
||||
if err := table.Write(cols, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
table.Flush()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
@ -30,9 +28,9 @@ var repoListCmd = &cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "list all repos",
|
||||
ArgsUsage: " ",
|
||||
Action: repoList,
|
||||
Flags: []cli.Flag{
|
||||
common.FormatFlag(tmplRepoList),
|
||||
Action: List,
|
||||
Flags: append(common.OutputFlags("table"), []cli.Flag{
|
||||
common.FormatFlag("", true),
|
||||
&cli.StringFlag{
|
||||
Name: "org",
|
||||
Usage: "filter by organization",
|
||||
@ -41,40 +39,38 @@ var repoListCmd = &cli.Command{
|
||||
Name: "all",
|
||||
Usage: "query all repos, including inactive ones",
|
||||
},
|
||||
},
|
||||
}...),
|
||||
}
|
||||
|
||||
func repoList(ctx context.Context, c *cli.Command) error {
|
||||
func List(ctx context.Context, c *cli.Command) error {
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repos, err := repoList(c, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repoOutput(c, repos)
|
||||
}
|
||||
|
||||
func repoList(c *cli.Command, client woodpecker.Client) ([]*woodpecker.Repo, error) {
|
||||
repos := make([]*woodpecker.Repo, 0)
|
||||
opt := woodpecker.RepoListOptions{
|
||||
All: c.Bool("all"),
|
||||
}
|
||||
|
||||
repos, err := client.RepoList(opt)
|
||||
if err != nil || len(repos) == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format") + "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
raw, err := client.RepoList(opt)
|
||||
if err != nil || len(raw) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
org := c.String("org")
|
||||
for _, repo := range repos {
|
||||
for _, repo := range raw {
|
||||
if org != "" && org != repo.Owner {
|
||||
continue
|
||||
}
|
||||
if err := tmpl.Execute(os.Stdout, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
return nil
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
// Template for repository list items.
|
||||
var tmplRepoList = "\x1b[33m{{ .FullName }}\x1b[0m (id: {{ .ID }}, forgeRemoteID: {{ .ForgeRemoteID }}, isActive: {{ .IsActive }})"
|
||||
|
@ -16,56 +16,45 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/common"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/internal"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
var repoShowCmd = &cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show repository information",
|
||||
ArgsUsage: "<repo-id|repo-full-name>",
|
||||
Action: repoShow,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplRepoInfo)},
|
||||
Action: Show,
|
||||
Flags: common.OutputFlags("table"),
|
||||
}
|
||||
|
||||
func repoShow(ctx context.Context, c *cli.Command) error {
|
||||
repoIDOrFullName := c.Args().First()
|
||||
func Show(ctx context.Context, c *cli.Command) error {
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
||||
repo, err := repoShow(c, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repoOutput(c, []*woodpecker.Repo{repo})
|
||||
}
|
||||
|
||||
func repoShow(c *cli.Command, client woodpecker.Client) (*woodpecker.Repo, error) {
|
||||
repoIDOrFullName := c.Args().First()
|
||||
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo, err := client.Repo(repoID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("_").Parse(c.String("format"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.Execute(os.Stdout, repo)
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
// tTemplate for repo information.
|
||||
var tmplRepoInfo = `Owner: {{ .Owner }}
|
||||
Repo: {{ .Name }}
|
||||
URL: {{ .ForgeURL }}
|
||||
Config path: {{ .Config }}
|
||||
Visibility: {{ .Visibility }}
|
||||
Private: {{ .IsSCMPrivate }}
|
||||
Trusted: {{ .IsTrusted }}
|
||||
Gated: {{ .IsGated }}
|
||||
Require approval for: {{ .RequireApproval }}
|
||||
Clone url: {{ .Clone }}
|
||||
Allow pull-requests: {{ .AllowPullRequests }}
|
||||
`
|
||||
|
72
cli/repo/repo_show_test.go
Normal file
@ -0,0 +1,72 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker/mocks"
|
||||
)
|
||||
|
||||
func TestRepoShow(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repoID int64
|
||||
mockRepo *woodpecker.Repo
|
||||
mockError error
|
||||
expectedError bool
|
||||
expected *woodpecker.Repo
|
||||
args []string
|
||||
}{
|
||||
{
|
||||
name: "valid repo by ID",
|
||||
repoID: 123,
|
||||
mockRepo: &woodpecker.Repo{Name: "test-repo"},
|
||||
expected: &woodpecker.Repo{Name: "test-repo"},
|
||||
args: []string{"show", "123"},
|
||||
},
|
||||
{
|
||||
name: "valid repo by full name",
|
||||
repoID: 456,
|
||||
mockRepo: &woodpecker.Repo{ID: 456, Name: "repo", Owner: "owner"},
|
||||
expected: &woodpecker.Repo{ID: 456, Name: "repo", Owner: "owner"},
|
||||
args: []string{"show", "owner/repo"},
|
||||
},
|
||||
{
|
||||
name: "invalid repo ID",
|
||||
repoID: 999,
|
||||
expectedError: true,
|
||||
args: []string{"show", "invalid"},
|
||||
mockError: errors.New("repo not found"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockClient := mocks.NewClient(t)
|
||||
mockClient.On("Repo", tt.repoID).Return(tt.mockRepo, tt.mockError).Maybe()
|
||||
mockClient.On("RepoLookup", "owner/repo").Return(tt.mockRepo, nil).Maybe()
|
||||
|
||||
command := repoShowCmd
|
||||
command.Writer = io.Discard
|
||||
command.Action = func(_ context.Context, c *cli.Command) error {
|
||||
output, err := repoShow(c, mockClient)
|
||||
if tt.expectedError {
|
||||
assert.Error(t, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expected, output)
|
||||
return nil
|
||||
}
|
||||
|
||||
_ = command.Run(context.Background(), tt.args)
|
||||
})
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ var repoSyncCmd = &cli.Command{
|
||||
Usage: "synchronize the repository list",
|
||||
ArgsUsage: " ",
|
||||
Action: repoSync,
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplRepoList)},
|
||||
Flags: []cli.Flag{common.FormatFlag(tmplRepoList, false)},
|
||||
}
|
||||
|
||||
// TODO: remove this and add an option to the list cmd as we do not store the remote repo list anymore
|
||||
@ -66,3 +66,6 @@ func repoSync(ctx context.Context, c *cli.Command) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Template for repository list items.
|
||||
var tmplRepoList = "\x1b[33m{{ .FullName }}\x1b[0m (id: {{ .ID }}, forgeRemoteID: {{ .ForgeRemoteID }}, isActive: {{ .IsActive }})"
|
||||
|
85
cli/repo/repo_test.go
Normal file
@ -0,0 +1,85 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cli/common"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
func TestRepoOutput(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
expected string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "table output with default columns",
|
||||
args: []string{},
|
||||
expected: "FULL NAME BRANCH FORGE URL VISIBILITY SCM PRIVATE ACTIVE ALLOW PULL\norg/repo1 main git.example.com public no yes yes\n",
|
||||
},
|
||||
{
|
||||
name: "table output with custom columns",
|
||||
args: []string{"output", "--output", "table=Name,Forge_URL,Trusted_Network"},
|
||||
expected: "NAME FORGE URL TRUSTED NETWORK\nrepo1 git.example.com yes\n",
|
||||
},
|
||||
{
|
||||
name: "table output with no header",
|
||||
args: []string{"output", "--output-no-headers"},
|
||||
expected: "org/repo1 main git.example.com public no yes yes\n",
|
||||
},
|
||||
{
|
||||
name: "go-template output",
|
||||
args: []string{"output", "--output", "go-template={{range . }}{{.Name}} {{.ForgeURL}} {{.Trusted.Network}}{{end}}"},
|
||||
expected: "repo1 git.example.com true\n",
|
||||
},
|
||||
}
|
||||
|
||||
repos := []*woodpecker.Repo{
|
||||
{
|
||||
Name: "repo1",
|
||||
FullName: "org/repo1",
|
||||
ForgeURL: "git.example.com",
|
||||
Branch: "main",
|
||||
Visibility: "public",
|
||||
IsActive: true,
|
||||
AllowPull: true,
|
||||
Trusted: woodpecker.TrustedConfiguration{
|
||||
Network: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
command := &cli.Command{
|
||||
Writer: io.Discard,
|
||||
Name: "output",
|
||||
Flags: common.OutputFlags("table"),
|
||||
Action: func(_ context.Context, c *cli.Command) error {
|
||||
var buf bytes.Buffer
|
||||
err := repoOutput(c, repos, &buf)
|
||||
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expected, buf.String())
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
_ = command.Run(context.Background(), tt.args)
|
||||
})
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ func TestReadAgentIDFileNotExists(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReadAgentIDFileExists(t *testing.T) {
|
||||
tmpF, errTmpF := os.CreateTemp("", "tmp_")
|
||||
tmpF, errTmpF := os.CreateTemp(t.TempDir(), "tmp_")
|
||||
if !assert.NoError(t, errTmpF) {
|
||||
return
|
||||
}
|
||||
@ -48,7 +48,7 @@ func TestReadAgentIDFileExists(t *testing.T) {
|
||||
actual = readAgentConfig(tmpF.Name())
|
||||
assert.EqualValues(t, 33, actual.AgentID)
|
||||
|
||||
tmpF2, errTmpF := os.CreateTemp("", "tmp_")
|
||||
tmpF2, errTmpF := os.CreateTemp(t.TempDir(), "tmp_")
|
||||
if !assert.NoError(t, errTmpF) {
|
||||
return
|
||||
}
|
||||
|
@ -56,6 +56,12 @@ var flags = append([]cli.Flag{
|
||||
Usage: "time an active connection is allowed to stay open",
|
||||
Value: 3 * time.Second,
|
||||
},
|
||||
&cli.UintFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_MAX_RETRIES"),
|
||||
Name: "db-max-retries",
|
||||
Usage: "max number of retries for the initial connection to the database",
|
||||
Value: 10,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_HOST"),
|
||||
Name: "server-host",
|
||||
@ -141,6 +147,12 @@ var flags = append([]cli.Flag{
|
||||
Name: "authenticate-public-repos",
|
||||
Usage: "Always use authentication to clone repositories even if they are public. Needed if the SCM requires to always authenticate as used by many companies.",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_ALLOW_PULL_REQUESTS"),
|
||||
Name: "default-allow-pull-requests",
|
||||
Usage: "The default value for allowing pull requests on a repo.",
|
||||
Value: true,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS"),
|
||||
Name: "default-cancel-previous-pipeline-events",
|
||||
|
@ -4306,7 +4306,7 @@ const docTemplate = `{
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Repo"
|
||||
"$ref": "#/definitions/RepoLastPipeline"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5054,6 +5054,12 @@ const docTemplate = `{
|
||||
"allow_pr": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"approval_allowed_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -5126,6 +5132,99 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"RepoLastPipeline": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_deploy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_pr": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"approval_allowed_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"cancel_previous_pipeline_events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/WebhookEvent"
|
||||
}
|
||||
},
|
||||
"clone_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"clone_url_ssh": {
|
||||
"type": "string"
|
||||
},
|
||||
"config_file": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"forge_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"forge_remote_id": {
|
||||
"description": "ForgeRemoteID is the unique identifier for the repository on the forge.",
|
||||
"type": "string"
|
||||
},
|
||||
"forge_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"full_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"last_pipeline": {
|
||||
"$ref": "#/definitions/Pipeline"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"netrc_trusted": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"org_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"pr_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"private": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"require_approval": {
|
||||
"$ref": "#/definitions/model.ApprovalMode"
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer"
|
||||
},
|
||||
"trusted": {
|
||||
"$ref": "#/definitions/model.TrustedConfiguration"
|
||||
},
|
||||
"visibility": {
|
||||
"$ref": "#/definitions/RepoVisibility"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RepoPatch": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -5135,6 +5234,12 @@ const docTemplate = `{
|
||||
"allow_pr": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"approval_allowed_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"cancel_previous_pipeline_events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v5"
|
||||
"github.com/gin-gonic/gin"
|
||||
prometheus_http "github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/rs/zerolog"
|
||||
@ -36,6 +37,7 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/cron"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/router"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/router/middleware"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/store"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/web"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/logger"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/version"
|
||||
@ -91,10 +93,19 @@ func run(ctx context.Context, c *cli.Command) error {
|
||||
)
|
||||
}
|
||||
|
||||
_store, err := setupStore(ctx, c)
|
||||
_store, err := backoff.Retry(ctx,
|
||||
func() (store.Store, error) {
|
||||
return setupStore(ctx, c)
|
||||
},
|
||||
backoff.WithBackOff(backoff.NewExponentialBackOff()),
|
||||
backoff.WithMaxTries(uint(c.Uint("db-max-retries"))),
|
||||
backoff.WithNotify(func(err error, delay time.Duration) {
|
||||
log.Error().Msgf("failed to setup store: %v: retry in %v", err, delay)
|
||||
}))
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't setup store: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := _store.Close(); err != nil {
|
||||
log.Error().Err(err).Msg("could not close store")
|
||||
|
@ -90,6 +90,10 @@ func setupStore(ctx context.Context, c *cli.Command) (store.Store, error) {
|
||||
return nil, fmt.Errorf("could not open datastore: %w", err)
|
||||
}
|
||||
|
||||
if err = store.Ping(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := store.Migrate(ctx, c.Bool("migrations-allow-long")); err != nil {
|
||||
return nil, fmt.Errorf("could not migrate datastore: %w", err)
|
||||
}
|
||||
@ -173,6 +177,9 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) (err e
|
||||
// authentication
|
||||
server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos")
|
||||
|
||||
// Pull requests
|
||||
server.Config.Pipeline.DefaultAllowPullRequests = c.Bool("default-allow-pull-requests")
|
||||
|
||||
// Cloning
|
||||
server.Config.Pipeline.DefaultClonePlugin = c.String("default-clone-plugin")
|
||||
server.Config.Pipeline.TrustedClonePlugins = c.StringSlice("plugins-trusted-clone")
|
||||
|
@ -3,7 +3,7 @@ version: '3'
|
||||
|
||||
services:
|
||||
gitea-database:
|
||||
image: postgres:17.2-alpine
|
||||
image: postgres:17.4-alpine
|
||||
environment:
|
||||
POSTGRES_USER: gitea
|
||||
POSTGRES_PASSWORD: 123456
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -1,9 +1,8 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS build
|
||||
|
||||
RUN groupadd -g 1000 woodpecker && \
|
||||
useradd -u 1000 -g 1000 woodpecker && \
|
||||
mkdir -p /etc/woodpecker && \
|
||||
chown -R woodpecker:woodpecker /etc/woodpecker
|
||||
mkdir -p /etc/woodpecker
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
@ -22,7 +21,7 @@ EXPOSE 3000
|
||||
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
# copy agent binary
|
||||
COPY --from=build /src/dist/woodpecker-agent /bin/
|
||||
COPY --from=build /etc/woodpecker /etc
|
||||
COPY --from=build --chown=woodpecker:woodpecker /etc/woodpecker /etc
|
||||
COPY --from=build /etc/passwd /etc/passwd
|
||||
COPY --from=build /etc/group /etc/group
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS build
|
||||
|
||||
RUN groupadd -g 1000 woodpecker && \
|
||||
useradd -u 1000 -g 1000 woodpecker
|
||||
|
@ -1,5 +1,5 @@
|
||||
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
||||
FROM docker.io/golang:1.23-alpine AS golang_image
|
||||
FROM docker.io/golang:1.24-alpine AS golang_image
|
||||
FROM docker.io/node:23-alpine
|
||||
|
||||
RUN apk add --no-cache --update make gcc binutils-gold musl-dev protoc && \
|
||||
|
@ -1,9 +1,8 @@
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS build
|
||||
|
||||
RUN groupadd -g 1000 woodpecker && \
|
||||
useradd -u 1000 -g 1000 woodpecker && \
|
||||
mkdir -p /var/lib/woodpecker && \
|
||||
chown -R woodpecker:woodpecker /var/lib/woodpecker
|
||||
mkdir -p /var/lib/woodpecker
|
||||
|
||||
FROM scratch
|
||||
ARG TARGETOS TARGETARCH
|
||||
@ -20,7 +19,7 @@ COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certifica
|
||||
COPY dist/server/${TARGETOS}_${TARGETARCH}/woodpecker-server /bin/
|
||||
COPY --from=build /etc/passwd /etc/passwd
|
||||
COPY --from=build /etc/group /etc/group
|
||||
COPY --from=build /var/lib/woodpecker /var/lib/woodpecker
|
||||
COPY --from=build --chown=woodpecker:woodpecker /var/lib/woodpecker /var/lib/woodpecker
|
||||
|
||||
USER woodpecker
|
||||
|
||||
|
@ -27,14 +27,12 @@ empowering you to automate and optimize workflows like never before.
|
||||
|
||||
Automate recurring tasks with ease using Woodpecker's new cron jobs feature.
|
||||
Schedule pipelines to run at specified intervals or times, optimizing repetitive workflows.
|
||||
[Read more](/docs/1.0/usage/cron)
|
||||
|
||||
### YAML Map Merge, Overrides, and Sequence Merge Support
|
||||
|
||||
With enhanced YAML support, managing complex configurations becomes a breeze.
|
||||
Merge maps, apply overrides, and sequence merging—all within your YAML files.
|
||||
This is providing more flexibility and control over your pipelines.
|
||||
[Read more](/docs/1.0/usage/advanced-yaml-syntax)
|
||||
|
||||
### Web-UI for Admins
|
||||
|
||||
@ -53,7 +51,6 @@ If your language is not available or only partially translated, consider contrib
|
||||
|
||||
Enhance pipeline flexibility with the new "when evaluate" filter, enabling or disabling steps based on custom conditions.
|
||||
Customize your workflows to dynamically respond to specific triggers and events.
|
||||
[Read more](/docs/1.0/usage/pipeline-syntax#evaluate)
|
||||
|
||||
### Global- and Organization-Secrets
|
||||
|
||||
|
@ -68,7 +68,7 @@ However, secrets are not included in the pipeline metadata and must be passed ma
|
||||
|
||||
Woodpecker now supports running rootless images by adjusting the entrypoints and directory permissions in the containers in a way that allows non-privileged users to execute tasks.
|
||||
|
||||
In addition, all images published by Woodpecker (Server, Agent, CLI) now use a non-privileged user (`woodpecker` with UID and GID 1000) by default.
|
||||
In addition, all images published by Woodpecker (Server, Agent, CLI) now use a non-privileged user (`woodpecker` with UID and GID `1000`) by default. If you have volumes attached to the containers, you may need to change the ownership of these directories from `root` to `woodpecker` by executing `chown -R 1000:1000 <mount dir>`.
|
||||
|
||||
:::info
|
||||
The agent image must remain rootful by default to be able to mount the Docker socket when Woodpecker is used with the `docker` backend.
|
||||
|
@ -23,4 +23,4 @@ Then you might want to jump directly into it and [start creating your first pipe
|
||||
|
||||
## Want to start from scratch and deploy your own Woodpecker instance?
|
||||
|
||||
Woodpecker is [pretty lightweight](../30-administration/00-getting-started.md#hardware-requirements) and will even run on your Raspberry Pi. You can follow the [deployment guide](../30-administration/00-getting-started.md) to set up your own Woodpecker instance.
|
||||
Woodpecker is lightweight and even runs on a Raspberry Pi. You can follow the [deployment guide](../30-administration/00-general.md) to set up your own Woodpecker instance.
|
||||
|
@ -83,20 +83,20 @@ the same workspace it can use the previously built binary and test it.
|
||||
|
||||
Sometimes you have some tasks that you need to do in every project. For example, deploying to Kubernetes or sending a Slack message. Therefore you can use one of the [official and community plugins](/plugins) or simply [create your own](./51-plugins/20-creating-plugins.md).
|
||||
|
||||
If you want to get a Slack notification after your pipeline has finished, you can add a Slack plugin to your pipeline:
|
||||
If you want to publish a file to an S3 bucket, you can add an S3 plugin to your pipeline:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
# ...
|
||||
- name: notify me on Slack
|
||||
image: plugins/slack
|
||||
- name: upload
|
||||
image: woodpeckerci/plugin-s3
|
||||
settings:
|
||||
channel: developers
|
||||
username: woodpecker
|
||||
password:
|
||||
from_secret: slack_token
|
||||
when:
|
||||
status: [success, failure] # This will execute the step on success and failure
|
||||
bucket: my-bucket-name
|
||||
access_key: a50d28f4dd477bc184fbd10b376de753
|
||||
secret_key:
|
||||
from_secret: aws_secret_key
|
||||
source: public/**/*
|
||||
target: /target/location
|
||||
```
|
||||
|
||||
To configure a plugin you can use the `settings` section.
|
||||
|
@ -47,9 +47,9 @@ Sometimes there are multiple terms that can be used to describe something. This
|
||||
[Event]: ../20-workflow-syntax.md#event
|
||||
[Pipeline]: ../20-workflow-syntax.md
|
||||
[Workflow]: ../25-workflows.md
|
||||
[Forge]: ../../30-administration/11-forges/11-overview.md
|
||||
[Forge]: ../../30-administration/10-configuration/12-forges/11-overview.md
|
||||
[Plugin]: ../51-plugins/51-overview.md
|
||||
[Workspace]: ../20-workflow-syntax.md#workspace
|
||||
[Matrix]: ../30-matrix-workflows.md
|
||||
[Docker]: ../../30-administration/22-backends/10-docker.md
|
||||
[Local]: ../../30-administration/22-backends/20-local.md
|
||||
[Docker]: ../../30-administration/10-configuration/11-backends/10-docker.md
|
||||
[Local]: ../../30-administration/10-configuration/11-backends/30-local.md
|
||||
|
@ -200,10 +200,8 @@ A condition can be a check like:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
- name: prettier
|
||||
image: woodpeckerci/plugin-prettier
|
||||
+ when:
|
||||
+ - event: pull_request
|
||||
+ repo: test/test
|
||||
@ -211,7 +209,7 @@ A condition can be a check like:
|
||||
+ branch: main
|
||||
```
|
||||
|
||||
The `slack` step is executed if one of these conditions is met:
|
||||
The `prettier` step is executed if one of these conditions is met:
|
||||
|
||||
1. The pipeline is executed from a pull request in the repo `test/test`
|
||||
2. The pipeline is executed from a push to `main`
|
||||
@ -222,10 +220,8 @@ Example conditional execution by repository:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
- name: prettier
|
||||
image: woodpeckerci/plugin-prettier
|
||||
+ when:
|
||||
+ - repo: test/test
|
||||
```
|
||||
@ -240,10 +236,8 @@ Example conditional execution by branch:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
- name: prettier
|
||||
image: woodpeckerci/plugin-prettier
|
||||
+ when:
|
||||
+ - branch: main
|
||||
```
|
||||
@ -342,14 +336,12 @@ when:
|
||||
|
||||
#### `status`
|
||||
|
||||
There are use cases for executing steps on failure, such as sending notifications for failed workflow / pipeline. Use the status constraint to execute steps even when the workflow fails:
|
||||
There are use cases for executing steps on failure, such as sending notifications for failed workflow/pipeline. Use the status constraint to execute steps even when the workflow fails:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
- name: notify
|
||||
image: alpine
|
||||
+ when:
|
||||
+ - status: [ success, failure ]
|
||||
```
|
||||
@ -604,7 +596,7 @@ For more details check the [matrix build docs](./30-matrix-workflows.md).
|
||||
|
||||
You can set labels for your workflow to select an agent to execute the workflow on. An agent will pick up and run a workflow when **every** label assigned to it matches the agents labels.
|
||||
|
||||
To set additional agent labels, check the [agent configuration options](../30-administration/15-agent-config.md#woodpecker_agent_labels). Agents will have at least four default labels: `platform=agent-os/agent-arch`, `hostname=my-agent`, `backend=docker` (type of the agent backend) and `repo=*`. Agents can use a `*` as a wildcard for a label. For example `repo=*` will match every repo.
|
||||
To set additional agent labels, check the [agent configuration options](../30-administration/10-configuration/30-agent.md#woodpecker_agent_labels). Agents will have at least four default labels: `platform=agent-os/agent-arch`, `hostname=my-agent`, `backend=docker` (type of the agent backend) and `repo=*`. Agents can use a `*` as a wildcard for a label. For example `repo=*` will match every repo.
|
||||
|
||||
Workflow labels with an empty value will be ignored.
|
||||
By default, each workflow has at least the `repo=your-user/your-repo-name` label. If you have set the [platform attribute](#platform) for your workflow it will have a label like `platform=your-os/your-arch` as well.
|
||||
@ -733,10 +725,8 @@ Example conditional execution by branch:
|
||||
+ branch: main
|
||||
+
|
||||
steps:
|
||||
- name: slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
- name: prettier
|
||||
image: woodpeckerci/plugin-prettier
|
||||
```
|
||||
|
||||
The workflow now triggers on `main`, but also if the target branch of a pull request is `main`.
|
||||
|
@ -139,5 +139,5 @@ steps:
|
||||
```
|
||||
|
||||
:::note
|
||||
If you want to control the architecture of a pipeline on a Kubernetes runner, see [the nodeSelector documentation of the Kubernetes backend](../30-administration/22-backends/40-kubernetes.md#node-selector).
|
||||
If you want to control the architecture of a pipeline on a Kubernetes runner, see [the nodeSelector documentation of the Kubernetes backend](../30-administration/10-configuration/11-backends/20-kubernetes.md#node-selector).
|
||||
:::
|
||||
|
@ -37,7 +37,7 @@ Example registry hostname matching logic:
|
||||
|
||||
## Global registry support
|
||||
|
||||
To make a private registry globally available, check the [server configuration docs](../30-administration/10-server-config.md#global-registry-setting).
|
||||
To make a private registry globally available, check the [server configuration docs](../30-administration/10-configuration/10-server.md#woodpecker_docker_config).
|
||||
|
||||
## GCR registry support
|
||||
|
||||
|
@ -23,7 +23,7 @@ steps:
|
||||
template: config/k8s/service.yaml
|
||||
```
|
||||
|
||||
Example pipeline using the Docker and Slack plugins:
|
||||
Example pipeline using the Docker and Prettier plugins:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
@ -33,16 +33,14 @@ steps:
|
||||
- go build
|
||||
- go test
|
||||
|
||||
- name: prettier
|
||||
image: woodpeckerci/plugin-prettier
|
||||
|
||||
- name: publish
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
repo: foo/bar
|
||||
tags: latest
|
||||
|
||||
- name: notify
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: dev
|
||||
```
|
||||
|
||||
## Plugin Isolation
|
||||
|
43
docs/docs/30-administration/00-general.md
Normal file
@ -0,0 +1,43 @@
|
||||
# General
|
||||
|
||||
Woodpecker consists of essential components (`server` and `agent`) and an optional component (`autoscaler`).
|
||||
|
||||
The **server** provides the user interface, processes webhook requests to the underlying forge, serves the API and analyzes the pipeline configurations from the YAML files.
|
||||
|
||||
The **agent** executes the [workflows](../20-usage/15-terminology/index.md) via a specific [backend](../20-usage/15-terminology/index.md) (Docker, Kubernetes, local) and connects to the server via GRPC. Multiple agents can coexist so that the job limits, choice of backend and other agent-related settings can be fine-tuned for a single instance.
|
||||
|
||||
The **autoscaler** allows spinning up new VMs on a cloud provider of choice to process pending builds. After the builds finished, the VMs are destroyed again (after a short transition time).
|
||||
|
||||
:::tip
|
||||
You can add more agents to increase the number of parallel workflows or set the agent's [`WOODPECKER_MAX_WORKFLOWS=1`](./10-configuration/30-agent.md#woodpecker_max_workflows) environment variable to increase the number of parallel workflows per agent.
|
||||
:::
|
||||
|
||||
## Database
|
||||
|
||||
Woodpecker uses a SQLite database by default, which requires no installation or configuration. For larger instances it is recommended to use it with a Postgres or MariaDB instance. For more details take a look at the [database settings](./10-configuration/10-server.md#databases) page.
|
||||
|
||||
## Forge
|
||||
|
||||
What would a CI/CD system be without any code. By connecting Woodpecker to your [forge](../20-usage/15-terminology/index.md), you can start pipelines on events like pushes or pull requests. Woodpecker will also use your forge to authenticate and report back the status of your pipelines. For more details take a look at the [forge settings](./10-configuration/12-forges/11-overview.md) page.
|
||||
|
||||
## Container images
|
||||
|
||||
:::info
|
||||
No `latest` tag exists to prevent accidental major version upgrades. Either use a SemVer tag or one of the rolling major/minor version tags. Alternatively, the `next` tag can be used for rolling builds from the `main` branch.
|
||||
:::
|
||||
|
||||
- `vX.Y.Z`: SemVer tags for specific releases, no entrypoint shell (scratch image)
|
||||
- `vX.Y`
|
||||
- `vX`
|
||||
- `vX.Y.Z-alpine`: SemVer tags for specific releases, rootless for Server and CLI (as of v3.0).
|
||||
- `vX.Y-alpine`
|
||||
- `vX-alpine`
|
||||
- `next`: Built from the `main` branch
|
||||
- `pull_<PR_ID>`: Images built from Pull Request branches.
|
||||
|
||||
Images are pushed to DockerHub and Quay.
|
||||
|
||||
- woodpecker-server ([DockerHub](https://hub.docker.com/r/woodpeckerci/woodpecker-server) or [Quay](https://quay.io/repository/woodpeckerci/woodpecker-server))
|
||||
- woodpecker-agent ([DockerHub](https://hub.docker.com/r/woodpeckerci/woodpecker-agent) or [Quay](https://quay.io/repository/woodpeckerci/woodpecker-agent))
|
||||
- woodpecker-cli ([DockerHub](https://hub.docker.com/r/woodpeckerci/woodpecker-cli) or [Quay](https://quay.io/repository/woodpeckerci/woodpecker-cli))
|
||||
- woodpecker-autoscaler ([DockerHub](https://hub.docker.com/r/woodpeckerci/autoscaler))
|
@ -1,59 +0,0 @@
|
||||
# Getting started
|
||||
|
||||
A Woodpecker deployment consists of two parts:
|
||||
|
||||
- A server which is the heart of Woodpecker and ships the web interface.
|
||||
- Next to one server, you can deploy any number of agents which will run the pipelines.
|
||||
|
||||
Each agent is able to process one [workflow](../20-usage/15-terminology/index.md) by default. If you have 4 agents installed and connected to the Woodpecker server, your system will process four workflows (not pipelines) in parallel.
|
||||
|
||||
:::tip
|
||||
You can add more agents to increase the number of parallel workflows or set the agent's `WOODPECKER_MAX_WORKFLOWS=1` environment variable to increase the number of parallel workflows per agent.
|
||||
:::
|
||||
|
||||
## Which version of Woodpecker should I use?
|
||||
|
||||
Woodpecker is having two different kinds of releases: **stable** and **next**.
|
||||
|
||||
Find more information about the different versions [here](/versions).
|
||||
|
||||
## Hardware Requirements
|
||||
|
||||
Below are minimal resources requirements for Woodpecker components itself:
|
||||
|
||||
| Component | Memory | CPU |
|
||||
| --------- | ------ | --- |
|
||||
| Server | 200 MB | 1 |
|
||||
| Agent | 32 MB | 1 |
|
||||
|
||||
Note, that those values do not include the operating system or workload (pipelines execution) resource consumption.
|
||||
|
||||
In addition you need at least some kind of database which requires additional resources depending on the selected database system.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install Woodpecker on multiple ways. If you are not sure which one to choose, we recommend using the [docker compose](./05-deployment-methods/10-docker-compose.md) method for the beginning:
|
||||
|
||||
- Using [docker compose](./05-deployment-methods/10-docker-compose.md) with the official [container images](./05-deployment-methods/10-docker-compose.md#docker-images)
|
||||
- Using [Kubernetes](./05-deployment-methods/20-kubernetes.md) via the Woodpecker Helm chart
|
||||
- Using binaries, DEBs or RPMs you can download from [latest release](https://github.com/woodpecker-ci/woodpecker/releases/latest)
|
||||
- Or using a [third-party installation method](./05-deployment-methods/30-third-party.md)
|
||||
|
||||
## Database
|
||||
|
||||
By default Woodpecker uses a SQLite database which requires zero installation or configuration. See the [database settings](./10-database.md) page if you want to use a different database system like MySQL or PostgreSQL.
|
||||
|
||||
## Forge
|
||||
|
||||
What would be a CI/CD system without any code? By connecting Woodpecker to your [forge](../20-usage/15-terminology/index.md) like GitHub or Gitea you can start running pipelines on events like pushes or pull requests. Woodpecker will also use your forge for authentication and to report back the status of your pipelines. See the [forge settings](./11-forges/11-overview.md) to connect it to Woodpecker.
|
||||
|
||||
## Configuration
|
||||
|
||||
Check the [server configuration](./10-server-config.md) and [agent configuration](./15-agent-config.md) pages to see if you need to adjust any additional parts and after that you should be ready to start with [your first pipeline](../20-usage/10-intro.md).
|
||||
|
||||
## Agent
|
||||
|
||||
The agent is the worker which executes the [workflows](../20-usage/15-terminology/index.md).
|
||||
Woodpecker agents can execute work using a [backend](../20-usage/15-terminology/index.md) like [docker](./22-backends/10-docker.md) or [kubernetes](./22-backends/40-kubernetes.md).
|
||||
By default if you choose to deploy an agent using [docker compose](./05-deployment-methods/10-docker-compose.md) the agent simply use docker for the backend as well.
|
||||
So nothing to worry about here. If you still prefer to adjust the agent to your needs, check the [agent configuration](./15-agent-config.md) page.
|
@ -1,30 +0,0 @@
|
||||
# Image variants
|
||||
|
||||
:::info
|
||||
The `latest` tag has been deprecated as of v3.0 and will be completely removed in the future.
|
||||
This was done to prevent accidental major version upgrades.
|
||||
:::
|
||||
|
||||
- `vX.Y.Z`: SemVer tags for specific releases, no entrypoint shell (scratch image)
|
||||
- `vX.Y`
|
||||
- `vX`
|
||||
- `vX.Y.Z-alpine`: SemVer tags for specific releases, based on Alpine, rootless for Server and CLI (as of v3.0).
|
||||
- `vX.Y-alpine`
|
||||
- `vX-alpine`
|
||||
- `next`: Built from the `main` branch
|
||||
- `pull_<PR_ID>`: Images built from Pull Request branches.
|
||||
|
||||
## Image registries
|
||||
|
||||
Images are pushed to DockerHub and Quay.
|
||||
|
||||
[woodpecker-server (DockerHub)](https://hub.docker.com/repository/docker/woodpeckerci/woodpecker-server)
|
||||
[woodpecker-server (Quay)](https://quay.io/repository/woodpeckerci/woodpecker-server)
|
||||
|
||||
[woodpecker-agent (DockerHub)](https://hub.docker.com/repository/docker/woodpeckerci/woodpecker-agent)
|
||||
[woodpecker-agent (Quay)](https://quay.io/repository/woodpeckerci/woodpecker-agent)
|
||||
|
||||
[woodpecker-cli (DockerHub)](https://hub.docker.com/repository/docker/woodpeckerci/woodpecker-cli)
|
||||
[woodpecker-cli (Quay)](https://quay.io/repository/woodpeckerci/woodpecker-cli)
|
||||
|
||||
[woodpecker-autoscaler (DockerHub)](https://hub.docker.com/repository/docker/woodpeckerci/autoscaler)
|
@ -1,140 +0,0 @@
|
||||
# docker compose
|
||||
|
||||
The below [docker compose](https://docs.docker.com/compose/) configuration can be used to start a Woodpecker server with a single agent.
|
||||
|
||||
It relies on a number of environment variables that you must set before running `docker compose up`. The variables are described below.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
image: woodpeckerci/woodpecker-server:latest
|
||||
ports:
|
||||
- 8000:8000
|
||||
volumes:
|
||||
- woodpecker-server-data:/var/lib/woodpecker/
|
||||
environment:
|
||||
- WOODPECKER_OPEN=true
|
||||
- WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
- WOODPECKER_GITHUB=true
|
||||
- WOODPECKER_GITHUB_CLIENT=${WOODPECKER_GITHUB_CLIENT}
|
||||
- WOODPECKER_GITHUB_SECRET=${WOODPECKER_GITHUB_SECRET}
|
||||
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
|
||||
woodpecker-agent:
|
||||
image: woodpeckerci/woodpecker-agent:latest
|
||||
command: agent
|
||||
restart: always
|
||||
depends_on:
|
||||
- woodpecker-server
|
||||
volumes:
|
||||
- woodpecker-agent-config:/etc/woodpecker
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
- WOODPECKER_SERVER=woodpecker-server:9000
|
||||
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
|
||||
volumes:
|
||||
woodpecker-server-data:
|
||||
woodpecker-agent-config:
|
||||
```
|
||||
|
||||
Woodpecker needs to know its own address. You must therefore provide the public address of it in `<scheme>://<hostname>` format. Please omit trailing slashes:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
```
|
||||
|
||||
Woodpecker can also have its ports configured. It uses a separate port for gRPC and for HTTP. The agent performs gRPC calls and connects to the gRPC port.
|
||||
They can be configured with `*_ADDR` variables:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_GRPC_ADDR=${WOODPECKER_GRPC_ADDR}
|
||||
+ - WOODPECKER_SERVER_ADDR=${WOODPECKER_HTTP_ADDR}
|
||||
```
|
||||
|
||||
Reverse proxying can also be [configured for gRPC](../40-advanced/10-proxy.md#caddy). If the agents are connecting over the internet, it should also be SSL encrypted. The agent then needs to be configured to be secure:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_GRPC_SECURE=true # defaults to false
|
||||
+ - WOODPECKER_GRPC_VERIFY=true # default
|
||||
```
|
||||
|
||||
As agents run pipeline steps as docker containers they require access to the host machine's Docker daemon:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
[...]
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
+ volumes:
|
||||
+ - /var/run/docker.sock:/var/run/docker.sock
|
||||
```
|
||||
|
||||
Agents require the server address for agent-to-server communication. The agent connects to the server's gRPC port:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
environment:
|
||||
+ - WOODPECKER_SERVER=woodpecker-server:9000
|
||||
```
|
||||
|
||||
The server and agents use a shared secret to authenticate communication. This should be a random string of your choosing and should be kept private. You can generate such string with `openssl rand -hex 32`:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
```
|
||||
|
||||
## Docker images
|
||||
|
||||
Image variants:
|
||||
|
||||
- The `vX.X.X` images are stable releases
|
||||
- The `vX.X` images are based on the current release branch (e.g. `release/v1.0`) and can be used to get bug fixes asap
|
||||
- The `vX` same as `vX.X` variant but also includes feature releases
|
||||
- The `next` images are based on the current `main` branch
|
||||
|
||||
:::note
|
||||
The `latest` tag is not available on purpose (and has been dropped with the 3.x release) to prevent accidental major version upgrades.
|
||||
Hence, users are forced to specify a fixed or rolling tag, omitting the tag identifier (which equals to pulling `latest` implicitly) won't work.
|
||||
:::
|
||||
|
||||
```bash
|
||||
# server
|
||||
docker pull woodpeckerci/woodpecker-server:v3
|
||||
docker pull woodpeckerci/woodpecker-server:v3-alpine
|
||||
|
||||
# agent
|
||||
docker pull woodpeckerci/woodpecker-agent:v3
|
||||
docker pull woodpeckerci/woodpecker-agent:v3-alpine
|
||||
|
||||
# cli
|
||||
docker pull woodpeckerci/woodpecker-cli:v3
|
||||
docker pull woodpeckerci/woodpecker-cli:v3-alpine
|
||||
```
|
@ -1,50 +0,0 @@
|
||||
# Kubernetes
|
||||
|
||||
We recommended to deploy Woodpecker using the [Woodpecker helm chart](https://github.com/woodpecker-ci/helm).
|
||||
Have a look at the [`values.yaml`](https://github.com/woodpecker-ci/helm/blob/main/charts/woodpecker/values.yaml) config files for all available settings.
|
||||
|
||||
The chart contains two sub-charts, `server` and `agent` which are automatically configured as needed.
|
||||
The chart started off with two independent charts but was merged into one to simplify the deployment at start of 2023.
|
||||
|
||||
A couple of backend-specific config env vars exists which are described in the [kubernetes backend docs](../22-backends/40-kubernetes.md).
|
||||
|
||||
## Metrics
|
||||
|
||||
Please see [Prometheus](../40-advanced/90-prometheus.md) for general information on configuration and usage.
|
||||
|
||||
For Kubernetes, you must set the following values when deploying via Helm chart to enable in-cluster metrics gathering:
|
||||
|
||||
```yaml
|
||||
metrics:
|
||||
enabled: true
|
||||
port: 9001
|
||||
```
|
||||
|
||||
This activates the `/metrics` endpoint on port `9001` without authentication. This port is not exposed externally by default. Use the instructions at [Prometheus](../40-advanced/90-prometheus.md) if you want to enable authenticated external access to metrics.
|
||||
|
||||
To enable Prometheus pod monitoring discovery, you must also make the following settings:
|
||||
|
||||
<!-- cspell:disable -->
|
||||
|
||||
```yaml
|
||||
prometheus:
|
||||
podmonitor:
|
||||
enabled: true
|
||||
interval: 60s
|
||||
labels: {}
|
||||
```
|
||||
|
||||
<!-- cspell:enable -->
|
||||
|
||||
### Troubleshooting Metrics
|
||||
|
||||
If you are not receiving metrics despite the steps above, ensure that in your Prometheus configuration either your namespace is explicitly configured in `podMonitorNamespaceSelector` or the selectors are disabled.
|
||||
|
||||
```yaml
|
||||
# Search all available namespaces
|
||||
podMonitorNamespaceSelector:
|
||||
matchLabels: {}
|
||||
# Enable all available pod monitors
|
||||
podMonitorSelector:
|
||||
matchLabels: {}
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
# Distribution packages
|
||||
|
||||
:::info
|
||||
Woodpecker itself is not responsible for creating these packages. Please reach out to the people responsible for packaging Woodpecker for the individual distributions.
|
||||
:::
|
||||
|
||||
- [NixOS](./40-nixos.md) via the [NixOS module](https://search.nixos.org/options?channel=unstable&size=200&sort=relevance&query=woodpecker)
|
||||
- [Alpine (Edge)](https://pkgs.alpinelinux.org/packages?name=woodpecker&branch=edge&repo=&arch=&maintainer=)
|
||||
- [Arch Linux](https://archlinux.org/packages/?q=woodpecker)
|
||||
- [openSUSE](https://software.opensuse.org/package/woodpecker)
|
||||
- [YunoHost](https://apps.yunohost.org/app/woodpecker)
|
||||
- [Cloudron](https://www.cloudron.io/store/org.woodpecker_ci.cloudronapp.html)
|
@ -1,90 +0,0 @@
|
||||
# NixOS
|
||||
|
||||
:::info
|
||||
Note that this module is not maintained by the Woodpecker developers.
|
||||
If you experience issues please open a bug report in the [nixpkgs repo](https://github.com/NixOS/nixpkgs/issues/new/choose) where the module is maintained.
|
||||
:::
|
||||
|
||||
The NixOS install is in theory quite similar to the binary install and supports multiple backends.
|
||||
In practice, the settings are specified declaratively in the NixOS configuration and no manual steps need to be taken.
|
||||
|
||||
## General Configuration
|
||||
|
||||
<!-- cspell:words Optimisation -->
|
||||
|
||||
```nix
|
||||
{ config
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
domain = "woodpecker.example.org";
|
||||
in
|
||||
{
|
||||
# This automatically sets up certificates via let's encrypt
|
||||
security.acme.defaults.email = "acme@example.com";
|
||||
security.acme.acceptTerms = true;
|
||||
security.acme.certs."${domain}" = { };
|
||||
|
||||
# Setting up a nginx proxy that handles tls for us
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3007";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.woodpecker-server = {
|
||||
enable = true;
|
||||
environment = {
|
||||
WOODPECKER_HOST = "https://${domain}";
|
||||
WOODPECKER_SERVER_ADDR = ":3007";
|
||||
WOODPECKER_OPEN = "true";
|
||||
};
|
||||
# You can pass a file with env vars to the system it could look like:
|
||||
# WOODPECKER_AGENT_SECRET=XXXXXXXXXXXXXXXXXXXXXX
|
||||
environmentFile = "/path/to/my/secrets/file";
|
||||
};
|
||||
|
||||
# This sets up a woodpecker agent
|
||||
services.woodpecker-agents.agents."docker" = {
|
||||
enable = true;
|
||||
# We need this to talk to the podman socket
|
||||
extraGroups = [ "podman" ];
|
||||
environment = {
|
||||
WOODPECKER_SERVER = "localhost:9000";
|
||||
WOODPECKER_MAX_WORKFLOWS = "4";
|
||||
DOCKER_HOST = "unix:///run/podman/podman.sock";
|
||||
WOODPECKER_BACKEND = "docker";
|
||||
};
|
||||
# Same as with woodpecker-server
|
||||
environmentFile = [ "/var/lib/secrets/woodpecker.env" ];
|
||||
};
|
||||
|
||||
# Here we setup podman and enable dns
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
defaultNetwork.settings = {
|
||||
dns_enabled = true;
|
||||
};
|
||||
};
|
||||
# This is needed for podman to be able to talk over dns
|
||||
networking.firewall.interfaces."podman0" = {
|
||||
allowedUDPPorts = [ 53 ];
|
||||
allowedTCPPorts = [ 53 ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
All configuration options can be found via [NixOS Search](https://search.nixos.org/options?channel=unstable&size=200&sort=relevance&query=woodpecker)
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
There are some resources on how to utilize Woodpecker more effectively with NixOS on the [Awesome Woodpecker](/awesome) page, like using the runners nix-store in the pipeline.
|
142
docs/docs/30-administration/05-installation/10-docker-compose.md
Normal file
@ -0,0 +1,142 @@
|
||||
# Docker Compose
|
||||
|
||||
This example [docker-compose](https://docs.docker.com/compose/) setup shows the deployment of a Woodpecker instance connected to GitHub (`WOODPECKER_GITHUB=true`). If you are using another forge, please change this including the respective secret settings.
|
||||
|
||||
It creates persistent volumes for the server and agent config directories. The bundled SQLite DB is stored in `/var/lib/woodpecker` and is the most important part to be persisted as it holds all users and repository information.
|
||||
|
||||
The server uses the default port `8000` and gets exposed to the host here, so WoodpeckerWO can be accessed through this port on the host or by a reverse proxy sitting in front of it.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
image: woodpeckerci/woodpecker-server:v3
|
||||
ports:
|
||||
- 8000:8000
|
||||
volumes:
|
||||
- woodpecker-server-data:/var/lib/woodpecker/
|
||||
environment:
|
||||
- WOODPECKER_OPEN=true
|
||||
- WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
- WOODPECKER_GITHUB=true
|
||||
- WOODPECKER_GITHUB_CLIENT=${WOODPECKER_GITHUB_CLIENT}
|
||||
- WOODPECKER_GITHUB_SECRET=${WOODPECKER_GITHUB_SECRET}
|
||||
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
|
||||
woodpecker-agent:
|
||||
image: woodpeckerci/woodpecker-agent:v3
|
||||
command: agent
|
||||
restart: always
|
||||
depends_on:
|
||||
- woodpecker-server
|
||||
volumes:
|
||||
- woodpecker-agent-config:/etc/woodpecker
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
- WOODPECKER_SERVER=woodpecker-server:9000
|
||||
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
|
||||
volumes:
|
||||
woodpecker-server-data:
|
||||
woodpecker-agent-config:
|
||||
```
|
||||
|
||||
Woodpecker must know its own address. You must therefore specify the public address in the format `<scheme>://<hostname>`. Please omit any trailing slashes:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
```
|
||||
|
||||
It is also possible to customize the ports used. Woodpecker uses a separate port for gRPC and for HTTP. The agent makes gRPC calls and connects to the gRPC port. They can be configured with `*_ADDR` variables:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_GRPC_ADDR=${WOODPECKER_GRPC_ADDR}
|
||||
+ - WOODPECKER_SERVER_ADDR=${WOODPECKER_HTTP_ADDR}
|
||||
```
|
||||
|
||||
If the agents establish a connection via the Internet, TLS encryption should be activated for gRPC. The agent must then be configured properly:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_GRPC_SECURE=true # defaults to false
|
||||
+ - WOODPECKER_GRPC_VERIFY=true # default
|
||||
```
|
||||
|
||||
As agents execute pipeline steps as Docker containers, they require access to the Docker daemon of the host machine:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
[...]
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
+ volumes:
|
||||
+ - /var/run/docker.sock:/var/run/docker.sock
|
||||
```
|
||||
|
||||
Agents require the server address for communication between agents and servers. The agent connects to the gRPC port of the server:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
environment:
|
||||
+ - WOODPECKER_SERVER=woodpecker-server:9000
|
||||
```
|
||||
|
||||
The server and the agents use a shared secret to authenticate the communication. This should be a random string, which you should keep secret. You can create such a string with `openssl rand -hex 32`:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
```
|
||||
|
||||
## Handling sensitive data
|
||||
|
||||
There are several options for handling sensitive data in `docker compose` or `docker swarm` configurations:
|
||||
|
||||
For Docker Compose, you can use an `.env` file next to your compose configuration to store the secrets outside the compose file. Although this separates the configuration from the secrets, it is still not very secure.
|
||||
|
||||
Alternatively, you can also use `docker-secrets`. As it can be difficult to use `docker-secrets` for environment variables, Woodpecker allows reading sensitive data from files by providing a `*_FILE` option for all sensitive configuration variables. Woodpecker will then attempt to read the value directly from this file. Note that the original environment variable will overwrite the value read from the file if it is specified at the same time.
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET_FILE=/run/secrets/woodpecker-agent-secret
|
||||
+ secrets:
|
||||
+ - woodpecker-agent-secret
|
||||
+
|
||||
+ secrets:
|
||||
+ woodpecker-agent-secret:
|
||||
+ external: true
|
||||
```
|
||||
|
||||
To store values in a docker secret you can use the following command:
|
||||
|
||||
```bash
|
||||
echo "my_agent_secret_key" | docker secret create woodpecker-agent-secret -
|
||||
```
|
45
docs/docs/30-administration/05-installation/20-helm-chart.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Helm Chart
|
||||
|
||||
Woodpecker provides a [Helm chart](https://github.com/woodpecker-ci/helm) for Kubernetes environments:
|
||||
|
||||
```bash
|
||||
helm repo add woodpecker oci://ghcr.io/woodpecker-ci/helm
|
||||
helm install woodpecker woodpecker/woodpecker
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
To enable metrics gathering, set the following in values.yml:
|
||||
|
||||
```yaml
|
||||
metrics:
|
||||
enabled: true
|
||||
port: 9001
|
||||
```
|
||||
|
||||
This activates the `/metrics` endpoint on port `9001` without authentication. This port is not exposed externally by default. Use the instructions at Prometheus if you want to enable authenticated external access to metrics.
|
||||
|
||||
To enable both Prometheus pod monitoring discovery, set:
|
||||
|
||||
<!-- cspell:disable -->
|
||||
|
||||
```yaml
|
||||
prometheus:
|
||||
podmonitor:
|
||||
enabled: true
|
||||
interval: 60s
|
||||
labels: {}
|
||||
```
|
||||
|
||||
<!-- cspell:enable -->
|
||||
|
||||
If you are not receiving metrics after following the steps above, verify that your Prometheus configuration includes your namespace explicitly in the podMonitorNamespaceSelector or that the selectors are disabled:
|
||||
|
||||
```yaml
|
||||
# Search all available namespaces
|
||||
podMonitorNamespaceSelector:
|
||||
matchLabels: {}
|
||||
# Enable all available pod monitors
|
||||
podMonitorSelector:
|
||||
matchLabels: {}
|
||||
```
|
176
docs/docs/30-administration/05-installation/30-packages.md
Normal file
@ -0,0 +1,176 @@
|
||||
# Distribution packages
|
||||
|
||||
## Official packages
|
||||
|
||||
- DEB
|
||||
- RPM
|
||||
|
||||
The pre-built packages are available on the [GitHub releases](https://github.com/woodpecker-ci/woodpecker/releases/latest) page. The packages can be installed using the package manager of your distribution.
|
||||
|
||||
```Shell
|
||||
# Debian/Ubuntu
|
||||
curl -L https://github.com/woodpecker-ci/woodpecker/releases/download/${RELEASE_VERSION}/woodpecker_${RELEASE_VERSION}_amd64.deb -o woodpecker-server.deb
|
||||
sudo apt --fix-broken install ./woodpecker-server.deb
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo dnf install https://github.com/woodpecker-ci/woodpecker/releases/download/${RELEASE_VERSION}/woodpecker_${RELEASE_VERSION}_amd64.rpm
|
||||
```
|
||||
|
||||
The package installation will create a systemd service file for the Woodpecker server and agent along with an example environment file. To configure the server, copy the example environment file `/etc/woodpecker/woodpecker-server.env.example` to `/etc/woodpecker/woodpecker-server.env` and adjust the values.
|
||||
|
||||
```ini title="/usr/local/lib/systemd/system/woodpecker-server.service"
|
||||
[Unit]
|
||||
Description=WoodpeckerCI server
|
||||
Documentation=https://woodpecker-ci.org/docs/administration/server-config
|
||||
Requires=network.target
|
||||
After=network.target
|
||||
ConditionFileNotEmpty=/etc/woodpecker/woodpecker-server.env
|
||||
ConditionPathExists=/etc/woodpecker/woodpecker-server.env
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=/etc/woodpecker/woodpecker-server.env
|
||||
User=woodpecker
|
||||
Group=woodpecker
|
||||
ExecStart=/usr/local/bin/woodpecker-server
|
||||
WorkingDirectory=/var/lib/woodpecker/
|
||||
StateDirectory=woodpecker
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```shell title="/etc/woodpecker/woodpecker-server.env"
|
||||
WOODPECKER_OPEN=true
|
||||
WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
WOODPECKER_GITHUB=true
|
||||
WOODPECKER_GITHUB_CLIENT=${WOODPECKER_GITHUB_CLIENT}
|
||||
WOODPECKER_GITHUB_SECRET=${WOODPECKER_GITHUB_SECRET}
|
||||
WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
```
|
||||
|
||||
After installing the agent, copy the example environment file `/etc/woodpecker/woodpecker-agent.env.example` to `/etc/woodpecker/woodpecker-agent.env` and adjust the values as well. The agent will automatically register itself with the server.
|
||||
|
||||
```ini title="/usr/local/lib/systemd/system/woodpecker-agent.service"
|
||||
[Unit]
|
||||
Description=WoodpeckerCI agent
|
||||
Documentation=https://woodpecker-ci.org/docs/administration/agent-config
|
||||
Requires=network.target
|
||||
After=network.target
|
||||
ConditionFileNotEmpty=/etc/woodpecker/woodpecker-agent.env
|
||||
ConditionPathExists=/etc/woodpecker/woodpecker-agent.env
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=/etc/woodpecker/woodpecker-agent.env
|
||||
User=woodpecker
|
||||
Group=woodpecker
|
||||
ExecStart=/usr/local/bin/woodpecker-agent
|
||||
WorkingDirectory=/var/lib/woodpecker/
|
||||
StateDirectory=woodpecker
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```shell title="/etc/woodpecker/woodpecker-agent.env"
|
||||
WOODPECKER_SERVER=localhost:9000
|
||||
WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||
```
|
||||
|
||||
## Community packages
|
||||
|
||||
:::info
|
||||
Woodpecker itself is not responsible for creating these packages. Please reach out to the people responsible for packaging Woodpecker for the individual distributions.
|
||||
:::
|
||||
|
||||
- [Alpine (Edge)](https://pkgs.alpinelinux.org/packages?name=woodpecker&branch=edge&repo=&arch=&maintainer=)
|
||||
- [Arch Linux](https://archlinux.org/packages/?q=woodpecker)
|
||||
- [openSUSE](https://software.opensuse.org/package/woodpecker)
|
||||
- [YunoHost](https://apps.yunohost.org/app/woodpecker)
|
||||
- [Cloudron](https://www.cloudron.io/store/org.woodpecker_ci.cloudronapp.html)
|
||||
|
||||
### NixOS
|
||||
|
||||
:::info
|
||||
This module is not maintained by the Woodpecker developers.
|
||||
If you experience issues please open a bug report in the [nixpkgs repo](https://github.com/NixOS/nixpkgs/issues/new/choose) where the module is maintained.
|
||||
:::
|
||||
|
||||
In theory, the NixOS installation is very similar to the binary installation and supports multiple backends.
|
||||
In practice, the settings are specified declaratively in the NixOS configuration and no manual steps need to be taken.
|
||||
|
||||
<!-- cspell:words Optimisation -->
|
||||
|
||||
```nix
|
||||
{ config
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
domain = "woodpecker.example.org";
|
||||
in
|
||||
{
|
||||
# This automatically sets up certificates via let's encrypt
|
||||
security.acme.defaults.email = "acme@example.com";
|
||||
security.acme.acceptTerms = true;
|
||||
security.acme.certs."${domain}" = { };
|
||||
|
||||
# Setting up a nginx proxy that handles tls for us
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3007";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.woodpecker-server = {
|
||||
enable = true;
|
||||
environment = {
|
||||
WOODPECKER_HOST = "https://${domain}";
|
||||
WOODPECKER_SERVER_ADDR = ":3007";
|
||||
WOODPECKER_OPEN = "true";
|
||||
};
|
||||
# You can pass a file with env vars to the system it could look like:
|
||||
# WOODPECKER_AGENT_SECRET=XXXXXXXXXXXXXXXXXXXXXX
|
||||
environmentFile = "/path/to/my/secrets/file";
|
||||
};
|
||||
|
||||
# This sets up a woodpecker agent
|
||||
services.woodpecker-agents.agents."docker" = {
|
||||
enable = true;
|
||||
# We need this to talk to the podman socket
|
||||
extraGroups = [ "podman" ];
|
||||
environment = {
|
||||
WOODPECKER_SERVER = "localhost:9000";
|
||||
WOODPECKER_MAX_WORKFLOWS = "4";
|
||||
DOCKER_HOST = "unix:///run/podman/podman.sock";
|
||||
WOODPECKER_BACKEND = "docker";
|
||||
};
|
||||
# Same as with woodpecker-server
|
||||
environmentFile = [ "/var/lib/secrets/woodpecker.env" ];
|
||||
};
|
||||
|
||||
# Here we setup podman and enable dns
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
defaultNetwork.settings = {
|
||||
dns_enabled = true;
|
||||
};
|
||||
};
|
||||
# This is needed for podman to be able to talk over dns
|
||||
networking.firewall.interfaces."podman0" = {
|
||||
allowedUDPPorts = [ 53 ];
|
||||
allowedTCPPorts = [ 53 ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
All configuration options can be found via [NixOS Search](https://search.nixos.org/options?channel=unstable&size=200&sort=relevance&query=woodpecker). There are also some additional resources on how to utilize Woodpecker more effectively with NixOS on the [Awesome Woodpecker](/awesome) page, like using the runners nix-store in the pipeline.
|
@ -1,3 +1,3 @@
|
||||
label: 'Forges'
|
||||
label: 'Installation'
|
||||
collapsible: true
|
||||
collapsed: true
|
980
docs/docs/30-administration/10-configuration/10-server.md
Normal file
@ -0,0 +1,980 @@
|
||||
---
|
||||
toc_max_heading_level: 3
|
||||
---
|
||||
|
||||
# Server
|
||||
|
||||
## Forge and User configuration
|
||||
|
||||
Woodpecker does not have its own user registration. Users are provided by your [forge](./12-forges/11-overview.md) (using OAuth2). The registration is closed by default (`WOODPECKER_OPEN=false`). If the registration is open, any user with an account can log in to Woodpecker with the configured forge.
|
||||
|
||||
You can also restrict the registration:
|
||||
|
||||
- closed registration and manually managing users with the CLI `woodpecker-cli user`
|
||||
- open registration and allowing certain admin users with the setting `WOODPECKER_ADMIN`
|
||||
|
||||
```ini
|
||||
WOODPECKER_OPEN=false
|
||||
WOODPECKER_ADMIN=john.smith,jane_doe
|
||||
```
|
||||
|
||||
- open registration and filtering by organizational affiliation with the setting `WOODPECKER_ORGS`
|
||||
|
||||
```ini
|
||||
WOODPECKER_OPEN=true
|
||||
WOODPECKER_ORGS=dolores,dog-patch
|
||||
```
|
||||
|
||||
Administrators should also be explicitly set in your configuration.
|
||||
|
||||
```ini
|
||||
WOODPECKER_ADMIN=john.smith,jane_doe
|
||||
```
|
||||
|
||||
## Repository configuration
|
||||
|
||||
Woodpecker works with the user's OAuth permissions on the forge. By default Woodpecker will synchronize all repositories the user has access to. Use the variable `WOODPECKER_REPO_OWNERS` to filter which repos should only be synchronized by GitHub users. Normally you should enter the GitHub name of your company here.
|
||||
|
||||
```ini
|
||||
WOODPECKER_REPO_OWNERS=my_company,my_company_oss_github_user
|
||||
```
|
||||
|
||||
## Databases
|
||||
|
||||
The default database engine of Woodpecker is an embedded SQLite database which requires zero installation or configuration. But you can replace it with a MySQL/MariaDB or PostgreSQL database. There are also some fundamentals to keep in mind:
|
||||
|
||||
- Woodpecker does not create your database automatically. If you are using the MySQL or Postgres driver you will need to manually create your database using `CREATE DATABASE`.
|
||||
|
||||
- Woodpecker does not perform data archival; it considered out-of-scope for the project. Woodpecker is rather conservative with the amount of data it stores, however, you should expect the database logs to grow the size of your database considerably.
|
||||
|
||||
- Woodpecker automatically handles database migration, including the initial creation of tables and indexes. New versions of Woodpecker will automatically upgrade the database unless otherwise specified in the release notes.
|
||||
|
||||
- Woodpecker does not perform database backups. This should be handled by separate third party tools provided by your database vendor of choice.
|
||||
|
||||
### SQLite
|
||||
|
||||
By default Woodpecker uses a SQLite database stored under `/var/lib/woodpecker/`. If using containers, you can mount a [data volume](https://docs.docker.com/storage/volumes/#create-and-manage-volumes) to persist the SQLite database.
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
+ volumes:
|
||||
+ - woodpecker-server-data:/var/lib/woodpecker/
|
||||
```
|
||||
|
||||
### MySQL/MariaDB
|
||||
|
||||
The below example demonstrates MySQL database configuration. See the official driver [documentation](https://github.com/go-sql-driver/mysql#dsn-data-source-name) for configuration options and examples.
|
||||
The minimum version of MySQL/MariaDB required is determined by the `go-sql-driver/mysql` - see [it's README](https://github.com/go-sql-driver/mysql#requirements) for more information.
|
||||
|
||||
```ini
|
||||
WOODPECKER_DATABASE_DRIVER=mysql
|
||||
WOODPECKER_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/woodpecker?parseTime=true
|
||||
```
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
The below example demonstrates Postgres database configuration. See the official driver [documentation](https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING) for configuration options and examples.
|
||||
Please use Postgres versions equal or higher than **11**.
|
||||
|
||||
```ini
|
||||
WOODPECKER_DATABASE_DRIVER=postgres
|
||||
WOODPECKER_DATABASE_DATASOURCE=postgres://root:password@1.2.3.4:5432/postgres?sslmode=disable
|
||||
```
|
||||
|
||||
## TLS
|
||||
|
||||
Woodpecker supports SSL configuration by mounting certificates into your container.
|
||||
|
||||
```ini
|
||||
WOODPECKER_SERVER_CERT=/etc/certs/woodpecker.example.com/server.crt
|
||||
WOODPECKER_SERVER_KEY=/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
||||
|
||||
TLS support is provided using the [ListenAndServeTLS](https://golang.org/pkg/net/http/#ListenAndServeTLS) function from the Go standard library.
|
||||
|
||||
### Container configuration
|
||||
|
||||
In addition to the ports shown in the [docker-compose](../05-installation/10-docker-compose.md) installation, port `443` must be exposed:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
ports:
|
||||
+ - 80:80
|
||||
+ - 443:443
|
||||
- 9000:9000
|
||||
```
|
||||
|
||||
Additionally, the certificate and key must be mounted and referenced:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
+ - WOODPECKER_SERVER_CERT=/etc/certs/woodpecker.example.com/server.crt
|
||||
+ - WOODPECKER_SERVER_KEY=/etc/certs/woodpecker.example.com/server.key
|
||||
volumes:
|
||||
+ - /etc/certs/woodpecker.example.com/server.crt:/etc/certs/woodpecker.example.com/server.crt
|
||||
+ - /etc/certs/woodpecker.example.com/server.key:/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
||||
|
||||
## Reverse Proxy
|
||||
|
||||
### Apache
|
||||
|
||||
This guide provides a brief overview for installing Woodpecker server behind the Apache2 web-server. This is an example configuration:
|
||||
|
||||
<!-- cspell:ignore apacheconf -->
|
||||
|
||||
```apacheconf
|
||||
ProxyPreserveHost On
|
||||
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
```
|
||||
|
||||
You must have these Apache modules installed:
|
||||
|
||||
- `proxy`
|
||||
- `proxy_http`
|
||||
|
||||
You must configure Apache to set `X-Forwarded-Proto` when using https.
|
||||
|
||||
```diff
|
||||
ProxyPreserveHost On
|
||||
|
||||
+RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
```
|
||||
|
||||
### Nginx
|
||||
|
||||
This guide provides a basic overview for installing Woodpecker server behind the Nginx web-server. For more advanced configuration options please consult the official Nginx [documentation](https://docs.nginx.com/nginx/admin-guide).
|
||||
|
||||
Example configuration:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name woodpecker.example.com;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
|
||||
chunked_transfer_encoding off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You must configure the proxy to set `X-Forwarded` proxy headers:
|
||||
|
||||
```diff
|
||||
server {
|
||||
listen 80;
|
||||
server_name woodpecker.example.com;
|
||||
|
||||
location / {
|
||||
+ proxy_set_header X-Forwarded-For $remote_addr;
|
||||
+ proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
|
||||
chunked_transfer_encoding off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Caddy
|
||||
|
||||
This guide provides a brief overview for installing Woodpecker server behind the [Caddy web-server](https://caddyserver.com/). This is an example caddyfile proxy configuration:
|
||||
|
||||
```caddy
|
||||
# expose WebUI and API
|
||||
woodpecker.example.com {
|
||||
reverse_proxy woodpecker-server:8000
|
||||
}
|
||||
|
||||
# expose gRPC
|
||||
woodpecker-agent.example.com {
|
||||
reverse_proxy h2c://woodpecker-server:9000
|
||||
}
|
||||
```
|
||||
|
||||
### Tunnelmole
|
||||
|
||||
[Tunnelmole](https://github.com/robbie-cahill/tunnelmole-client) is an open source tunneling tool.
|
||||
|
||||
Start by [installing tunnelmole](https://github.com/robbie-cahill/tunnelmole-client#installation).
|
||||
|
||||
After the installation, run the following command to start tunnelmole:
|
||||
|
||||
```bash
|
||||
tmole 8000
|
||||
```
|
||||
|
||||
It will start a tunnel and will give a response like this:
|
||||
|
||||
```bash
|
||||
➜ ~ tmole 8000
|
||||
http://bvdo5f-ip-49-183-170-144.tunnelmole.net is forwarding to localhost:8000
|
||||
https://bvdo5f-ip-49-183-170-144.tunnelmole.net is forwarding to localhost:8000
|
||||
```
|
||||
|
||||
Set `WOODPECKER_HOST` to the Tunnelmole URL (`xxx.tunnelmole.net`) and start the server.
|
||||
|
||||
### Ngrok
|
||||
|
||||
[Ngrok](https://ngrok.com/) is a popular closed source tunnelling tool. After installing ngrok, open a new console and run the following command:
|
||||
|
||||
```bash
|
||||
ngrok http 8000
|
||||
```
|
||||
|
||||
Set `WOODPECKER_HOST` to the ngrok URL (usually xxx.ngrok.io) and start the server.
|
||||
|
||||
### Traefik
|
||||
|
||||
To install the Woodpecker server behind a [Traefik](https://traefik.io/) load balancer, you must expose both the `http` and the `gRPC` ports. Here is a comprehensive example, considering you are running Traefik with docker swarm and want to do TLS termination and automatic redirection from http to https.
|
||||
|
||||
<!-- cspell:words redirectscheme certresolver -->
|
||||
|
||||
```yaml
|
||||
services:
|
||||
server:
|
||||
image: woodpeckerci/woodpecker-server:latest
|
||||
environment:
|
||||
- WOODPECKER_OPEN=true
|
||||
- WOODPECKER_ADMIN=your_admin_user
|
||||
# other settings ...
|
||||
|
||||
networks:
|
||||
- dmz # externally defined network, so that traefik can connect to the server
|
||||
volumes:
|
||||
- woodpecker-server-data:/var/lib/woodpecker/
|
||||
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
|
||||
# web server
|
||||
- traefik.http.services.woodpecker-service.loadbalancer.server.port=8000
|
||||
|
||||
- traefik.http.routers.woodpecker-secure.rule=Host(`ci.example.com`)
|
||||
- traefik.http.routers.woodpecker-secure.tls=true
|
||||
- traefik.http.routers.woodpecker-secure.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.woodpecker-secure.entrypoints=web-secure
|
||||
- traefik.http.routers.woodpecker-secure.service=woodpecker-service
|
||||
|
||||
- traefik.http.routers.woodpecker.rule=Host(`ci.example.com`)
|
||||
- traefik.http.routers.woodpecker.entrypoints=web
|
||||
- traefik.http.routers.woodpecker.service=woodpecker-service
|
||||
|
||||
- traefik.http.middlewares.woodpecker-redirect.redirectscheme.scheme=https
|
||||
- traefik.http.middlewares.woodpecker-redirect.redirectscheme.permanent=true
|
||||
- traefik.http.routers.woodpecker.middlewares=woodpecker-redirect@docker
|
||||
|
||||
# gRPC service
|
||||
- traefik.http.services.woodpecker-grpc.loadbalancer.server.port=9000
|
||||
- traefik.http.services.woodpecker-grpc.loadbalancer.server.scheme=h2c
|
||||
|
||||
- traefik.http.routers.woodpecker-grpc-secure.rule=Host(`woodpecker-grpc.example.com`)
|
||||
- traefik.http.routers.woodpecker-grpc-secure.tls=true
|
||||
- traefik.http.routers.woodpecker-grpc-secure.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.woodpecker-grpc-secure.entrypoints=web-secure
|
||||
- traefik.http.routers.woodpecker-grpc-secure.service=woodpecker-grpc
|
||||
|
||||
- traefik.http.routers.woodpecker-grpc.rule=Host(`woodpecker-grpc.example.com`)
|
||||
- traefik.http.routers.woodpecker-grpc.entrypoints=web
|
||||
- traefik.http.routers.woodpecker-grpc.service=woodpecker-grpc
|
||||
|
||||
- traefik.http.middlewares.woodpecker-grpc-redirect.redirectscheme.scheme=https
|
||||
- traefik.http.middlewares.woodpecker-grpc-redirect.redirectscheme.permanent=true
|
||||
- traefik.http.routers.woodpecker-grpc.middlewares=woodpecker-grpc-redirect@docker
|
||||
|
||||
volumes:
|
||||
woodpecker-server-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
dmz:
|
||||
external: true
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
### Endpoint
|
||||
|
||||
Woodpecker is compatible with Prometheus and exposes a `/metrics` endpoint if the environment variable `WOODPECKER_PROMETHEUS_AUTH_TOKEN` is set. Please note that access to the metrics endpoint is restricted and requires the authorization token from the environment variable mentioned above.
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
bearer_token: dummyToken...
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
### Authorization
|
||||
|
||||
An administrator will need to generate a user API token and configure in the Prometheus configuration file as a bearer token. Please see the following example:
|
||||
|
||||
```diff
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
+ bearer_token: dummyToken...
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
As an alternative, the token can also be read from a file:
|
||||
|
||||
```diff
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
+ bearer_token_file: /etc/secrets/woodpecker-monitoring-token
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
### Reference
|
||||
|
||||
List of Prometheus metrics specific to Woodpecker:
|
||||
|
||||
```yaml
|
||||
# HELP woodpecker_pipeline_count Pipeline count.
|
||||
# TYPE woodpecker_pipeline_count counter
|
||||
woodpecker_pipeline_count{branch="main",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3
|
||||
woodpecker_pipeline_count{branch="dev",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3
|
||||
# HELP woodpecker_pipeline_time Build time.
|
||||
# TYPE woodpecker_pipeline_time gauge
|
||||
woodpecker_pipeline_time{branch="main",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 116
|
||||
woodpecker_pipeline_time{branch="dev",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 155
|
||||
# HELP woodpecker_pipeline_total_count Total number of builds.
|
||||
# TYPE woodpecker_pipeline_total_count gauge
|
||||
woodpecker_pipeline_total_count 1025
|
||||
# HELP woodpecker_pending_steps Total number of pending pipeline steps.
|
||||
# TYPE woodpecker_pending_steps gauge
|
||||
woodpecker_pending_steps 0
|
||||
# HELP woodpecker_repo_count Total number of repos.
|
||||
# TYPE woodpecker_repo_count gauge
|
||||
woodpecker_repo_count 9
|
||||
# HELP woodpecker_running_steps Total number of running pipeline steps.
|
||||
# TYPE woodpecker_running_steps gauge
|
||||
woodpecker_running_steps 0
|
||||
# HELP woodpecker_user_count Total number of users.
|
||||
# TYPE woodpecker_user_count gauge
|
||||
woodpecker_user_count 1
|
||||
# HELP woodpecker_waiting_steps Total number of pipeline waiting on deps.
|
||||
# TYPE woodpecker_waiting_steps gauge
|
||||
woodpecker_waiting_steps 0
|
||||
# HELP woodpecker_worker_count Total number of workers.
|
||||
# TYPE woodpecker_worker_count gauge
|
||||
woodpecker_worker_count 4
|
||||
```
|
||||
|
||||
## External Configuration API
|
||||
|
||||
To provide additional management and preprocessing capabilities for pipeline configurations Woodpecker supports an HTTP API which can be enabled to call an external config service.
|
||||
Before the run or restart of any pipeline Woodpecker will make a POST request to an external HTTP API sending the current repository, build information and all current config files retrieved from the repository. The external API can then send back new pipeline configurations that will be used immediately or respond with `HTTP 204` to tell the system to use the existing configuration.
|
||||
|
||||
Every request sent by Woodpecker is signed using a [http-signature](https://datatracker.ietf.org/doc/html/rfc9421) by a private key (ed25519) generated on the first start of the Woodpecker server. You can get the public key for the verification of the http-signature from `http(s)://your-woodpecker-server/api/signature/public-key`.
|
||||
|
||||
A simplistic example configuration service can be found here: [https://github.com/woodpecker-ci/example-config-service](https://github.com/woodpecker-ci/example-config-service)
|
||||
|
||||
:::warning
|
||||
You need to trust the external config service as it is getting secret information about the repository and pipeline and has the ability to change pipeline configs that could run malicious tasks.
|
||||
:::
|
||||
|
||||
### Configuration
|
||||
|
||||
```ini title="Server"
|
||||
WOODPECKER_CONFIG_SERVICE_ENDPOINT=https://example.com/ciconfig
|
||||
```
|
||||
|
||||
#### Example request made by Woodpecker
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": {
|
||||
"id": 100,
|
||||
"uid": "",
|
||||
"user_id": 0,
|
||||
"namespace": "",
|
||||
"name": "woodpecker-test-pipe",
|
||||
"slug": "",
|
||||
"scm": "git",
|
||||
"git_http_url": "",
|
||||
"git_ssh_url": "",
|
||||
"link": "",
|
||||
"default_branch": "",
|
||||
"private": true,
|
||||
"visibility": "private",
|
||||
"active": true,
|
||||
"config": "",
|
||||
"trusted": false,
|
||||
"protected": false,
|
||||
"ignore_forks": false,
|
||||
"ignore_pulls": false,
|
||||
"cancel_pulls": false,
|
||||
"timeout": 60,
|
||||
"counter": 0,
|
||||
"synced": 0,
|
||||
"created": 0,
|
||||
"updated": 0,
|
||||
"version": 0
|
||||
},
|
||||
"pipeline": {
|
||||
"author": "myUser",
|
||||
"author_avatar": "https://myforge.com/avatars/d6b3f7787a685fcdf2a44e2c685c7e03",
|
||||
"author_email": "my@email.com",
|
||||
"branch": "main",
|
||||
"changed_files": ["some-file-name.txt"],
|
||||
"commit": "2fff90f8d288a4640e90f05049fe30e61a14fd50",
|
||||
"created_at": 0,
|
||||
"deploy_to": "",
|
||||
"enqueued_at": 0,
|
||||
"error": "",
|
||||
"event": "push",
|
||||
"finished_at": 0,
|
||||
"id": 0,
|
||||
"link_url": "https://myforge.com/myUser/woodpecker-testpipe/commit/2fff90f8d288a4640e90f05049fe30e61a14fd50",
|
||||
"message": "test old config\n",
|
||||
"number": 0,
|
||||
"parent": 0,
|
||||
"ref": "refs/heads/main",
|
||||
"refspec": "",
|
||||
"clone_url": "",
|
||||
"reviewed_at": 0,
|
||||
"reviewed_by": "",
|
||||
"sender": "myUser",
|
||||
"signed": false,
|
||||
"started_at": 0,
|
||||
"status": "",
|
||||
"timestamp": 1645962783,
|
||||
"title": "",
|
||||
"updated_at": 0,
|
||||
"verified": false
|
||||
},
|
||||
"netrc": {
|
||||
"machine": "https://example.com",
|
||||
"login": "user",
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example response structure
|
||||
|
||||
```json
|
||||
{
|
||||
"configs": [
|
||||
{
|
||||
"name": "central-override",
|
||||
"data": "steps:\n - name: backend\n image: alpine\n commands:\n - echo \"Hello there from ConfigAPI\"\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## UI customization
|
||||
|
||||
Woodpecker supports custom JS and CSS files. These files must be present in the server's filesystem.
|
||||
They can be backed in a Docker image or mounted from a ConfigMap inside a Kubernetes environment.
|
||||
The configuration variables are independent of each other, which means it can be just one file present, or both.
|
||||
|
||||
```ini
|
||||
WOODPECKER_CUSTOM_CSS_FILE=/usr/local/www/woodpecker.css
|
||||
WOODPECKER_CUSTOM_JS_FILE=/usr/local/www/woodpecker.js
|
||||
```
|
||||
|
||||
The examples below show how to place a banner message in the top navigation bar of Woodpecker.
|
||||
|
||||
```css title="woodpecker.css"
|
||||
.banner-message {
|
||||
position: absolute;
|
||||
width: 280px;
|
||||
height: 40px;
|
||||
margin-left: 240px;
|
||||
margin-top: 5px;
|
||||
padding-top: 5px;
|
||||
font-weight: bold;
|
||||
background: red no-repeat;
|
||||
text-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
```javascript title="woodpecker.js"
|
||||
// place/copy a minified version of your preferred lightweight JavaScript library here ...
|
||||
!(function () {
|
||||
'use strict';
|
||||
function e() {} /*...*/
|
||||
})();
|
||||
|
||||
$().ready(function () {
|
||||
$('.app nav img').first().htmlAfter("<div class='banner-message'>This is a demo banner message :)</div>");
|
||||
});
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
|
||||
### `WOODPECKER_LOG_LEVEL`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures the logging level. Possible values are `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic`, `disabled` and empty.
|
||||
|
||||
### `WOODPECKER_LOG_FILE`
|
||||
|
||||
> Default: `stderr`
|
||||
|
||||
Output destination for logs.
|
||||
'stdout' and 'stderr' can be used as special keywords.
|
||||
|
||||
### `WOODPECKER_DATABASE_LOG`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable logging in database engine (currently xorm).
|
||||
|
||||
### `WOODPECKER_DATABASE_LOG_SQL`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable logging of sql commands.
|
||||
|
||||
### `WOODPECKER_DATABASE_MAX_CONNECTIONS`
|
||||
|
||||
> Default: `100`
|
||||
|
||||
Max database connections xorm is allowed create.
|
||||
|
||||
### `WOODPECKER_DATABASE_IDLE_CONNECTIONS`
|
||||
|
||||
> Default: `2`
|
||||
|
||||
Amount of database connections xorm will hold open.
|
||||
|
||||
### `WOODPECKER_DATABASE_CONNECTION_TIMEOUT`
|
||||
|
||||
> Default: `3 Seconds`
|
||||
|
||||
Time an active database connection is allowed to stay open.
|
||||
|
||||
### `WOODPECKER_DEBUG_PRETTY`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable pretty-printed debug output.
|
||||
|
||||
### `WOODPECKER_DEBUG_NOCOLOR`
|
||||
|
||||
> Default: `true`
|
||||
|
||||
Disable colored debug output.
|
||||
|
||||
### `WOODPECKER_HOST`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Server fully qualified URL of the user-facing hostname, port (if not default for HTTP/HTTPS) and path prefix.
|
||||
|
||||
Examples:
|
||||
|
||||
- `WOODPECKER_HOST=http://woodpecker.example.org`
|
||||
- `WOODPECKER_HOST=http://example.org/woodpecker`
|
||||
- `WOODPECKER_HOST=http://example.org:1234/woodpecker`
|
||||
|
||||
### `WOODPECKER_SERVER_ADDR`
|
||||
|
||||
> Default: `:8000`
|
||||
|
||||
Configures the HTTP listener port.
|
||||
|
||||
### `WOODPECKER_SERVER_ADDR_TLS`
|
||||
|
||||
> Default: `:443`
|
||||
|
||||
Configures the HTTPS listener port when SSL is enabled.
|
||||
|
||||
### `WOODPECKER_SERVER_CERT`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Path to an SSL certificate used by the server to accept HTTPS requests.
|
||||
|
||||
Example: `WOODPECKER_SERVER_CERT=/path/to/cert.pem`
|
||||
|
||||
### `WOODPECKER_SERVER_KEY`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Path to an SSL certificate key used by the server to accept HTTPS requests.
|
||||
|
||||
Example: `WOODPECKER_SERVER_KEY=/path/to/key.pem`
|
||||
|
||||
### `WOODPECKER_CUSTOM_CSS_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
File path for the server to serve a custom .CSS file, used for customizing the UI.
|
||||
Can be used for showing banner messages, logos, or environment-specific hints (a.k.a. white-labeling).
|
||||
The file must be UTF-8 encoded, to ensure all special characters are preserved.
|
||||
|
||||
Example: `WOODPECKER_CUSTOM_CSS_FILE=/usr/local/www/woodpecker.css`
|
||||
|
||||
### `WOODPECKER_CUSTOM_JS_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
File path for the server to serve a custom .JS file, used for customizing the UI.
|
||||
Can be used for showing banner messages, logos, or environment-specific hints (a.k.a. white-labeling).
|
||||
The file must be UTF-8 encoded, to ensure all special characters are preserved.
|
||||
|
||||
Example: `WOODPECKER_CUSTOM_JS_FILE=/usr/local/www/woodpecker.js`
|
||||
|
||||
### `WOODPECKER_GRPC_ADDR`
|
||||
|
||||
> Default: `:9000`
|
||||
|
||||
Configures the gRPC listener port.
|
||||
|
||||
### `WOODPECKER_GRPC_SECRET`
|
||||
|
||||
> Default: `secret`
|
||||
|
||||
Configures the gRPC JWT secret.
|
||||
|
||||
### `WOODPECKER_GRPC_SECRET_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_GRPC_SECRET` from the specified filepath.
|
||||
|
||||
### `WOODPECKER_METRICS_SERVER_ADDR`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures an unprotected metrics endpoint. An empty value disables the metrics endpoint completely.
|
||||
|
||||
Example: `:9001`
|
||||
|
||||
### `WOODPECKER_ADMIN`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of admin accounts.
|
||||
|
||||
Example: `WOODPECKER_ADMIN=user1,user2`
|
||||
|
||||
### `WOODPECKER_ORGS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of approved organizations.
|
||||
|
||||
Example: `org1,org2`
|
||||
|
||||
### `WOODPECKER_REPO_OWNERS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Repositories by those owners will be allowed to be used in woodpecker.
|
||||
|
||||
Example: `user1,user2`
|
||||
|
||||
### `WOODPECKER_OPEN`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable to allow user registration.
|
||||
|
||||
### `WOODPECKER_AUTHENTICATE_PUBLIC_REPOS`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Always use authentication to clone repositories even if they are public. Needed if the forge requires to always authenticate as used by many companies.
|
||||
|
||||
### `WOODPECKER_DEFAULT_ALLOW_PULL_REQUESTS`
|
||||
|
||||
> Default: `true`
|
||||
|
||||
The default setting for allowing pull requests on a repo.
|
||||
|
||||
### `WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS`
|
||||
|
||||
> Default: `pull_request, push`
|
||||
|
||||
List of event names that will be canceled when a new pipeline for the same context (tag, branch) is created.
|
||||
|
||||
### `WOODPECKER_DEFAULT_CLONE_PLUGIN`
|
||||
|
||||
> Default is defined in [shared/constant/constant.go](https://github.com/woodpecker-ci/woodpecker/blob/main/shared/constant/constant.go)
|
||||
|
||||
The default docker image to be used when cloning the repo.
|
||||
|
||||
It is also added to the trusted clone plugin list.
|
||||
|
||||
### `WOODPECKER_DEFAULT_WORKFLOW_LABELS`
|
||||
|
||||
> By default run workflows on any agent if no label conditions are set in workflow definition.
|
||||
|
||||
You can specify default label/platform conditions that will be used for agent selection for workflows that does not have labels conditions set.
|
||||
|
||||
Example: `platform=linux/amd64,backend=docker`
|
||||
|
||||
### `WOODPECKER_DEFAULT_PIPELINE_TIMEOUT`
|
||||
|
||||
> 60 (minutes)
|
||||
|
||||
The default time for a repo in minutes before a pipeline gets killed
|
||||
|
||||
### `WOODPECKER_MAX_PIPELINE_TIMEOUT`
|
||||
|
||||
> 120 (minutes)
|
||||
|
||||
The maximum time in minutes you can set in the repo settings before a pipeline gets killed
|
||||
|
||||
### `WOODPECKER_SESSION_EXPIRES`
|
||||
|
||||
> Default: `72h`
|
||||
|
||||
Configures the session expiration time.
|
||||
Context: when someone does log into Woodpecker, a temporary session token is created.
|
||||
As long as the session is valid (until it expires or log-out),
|
||||
a user can log into Woodpecker, without re-authentication.
|
||||
|
||||
### `WOODPECKER_PLUGINS_PRIVILEGED`
|
||||
|
||||
Docker images to run in privileged mode. Only change if you are sure what you do!
|
||||
|
||||
You should specify the tag of your images too, as this enforces exact matches.
|
||||
|
||||
### WOODPECKER_PLUGINS_TRUSTED_CLONE
|
||||
|
||||
> Defaults are defined in [shared/constant/constant.go](https://github.com/woodpecker-ci/woodpecker/blob/main/shared/constant/constant.go)
|
||||
|
||||
Plugins which are trusted to handle the Git credential info in clone steps.
|
||||
If a clone step use an image not in this list, Git credentials will not be injected and users have to use other methods (e.g. secrets) to clone non-public repos.
|
||||
|
||||
You should specify the tag of your images too, as this enforces exact matches.
|
||||
|
||||
<!--
|
||||
### `WOODPECKER_VOLUME`
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of Docker volumes that are mounted into every pipeline step.
|
||||
|
||||
Example: `WOODPECKER_VOLUME=/path/on/host:/path/in/container:rw`|
|
||||
-->
|
||||
|
||||
### `WOODPECKER_DOCKER_CONFIG`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures a specific private registry config for all pipelines.
|
||||
|
||||
Example: `WOODPECKER_DOCKER_CONFIG=/home/user/.docker/config.json`
|
||||
|
||||
<!--
|
||||
### `WOODPECKER_ENVIRONMENT`
|
||||
> Default: empty
|
||||
|
||||
TODO
|
||||
|
||||
### `WOODPECKER_NETWORK`
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of Docker networks that are attached to every pipeline step.
|
||||
|
||||
Example: `WOODPECKER_NETWORK=network1,network2`
|
||||
-->
|
||||
|
||||
### `WOODPECKER_AGENT_SECRET`
|
||||
|
||||
> Default: empty
|
||||
|
||||
A shared secret used by server and agents to authenticate communication. A secret can be generated by `openssl rand -hex 32`.
|
||||
|
||||
### `WOODPECKER_AGENT_SECRET_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_AGENT_SECRET` from the specified filepath
|
||||
|
||||
### `WOODPECKER_DISABLE_USER_AGENT_REGISTRATION`
|
||||
|
||||
> Default: false
|
||||
|
||||
By default, users can create new agents for their repos they have admin access to.
|
||||
If an instance admin doesn't want this feature enabled, they can disable the API and hide the Web UI elements.
|
||||
|
||||
:::note
|
||||
You should set this option if you have, for example,
|
||||
global secrets and don't trust your users to create a rogue agent and pipeline for secret extraction.
|
||||
:::
|
||||
|
||||
### `WOODPECKER_KEEPALIVE_MIN_TIME`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Server-side enforcement policy on the minimum amount of time a client should wait before sending a keepalive ping.
|
||||
|
||||
Example: `WOODPECKER_KEEPALIVE_MIN_TIME=10s`
|
||||
|
||||
### `WOODPECKER_DATABASE_DRIVER`
|
||||
|
||||
> Default: `sqlite3`
|
||||
|
||||
The database driver name. Possible values are `sqlite3`, `mysql` or `postgres`.
|
||||
|
||||
### `WOODPECKER_DATABASE_DATASOURCE`
|
||||
|
||||
> Default: `woodpecker.sqlite` if not running inside a container, `/var/lib/woodpecker/woodpecker.sqlite` if running inside a container
|
||||
|
||||
The database connection string. The default value is the path of the embedded SQLite database file.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
# MySQL
|
||||
# https://github.com/go-sql-driver/mysql#dsn-data-source-name
|
||||
WOODPECKER_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/woodpecker?parseTime=true
|
||||
|
||||
# PostgreSQL
|
||||
# https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
WOODPECKER_DATABASE_DATASOURCE=postgres://root:password@1.2.3.4:5432/woodpecker?sslmode=disable
|
||||
```
|
||||
|
||||
### `WOODPECKER_DATABASE_DATASOURCE_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_DATABASE_DATASOURCE` from the specified filepath
|
||||
|
||||
### `WOODPECKER_PROMETHEUS_AUTH_TOKEN`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Token to secure the Prometheus metrics endpoint.
|
||||
Must be set to enable the endpoint.
|
||||
|
||||
### `WOODPECKER_PROMETHEUS_AUTH_TOKEN_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_PROMETHEUS_AUTH_TOKEN` from the specified filepath
|
||||
|
||||
### `WOODPECKER_STATUS_CONTEXT`
|
||||
|
||||
> Default: `ci/woodpecker`
|
||||
|
||||
Context prefix Woodpecker will use to publish status messages to SCM. You probably will only need to change it if you run multiple Woodpecker instances for a single repository.
|
||||
|
||||
### `WOODPECKER_STATUS_CONTEXT_FORMAT`
|
||||
|
||||
> Default: `{{ .context }}/{{ .event }}/{{ .workflow }}{{if not (eq .axis_id 0)}}/{{.axis_id}}{{end}}`
|
||||
|
||||
Template for the status messages published to forges, uses [Go templates](https://pkg.go.dev/text/template) as template language.
|
||||
Supported variables:
|
||||
|
||||
- `context`: Woodpecker's context (see `WOODPECKER_STATUS_CONTEXT`)
|
||||
- `event`: the event which started the pipeline
|
||||
- `workflow`: the workflow's name
|
||||
- `owner`: the repo's owner
|
||||
- `repo`: the repo's name
|
||||
|
||||
---
|
||||
|
||||
### `WOODPECKER_CONFIG_SERVICE_ENDPOINT`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Specify a configuration service endpoint, see [Configuration Extension](#external-configuration-api)
|
||||
|
||||
### `WOODPECKER_FORGE_TIMEOUT`
|
||||
|
||||
> Default: 5s
|
||||
|
||||
Specify timeout when fetching the Woodpecker configuration from forge. See <https://pkg.go.dev/time#ParseDuration> for syntax reference.
|
||||
|
||||
### `WOODPECKER_FORGE_RETRY`
|
||||
|
||||
> Default: 3
|
||||
|
||||
Specify how many retries of fetching the Woodpecker configuration from a forge are done before we fail.
|
||||
|
||||
### `WOODPECKER_ENABLE_SWAGGER`
|
||||
|
||||
> Default: true
|
||||
|
||||
Enable the Swagger UI for API documentation.
|
||||
|
||||
### `WOODPECKER_DISABLE_VERSION_CHECK`
|
||||
|
||||
> Default: false
|
||||
|
||||
Disable version check in admin web UI.
|
||||
|
||||
### `WOODPECKER_LOG_STORE`
|
||||
|
||||
> Default: `database`
|
||||
|
||||
Where to store logs. Possible values: `database` or `file`.
|
||||
|
||||
### `WOODPECKER_LOG_STORE_FILE_PATH`
|
||||
|
||||
> Default empty
|
||||
|
||||
Directory to store logs in if [`WOODPECKER_LOG_STORE`](#woodpecker_log_store) is `file`.
|
||||
|
||||
---
|
||||
|
||||
### `WOODPECKER_GITHUB_...`
|
||||
|
||||
See [GitHub configuration](./12-forges/20-github.md#configuration)
|
||||
|
||||
### `WOODPECKER_GITEA_...`
|
||||
|
||||
See [Gitea configuration](./12-forges/30-gitea.md#configuration)
|
||||
|
||||
### `WOODPECKER_BITBUCKET_...`
|
||||
|
||||
See [Bitbucket configuration](./12-forges/50-bitbucket.md#configuration)
|
||||
|
||||
### `WOODPECKER_GITLAB_...`
|
||||
|
||||
See [GitLab configuration](./12-forges/40-gitlab.md#configuration)
|
||||
|
||||
### `WOODPECKER_ADDON_FORGE`
|
||||
|
||||
See [addon forges](./12-forges/100-addon.md).
|
@ -2,13 +2,13 @@
|
||||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
# Docker backend
|
||||
# Docker
|
||||
|
||||
This is the original backend used with Woodpecker. The docker backend executes each step inside a separate container started on the agent.
|
||||
|
||||
## Docker credentials
|
||||
## Private registries
|
||||
|
||||
Woodpecker supports [Docker credentials](https://github.com/docker/docker-credential-helpers) to securely store registry credentials. Install your corresponding credential helper and configure it in your Docker config file passed via [`WOODPECKER_DOCKER_CONFIG`](../10-server-config.md#woodpecker_docker_config).
|
||||
Woodpecker supports [Docker credentials](https://github.com/docker/docker-credential-helpers) to securely store registry credentials. Install your corresponding credential helper and configure it in your Docker config file passed via [`WOODPECKER_DOCKER_CONFIG`](../10-server.md#woodpecker_docker_config).
|
||||
|
||||
To add your credential helper to the Woodpecker server container you could use the following code to build a custom image:
|
||||
|
||||
@ -37,7 +37,9 @@ steps:
|
||||
|
||||
The syntax is the same as the [docker run](https://docs.docker.com/engine/reference/run/#user) `--user` flag.
|
||||
|
||||
## Image cleanup
|
||||
## Tips and tricks
|
||||
|
||||
### Image cleanup
|
||||
|
||||
The agent **will not** automatically remove images from the host. This task should be managed by the host system. For example, you can use a cron job to periodically do clean-up tasks for the CI runner.
|
||||
|
||||
@ -45,27 +47,25 @@ The agent **will not** automatically remove images from the host. This task shou
|
||||
The following commands **are destructive** and **irreversible** it is highly recommended that you test these commands on your system before running them in production via a cron job or other automation.
|
||||
:::
|
||||
|
||||
### Remove all unused images
|
||||
- Remove all unused images
|
||||
|
||||
<!-- cspell:ignore trunc -->
|
||||
<!-- cspell:ignore trunc -->
|
||||
|
||||
```bash
|
||||
docker image rm $(docker images --filter "dangling=true" -q --no-trunc)
|
||||
```
|
||||
```bash
|
||||
docker image rm $(docker images --filter "dangling=true" -q --no-trunc)
|
||||
```
|
||||
|
||||
### Remove Woodpecker volumes
|
||||
- Remove Woodpecker volumes
|
||||
|
||||
```bash
|
||||
docker volume rm $(docker volume ls --filter name=^wp_* --filter dangling=true -q)
|
||||
```
|
||||
|
||||
## Tips and tricks
|
||||
```bash
|
||||
docker volume rm $(docker volume ls --filter name=^wp_* --filter dangling=true -q)
|
||||
```
|
||||
|
||||
### Podman
|
||||
|
||||
There is no official support for Podman, but one can try to set the environment variable `DOCKER_HOST` to point to the Podman socket. It might work. See also the [Blog posts](https://woodpecker-ci.org/blog).
|
||||
|
||||
## Configuration
|
||||
## Environment variables
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_NETWORK`
|
||||
|
@ -2,13 +2,13 @@
|
||||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
# Kubernetes backend
|
||||
# Kubernetes
|
||||
|
||||
The Kubernetes backend executes steps inside standalone Pods. A temporary PVC is created for the lifetime of the pipeline to transfer files between steps.
|
||||
|
||||
## Images from private registries
|
||||
## Private registries
|
||||
|
||||
In addition to [registries specified in the UI](../../20-usage/41-registries.md), you may provide [registry credentials in Kubernetes Secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) to pull private container images defined in your pipeline YAML.
|
||||
In addition to [registries specified in the UI](../../../20-usage/41-registries.md), you may provide [registry credentials in Kubernetes Secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) to pull private container images defined in your pipeline YAML.
|
||||
|
||||
Place these Secrets in namespace defined by `WOODPECKER_BACKEND_K8S_NAMESPACE` and provide the Secret names to Agents via `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES`.
|
||||
|
||||
@ -279,7 +279,7 @@ It configures the address of the Kubernetes API server to connect to.
|
||||
|
||||
If running the agent within Kubernetes, this will already be set and you don't have to add it manually.
|
||||
|
||||
## Configuration
|
||||
## Environment variables
|
||||
|
||||
These env vars can be set in the `env:` sections of the agent.
|
||||
|
@ -1,15 +1,15 @@
|
||||
---
|
||||
toc_max_heading_level: 3
|
||||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
# Local backend
|
||||
# Local
|
||||
|
||||
:::danger
|
||||
The local backend executes pipelines on the local system without any isolation.
|
||||
:::
|
||||
|
||||
:::note
|
||||
Currently we do not support [services](../../20-usage/60-services.md) for this backend.
|
||||
Currently we do not support [services](../../../20-usage/60-services.md) for this backend.
|
||||
[Read more here](https://github.com/woodpecker-ci/woodpecker/issues/3095).
|
||||
:::
|
||||
|
||||
@ -27,13 +27,7 @@ code and execute commands.
|
||||
In order to use this backend, you need to download (or build) the
|
||||
[agent](https://github.com/woodpecker-ci/woodpecker/releases/latest), configure it and run it on the host machine.
|
||||
|
||||
## Usage
|
||||
|
||||
To enable the local backend, set the following:
|
||||
|
||||
```ini
|
||||
WOODPECKER_BACKEND=local
|
||||
```
|
||||
## Step specific configuration
|
||||
|
||||
### Shell
|
||||
|
||||
@ -58,9 +52,9 @@ steps:
|
||||
If no commands are provided, plugins are treated in the usual manner.
|
||||
In the context of the local backend, plugins are simply executable binaries, which can be located using their name if they are listed in `$PATH`, or through an absolute path.
|
||||
|
||||
### Options
|
||||
## Environment variables
|
||||
|
||||
#### `WOODPECKER_BACKEND_LOCAL_TEMP_DIR`
|
||||
### `WOODPECKER_BACKEND_LOCAL_TEMP_DIR`
|
||||
|
||||
> Default: default temp directory
|
||||
|
@ -0,0 +1,18 @@
|
||||
# Custom
|
||||
|
||||
If none of our backends fit your use case, you can write your own. To do this, implement the interface `“go.woodpecker-ci.org/woodpecker/woodpecker/v3/pipeline/backend/types”.backend` and create a custom agent that uses your backend:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cmd/agent/core"
|
||||
backendTypes "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
core.RunAgent([]backendTypes.Backend{
|
||||
yourBackend,
|
||||
})
|
||||
}
|
||||
```
|
@ -1,13 +1,13 @@
|
||||
# Addon forges
|
||||
# Custom
|
||||
|
||||
If the forge you're using does not comply with [Woodpecker's requirements](../../92-development/02-core-ideas.md#forges) or your setup is too specific to be added to Woodpecker's core, you can write your own forge using an addon forge.
|
||||
If the forge you are using does not meet the [Woodpecker requirements](../../../92-development/02-core-ideas.md#forges) or your setup is too specific to be included in the Woodpecker core, you can write an addon forge.
|
||||
|
||||
:::warning
|
||||
Addon forges are still experimental. Their implementation can change and break at any time.
|
||||
:::
|
||||
|
||||
:::danger
|
||||
You need to trust the author of the addon forge you use. It can access authentication codes and other possibly sensitive information.
|
||||
You must trust the author of the addon forge you are using. They may have access to authentication codes and other potentially sensitive information.
|
||||
:::
|
||||
|
||||
## Usage
|
||||
@ -26,9 +26,7 @@ If you experience bugs, please check which component has the issue. If it's the
|
||||
|
||||
## List of addon forges
|
||||
|
||||
If you wrote or found an addon forge, please add it here so others can find it!
|
||||
|
||||
_Be the first one to add your addon forge!_
|
||||
- [Radicle](https://radicle.xyz/): Open source, peer-to-peer code collaboration stack built on Git. Radicle addon for Woodpecker CI can be found at [this repo](https://explorer.radicle.gr/nodes/seed.radicle.gr/rad:z39Cf1XzrvCLRZZJRUZnx9D1fj5ws).
|
||||
|
||||
## Creating addon forges
|
||||
|
||||
@ -43,6 +41,10 @@ Directly import Woodpecker's Go packages (`go.woodpecker-ci.org/woodpecker/v3`)
|
||||
In the `main` function, just call `"go.woodpecker-ci.org/woodpecker/v3/server/forge/addon".Serve` with a `"go.woodpecker-ci.org/woodpecker/v3/server/forge".Forge` as argument.
|
||||
This will take care of connecting the addon forge to the server.
|
||||
|
||||
:::note
|
||||
It is not possible to access global variables from Woodpecker, for example the server configuration. You must therefore parse the environment variables in your addon. The reason for this is that the addon runs in a completely separate process.
|
||||
:::
|
||||
|
||||
### Example structure
|
||||
|
||||
```go
|
@ -0,0 +1,15 @@
|
||||
# Forges
|
||||
|
||||
## Supported features
|
||||
|
||||
| Feature | [GitHub](20-github.md) | [Gitea](30-gitea.md) | [Forgejo](35-forgejo.md) | [Gitlab](40-gitlab.md) | [Bitbucket](50-bitbucket.md) | [Bitbucket Datacenter](60-bitbucket_datacenter.md) |
|
||||
| ---------------------------------------------------------------- | :--------------------: | :------------------: | :----------------------: | :--------------------: | :--------------------------: | :------------------------------------------------: |
|
||||
| Event: Push | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Tag | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Pull-Request | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Release | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: |
|
||||
| Event: Deploy¹ | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
| [Multiple workflows](../../../20-usage/25-workflows.md) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| [when.path filter](../../../20-usage/20-workflow-syntax.md#path) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: |
|
||||
|
||||
¹ The deployment event can be triggered for all forges from Woodpecker directly. However, only GitHub can trigger them using webhooks.
|
@ -33,7 +33,7 @@ To configure the Docker network if the network's name is `gitea`, configure it l
|
||||
|
||||
## Registration
|
||||
|
||||
Register your application with Gitea to create your client id and secret. You can find the OAuth applications settings of Gitea at `https://gitea.<host>/user/settings/`. It is very import the authorization callback URL matches your http(s) scheme and hostname exactly with `https://<host>/authorize` as the path.
|
||||
Register your application with Gitea to create your client id and secret. You can find the OAuth applications settings of Gitea at `https://gitea.<host>/user/settings/`. It is very important that authorization callback URL matches your http(s) scheme and hostname exactly with `https://<host>/authorize` as the path.
|
||||
|
||||
If you run the Woodpecker CI server on the same host as the Gitea instance, you might also need to allow local connections in Gitea, since version `v1.16`. Otherwise webhooks will fail. Add the following lines to your Gitea configuration (usually at `/etc/gitea/conf/app.ini`).
|
||||
|
@ -33,7 +33,7 @@ To configure the Docker network if the network's name is `forgejo`, configure it
|
||||
|
||||
## Registration
|
||||
|
||||
Register your application with Forgejo to create your client id and secret. You can find the OAuth applications settings of Forgejo at `https://forgejo.<host>/user/settings/`. It is very import the authorization callback URL matches your http(s) scheme and hostname exactly with `https://<host>/authorize` as the path.
|
||||
Register your application with Forgejo to create your client id and secret. You can find the OAuth applications settings of Forgejo at `https://forgejo.<host>/user/settings/`. It is very important that authorization callback URL matches your http(s) scheme and hostname exactly with `https://<host>/authorize` as the path.
|
||||
|
||||
If you run the Woodpecker CI server on the same host as the Forgejo instance, you might also need to allow local connections in Forgejo. Otherwise webhooks will fail. Add the following lines to your Forgejo configuration (usually at `/etc/forgejo/conf/app.ini`).
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@ -1,8 +1,8 @@
|
||||
---
|
||||
toc_max_heading_level: 2
|
||||
toc_max_heading_level: 3
|
||||
---
|
||||
|
||||
# Agent configuration
|
||||
# Agent
|
||||
|
||||
Agents are configured by the command line or environment variables. At the minimum you need the following information:
|
||||
|
||||
@ -56,9 +56,7 @@ To get an _agent token_ you have to register the agent manually in the server us
|
||||
1. The agent will connect to the server using the provided token and will update its status in the UI:
|
||||

|
||||
|
||||
## All agent configuration options
|
||||
|
||||
Here is the full list of configuration options and their default variables.
|
||||
## Environment variables
|
||||
|
||||
### `WOODPECKER_SERVER`
|
||||
|
||||
@ -127,7 +125,7 @@ Configures the number of parallel workflows.
|
||||
Configures custom labels for the agent, to let workflows filter by it.
|
||||
Use a list of key-value pairs like `key=value,second-key=*`. `*` can be used as a wildcard.
|
||||
By default, agents provide three additional labels `platform=os/arch`, `hostname=my-agent` and `repo=*` which can be overwritten if needed.
|
||||
To learn how labels work, check out the [pipeline syntax page](../20-usage/20-workflow-syntax.md#labels).
|
||||
To learn how labels work, check out the [pipeline syntax page](../../20-usage/20-workflow-syntax.md#labels).
|
||||
|
||||
### `WOODPECKER_HEALTHCHECK`
|
||||
|
||||
@ -173,29 +171,29 @@ Configures the backend engine to run pipelines on. Possible values are `auto-det
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_*`
|
||||
|
||||
See [Docker backend configuration](./22-backends/10-docker.md#configuration)
|
||||
See [Docker backend configuration](./11-backends/10-docker.md#environment-variables)
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_*`
|
||||
|
||||
See [Kubernetes backend configuration](./22-backends/40-kubernetes.md#configuration)
|
||||
See [Kubernetes backend configuration](./11-backends/20-kubernetes.md#environment-variables)
|
||||
|
||||
### `WOODPECKER_BACKEND_LOCAL_*`
|
||||
|
||||
See [Local backend configuration](./22-backends/20-local.md#options)
|
||||
See [Local backend configuration](./11-backends/30-local.md#environment-variables)
|
||||
|
||||
## Advanced Settings
|
||||
### Advanced Settings
|
||||
|
||||
:::warning
|
||||
Only change these If you know what you do.
|
||||
:::
|
||||
|
||||
### `WOODPECKER_CONNECT_RETRY_COUNT`
|
||||
#### `WOODPECKER_CONNECT_RETRY_COUNT`
|
||||
|
||||
> Default: `5`
|
||||
|
||||
Configures number of times agent retries to connect to the server.
|
||||
|
||||
### `WOODPECKER_CONNECT_RETRY_DELAY`
|
||||
#### `WOODPECKER_CONNECT_RETRY_DELAY`
|
||||
|
||||
> Default: `2s`
|
||||
|
@ -1,3 +1,3 @@
|
||||
label: 'Deployment methods'
|
||||
label: 'Configuration'
|
||||
collapsible: true
|
||||
collapsed: true
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@ -1,51 +0,0 @@
|
||||
# Databases
|
||||
|
||||
The default database engine of Woodpecker is an embedded SQLite database which requires zero installation or configuration. But you can replace it with a MySQL/MariaDB or Postgres database.
|
||||
|
||||
## Configure SQLite
|
||||
|
||||
By default Woodpecker uses a SQLite database stored under `/var/lib/woodpecker/`. If using containers, you can mount a [data volume](https://docs.docker.com/storage/volumes/#create-and-manage-volumes) to persist the SQLite database.
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
+ volumes:
|
||||
+ - woodpecker-server-data:/var/lib/woodpecker/
|
||||
```
|
||||
|
||||
## Configure MySQL/MariaDB
|
||||
|
||||
The below example demonstrates MySQL database configuration. See the official driver [documentation](https://github.com/go-sql-driver/mysql#dsn-data-source-name) for configuration options and examples.
|
||||
The minimum version of MySQL/MariaDB required is determined by the `go-sql-driver/mysql` - see [it's README](https://github.com/go-sql-driver/mysql#requirements) for more information.
|
||||
|
||||
```ini
|
||||
WOODPECKER_DATABASE_DRIVER=mysql
|
||||
WOODPECKER_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/woodpecker?parseTime=true
|
||||
```
|
||||
|
||||
## Configure Postgres
|
||||
|
||||
The below example demonstrates Postgres database configuration. See the official driver [documentation](https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING) for configuration options and examples.
|
||||
Please use Postgres versions equal or higher than **11**.
|
||||
|
||||
```ini
|
||||
WOODPECKER_DATABASE_DRIVER=postgres
|
||||
WOODPECKER_DATABASE_DATASOURCE=postgres://root:password@1.2.3.4:5432/postgres?sslmode=disable
|
||||
```
|
||||
|
||||
## Database Creation
|
||||
|
||||
Woodpecker does not create your database automatically. If you are using the MySQL or Postgres driver you will need to manually create your database using `CREATE DATABASE`.
|
||||
|
||||
## Database Migration
|
||||
|
||||
Woodpecker automatically handles database migration, including the initial creation of tables and indexes. New versions of Woodpecker will automatically upgrade the database unless otherwise specified in the release notes.
|
||||
|
||||
## Database Backups
|
||||
|
||||
Woodpecker does not perform database backups. This should be handled by separate third party tools provided by your database vendor of choice.
|
||||
|
||||
## Database Archiving
|
||||
|
||||
Woodpecker does not perform data archival; it considered out-of-scope for the project. Woodpecker is rather conservative with the amount of data it stores, however, you should expect the database logs to grow the size of your database considerably.
|
@ -1,581 +0,0 @@
|
||||
---
|
||||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
# Server configuration
|
||||
|
||||
## User registration
|
||||
|
||||
Woodpecker does not have its own user registry; users are provided from your [forge](./11-forges/11-overview.md) (using OAuth2).
|
||||
|
||||
Registration is closed by default (`WOODPECKER_OPEN=false`). If registration is open (`WOODPECKER_OPEN=true`) then every user with an account at the configured forge can login to Woodpecker.
|
||||
|
||||
To open registration:
|
||||
|
||||
```ini
|
||||
WOODPECKER_OPEN=true
|
||||
```
|
||||
|
||||
You can **also restrict** registration, by keep registration closed and:
|
||||
|
||||
- **adding** new **users manually** via the CLI: `woodpecker-cli user add`
|
||||
- allowing specific **admin users** via the `WOODPECKER_ADMIN` setting
|
||||
- by open registration and **filter by organization** membership through the `WOODPECKER_ORGS` setting
|
||||
|
||||
### Close registration, but allow specific admin users
|
||||
|
||||
```ini
|
||||
WOODPECKER_OPEN=false
|
||||
WOODPECKER_ADMIN=john.smith,jane_doe
|
||||
```
|
||||
|
||||
### Only allow registration of users, who are members of approved organizations
|
||||
|
||||
```ini
|
||||
WOODPECKER_OPEN=true
|
||||
WOODPECKER_ORGS=dolores,dog-patch
|
||||
```
|
||||
|
||||
## Administrators
|
||||
|
||||
Administrators should also be enumerated in your configuration.
|
||||
|
||||
```ini
|
||||
WOODPECKER_ADMIN=john.smith,jane_doe
|
||||
```
|
||||
|
||||
## Filtering repositories
|
||||
|
||||
Woodpecker operates with the user's OAuth permission. Due to the coarse permission handling of GitHub, you may end up syncing more repos into Woodpecker than preferred.
|
||||
|
||||
Use the `WOODPECKER_REPO_OWNERS` variable to filter which GitHub user's repos should be synced only. You typically want to put here your company's GitHub name.
|
||||
|
||||
```ini
|
||||
WOODPECKER_REPO_OWNERS=my_company,my_company_oss_github_user
|
||||
```
|
||||
|
||||
## Disallow normal users to create agents
|
||||
|
||||
By default, users can create new agents for their repos they have admin access to.
|
||||
If an instance admin doesn't want this feature enabled, they can disable the API and hide the Web UI elements.
|
||||
|
||||
:::note
|
||||
You should set this option if you have, for example,
|
||||
global secrets and don't trust your users to create a rogue agent and pipeline for secret extraction.
|
||||
:::
|
||||
|
||||
```ini
|
||||
WOODPECKER_DISABLE_USER_AGENT_REGISTRATION=true
|
||||
```
|
||||
|
||||
## Global registry setting
|
||||
|
||||
If you want to make available a specific private registry to all pipelines, use the `WOODPECKER_DOCKER_CONFIG` server configuration.
|
||||
Point it to your server's docker config.
|
||||
|
||||
```ini
|
||||
WOODPECKER_DOCKER_CONFIG=/root/.docker/config.json
|
||||
```
|
||||
|
||||
## Handling sensitive data in **docker compose** and **docker swarm**
|
||||
|
||||
To handle sensitive data in `docker compose` or `docker swarm` configurations there are several options:
|
||||
|
||||
For docker compose you can use a `.env` file next to your compose configuration to store the secrets outside of the compose file. While this separates configuration from secrets it is still not very secure.
|
||||
|
||||
Alternatively use docker-secrets. As it may be difficult to use docker secrets for environment variables Woodpecker allows to read sensible data from files by providing a `*_FILE` option of all sensible configuration variables. Woodpecker will try to read the value directly from this file. Keep in mind that when the original environment variable gets specified at the same time it will override the value read from the file.
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
- [...]
|
||||
+ - WOODPECKER_AGENT_SECRET_FILE=/run/secrets/woodpecker-agent-secret
|
||||
+ secrets:
|
||||
+ - woodpecker-agent-secret
|
||||
+
|
||||
+ secrets:
|
||||
+ woodpecker-agent-secret:
|
||||
+ external: true
|
||||
```
|
||||
|
||||
Store a value to a docker secret like this:
|
||||
|
||||
```bash
|
||||
echo "my_agent_secret_key" | docker secret create woodpecker-agent-secret -
|
||||
```
|
||||
|
||||
or generate a random one like this:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32 | docker secret create woodpecker-agent-secret -
|
||||
```
|
||||
|
||||
## Custom JavaScript and CSS
|
||||
|
||||
Woodpecker supports custom JS and CSS files.
|
||||
These files must be present in the server's filesystem.
|
||||
They can be backed in a Docker image or mounted from a ConfigMap inside a Kubernetes environment.
|
||||
The configuration variables are independent of each other, which means it can be just one file present, or both.
|
||||
|
||||
```ini
|
||||
WOODPECKER_CUSTOM_CSS_FILE=/usr/local/www/woodpecker.css
|
||||
WOODPECKER_CUSTOM_JS_FILE=/usr/local/www/woodpecker.js
|
||||
```
|
||||
|
||||
The examples below show how to place a banner message in the top navigation bar of Woodpecker.
|
||||
|
||||
### `woodpecker.css`
|
||||
|
||||
```css
|
||||
.banner-message {
|
||||
position: absolute;
|
||||
width: 280px;
|
||||
height: 40px;
|
||||
margin-left: 240px;
|
||||
margin-top: 5px;
|
||||
padding-top: 5px;
|
||||
font-weight: bold;
|
||||
background: red no-repeat;
|
||||
text-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
### `woodpecker.js`
|
||||
|
||||
```javascript
|
||||
// place/copy a minified version of your preferred lightweight JavaScript library here ...
|
||||
!(function () {
|
||||
'use strict';
|
||||
function e() {} /*...*/
|
||||
})();
|
||||
|
||||
$().ready(function () {
|
||||
$('.app nav img').first().htmlAfter("<div class='banner-message'>This is a demo banner message :)</div>");
|
||||
});
|
||||
```
|
||||
|
||||
## All server configuration options
|
||||
|
||||
The following list describes all available server configuration options.
|
||||
|
||||
### `WOODPECKER_LOG_LEVEL`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures the logging level. Possible values are `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic`, `disabled` and empty.
|
||||
|
||||
### `WOODPECKER_LOG_FILE`
|
||||
|
||||
> Default: `stderr`
|
||||
|
||||
Output destination for logs.
|
||||
'stdout' and 'stderr' can be used as special keywords.
|
||||
|
||||
### `WOODPECKER_DATABASE_LOG`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable logging in database engine (currently xorm).
|
||||
|
||||
### `WOODPECKER_DATABASE_LOG_SQL`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable logging of sql commands.
|
||||
|
||||
### `WOODPECKER_DATABASE_MAX_CONNECTIONS`
|
||||
|
||||
> Default: `100`
|
||||
|
||||
Max database connections xorm is allowed create.
|
||||
|
||||
### `WOODPECKER_DATABASE_IDLE_CONNECTIONS`
|
||||
|
||||
> Default: `2`
|
||||
|
||||
Amount of database connections xorm will hold open.
|
||||
|
||||
### `WOODPECKER_DATABASE_CONNECTION_TIMEOUT`
|
||||
|
||||
> Default: `3 Seconds`
|
||||
|
||||
Time an active database connection is allowed to stay open.
|
||||
|
||||
### `WOODPECKER_DEBUG_PRETTY`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable pretty-printed debug output.
|
||||
|
||||
### `WOODPECKER_DEBUG_NOCOLOR`
|
||||
|
||||
> Default: `true`
|
||||
|
||||
Disable colored debug output.
|
||||
|
||||
### `WOODPECKER_HOST`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Server fully qualified URL of the user-facing hostname, port (if not default for HTTP/HTTPS) and path prefix.
|
||||
|
||||
Examples:
|
||||
|
||||
- `WOODPECKER_HOST=http://woodpecker.example.org`
|
||||
- `WOODPECKER_HOST=http://example.org/woodpecker`
|
||||
- `WOODPECKER_HOST=http://example.org:1234/woodpecker`
|
||||
|
||||
### `WOODPECKER_SERVER_ADDR`
|
||||
|
||||
> Default: `:8000`
|
||||
|
||||
Configures the HTTP listener port.
|
||||
|
||||
### `WOODPECKER_SERVER_ADDR_TLS`
|
||||
|
||||
> Default: `:443`
|
||||
|
||||
Configures the HTTPS listener port when SSL is enabled.
|
||||
|
||||
### `WOODPECKER_SERVER_CERT`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Path to an SSL certificate used by the server to accept HTTPS requests.
|
||||
|
||||
Example: `WOODPECKER_SERVER_CERT=/path/to/cert.pem`
|
||||
|
||||
### `WOODPECKER_SERVER_KEY`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Path to an SSL certificate key used by the server to accept HTTPS requests.
|
||||
|
||||
Example: `WOODPECKER_SERVER_KEY=/path/to/key.pem`
|
||||
|
||||
### `WOODPECKER_CUSTOM_CSS_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
File path for the server to serve a custom .CSS file, used for customizing the UI.
|
||||
Can be used for showing banner messages, logos, or environment-specific hints (a.k.a. white-labeling).
|
||||
The file must be UTF-8 encoded, to ensure all special characters are preserved.
|
||||
|
||||
Example: `WOODPECKER_CUSTOM_CSS_FILE=/usr/local/www/woodpecker.css`
|
||||
|
||||
### `WOODPECKER_CUSTOM_JS_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
File path for the server to serve a custom .JS file, used for customizing the UI.
|
||||
Can be used for showing banner messages, logos, or environment-specific hints (a.k.a. white-labeling).
|
||||
The file must be UTF-8 encoded, to ensure all special characters are preserved.
|
||||
|
||||
Example: `WOODPECKER_CUSTOM_JS_FILE=/usr/local/www/woodpecker.js`
|
||||
|
||||
### `WOODPECKER_GRPC_ADDR`
|
||||
|
||||
> Default: `:9000`
|
||||
|
||||
Configures the gRPC listener port.
|
||||
|
||||
### `WOODPECKER_GRPC_SECRET`
|
||||
|
||||
> Default: `secret`
|
||||
|
||||
Configures the gRPC JWT secret.
|
||||
|
||||
### `WOODPECKER_GRPC_SECRET_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_GRPC_SECRET` from the specified filepath.
|
||||
|
||||
### `WOODPECKER_METRICS_SERVER_ADDR`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures an unprotected metrics endpoint. An empty value disables the metrics endpoint completely.
|
||||
|
||||
Example: `:9001`
|
||||
|
||||
### `WOODPECKER_ADMIN`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of admin accounts.
|
||||
|
||||
Example: `WOODPECKER_ADMIN=user1,user2`
|
||||
|
||||
### `WOODPECKER_ORGS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of approved organizations.
|
||||
|
||||
Example: `org1,org2`
|
||||
|
||||
### `WOODPECKER_REPO_OWNERS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Repositories by those owners will be allowed to be used in woodpecker.
|
||||
|
||||
Example: `user1,user2`
|
||||
|
||||
### `WOODPECKER_OPEN`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable to allow user registration.
|
||||
|
||||
### `WOODPECKER_AUTHENTICATE_PUBLIC_REPOS`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Always use authentication to clone repositories even if they are public. Needed if the forge requires to always authenticate as used by many companies.
|
||||
|
||||
### `WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS`
|
||||
|
||||
> Default: `pull_request, push`
|
||||
|
||||
List of event names that will be canceled when a new pipeline for the same context (tag, branch) is created.
|
||||
|
||||
### `WOODPECKER_DEFAULT_CLONE_PLUGIN`
|
||||
|
||||
> Default is defined in [shared/constant/constant.go](https://github.com/woodpecker-ci/woodpecker/blob/main/shared/constant/constant.go)
|
||||
|
||||
The default docker image to be used when cloning the repo.
|
||||
|
||||
It is also added to the trusted clone plugin list.
|
||||
|
||||
### `WOODPECKER_DEFAULT_WORKFLOW_LABELS`
|
||||
|
||||
> By default run workflows on any agent if no label conditions are set in workflow definition.
|
||||
|
||||
You can specify default label/platform conditions that will be used for agent selection for workflows that does not have labels conditions set.
|
||||
|
||||
Example: `platform=linux/amd64,backend=docker`
|
||||
|
||||
### `WOODPECKER_DEFAULT_PIPELINE_TIMEOUT`
|
||||
|
||||
> 60 (minutes)
|
||||
|
||||
The default time for a repo in minutes before a pipeline gets killed
|
||||
|
||||
### `WOODPECKER_MAX_PIPELINE_TIMEOUT`
|
||||
|
||||
> 120 (minutes)
|
||||
|
||||
The maximum time in minutes you can set in the repo settings before a pipeline gets killed
|
||||
|
||||
### `WOODPECKER_SESSION_EXPIRES`
|
||||
|
||||
> Default: `72h`
|
||||
|
||||
Configures the session expiration time.
|
||||
Context: when someone does log into Woodpecker, a temporary session token is created.
|
||||
As long as the session is valid (until it expires or log-out),
|
||||
a user can log into Woodpecker, without re-authentication.
|
||||
|
||||
### `WOODPECKER_PLUGINS_PRIVILEGED`
|
||||
|
||||
Docker images to run in privileged mode. Only change if you are sure what you do!
|
||||
|
||||
You should specify the tag of your images too, as this enforces exact matches.
|
||||
|
||||
### WOODPECKER_PLUGINS_TRUSTED_CLONE
|
||||
|
||||
> Defaults are defined in [shared/constant/constant.go](https://github.com/woodpecker-ci/woodpecker/blob/main/shared/constant/constant.go)
|
||||
|
||||
Plugins which are trusted to handle the Git credential info in clone steps.
|
||||
If a clone step use an image not in this list, Git credentials will not be injected and users have to use other methods (e.g. secrets) to clone non-public repos.
|
||||
|
||||
You should specify the tag of your images too, as this enforces exact matches.
|
||||
|
||||
<!--
|
||||
### `WOODPECKER_VOLUME`
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of Docker volumes that are mounted into every pipeline step.
|
||||
|
||||
Example: `WOODPECKER_VOLUME=/path/on/host:/path/in/container:rw`|
|
||||
-->
|
||||
|
||||
### `WOODPECKER_DOCKER_CONFIG`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures a specific private registry config for all pipelines.
|
||||
|
||||
Example: `WOODPECKER_DOCKER_CONFIG=/home/user/.docker/config.json`
|
||||
|
||||
<!--
|
||||
### `WOODPECKER_ENVIRONMENT`
|
||||
> Default: empty
|
||||
|
||||
TODO
|
||||
|
||||
### `WOODPECKER_NETWORK`
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list of Docker networks that are attached to every pipeline step.
|
||||
|
||||
Example: `WOODPECKER_NETWORK=network1,network2`
|
||||
-->
|
||||
|
||||
### `WOODPECKER_AGENT_SECRET`
|
||||
|
||||
> Default: empty
|
||||
|
||||
A shared secret used by server and agents to authenticate communication. A secret can be generated by `openssl rand -hex 32`.
|
||||
|
||||
### `WOODPECKER_AGENT_SECRET_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_AGENT_SECRET` from the specified filepath
|
||||
|
||||
### `WOODPECKER_DISABLE_USER_AGENT_REGISTRATION`
|
||||
|
||||
> Default: false
|
||||
|
||||
[Read about "Disallow normal users to create agents"](./10-server-config.md#disallow-normal-users-to-create-agents)
|
||||
|
||||
### `WOODPECKER_KEEPALIVE_MIN_TIME`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Server-side enforcement policy on the minimum amount of time a client should wait before sending a keepalive ping.
|
||||
|
||||
Example: `WOODPECKER_KEEPALIVE_MIN_TIME=10s`
|
||||
|
||||
### `WOODPECKER_DATABASE_DRIVER`
|
||||
|
||||
> Default: `sqlite3`
|
||||
|
||||
The database driver name. Possible values are `sqlite3`, `mysql` or `postgres`.
|
||||
|
||||
### `WOODPECKER_DATABASE_DATASOURCE`
|
||||
|
||||
> Default: `woodpecker.sqlite` if not running inside a container, `/var/lib/woodpecker/woodpecker.sqlite` if running inside a container
|
||||
|
||||
The database connection string. The default value is the path of the embedded SQLite database file.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
# MySQL
|
||||
# https://github.com/go-sql-driver/mysql#dsn-data-source-name
|
||||
WOODPECKER_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/woodpecker?parseTime=true
|
||||
|
||||
# PostgreSQL
|
||||
# https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
WOODPECKER_DATABASE_DATASOURCE=postgres://root:password@1.2.3.4:5432/woodpecker?sslmode=disable
|
||||
```
|
||||
|
||||
### `WOODPECKER_DATABASE_DATASOURCE_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_DATABASE_DATASOURCE` from the specified filepath
|
||||
|
||||
### `WOODPECKER_PROMETHEUS_AUTH_TOKEN`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Token to secure the Prometheus metrics endpoint.
|
||||
Must be set to enable the endpoint.
|
||||
|
||||
### `WOODPECKER_PROMETHEUS_AUTH_TOKEN_FILE`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Read the value for `WOODPECKER_PROMETHEUS_AUTH_TOKEN` from the specified filepath
|
||||
|
||||
### `WOODPECKER_STATUS_CONTEXT`
|
||||
|
||||
> Default: `ci/woodpecker`
|
||||
|
||||
Context prefix Woodpecker will use to publish status messages to SCM. You probably will only need to change it if you run multiple Woodpecker instances for a single repository.
|
||||
|
||||
### `WOODPECKER_STATUS_CONTEXT_FORMAT`
|
||||
|
||||
> Default: `{{ .context }}/{{ .event }}/{{ .workflow }}{{if not (eq .axis_id 0)}}/{{.axis_id}}{{end}}`
|
||||
|
||||
Template for the status messages published to forges, uses [Go templates](https://pkg.go.dev/text/template) as template language.
|
||||
Supported variables:
|
||||
|
||||
- `context`: Woodpecker's context (see `WOODPECKER_STATUS_CONTEXT`)
|
||||
- `event`: the event which started the pipeline
|
||||
- `workflow`: the workflow's name
|
||||
- `owner`: the repo's owner
|
||||
- `repo`: the repo's name
|
||||
|
||||
---
|
||||
|
||||
### `WOODPECKER_CONFIG_SERVICE_ENDPOINT`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Specify a configuration service endpoint, see [Configuration Extension](./40-advanced/100-external-configuration-api.md)
|
||||
|
||||
### `WOODPECKER_FORGE_TIMEOUT`
|
||||
|
||||
> Default: 5s
|
||||
|
||||
Specify timeout when fetching the Woodpecker configuration from forge. See <https://pkg.go.dev/time#ParseDuration> for syntax reference.
|
||||
|
||||
### `WOODPECKER_FORGE_RETRY`
|
||||
|
||||
> Default: 3
|
||||
|
||||
Specify how many retries of fetching the Woodpecker configuration from a forge are done before we fail.
|
||||
|
||||
### `WOODPECKER_ENABLE_SWAGGER`
|
||||
|
||||
> Default: true
|
||||
|
||||
Enable the Swagger UI for API documentation.
|
||||
|
||||
### `WOODPECKER_DISABLE_VERSION_CHECK`
|
||||
|
||||
> Default: false
|
||||
|
||||
Disable version check in admin web UI.
|
||||
|
||||
### `WOODPECKER_LOG_STORE`
|
||||
|
||||
> Default: `database`
|
||||
|
||||
Where to store logs. Possible values: `database` or `file`.
|
||||
|
||||
### `WOODPECKER_LOG_STORE_FILE_PATH`
|
||||
|
||||
> Default empty
|
||||
|
||||
Directory to store logs in if [`WOODPECKER_LOG_STORE`](#woodpecker_log_store) is `file`.
|
||||
|
||||
---
|
||||
|
||||
### `WOODPECKER_GITHUB_...`
|
||||
|
||||
See [GitHub configuration](./11-forges/20-github.md#configuration)
|
||||
|
||||
### `WOODPECKER_GITEA_...`
|
||||
|
||||
See [Gitea configuration](./11-forges/30-gitea.md#configuration)
|
||||
|
||||
### `WOODPECKER_BITBUCKET_...`
|
||||
|
||||
See [Bitbucket configuration](./11-forges/50-bitbucket.md#configuration)
|
||||
|
||||
### `WOODPECKER_GITLAB_...`
|
||||
|
||||
See [GitLab configuration](./11-forges/40-gitlab.md#configuration)
|
||||
|
||||
### `WOODPECKER_ADDON_FORGE`
|
||||
|
||||
See [addon forges](./11-forges/100-addon.md).
|
@ -1,15 +0,0 @@
|
||||
# Forges
|
||||
|
||||
## Supported features
|
||||
|
||||
| Feature | [GitHub](20-github.md) | [Gitea](30-gitea.md) | [Forgejo](35-forgejo.md) | [Gitlab](40-gitlab.md) | [Bitbucket](50-bitbucket.md) | [Bitbucket Datacenter](60-bitbucket_datacenter.md) |
|
||||
| ------------------------------------------------------------- | :--------------------: | :------------------: | :----------------------: | :--------------------: | :--------------------------: | :------------------------------------------------: |
|
||||
| Event: Push | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Tag | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Pull-Request | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Release | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: |
|
||||
| Event: Deploy¹ | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
| [Multiple workflows](../../20-usage/25-workflows.md) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| [when.path filter](../../20-usage/20-workflow-syntax.md#path) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: |
|
||||
|
||||
¹ The deployment event can be triggered for all forges from Woodpecker directly. However, only GitHub can trigger them using webhooks.
|
@ -1,23 +0,0 @@
|
||||
# Custom backends
|
||||
|
||||
If none of our backends fits your usecase, you can write your own.
|
||||
|
||||
Therefore, implement the interface `"go.woodpecker-ci.org/woodpecker/woodpecker/v3/pipeline/backend/types".Backend` and
|
||||
build a custom agent using your backend with this `main.go`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cmd/agent/core"
|
||||
backendTypes "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
core.RunAgent([]backendTypes.Backend{
|
||||
yourBackend,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
It is also possible to use multiple backends, you can select with [`WOODPECKER_BACKEND`](../15-agent-config.md#woodpecker_backend) between them.
|
@ -1,201 +0,0 @@
|
||||
# Proxy
|
||||
|
||||
## Apache
|
||||
|
||||
This guide provides a brief overview for installing Woodpecker server behind the Apache2 web-server. This is an example configuration:
|
||||
|
||||
<!-- cspell:ignore apacheconf -->
|
||||
|
||||
```apacheconf
|
||||
ProxyPreserveHost On
|
||||
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
```
|
||||
|
||||
You must have these Apache modules installed:
|
||||
|
||||
- `proxy`
|
||||
- `proxy_http`
|
||||
|
||||
You must configure Apache to set `X-Forwarded-Proto` when using https.
|
||||
|
||||
```diff
|
||||
ProxyPreserveHost On
|
||||
|
||||
+RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
```
|
||||
|
||||
## Nginx
|
||||
|
||||
This guide provides a basic overview for installing Woodpecker server behind the Nginx web-server. For more advanced configuration options please consult the official Nginx [documentation](https://docs.nginx.com/nginx/admin-guide).
|
||||
|
||||
Example configuration:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name woodpecker.example.com;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
|
||||
chunked_transfer_encoding off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You must configure the proxy to set `X-Forwarded` proxy headers:
|
||||
|
||||
```diff
|
||||
server {
|
||||
listen 80;
|
||||
server_name woodpecker.example.com;
|
||||
|
||||
location / {
|
||||
+ proxy_set_header X-Forwarded-For $remote_addr;
|
||||
+ proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
|
||||
chunked_transfer_encoding off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Caddy
|
||||
|
||||
This guide provides a brief overview for installing Woodpecker server behind the [Caddy web-server](https://caddyserver.com/). This is an example caddyfile proxy configuration:
|
||||
|
||||
```caddy
|
||||
# expose WebUI and API
|
||||
woodpecker.example.com {
|
||||
reverse_proxy woodpecker-server:8000
|
||||
}
|
||||
|
||||
# expose gRPC
|
||||
woodpecker-agent.example.com {
|
||||
reverse_proxy h2c://woodpecker-server:9000
|
||||
}
|
||||
```
|
||||
|
||||
:::note
|
||||
Above configuration shows how to create reverse-proxies for web and agent communication. If your agent uses SSL do not forget to enable [`WOODPECKER_GRPC_SECURE`](../15-agent-config.md#woodpecker_grpc_secure).
|
||||
:::
|
||||
|
||||
## Tunnelmole
|
||||
|
||||
[Tunnelmole](https://github.com/robbie-cahill/tunnelmole-client) is an open source tunneling tool.
|
||||
|
||||
Start by [installing tunnelmole](https://github.com/robbie-cahill/tunnelmole-client#installation).
|
||||
|
||||
After the installation, run the following command to start tunnelmole:
|
||||
|
||||
```bash
|
||||
tmole 8000
|
||||
```
|
||||
|
||||
It will start a tunnel and will give a response like this:
|
||||
|
||||
```bash
|
||||
➜ ~ tmole 8000
|
||||
http://bvdo5f-ip-49-183-170-144.tunnelmole.net is forwarding to localhost:8000
|
||||
https://bvdo5f-ip-49-183-170-144.tunnelmole.net is forwarding to localhost:8000
|
||||
```
|
||||
|
||||
Set `WOODPECKER_HOST` to the Tunnelmole URL (`xxx.tunnelmole.net`) and start the server.
|
||||
|
||||
## Ngrok
|
||||
|
||||
[Ngrok](https://ngrok.com/) is a popular closed source tunnelling tool. After installing ngrok, open a new console and run the following command:
|
||||
|
||||
```bash
|
||||
ngrok http 8000
|
||||
```
|
||||
|
||||
Set `WOODPECKER_HOST` to the ngrok URL (usually xxx.ngrok.io) and start the server.
|
||||
|
||||
## Traefik
|
||||
|
||||
To install the Woodpecker server behind a [Traefik](https://traefik.io/) load balancer, you must expose both the `http` and the `gRPC` ports. Here is a comprehensive example, considering you are running Traefik with docker swarm and want to do TLS termination and automatic redirection from http to https.
|
||||
|
||||
<!-- cspell:words redirectscheme certresolver -->
|
||||
|
||||
```yaml
|
||||
services:
|
||||
server:
|
||||
image: woodpeckerci/woodpecker-server:latest
|
||||
environment:
|
||||
- WOODPECKER_OPEN=true
|
||||
- WOODPECKER_ADMIN=your_admin_user
|
||||
# other settings ...
|
||||
|
||||
networks:
|
||||
- dmz # externally defined network, so that traefik can connect to the server
|
||||
volumes:
|
||||
- woodpecker-server-data:/var/lib/woodpecker/
|
||||
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
|
||||
# web server
|
||||
- traefik.http.services.woodpecker-service.loadbalancer.server.port=8000
|
||||
|
||||
- traefik.http.routers.woodpecker-secure.rule=Host(`cd.your-domain.com`)
|
||||
- traefik.http.routers.woodpecker-secure.tls=true
|
||||
- traefik.http.routers.woodpecker-secure.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.woodpecker-secure.entrypoints=web-secure
|
||||
- traefik.http.routers.woodpecker-secure.service=woodpecker-service
|
||||
|
||||
- traefik.http.routers.woodpecker.rule=Host(`cd.your-domain.com`)
|
||||
- traefik.http.routers.woodpecker.entrypoints=web
|
||||
- traefik.http.routers.woodpecker.service=woodpecker-service
|
||||
|
||||
- traefik.http.middlewares.woodpecker-redirect.redirectscheme.scheme=https
|
||||
- traefik.http.middlewares.woodpecker-redirect.redirectscheme.permanent=true
|
||||
- traefik.http.routers.woodpecker.middlewares=woodpecker-redirect@docker
|
||||
|
||||
# gRPC service
|
||||
- traefik.http.services.woodpecker-grpc.loadbalancer.server.port=9000
|
||||
- traefik.http.services.woodpecker-grpc.loadbalancer.server.scheme=h2c
|
||||
|
||||
- traefik.http.routers.woodpecker-grpc-secure.rule=Host(`woodpecker-grpc.your-domain.com`)
|
||||
- traefik.http.routers.woodpecker-grpc-secure.tls=true
|
||||
- traefik.http.routers.woodpecker-grpc-secure.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.woodpecker-grpc-secure.entrypoints=web-secure
|
||||
- traefik.http.routers.woodpecker-grpc-secure.service=woodpecker-grpc
|
||||
|
||||
- traefik.http.routers.woodpecker-grpc.rule=Host(`woodpecker-grpc.your-domain.com`)
|
||||
- traefik.http.routers.woodpecker-grpc.entrypoints=web
|
||||
- traefik.http.routers.woodpecker-grpc.service=woodpecker-grpc
|
||||
|
||||
- traefik.http.middlewares.woodpecker-grpc-redirect.redirectscheme.scheme=https
|
||||
- traefik.http.middlewares.woodpecker-grpc-redirect.redirectscheme.permanent=true
|
||||
- traefik.http.routers.woodpecker-grpc.middlewares=woodpecker-grpc-redirect@docker
|
||||
|
||||
volumes:
|
||||
woodpecker-server-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
dmz:
|
||||
external: true
|
||||
```
|
||||
|
||||
You should pass `WOODPECKER_GRPC_SECURE=true` and `WOODPECKER_GRPC_VERIFY=true` to your agent when using this configuration.
|
@ -1,103 +0,0 @@
|
||||
# External Configuration API
|
||||
|
||||
To provide additional management and preprocessing capabilities for pipeline configurations Woodpecker supports an HTTP API which can be enabled to call an external config service.
|
||||
Before the run or restart of any pipeline Woodpecker will make a POST request to an external HTTP API sending the current repository, build information and all current config files retrieved from the repository. The external API can then send back new pipeline configurations that will be used immediately or respond with `HTTP 204` to tell the system to use the existing configuration.
|
||||
|
||||
Every request sent by Woodpecker is signed using a [http-signature](https://datatracker.ietf.org/doc/html/rfc9421) by a private key (ed25519) generated on the first start of the Woodpecker server. You can get the public key for the verification of the http-signature from `http(s)://your-woodpecker-server/api/signature/public-key`.
|
||||
|
||||
A simplistic example configuration service can be found here: [https://github.com/woodpecker-ci/example-config-service](https://github.com/woodpecker-ci/example-config-service)
|
||||
|
||||
:::warning
|
||||
You need to trust the external config service as it is getting secret information about the repository and pipeline and has the ability to change pipeline configs that could run malicious tasks.
|
||||
:::
|
||||
|
||||
## Config
|
||||
|
||||
```ini title="Server"
|
||||
WOODPECKER_CONFIG_SERVICE_ENDPOINT=https://example.com/ciconfig
|
||||
```
|
||||
|
||||
### Example request made by Woodpecker
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": {
|
||||
"id": 100,
|
||||
"uid": "",
|
||||
"user_id": 0,
|
||||
"namespace": "",
|
||||
"name": "woodpecker-test-pipe",
|
||||
"slug": "",
|
||||
"scm": "git",
|
||||
"git_http_url": "",
|
||||
"git_ssh_url": "",
|
||||
"link": "",
|
||||
"default_branch": "",
|
||||
"private": true,
|
||||
"visibility": "private",
|
||||
"active": true,
|
||||
"config": "",
|
||||
"trusted": false,
|
||||
"protected": false,
|
||||
"ignore_forks": false,
|
||||
"ignore_pulls": false,
|
||||
"cancel_pulls": false,
|
||||
"timeout": 60,
|
||||
"counter": 0,
|
||||
"synced": 0,
|
||||
"created": 0,
|
||||
"updated": 0,
|
||||
"version": 0
|
||||
},
|
||||
"pipeline": {
|
||||
"author": "myUser",
|
||||
"author_avatar": "https://myforge.com/avatars/d6b3f7787a685fcdf2a44e2c685c7e03",
|
||||
"author_email": "my@email.com",
|
||||
"branch": "main",
|
||||
"changed_files": ["some-file-name.txt"],
|
||||
"commit": "2fff90f8d288a4640e90f05049fe30e61a14fd50",
|
||||
"created_at": 0,
|
||||
"deploy_to": "",
|
||||
"enqueued_at": 0,
|
||||
"error": "",
|
||||
"event": "push",
|
||||
"finished_at": 0,
|
||||
"id": 0,
|
||||
"link_url": "https://myforge.com/myUser/woodpecker-testpipe/commit/2fff90f8d288a4640e90f05049fe30e61a14fd50",
|
||||
"message": "test old config\n",
|
||||
"number": 0,
|
||||
"parent": 0,
|
||||
"ref": "refs/heads/main",
|
||||
"refspec": "",
|
||||
"clone_url": "",
|
||||
"reviewed_at": 0,
|
||||
"reviewed_by": "",
|
||||
"sender": "myUser",
|
||||
"signed": false,
|
||||
"started_at": 0,
|
||||
"status": "",
|
||||
"timestamp": 1645962783,
|
||||
"title": "",
|
||||
"updated_at": 0,
|
||||
"verified": false
|
||||
},
|
||||
"netrc": {
|
||||
"machine": "https://example.com",
|
||||
"login": "user",
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example response structure
|
||||
|
||||
```json
|
||||
{
|
||||
"configs": [
|
||||
{
|
||||
"name": "central-override",
|
||||
"data": "steps:\n - name: backend\n image: alpine\n commands:\n - echo \"Hello there from ConfigAPI\"\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
@ -1,54 +0,0 @@
|
||||
# SSL
|
||||
|
||||
Woodpecker supports SSL configuration by mounting certificates into your container.
|
||||
|
||||
```ini
|
||||
WOODPECKER_SERVER_CERT=/etc/certs/woodpecker.example.com/server.crt
|
||||
WOODPECKER_SERVER_KEY=/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
||||
|
||||
## Certificate Chain
|
||||
|
||||
The most common problem encountered is providing a certificate file without the intermediate chain.
|
||||
|
||||
> LoadX509KeyPair reads and parses a public/private key pair from a pair of files. The files must contain PEM encoded data. The certificate file may contain intermediate certificates following the leaf certificate to form a certificate chain.
|
||||
|
||||
## Certificate Errors
|
||||
|
||||
SSL support is provided using the [ListenAndServeTLS](https://golang.org/pkg/net/http/#ListenAndServeTLS) function from the Go standard library. If you receive certificate errors or warnings please examine your configuration more closely.
|
||||
|
||||
## Running in containers
|
||||
|
||||
Update your configuration to expose the following ports:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
ports:
|
||||
+ - 80:80
|
||||
+ - 443:443
|
||||
- 9000:9000
|
||||
```
|
||||
|
||||
Update your configuration to mount your certificate and key:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
volumes:
|
||||
+ - /etc/certs/woodpecker.example.com/server.crt:/etc/certs/woodpecker.example.com/server.crt
|
||||
+ - /etc/certs/woodpecker.example.com/server.key:/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
||||
|
||||
Update your configuration to provide the paths of your certificate and key:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
environment:
|
||||
+ - WOODPECKER_SERVER_CERT=/etc/certs/woodpecker.example.com/server.crt
|
||||
+ - WOODPECKER_SERVER_KEY=/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
@ -1,25 +0,0 @@
|
||||
# Advanced options
|
||||
|
||||
Why should we be happy with a default setup? We should not! Woodpecker offers a lot of advanced options to configure it to your needs.
|
||||
|
||||
## Behind a proxy
|
||||
|
||||
See the [proxy guide](./10-proxy.md) if you want to see a setup behind Apache, Nginx, Caddy or ngrok.
|
||||
|
||||
In the case you need to use Woodpecker with a URL path prefix (like: <https://example.org/woodpecker/>), add the root path to [`WOODPECKER_HOST`](../10-server-config.md#woodpecker_host).
|
||||
|
||||
## SSL
|
||||
|
||||
Woodpecker supports SSL configuration by using Let's encrypt or by using own certificates. See the [SSL guide](./20-ssl.md).
|
||||
|
||||
## Metrics
|
||||
|
||||
A [Prometheus endpoint](./90-prometheus.md) is exposed by Woodpecker to collect metrics.
|
||||
|
||||
## Autoscaling
|
||||
|
||||
The [autoscaler](./30-autoscaler.md) can be used to deploy new agents to a cloud provider based on the current workload your server is experiencing.
|
||||
|
||||
## Configuration service
|
||||
|
||||
Sometime the normal yaml configuration compiler isn't enough. You can use the [configuration service](./100-external-configuration-api.md) to process your configuration files by your own.
|
@ -1,81 +0,0 @@
|
||||
# Prometheus
|
||||
|
||||
Woodpecker is compatible with Prometheus and exposes a `/metrics` endpoint if the environment variable `WOODPECKER_PROMETHEUS_AUTH_TOKEN` is set. Please note that access to the metrics endpoint is restricted and requires the authorization token from the environment variable mentioned above.
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
bearer_token: dummyToken...
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
## Authorization
|
||||
|
||||
An administrator will need to generate a user API token and configure in the Prometheus configuration file as a bearer token. Please see the following example:
|
||||
|
||||
```diff
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
+ bearer_token: dummyToken...
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
As an alternative, the token can also be read from a file:
|
||||
|
||||
```diff
|
||||
global:
|
||||
scrape_interval: 60s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'woodpecker'
|
||||
+ bearer_token_file: /etc/secrets/woodpecker-monitoring-token
|
||||
|
||||
static_configs:
|
||||
- targets: ['woodpecker.domain.com']
|
||||
```
|
||||
|
||||
## Metric Reference
|
||||
|
||||
List of Prometheus metrics specific to Woodpecker:
|
||||
|
||||
```yaml
|
||||
# HELP woodpecker_pipeline_count Pipeline count.
|
||||
# TYPE woodpecker_pipeline_count counter
|
||||
woodpecker_pipeline_count{branch="main",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3
|
||||
woodpecker_pipeline_count{branch="dev",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 3
|
||||
# HELP woodpecker_pipeline_time Build time.
|
||||
# TYPE woodpecker_pipeline_time gauge
|
||||
woodpecker_pipeline_time{branch="main",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 116
|
||||
woodpecker_pipeline_time{branch="dev",pipeline="total",repo="woodpecker-ci/woodpecker",status="success"} 155
|
||||
# HELP woodpecker_pipeline_total_count Total number of builds.
|
||||
# TYPE woodpecker_pipeline_total_count gauge
|
||||
woodpecker_pipeline_total_count 1025
|
||||
# HELP woodpecker_pending_steps Total number of pending pipeline steps.
|
||||
# TYPE woodpecker_pending_steps gauge
|
||||
woodpecker_pending_steps 0
|
||||
# HELP woodpecker_repo_count Total number of repos.
|
||||
# TYPE woodpecker_repo_count gauge
|
||||
woodpecker_repo_count 9
|
||||
# HELP woodpecker_running_steps Total number of running pipeline steps.
|
||||
# TYPE woodpecker_running_steps gauge
|
||||
woodpecker_running_steps 0
|
||||
# HELP woodpecker_user_count Total number of users.
|
||||
# TYPE woodpecker_user_count gauge
|
||||
woodpecker_user_count 1
|
||||
# HELP woodpecker_waiting_steps Total number of pipeline waiting on deps.
|
||||
# TYPE woodpecker_waiting_steps gauge
|
||||
woodpecker_waiting_steps 0
|
||||
# HELP woodpecker_worker_count Total number of workers.
|
||||
# TYPE woodpecker_worker_count gauge
|
||||
woodpecker_worker_count 4
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
label: 'Advanced'
|
||||
collapsible: true
|
||||
collapsed: true
|
||||
link:
|
||||
type: 'doc'
|
||||
id: 'advanced'
|
@ -81,7 +81,7 @@ WOODPECKER_HEALTHCHECK=false
|
||||
|
||||
### Setup OAuth
|
||||
|
||||
Create an OAuth app for your forge as described in the [forges documentation](../30-administration/11-forges/11-overview.md).
|
||||
Create an OAuth app for your forge as described in the [forges documentation](../30-administration/10-configuration/12-forges/11-overview.md).
|
||||
|
||||
## Developing with VS Code
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
## Addons and extensions
|
||||
|
||||
If you are wondering whether your contribution will be accepted to be merged in the Woodpecker core, or whether it's better to write an
|
||||
[addon forge](../30-administration/11-forges/100-addon.md), [extension](../30-administration/40-advanced/100-external-configuration-api.md) or an
|
||||
[external custom backend](../30-administration/22-backends/50-custom-backends.md), please check these points:
|
||||
[addon forge](../30-administration/10-configuration/12-forges/100-addon.md), [extension](../30-administration/10-configuration/10-server.md#external-configuration-api) or an
|
||||
[external custom backend](../30-administration/10-configuration/11-backends/50-custom.md), please check these points:
|
||||
|
||||
- Is your change very specific to your setup and unlikely to be used by anyone else?
|
||||
- Does your change violate the [guidelines](#guidelines)?
|
||||
|
@ -69,7 +69,7 @@ const config = {
|
||||
},
|
||||
{ to: 'blog', label: 'Blog', position: 'left' },
|
||||
{
|
||||
label: 'More Resources',
|
||||
label: 'More',
|
||||
position: 'left',
|
||||
items: [
|
||||
{
|
||||
@ -102,17 +102,18 @@ const config = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Sponsor Us',
|
||||
position: 'right',
|
||||
className: 'header-sponsor-link',
|
||||
href: 'https://opencollective.com/woodpecker-ci',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/woodpecker-ci/woodpecker',
|
||||
position: 'right',
|
||||
className: 'header-github-link',
|
||||
'aria-label': 'GitHub repository',
|
||||
},
|
||||
{
|
||||
label: '🧡 Sponsor Us',
|
||||
position: 'right',
|
||||
href: 'https://opencollective.com/woodpecker-ci',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
@ -122,7 +123,7 @@ const config = {
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Introduction',
|
||||
label: 'Welcome to Woodpecker',
|
||||
to: '/docs/intro',
|
||||
},
|
||||
{
|
||||
@ -130,9 +131,27 @@ const config = {
|
||||
to: '/docs/usage/intro',
|
||||
},
|
||||
{
|
||||
label: 'Server setup',
|
||||
label: 'Administration',
|
||||
to: '/docs/administration/getting-started',
|
||||
},
|
||||
{
|
||||
to: '/migrations', // Always point to newest migration guide
|
||||
activeBaseRegex: 'migrations',
|
||||
label: 'Migrations',
|
||||
},
|
||||
{
|
||||
to: '/awesome', // Always point to newest awesome list
|
||||
activeBaseRegex: 'awesome',
|
||||
label: 'Awesome',
|
||||
},
|
||||
{
|
||||
to: '/api',
|
||||
label: 'API',
|
||||
},
|
||||
{
|
||||
to: '/about',
|
||||
label: 'About',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -146,6 +165,10 @@ const config = {
|
||||
label: 'Mastodon',
|
||||
href: 'https://floss.social/@WoodpeckerCI',
|
||||
},
|
||||
{
|
||||
label: 'Bluesky',
|
||||
href: 'https://bsky.app/profile/woodpecker-ci.org',
|
||||
},
|
||||
{
|
||||
label: 'X',
|
||||
href: 'https://twitter.com/woodpeckerci',
|
||||
|