Merge branch 'main' into pr/4861
@@ -208,6 +208,7 @@
|
||||
"unsanitize",
|
||||
"Upsert",
|
||||
"urfave",
|
||||
"useragent",
|
||||
"usecase",
|
||||
"varchar",
|
||||
"varz",
|
||||
|
||||
@@ -10,7 +10,7 @@ tasks:
|
||||
WOODPECKER_BACKEND_DOCKER_NETWORK: ci_default
|
||||
init: |
|
||||
# renovate: datasource=golang-version depName=golang
|
||||
GO_VERSION=1.25.3
|
||||
GO_VERSION=1.25.5
|
||||
rm -rf ~/go
|
||||
curl -fsSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz | tar xzs -C ~/
|
||||
go mod tidy
|
||||
|
||||
@@ -12,11 +12,11 @@ repos:
|
||||
- id: trailing-whitespace
|
||||
exclude: ^docs/versioned_docs/.+/40-cli.md$
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v2.6.0
|
||||
rev: v2.7.2
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.45.0
|
||||
rev: v0.47.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
exclude: '^(docs/versioned_docs/.*|CHANGELOG.md)$'
|
||||
@@ -31,7 +31,7 @@ repos:
|
||||
hooks:
|
||||
- id: hadolint
|
||||
- repo: https://github.com/rbubley/mirrors-prettier
|
||||
rev: v3.6.2
|
||||
rev: v3.7.4
|
||||
hooks:
|
||||
- id: prettier
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.25'
|
||||
- &node_image 'docker.io/node:24-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.22'
|
||||
- &alpine_image 'docker.io/alpine:3.23'
|
||||
- path: &when_path
|
||||
- 'docs/**'
|
||||
- '.woodpecker/docs.yaml'
|
||||
@@ -37,7 +37,7 @@ when:
|
||||
evaluate: 'TASK == "docs"'
|
||||
|
||||
steps:
|
||||
install-dependencies:
|
||||
- name: install-dependencies
|
||||
image: *node_image
|
||||
directory: docs/
|
||||
commands:
|
||||
@@ -48,7 +48,7 @@ steps:
|
||||
event: [tag, pull_request, push]
|
||||
- event: manual
|
||||
|
||||
format-check:
|
||||
- name: format-check
|
||||
image: *node_image
|
||||
directory: docs/
|
||||
commands:
|
||||
@@ -58,7 +58,7 @@ steps:
|
||||
- path: *when_path
|
||||
event: pull_request
|
||||
|
||||
build-cli:
|
||||
- name: build-cli
|
||||
image: *golang_image
|
||||
commands:
|
||||
- make generate-docs
|
||||
@@ -67,7 +67,7 @@ steps:
|
||||
event: [tag, pull_request, push]
|
||||
- event: manual
|
||||
|
||||
build:
|
||||
- name: build
|
||||
image: *node_image
|
||||
directory: docs/
|
||||
commands:
|
||||
@@ -78,7 +78,7 @@ steps:
|
||||
event: [tag, pull_request, push]
|
||||
- event: manual
|
||||
|
||||
deploy-preview:
|
||||
- name: deploy-preview
|
||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.4.1
|
||||
settings:
|
||||
path: 'docs/build/'
|
||||
@@ -91,7 +91,7 @@ steps:
|
||||
- event: [pull_request, pull_request_closed]
|
||||
path: *when_path
|
||||
|
||||
deploy-prepare:
|
||||
- name: deploy-prepare
|
||||
image: *alpine_image
|
||||
environment:
|
||||
BOT_PRIVATE_KEY:
|
||||
@@ -112,7 +112,7 @@ steps:
|
||||
- event: [manual, tag]
|
||||
|
||||
# update latest and next version
|
||||
version-next:
|
||||
- name: version-next
|
||||
image: *alpine_image
|
||||
commands:
|
||||
- apk add jq
|
||||
@@ -123,7 +123,7 @@ steps:
|
||||
path: *docker_path
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
|
||||
version-release:
|
||||
- name: version-release
|
||||
image: *alpine_image
|
||||
commands:
|
||||
- apk add jq
|
||||
@@ -133,7 +133,7 @@ steps:
|
||||
when:
|
||||
- event: tag
|
||||
|
||||
copy-files:
|
||||
- name: copy-files
|
||||
image: *alpine_image
|
||||
commands:
|
||||
- apk add rsync
|
||||
@@ -145,7 +145,7 @@ steps:
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
- event: manual
|
||||
|
||||
deploy:
|
||||
- name: deploy
|
||||
image: *alpine_image
|
||||
environment:
|
||||
BOT_PRIVATE_KEY:
|
||||
|
||||
@@ -4,7 +4,7 @@ when:
|
||||
|
||||
steps:
|
||||
- name: links
|
||||
image: docker.io/lycheeverse/lychee:0.15.1
|
||||
image: docker.io/lycheeverse/lychee:0.22.0
|
||||
failure: ignore
|
||||
depends_on: []
|
||||
commands:
|
||||
@@ -14,7 +14,7 @@ steps:
|
||||
- echo -e "\nLast checked:$(date)" >> links.md
|
||||
|
||||
- name: Update issue
|
||||
image: docker.io/alpine:3.22
|
||||
image: docker.io/alpine:3.23
|
||||
depends_on: links
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
|
||||
@@ -5,7 +5,7 @@ when:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
|
||||
variables:
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.4.3
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.4.4
|
||||
|
||||
steps:
|
||||
backend:
|
||||
|
||||
@@ -55,7 +55,7 @@ steps:
|
||||
lint:
|
||||
depends_on:
|
||||
- vendor
|
||||
image: *golang_image
|
||||
image: golangci/golangci-lint:v2.7.2
|
||||
commands:
|
||||
- make lint
|
||||
when: *when
|
||||
@@ -73,7 +73,7 @@ steps:
|
||||
lint-license-header:
|
||||
image: *golang_image
|
||||
commands:
|
||||
- go install github.com/google/addlicense@latest # cspell:words addlicense
|
||||
- make install-addlicense # cspell:words addlicense
|
||||
- 'addlicense -check -ignore "vendor/**" **/*.go'
|
||||
when: *when
|
||||
|
||||
|
||||
108
CHANGELOG.md
@@ -1,5 +1,113 @@
|
||||
# Changelog
|
||||
|
||||
## [3.12.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.12.0) - 2025-11-18
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@1001Josias, @6543, @JohnWalkerx, @LUKIEYF, @MeurillonGuillaume, @Utkarsh9571, @Xuxe, @anbraten, @chamburr, @henkka, @hhamalai, @marcusramberg, @pixelateapotato, @qwerty287, @yyewolf
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- chore(deps): update dependency vite to v7.1.11 [security] [[#5660](https://github.com/woodpecker-ci/woodpecker/pull/5660)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- feat(bitbucketserver): get changes from all commits in a single push event [[#5748](https://github.com/woodpecker-ci/woodpecker/pull/5748)]
|
||||
- Support for file changes in Bitbucket Cloud [[#5730](https://github.com/woodpecker-ci/woodpecker/pull/5730)]
|
||||
- feat(agent): log agent version on startup [[#5724](https://github.com/woodpecker-ci/woodpecker/pull/5724)]
|
||||
- Add Header User-Agent for request client [[#5664](https://github.com/woodpecker-ci/woodpecker/pull/5664)]
|
||||
- Switch from BoolTrue to optional.Option[bool] [[#5693](https://github.com/woodpecker-ci/woodpecker/pull/5693)]
|
||||
- Enhancement log stream reading and writing and handle new lines and max-size [[#5683](https://github.com/woodpecker-ci/woodpecker/pull/5683)]
|
||||
- Make local backend work with `cli exec` [[#4102](https://github.com/woodpecker-ci/woodpecker/pull/4102)]
|
||||
- Make pipeline/frontend/yaml/* types able to be marshaled back to YAML [[#1835](https://github.com/woodpecker-ci/woodpecker/pull/1835)]
|
||||
- Add log service addon [[#5507](https://github.com/woodpecker-ci/woodpecker/pull/5507)]
|
||||
- Support multiple users with same login name but different forges [[#5612](https://github.com/woodpecker-ci/woodpecker/pull/5612)]
|
||||
- Release linux/riscv64 binaries [[#5663](https://github.com/woodpecker-ci/woodpecker/pull/5663)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Fix crash when a HTTP/2 client goes away on SSE streams [[#5738](https://github.com/woodpecker-ci/woodpecker/pull/5738)]
|
||||
- Add created icon [[#5747](https://github.com/woodpecker-ci/woodpecker/pull/5747)]
|
||||
- Fix badge label padding [[#5725](https://github.com/woodpecker-ci/woodpecker/pull/5725)]
|
||||
- Fix workflow path filter for GitHub [[#5721](https://github.com/woodpecker-ci/woodpecker/pull/5721)]
|
||||
- Fix secret on new forge [[#5715](https://github.com/woodpecker-ci/woodpecker/pull/5715)]
|
||||
- Revert to forge internal implementation of pagination for `Repos()` and `Teams()` for gitea/forgejo [[#5679](https://github.com/woodpecker-ci/woodpecker/pull/5679)]
|
||||
- fix: panic due to an invalid memory address when injectSecretRecursive encounters nil values [[#5699](https://github.com/woodpecker-ci/woodpecker/pull/5699)]
|
||||
- Fix so agents don't need to specify a required label twice [[#5684](https://github.com/woodpecker-ci/woodpecker/pull/5684)]
|
||||
- Fix nil pointer dereference during GitHub Hook parsing [[#5681](https://github.com/woodpecker-ci/woodpecker/pull/5681)]
|
||||
- Allow username to be used with multiple forges [[#5676](https://github.com/woodpecker-ci/woodpecker/pull/5676)]
|
||||
- Create GitHub forge via WebUI fails to be loaded [[#5675](https://github.com/woodpecker-ci/woodpecker/pull/5675)]
|
||||
- Bitbucket: ignore push hooks with no changes propperly [[#5672](https://github.com/woodpecker-ci/woodpecker/pull/5672)]
|
||||
- fix(bitbucketdatacenter): prevent adding new repos with empty branch [[#5669](https://github.com/woodpecker-ci/woodpecker/pull/5669)]
|
||||
- cli: show description of default value for `--backend-local-temp-dir` instead of value [[#5656](https://github.com/woodpecker-ci/woodpecker/pull/5656)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Add docs for 3.12 [[#5763](https://github.com/woodpecker-ci/woodpecker/pull/5763)]
|
||||
- chore(deps): lock file maintenance [[#5760](https://github.com/woodpecker-ci/woodpecker/pull/5760)]
|
||||
- chore(deps): update docs npm deps non-major [[#5752](https://github.com/woodpecker-ci/woodpecker/pull/5752)]
|
||||
- chore(deps): update docs npm deps non-major [[#5733](https://github.com/woodpecker-ci/woodpecker/pull/5733)]
|
||||
- Fix typo in about.md [[#5716](https://github.com/woodpecker-ci/woodpecker/pull/5716)]
|
||||
- docs: add warning about 27-axis matrix limit [[#5700](https://github.com/woodpecker-ci/woodpecker/pull/5700)]
|
||||
- chore(deps): update dependency isomorphic-dompurify to v2.31.0 [[#5709](https://github.com/woodpecker-ci/woodpecker/pull/5709)]
|
||||
- chore(deps): update dependency @types/node to v24 [[#5706](https://github.com/woodpecker-ci/woodpecker/pull/5706)]
|
||||
- chore(deps): update docs npm deps non-major [[#5701](https://github.com/woodpecker-ci/woodpecker/pull/5701)]
|
||||
- Update path to plugins moved to woodpecker-community [[#5698](https://github.com/woodpecker-ci/woodpecker/pull/5698)]
|
||||
- chore(deps): update docs npm deps non-major [[#5688](https://github.com/woodpecker-ci/woodpecker/pull/5688)]
|
||||
- docs(plugins): add github-app-token and github-comment plugins to repository [[#5671](https://github.com/woodpecker-ci/woodpecker/pull/5671)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- fix(deps): update module github.com/urfave/cli/v3 to v3.6.1 [[#5759](https://github.com/woodpecker-ci/woodpecker/pull/5759)]
|
||||
- chore(deps): update dependency vue-tsc to v3.1.4 [[#5758](https://github.com/woodpecker-ci/woodpecker/pull/5758)]
|
||||
- fix(deps): update module github.com/google/go-github/v78 to v79 [[#5757](https://github.com/woodpecker-ci/woodpecker/pull/5757)]
|
||||
- fix(deps): update module github.com/docker/cli to v29 [[#5756](https://github.com/woodpecker-ci/woodpecker/pull/5756)]
|
||||
- chore(deps): update postgres docker tag to v18.1 [[#5755](https://github.com/woodpecker-ci/woodpecker/pull/5755)]
|
||||
- chore(deps): update web npm deps non-major [[#5754](https://github.com/woodpecker-ci/woodpecker/pull/5754)]
|
||||
- chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.2 [[#5753](https://github.com/woodpecker-ci/woodpecker/pull/5753)]
|
||||
- chore(deps): update dependency golangci/golangci-lint to v2.6.2 [[#5751](https://github.com/woodpecker-ci/woodpecker/pull/5751)]
|
||||
- fix(deps): update golang-packages [[#5746](https://github.com/woodpecker-ci/woodpecker/pull/5746)]
|
||||
- fix(deps): update golang-packages [[#5745](https://github.com/woodpecker-ci/woodpecker/pull/5745)]
|
||||
- fix(deps): update module github.com/urfave/cli/v3 to v3.6.0 [[#5743](https://github.com/woodpecker-ci/woodpecker/pull/5743)]
|
||||
- chore(deps): lock file maintenance [[#5744](https://github.com/woodpecker-ci/woodpecker/pull/5744)]
|
||||
- fix(deps): update golang-packages [[#5741](https://github.com/woodpecker-ci/woodpecker/pull/5741)]
|
||||
- chore(deps): update dependency simple-icons to v15.20.0 [[#5742](https://github.com/woodpecker-ci/woodpecker/pull/5742)]
|
||||
- fix(deps): update module github.com/google/go-github/v77 to v78 [[#5739](https://github.com/woodpecker-ci/woodpecker/pull/5739)]
|
||||
- fix(deps): update module github.com/google/go-github/v76 to v77 [[#5737](https://github.com/woodpecker-ci/woodpecker/pull/5737)]
|
||||
- fix(deps): update dependency marked to v17 [[#5736](https://github.com/woodpecker-ci/woodpecker/pull/5736)]
|
||||
- chore(deps): update web npm deps non-major [[#5735](https://github.com/woodpecker-ci/woodpecker/pull/5735)]
|
||||
- chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.1 [[#5734](https://github.com/woodpecker-ci/woodpecker/pull/5734)]
|
||||
- chore(deps): update dependency golangci/golangci-lint to v2.6.1 [[#5732](https://github.com/woodpecker-ci/woodpecker/pull/5732)]
|
||||
- chore(deps): update dependency golang to v1.25.4 [[#5731](https://github.com/woodpecker-ci/woodpecker/pull/5731)]
|
||||
- fix(deps): update golang-packages to v28.5.2+incompatible [[#5723](https://github.com/woodpecker-ci/woodpecker/pull/5723)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.159.0 [[#5720](https://github.com/woodpecker-ci/woodpecker/pull/5720)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.158.0 [[#5718](https://github.com/woodpecker-ci/woodpecker/pull/5718)]
|
||||
- chore(deps): lock file maintenance [[#5711](https://github.com/woodpecker-ci/woodpecker/pull/5711)]
|
||||
- chore(deps): update dependency golangci/golangci-lint to v2.6.0 [[#5702](https://github.com/woodpecker-ci/woodpecker/pull/5702)]
|
||||
- chore(deps): update web npm deps non-major [[#5705](https://github.com/woodpecker-ci/woodpecker/pull/5705)]
|
||||
- fix(deps): update module github.com/yaronf/httpsign to v0.4.1 [[#5708](https://github.com/woodpecker-ci/woodpecker/pull/5708)]
|
||||
- chore(deps): update node.js to v24 [[#5707](https://github.com/woodpecker-ci/woodpecker/pull/5707)]
|
||||
- chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.0 [[#5704](https://github.com/woodpecker-ci/woodpecker/pull/5704)]
|
||||
- chore(deps): update gitea/gitea docker tag to v1.25 [[#5703](https://github.com/woodpecker-ci/woodpecker/pull/5703)]
|
||||
- fix(deps): update module gitlab.com/gitlab-org/api/client-go to v0.157.1 [[#5697](https://github.com/woodpecker-ci/woodpecker/pull/5697)]
|
||||
- chore(deps): lock file maintenance [[#5695](https://github.com/woodpecker-ci/woodpecker/pull/5695)]
|
||||
- chore(deps): update web npm deps non-major [[#5694](https://github.com/woodpecker-ci/woodpecker/pull/5694)]
|
||||
- fix(deps): update dependency @vueuse/core to v14 [[#5692](https://github.com/woodpecker-ci/woodpecker/pull/5692)]
|
||||
- chore(deps): update dependency vitest to v4 [[#5691](https://github.com/woodpecker-ci/woodpecker/pull/5691)]
|
||||
- chore(deps): update docker.io/mysql docker tag to v9.5.0 [[#5690](https://github.com/woodpecker-ci/woodpecker/pull/5690)]
|
||||
- chore(deps): update web npm deps non-major [[#5689](https://github.com/woodpecker-ci/woodpecker/pull/5689)]
|
||||
- chore(deps): update dependency mvdan/gofumpt to v0.9.2 [[#5687](https://github.com/woodpecker-ci/woodpecker/pull/5687)]
|
||||
- fix(deps): update github.com/urfave/cli-docs/v3 digest to 72b87d1 [[#5686](https://github.com/woodpecker-ci/woodpecker/pull/5686)]
|
||||
- fix(deps): update module code.gitea.io/sdk/gitea to v0.22.1 [[#5682](https://github.com/woodpecker-ci/woodpecker/pull/5682)]
|
||||
- fix(deps): update module github.com/urfave/cli/v3 to v3.5.0 [[#5668](https://github.com/woodpecker-ci/woodpecker/pull/5668)]
|
||||
- fix(deps): update module xorm.io/xorm to v1.3.11 [[#5662](https://github.com/woodpecker-ci/woodpecker/pull/5662)]
|
||||
- chore(deps): lock file maintenance [[#5657](https://github.com/woodpecker-ci/woodpecker/pull/5657)]
|
||||
|
||||
### Misc
|
||||
|
||||
- Also create image preview on label change only [[#5673](https://github.com/woodpecker-ci/woodpecker/pull/5673)]
|
||||
- Add migration tests for postgres [[#669](https://github.com/woodpecker-ci/woodpecker/pull/669)]
|
||||
|
||||
## [3.11.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.11.0) - 2025-10-19
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
58
Makefile
@@ -1,7 +1,7 @@
|
||||
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
||||
GOFUMPT_VERSION := v0.9.2
|
||||
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
||||
GOLANGCI_LINT_VERSION := v2.6.0
|
||||
GOLANGCI_LINT_VERSION := v2.7.2
|
||||
# renovate: datasource=docker depName=docker.io/techknowlogick/xgo
|
||||
XGO_VERSION := go-1.25.x
|
||||
|
||||
@@ -102,7 +102,7 @@ vendor: ## Update the vendor directory
|
||||
go mod tidy
|
||||
go mod vendor
|
||||
|
||||
format: install-tools ## Format source code
|
||||
format: install-gofumpt ## Format source code
|
||||
@gofumpt -extra -w .
|
||||
|
||||
.PHONY: clean
|
||||
@@ -118,15 +118,15 @@ clean-all: clean ## Clean all artifacts
|
||||
rm -rf docs/docs/40-cli.md docs/openapi.json
|
||||
|
||||
.PHONY: generate
|
||||
generate: install-tools generate-openapi ## Run all code generations
|
||||
generate: install-mockery generate-openapi ## Run all code generations
|
||||
mockery
|
||||
CGO_ENABLED=0 go generate ./...
|
||||
|
||||
generate-openapi: install-tools ## Run openapi code generation and format it
|
||||
generate-openapi: ## Run openapi code generation and format it
|
||||
CGO_ENABLED=0 go run github.com/swaggo/swag/cmd/swag fmt --exclude pipeline/rpc/proto
|
||||
CGO_ENABLED=0 go generate cmd/server/openapi.go
|
||||
|
||||
generate-license-header: install-tools
|
||||
generate-license-header: install-addlicense
|
||||
addlicense -c "Woodpecker Authors" -ignore "vendor/**" **/*.go
|
||||
|
||||
check-xgo: ## Check if xgo is installed
|
||||
@@ -134,33 +134,43 @@ check-xgo: ## Check if xgo is installed
|
||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
||||
fi
|
||||
|
||||
install-tools: ## Install development tools
|
||||
install-golangci-lint:
|
||||
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) ; \
|
||||
fi ; \
|
||||
hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
fi
|
||||
|
||||
install-gofumpt:
|
||||
@hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION); \
|
||||
fi ; \
|
||||
hash addlicense > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
fi
|
||||
|
||||
install-addlicense:
|
||||
@hash addlicense > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install github.com/google/addlicense@latest; \
|
||||
fi ; \
|
||||
hash mockery > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
fi
|
||||
|
||||
install-mockery:
|
||||
@hash mockery > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install github.com/vektra/mockery/v3@latest; \
|
||||
fi ; \
|
||||
hash protoc-gen-go > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
fi
|
||||
|
||||
install-protoc-gen-go:
|
||||
@hash protoc-gen-go > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest; \
|
||||
fi ; \
|
||||
hash protoc-gen-go-grpc > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest; \
|
||||
fi
|
||||
|
||||
install-tools: install-golangci-lint install-gofumpt install-addlicense install-mockery install-protoc-gen-go ## Install development tools
|
||||
|
||||
ui-dependencies: ## Install UI dependencies
|
||||
(cd web/; pnpm install --frozen-lockfile)
|
||||
|
||||
##@ Test
|
||||
|
||||
.PHONY: lint
|
||||
lint: install-tools ## Lint code
|
||||
lint: install-golangci-lint ## Lint code
|
||||
@echo "Running golangci-lint"
|
||||
golangci-lint run
|
||||
|
||||
@@ -223,7 +233,7 @@ build-tarball: ## Build tar archive
|
||||
.PHONY: build
|
||||
build: build-agent build-server build-cli ## Build all binaries
|
||||
|
||||
release-frontend: build-frontend ## Build frontend
|
||||
release-frontend: build-ui ## Build frontend
|
||||
|
||||
cross-compile-server: ## Cross compile the server
|
||||
$(foreach platform,$(subst ;, ,$(PLATFORMS)),\
|
||||
@@ -361,4 +371,20 @@ generate-docs: ## Generate docs (currently only for the cli)
|
||||
build-docs: generate-docs docs-dependencies ## Build the docs
|
||||
(cd docs/; pnpm build)
|
||||
|
||||
##@ Man Pages
|
||||
.PHONY: man-cli
|
||||
man-cli: ## Generate man pages for cli
|
||||
mkdir -p dist/ && CGO_ENABLED=0 go run -tags man cmd/cli/man.go cmd/cli/app.go > dist/woodpecker-cli.man.1 && gzip -9 -f dist/woodpecker-cli.man.1
|
||||
|
||||
.PHONY: man-agent
|
||||
man-agent: ## Generate man pages for agent
|
||||
mkdir -p dist/ && CGO_ENABLED=0 go run -tags man cmd/agent/man.go > dist/woodpecker-agent.man.1 && gzip -9 -f dist/woodpecker-agent.man.1
|
||||
|
||||
.PHONY: man-server
|
||||
man-server: ## Generate man pages for server
|
||||
mkdir -p dist/ && CGO_ENABLED=0 go run -tags man go.woodpecker-ci.org/woodpecker/v3/cmd/server > dist/woodpecker-server.man.1 && gzip -9 -f dist/woodpecker-server.man.1
|
||||
|
||||
.PHONY: man
|
||||
man: man-cli man-agent man-server ## Generate all man pages
|
||||
|
||||
endif
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"golang.org/x/net/proxy"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/httputil"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
@@ -72,23 +73,27 @@ func NewClient(ctx context.Context, c *cli.Command) (woodpecker.Client, error) {
|
||||
|
||||
trans, _ := client.Transport.(*oauth2.Transport)
|
||||
|
||||
var baseTransport http.RoundTripper
|
||||
if len(socks) != 0 && !socksOff {
|
||||
dialer, err := proxy.SOCKS5("tcp", socks, nil, proxy.Direct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
trans.Base = &http.Transport{
|
||||
baseTransport = &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: dialer.Dial,
|
||||
}
|
||||
} else {
|
||||
trans.Base = &http.Transport{
|
||||
baseTransport = &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the base transport with User-Agent support
|
||||
trans.Base = httputil.NewUserAgentRoundTripper(baseTransport, "cli")
|
||||
|
||||
return woodpecker.NewClient(server, client), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,21 @@ var repoUpdateCmd = &cli.Command{
|
||||
Action: repoUpdate,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "trusted",
|
||||
Usage: "repository is trusted",
|
||||
Name: "trusted-security",
|
||||
Usage: "repository is security trusted",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "trusted-volumes",
|
||||
Usage: "repository is volumes trusted",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "trusted-network",
|
||||
Usage: "repository is network trusted",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "trusted", // TODO: remove in next release
|
||||
Usage: "repository is trusted",
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "gated", // TODO: remove in next release
|
||||
@@ -81,15 +94,36 @@ func repoUpdate(ctx context.Context, c *cli.Command) error {
|
||||
visibility = c.String("visibility")
|
||||
config = c.String("config")
|
||||
timeout = c.Duration("timeout")
|
||||
trusted = c.Bool("trusted")
|
||||
requireApproval = c.String("require-approval")
|
||||
pipelineCounter = c.Int("pipeline-counter")
|
||||
unsafe = c.Bool("unsafe")
|
||||
)
|
||||
|
||||
patch := new(woodpecker.RepoPatch)
|
||||
// TODO remove in next release
|
||||
if c.IsSet("trusted") {
|
||||
patch.IsTrusted = &trusted
|
||||
trusted := c.Bool("trusted")
|
||||
patch.Trusted = &woodpecker.TrustedConfigurationPatch{
|
||||
Network: &trusted,
|
||||
Security: &trusted,
|
||||
Volumes: &trusted,
|
||||
}
|
||||
}
|
||||
if c.IsSet("trusted-security") || c.IsSet("trusted-network") || c.IsSet("trusted-volumes") {
|
||||
patch.Trusted = new(woodpecker.TrustedConfigurationPatch)
|
||||
|
||||
if c.IsSet("trusted-security") {
|
||||
t := c.Bool("trusted-security")
|
||||
patch.Trusted.Security = &t
|
||||
}
|
||||
if c.IsSet("trusted-network") {
|
||||
t := c.Bool("trusted-network")
|
||||
patch.Trusted.Security = &t
|
||||
}
|
||||
if c.IsSet("trusted-volumes") {
|
||||
t := c.Bool("trusted-volumes")
|
||||
patch.Trusted.Security = &t
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove in next release
|
||||
|
||||
@@ -65,6 +65,8 @@ var (
|
||||
)
|
||||
|
||||
func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
||||
log.Info().Str("version", version.String()).Msg("Starting Woodpecker agent")
|
||||
|
||||
agentCtx, ctxCancel := context.WithCancelCause(ctx)
|
||||
stopAgentFunc = func(err error) {
|
||||
msg := "shutdown of whole agent"
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/version"
|
||||
)
|
||||
|
||||
func RunAgent(ctx context.Context, backends []backend.Backend) {
|
||||
func GenApp(backends []backend.Backend) *cli.Command {
|
||||
app := &cli.Command{}
|
||||
app.Name = "woodpecker-agent"
|
||||
app.Version = version.String()
|
||||
@@ -47,6 +47,11 @@ func RunAgent(ctx context.Context, backends []backend.Backend) {
|
||||
agentFlags = utils.MergeSlices(agentFlags, b.Flags())
|
||||
}
|
||||
app.Flags = agentFlags
|
||||
return app
|
||||
}
|
||||
|
||||
func RunAgent(ctx context.Context, backends []backend.Backend) {
|
||||
app := GenApp(backends)
|
||||
|
||||
if err := app.Run(ctx, os.Args); err != nil {
|
||||
log.Fatal().Err(err).Msg("error running agent") //nolint:forbidigo
|
||||
|
||||
44
cmd/agent/man.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2025 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build man
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
docs "github.com/urfave/cli-docs/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/cmd/agent/core"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/docker"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/kubernetes"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/local"
|
||||
backendTypes "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||
)
|
||||
|
||||
var backends = []backendTypes.Backend{
|
||||
kubernetes.New(),
|
||||
docker.New(),
|
||||
local.New(),
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := core.GenApp(backends)
|
||||
md, err := docs.ToMan(app)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print(md)
|
||||
}
|
||||
32
cmd/cli/man.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2025 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build man
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
docs "github.com/urfave/cli-docs/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
md, err := docs.ToMan(app)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print(md)
|
||||
}
|
||||
39
cmd/server/app.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2025 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v3/version"
|
||||
)
|
||||
|
||||
func genApp() *cli.Command {
|
||||
app := &cli.Command{}
|
||||
app.Name = "woodpecker-server"
|
||||
app.Version = version.String()
|
||||
app.Usage = "woodpecker server"
|
||||
app.Action = run
|
||||
app.Commands = []*cli.Command{
|
||||
{
|
||||
Name: "ping",
|
||||
Usage: "ping the server",
|
||||
Action: pinger,
|
||||
},
|
||||
}
|
||||
app.Flags = flags
|
||||
|
||||
return app
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !generate
|
||||
//go:build !generate && !man
|
||||
|
||||
package main
|
||||
|
||||
@@ -22,11 +22,9 @@ import (
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
_ "go.woodpecker-ci.org/woodpecker/v3/cmd/server/openapi"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/utils"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/version"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -34,19 +32,7 @@ func main() {
|
||||
log.Info().Msg("termination signal is received, shutting down server")
|
||||
})
|
||||
|
||||
app := cli.Command{}
|
||||
app.Name = "woodpecker-server"
|
||||
app.Version = version.String()
|
||||
app.Usage = "woodpecker server"
|
||||
app.Action = run
|
||||
app.Commands = []*cli.Command{
|
||||
{
|
||||
Name: "ping",
|
||||
Usage: "ping the server",
|
||||
Action: pinger,
|
||||
},
|
||||
}
|
||||
app.Flags = flags
|
||||
app := genApp()
|
||||
|
||||
setupOpenAPIStaticConfig()
|
||||
|
||||
|
||||
35
cmd/server/man.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2025 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build man
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
docs "github.com/urfave/cli-docs/v3"
|
||||
|
||||
_ "go.woodpecker-ci.org/woodpecker/v3/cmd/server/openapi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := genApp()
|
||||
md, err := docs.ToMan(app)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print(md)
|
||||
}
|
||||
@@ -665,7 +665,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Forge"
|
||||
"$ref": "#/definitions/ForgeWithOAuthClientSecret"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -774,7 +774,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Forge"
|
||||
"$ref": "#/definitions/ForgeWithOAuthClientSecret"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -4809,6 +4809,37 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"ForgeWithOAuthClientSecret": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"additional_options": {
|
||||
"type": "object",
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"client": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"oauth_client_secret": {
|
||||
"type": "string"
|
||||
},
|
||||
"oauth_host": {
|
||||
"description": "public url for oauth if different from url",
|
||||
"type": "string"
|
||||
},
|
||||
"skip_verify": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/model.ForgeType"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LogEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -3,7 +3,7 @@ version: '3'
|
||||
|
||||
services:
|
||||
gitea-database:
|
||||
image: postgres:18.0-alpine
|
||||
image: postgres:18.1-alpine
|
||||
environment:
|
||||
POSTGRES_USER: gitea
|
||||
POSTGRES_PASSWORD: 123456
|
||||
|
||||
@@ -7,7 +7,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg \
|
||||
make build-agent
|
||||
|
||||
FROM docker.io/alpine:3.22
|
||||
FROM docker.io/alpine:3.23
|
||||
|
||||
RUN apk add -U --no-cache ca-certificates && \
|
||||
adduser -u 1000 -g 1000 woodpecker -D && \
|
||||
|
||||
@@ -7,7 +7,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg \
|
||||
make build-cli
|
||||
|
||||
FROM docker.io/alpine:3.22
|
||||
FROM docker.io/alpine:3.23
|
||||
|
||||
WORKDIR /woodpecker
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM docker.io/alpine:3.22
|
||||
FROM docker.io/alpine:3.23
|
||||
|
||||
ARG TARGETOS TARGETARCH
|
||||
RUN apk add -U --no-cache ca-certificates && \
|
||||
|
||||
@@ -393,7 +393,7 @@ when:
|
||||
#### `path`
|
||||
|
||||
:::info
|
||||
Path conditions are applied only to **push** and **pull_request** events. This feature is currently available for all forges except Bitbucket Cloud.
|
||||
Path conditions are applied only to **push** and **pull_request** events.
|
||||
:::
|
||||
|
||||
Execute a step only on a pipeline with certain files being changed:
|
||||
|
||||
@@ -15,4 +15,10 @@ The status badge displays the status for the latest build to your default branch
|
||||
+<scheme>://<hostname>/api/badges/<repo-id>/status.svg?branch=<branch>
|
||||
```
|
||||
|
||||
Please note status badges do not include pull request results, since the status of a pull request does not provide an accurate representation of your repository state.
|
||||
By default status badges do not include pull request results, since the status of a pull request does not provide an accurate representation of your repository state.
|
||||
If you'd like to respect other or further events, you can add the `events` query parameter, otherwise the badge represents only the state of the last push event:
|
||||
|
||||
```diff
|
||||
-<scheme>://<hostname>/api/badges/<repo-id>/status.svg
|
||||
+<scheme>://<hostname>/api/badges/<repo-id>/status.svg?events=manual,cron
|
||||
```
|
||||
|
||||
@@ -114,7 +114,7 @@ steps:
|
||||
- name: debug
|
||||
image: bash
|
||||
commands:
|
||||
- source envvars
|
||||
- source ./envvars
|
||||
- echo $FOO
|
||||
```
|
||||
|
||||
|
||||
@@ -145,6 +145,100 @@ steps:
|
||||
value: 'value1'
|
||||
effect: 'NoSchedule'
|
||||
tolerationSeconds: 3600
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: topology.kubernetes.io/zone
|
||||
operator: In
|
||||
values:
|
||||
- eu-central-1a
|
||||
- eu-central-1b
|
||||
```
|
||||
|
||||
### Affinity
|
||||
|
||||
Kubernetes [affinity and anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) rules allow you to constrain which nodes your pods can be scheduled on based on node labels, or co-locate/spread pods relative to other pods.
|
||||
|
||||
You can configure affinity at two levels:
|
||||
|
||||
1. **Per-step via `backend_options.kubernetes.affinity`** (shown in example above) - requires agent configuration to allow it
|
||||
2. **Agent-wide via `WOODPECKER_BACKEND_K8S_POD_AFFINITY`** - applies to all pods unless overridden
|
||||
|
||||
#### Agent-wide affinity
|
||||
|
||||
To apply affinity rules to all workflow pods, configure the agent with YAML-formatted affinity:
|
||||
|
||||
```yaml
|
||||
WOODPECKER_BACKEND_K8S_POD_AFFINITY: |
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/worker
|
||||
operator: In
|
||||
values:
|
||||
- "true"
|
||||
```
|
||||
|
||||
By default, per-step affinity settings are **not allowed** for security reasons. To enable them:
|
||||
|
||||
```bash
|
||||
WOODPECKER_BACKEND_K8S_POD_AFFINITY_ALLOW_FROM_STEP: true
|
||||
```
|
||||
|
||||
:::warning
|
||||
Enabling `WOODPECKER_BACKEND_K8S_POD_AFFINITY_ALLOW_FROM_STEP` in multi-tenant environments allows pipeline authors to control pod placement, which may have security or resource isolation implications.
|
||||
:::
|
||||
|
||||
When per-step affinity is allowed and specified, it **replaces** the agent-wide affinity entirely (not merged).
|
||||
|
||||
#### Example: agent affinity for co-location
|
||||
|
||||
This example configures all workflow pods within a workflow to be co-located on the same node, while requiring other workflows run on different nodes.
|
||||
|
||||
It uses `matchLabelKeys` to dynamically match pods with the same `woodpecker-ci.org/task-uuid`, and `mismatchLabelKeys` to separating pods with different task UUIDs:
|
||||
|
||||
```yaml
|
||||
WOODPECKER_BACKEND_K8S_POD_AFFINITY: |
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector: {}
|
||||
matchLabelKeys:
|
||||
- woodpecker-ci.org/task-uuid
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector: {}
|
||||
mismatchLabelKeys:
|
||||
- woodpecker-ci.org/task-uuid
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
```
|
||||
|
||||
:::note
|
||||
The `matchLabelKeys` and `mismatchLabelKeys` features require Kubernetes v1.29+ (alpha with feature gate `MatchLabelKeysInPodAffinity`) or v1.33+ (beta, enabled by default). These fields allow the Kubernetes API server to dynamically populate label selectors at pod creation time, eliminating the need to hardcode values like `$(WOODPECKER_TASK_UUID)`.
|
||||
:::
|
||||
|
||||
#### Example: Node affinity for GPU workloads
|
||||
|
||||
Ensure a step runs only on GPU-enabled nodes:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: train-model
|
||||
image: tensorflow/tensorflow:latest-gpu
|
||||
backend_options:
|
||||
kubernetes:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: accelerator
|
||||
operator: In
|
||||
values:
|
||||
- nvidia-tesla-v100
|
||||
```
|
||||
|
||||
### Volumes
|
||||
@@ -153,7 +247,7 @@ To mount volumes a PersistentVolume (PV) and PersistentVolumeClaim (PVC) are nee
|
||||
|
||||
Persistent volumes must be created manually. Use the Kubernetes [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) documentation as a reference.
|
||||
|
||||
_If your PVC is not highly available or NFS-based, you may also need to integrate affinity settings to ensure that your steps are executed on the correct node._
|
||||
_If your PVC is not highly available or NFS-based, use the `affinity` settings (documented above) to ensure that your steps are executed on the correct node._
|
||||
|
||||
NOTE: If you plan to use this volume in more than one workflow concurrently, make sure you have configured the PVC in `RWX` mode. Keep in mind that this feature must be supported by the used CSI driver:
|
||||
|
||||
@@ -304,6 +398,36 @@ 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.
|
||||
|
||||
### Headless services
|
||||
|
||||
For each workflow run a [headless services](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services) is created,
|
||||
and all steps asigned the subdomain that matches the headless service, so any step can reach other steps via DNS by using the step name as hostname.
|
||||
|
||||
Using the headless services, the step pod is connected to directly, so any port on the other step pods can be reached.
|
||||
|
||||
This is useful for some use-cases, like test-containers in a docker-in-docker setup, where the step needs to connect to many ports on the docker host service.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: test
|
||||
image: docker:cli # use 'docker:<major-version>-cli' or similar in production
|
||||
environment:
|
||||
DOCKER_HOST: 'tcp://docker:2376'
|
||||
DOCKER_CERT_PATH: '/woodpecker/dind-certs/client'
|
||||
DOCKER_TLS_VERIFY: '1'
|
||||
commands:
|
||||
- docker run hello-world
|
||||
|
||||
- name: docker
|
||||
image: docker:dind # use 'docker:<major-version>-dind' or similar in production
|
||||
detached: true
|
||||
privileged: true
|
||||
environment:
|
||||
DOCKER_TLS_CERTDIR: /woodpecker/dind-certs
|
||||
```
|
||||
|
||||
If ports are defined on a service, then woodpecker will create a normal service for the pod, which use hosts override using the services cluster IP.
|
||||
|
||||
## Environment variables
|
||||
|
||||
These env vars can be set in the `env:` sections of the agent.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| Event: Deploy¹ | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
| [Event: Pull-Request-Metadata](../../../20-usage/50-environment.md#pull_request_metadata-specific-event-reason-values) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :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: | :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: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
¹ The deployment event can be triggered for all forges from Woodpecker directly. However, only GitHub can trigger them using webhooks.
|
||||
|
||||
|
||||
18
docs/docs/92-development/10-packaging.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Packaging
|
||||
|
||||
If you repackage it, we encourage to build from source, which requires internet connection.
|
||||
|
||||
For offline builds, we also offer a tarball with all vendored dependencies and a pre-built web UI
|
||||
on the [release page](https://github.com/woodpecker-ci/woodpecker/releases).
|
||||
|
||||
## Distribute web UI in own directory
|
||||
|
||||
If you do not want to embed the web UI in the binary, you can compile a custom root path for the web UI into the binary.
|
||||
|
||||
Add `external_web` to the tags and use the build flag `-X go.woodpecker-ci.org/woodpecker/v3/web.webUIRoot=/some/path` to set a custom path.
|
||||
|
||||
Example: <!-- cspell:ignore webui -->
|
||||
|
||||
```sh
|
||||
go build -tags 'external_web' -ldflags '-s -w -extldflags "-static" -X go.woodpecker-ci.org/woodpecker/v3/version.Version=3.12.0 -X go.woodpecker-ci.org/woodpecker/v3/web.webUIRoot=/nix/store/maaajlp8h5gy9zyjgfhaipzj07qnnmrl-woodpecker-WebUI-3.12.0' -o dist/woodpecker-server go.woodpecker-ci.org/woodpecker/v3/cmd/server
|
||||
```
|
||||
@@ -18,7 +18,7 @@
|
||||
"axios": "^1.7.9",
|
||||
"concurrently": "^9.1.2",
|
||||
"isomorphic-dompurify": "^2.19.0",
|
||||
"marked": "^16.0.0",
|
||||
"marked": "^17.0.0",
|
||||
"slugify": "^1.6.6",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.7.2"
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Codeberg Pages Deploy",
|
||||
"docs": "https://codeberg.org/xfix/plugin-codeberg-pages-deploy/raw/branch/master/README.md",
|
||||
"docs": "https://codeberg.org/sugar700/plugin-codeberg-pages-deploy/raw/branch/master/README.md",
|
||||
"verified": false
|
||||
},
|
||||
{
|
||||
|
||||
2155
docs/pnpm-lock.yaml
generated
@@ -33,6 +33,7 @@ Here you can find documentation for previous versions of Woodpecker.
|
||||
|
||||
| | | |
|
||||
| ------- | ---------- | ------------------------------------------------------------------------------------- |
|
||||
| 3.12.0 | 2025-11-18 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v3.12.0/docs/docs/) |
|
||||
| 3.11.0 | 2025-10-19 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v3.11.0/docs/docs/) |
|
||||
| 3.10.0 | 2025-09-28 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v3.10.0/docs/docs/) |
|
||||
| 3.9.0 | 2025-08-20 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v3.9.0/docs/docs/) |
|
||||
|
||||
@@ -114,7 +114,7 @@ steps:
|
||||
- name: debug
|
||||
image: bash
|
||||
commands:
|
||||
- source envvars
|
||||
- source ./envvars
|
||||
- echo $FOO
|
||||
```
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ steps:
|
||||
- name: debug
|
||||
image: bash
|
||||
commands:
|
||||
- source envvars
|
||||
- source ./envvars
|
||||
- echo $FOO
|
||||
```
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ steps:
|
||||
- name: debug
|
||||
image: bash
|
||||
commands:
|
||||
- source envvars
|
||||
- source ./envvars
|
||||
- echo $FOO
|
||||
```
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -284,6 +284,7 @@ The available events are:
|
||||
- `push`: triggered when a commit is pushed to a branch.
|
||||
- `pull_request`: triggered when a pull request is opened or a new commit is pushed to it.
|
||||
- `pull_request_closed`: triggered when a pull request is closed or merged.
|
||||
- `pull_request_metadata`: triggered when a pull request metadata has changed (e.g. title, body, label, milestone, ...).
|
||||
- `tag`: triggered when a tag is pushed.
|
||||
- `release`: triggered when a release, pre-release or draft is created. (You can apply further filters using [evaluate](#evaluate) with [environment variables](./50-environment.md#built-in-environment-variables).)
|
||||
- `deployment`: triggered when a deployment is created in the repository. (This event can be triggered from Woodpecker directly. GitHub also supports webhook triggers.)
|
||||
@@ -392,7 +393,7 @@ when:
|
||||
#### `path`
|
||||
|
||||
:::info
|
||||
Path conditions are applied only to **push** and **pull_request** events. This feature is currently available for all forges except Bitbucket Cloud.
|
||||
Path conditions are applied only to **push** and **pull_request** events.
|
||||
:::
|
||||
|
||||
Execute a step only on a pipeline with certain files being changed:
|
||||
259
docs/versioned_docs/version-3.12/20-usage/50-environment.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# Environment variables
|
||||
|
||||
Woodpecker provides the ability to pass environment variables to individual pipeline steps. Note that these can't overwrite any existing, built-in variables. Example pipeline step with custom environment variables:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: build
|
||||
image: golang
|
||||
+ environment:
|
||||
+ CGO: 0
|
||||
+ GOOS: linux
|
||||
+ GOARCH: amd64
|
||||
commands:
|
||||
- go build
|
||||
- go test
|
||||
```
|
||||
|
||||
Please note that the environment section is not able to expand environment variables. If you need to expand variables they should be exported in the commands section.
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: build
|
||||
image: golang
|
||||
- environment:
|
||||
- - PATH=$PATH:/go
|
||||
commands:
|
||||
+ - export PATH=$PATH:/go
|
||||
- go build
|
||||
- go test
|
||||
```
|
||||
|
||||
:::warning
|
||||
`${variable}` expressions are subject to pre-processing. If you do not want the pre-processor to evaluate your expression it must be escaped:
|
||||
:::
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: build
|
||||
image: golang
|
||||
commands:
|
||||
- - export PATH=${PATH}:/go
|
||||
+ - export PATH=$${PATH}:/go
|
||||
- go build
|
||||
- go test
|
||||
```
|
||||
|
||||
## Built-in environment variables
|
||||
|
||||
This is the reference list of all environment variables available to your pipeline containers. These are injected into your pipeline step and plugins containers, at runtime.
|
||||
|
||||
| NAME | Description | Example |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `CI` | CI environment name | `woodpecker` |
|
||||
| | **Repository** | |
|
||||
| `CI_REPO` | repository full name `<owner>/<name>` | `john-doe/my-repo` |
|
||||
| `CI_REPO_OWNER` | repository owner | `john-doe` |
|
||||
| `CI_REPO_NAME` | repository name | `my-repo` |
|
||||
| `CI_REPO_REMOTE_ID` | repository remote ID, is the UID it has in the forge | `82` |
|
||||
| `CI_REPO_URL` | repository web URL | `https://git.example.com/john-doe/my-repo` |
|
||||
| `CI_REPO_CLONE_URL` | repository clone URL | `https://git.example.com/john-doe/my-repo.git` |
|
||||
| `CI_REPO_CLONE_SSH_URL` | repository SSH clone URL | `git@git.example.com:john-doe/my-repo.git` |
|
||||
| `CI_REPO_DEFAULT_BRANCH` | repository default branch | `main` |
|
||||
| `CI_REPO_PRIVATE` | repository is private | `true` |
|
||||
| `CI_REPO_TRUSTED_NETWORK` | repository has trusted network access | `false` |
|
||||
| `CI_REPO_TRUSTED_VOLUMES` | repository has trusted volumes access | `false` |
|
||||
| `CI_REPO_TRUSTED_SECURITY` | repository has trusted security access | `false` |
|
||||
| | **Current Commit** | |
|
||||
| `CI_COMMIT_SHA` | commit SHA | `eba09b46064473a1d345da7abf28b477468e8dbd` |
|
||||
| `CI_COMMIT_REF` | commit ref | `refs/heads/main` |
|
||||
| `CI_COMMIT_REFSPEC` | commit ref spec | `issue-branch:main` |
|
||||
| `CI_COMMIT_BRANCH` | commit branch (equals target branch for pull requests) | `main` |
|
||||
| `CI_COMMIT_SOURCE_BRANCH` | commit source branch (set only for pull request events) | `issue-branch` |
|
||||
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (set only for pull request events) | `main` |
|
||||
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) | `v1.10.3` |
|
||||
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (set only for pull request events) | `1` |
|
||||
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (set only for pull request events) | `server` |
|
||||
| `CI_COMMIT_PULL_REQUEST_MILESTONE` | milestone assigned to pull request (set only for `pull_request` and `pull_request_closed` events) | `summer-sprint` |
|
||||
| `CI_COMMIT_MESSAGE` | commit message | `Initial commit` |
|
||||
| `CI_COMMIT_AUTHOR` | commit author username | `john-doe` |
|
||||
| `CI_COMMIT_AUTHOR_EMAIL` | commit author email address | `john-doe@example.com` |
|
||||
| `CI_COMMIT_PRERELEASE` | release is a pre-release (empty if event is not `release`) | `false` |
|
||||
| | **Current pipeline** | |
|
||||
| `CI_PIPELINE_NUMBER` | pipeline number | `8` |
|
||||
| `CI_PIPELINE_PARENT` | number of parent pipeline | `0` |
|
||||
| `CI_PIPELINE_EVENT` | pipeline event (see [`event`](../20-usage/20-workflow-syntax.md#event)) | `push`, `pull_request`, `pull_request_closed`, `pull_request_metadata`, `tag`, `release`, `manual`, `cron` |
|
||||
| `CI_PIPELINE_EVENT_REASON` | exact reason why `pull_request_metadata` event was send. it is forge instance specific and can change | `label_updated`, `milestoned`, `demilestoned`, `assigned`, `edited`, ... |
|
||||
| `CI_PIPELINE_URL` | link to the web UI for the pipeline | `https://ci.example.com/repos/7/pipeline/8` |
|
||||
| `CI_PIPELINE_FORGE_URL` | link to the forge's web UI for the commit(s) or tag that triggered the pipeline | `https://git.example.com/john-doe/my-repo/commit/eba09b46064473a1d345da7abf28b477468e8dbd` |
|
||||
| `CI_PIPELINE_DEPLOY_TARGET` | pipeline deploy target for `deployment` events | `production` |
|
||||
| `CI_PIPELINE_DEPLOY_TASK` | pipeline deploy task for `deployment` events | `migration` |
|
||||
| `CI_PIPELINE_CREATED` | pipeline created UNIX timestamp | `1722617519` |
|
||||
| `CI_PIPELINE_STARTED` | pipeline started UNIX timestamp | `1722617519` |
|
||||
| `CI_PIPELINE_FILES` | changed files (empty if event is not `push` or `pull_request`), it is undefined if more than 500 files are touched | `[]`, `[".woodpecker.yml","README.md"]` |
|
||||
| `CI_PIPELINE_AUTHOR` | pipeline author username | `octocat` |
|
||||
| `CI_PIPELINE_AVATAR` | pipeline author avatar | `https://git.example.com/avatars/5dcbcadbce6f87f8abef` |
|
||||
| | **Current workflow** | |
|
||||
| `CI_WORKFLOW_NAME` | workflow name | `release` |
|
||||
| | **Current step** | |
|
||||
| `CI_STEP_NAME` | step name | `build package` |
|
||||
| `CI_STEP_NUMBER` | step number | `0` |
|
||||
| `CI_STEP_STARTED` | step started UNIX timestamp | `1722617519` |
|
||||
| `CI_STEP_URL` | URL to step in UI | `https://ci.example.com/repos/7/pipeline/8` |
|
||||
| | **Previous commit** | |
|
||||
| `CI_PREV_COMMIT_SHA` | previous commit SHA | `15784117e4e103f36cba75a9e29da48046eb82c4` |
|
||||
| `CI_PREV_COMMIT_REF` | previous commit ref | `refs/heads/main` |
|
||||
| `CI_PREV_COMMIT_REFSPEC` | previous commit ref spec | `issue-branch:main` |
|
||||
| `CI_PREV_COMMIT_BRANCH` | previous commit branch | `main` |
|
||||
| `CI_PREV_COMMIT_SOURCE_BRANCH` | previous commit source branch (set only for pull request events) | `issue-branch` |
|
||||
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch (set only for pull request events) | `main` |
|
||||
| `CI_PREV_COMMIT_URL` | previous commit link in forge | `https://git.example.com/john-doe/my-repo/commit/15784117e4e103f36cba75a9e29da48046eb82c4` |
|
||||
| `CI_PREV_COMMIT_MESSAGE` | previous commit message | `test` |
|
||||
| `CI_PREV_COMMIT_AUTHOR` | previous commit author username | `john-doe` |
|
||||
| `CI_PREV_COMMIT_AUTHOR_EMAIL` | previous commit author email address | `john-doe@example.com` |
|
||||
| | **Previous pipeline** | |
|
||||
| `CI_PREV_PIPELINE_NUMBER` | previous pipeline number | `7` |
|
||||
| `CI_PREV_PIPELINE_PARENT` | previous pipeline number of parent pipeline | `0` |
|
||||
| `CI_PREV_PIPELINE_EVENT` | previous pipeline event (see [`event`](../20-usage/20-workflow-syntax.md#event)) | `push`, `pull_request`, `pull_request_closed`, `pull_request_metadata`, `tag`, `release`, `manual`, `cron` |
|
||||
| `CI_PREV_PIPELINE_EVENT_REASON` | previous exact reason `pull_request_metadata` event was send. it is forge instance specific and can change | `label_updated`, `milestoned`, `demilestoned`, `assigned`, `edited`, ... |
|
||||
| `CI_PREV_PIPELINE_URL` | previous pipeline link in CI | `https://ci.example.com/repos/7/pipeline/7` |
|
||||
| `CI_PREV_PIPELINE_FORGE_URL` | previous pipeline link to event in forge | `https://git.example.com/john-doe/my-repo/commit/15784117e4e103f36cba75a9e29da48046eb82c4` |
|
||||
| `CI_PREV_PIPELINE_DEPLOY_TARGET` | previous pipeline deploy target for `deployment` events | `production` |
|
||||
| `CI_PREV_PIPELINE_DEPLOY_TASK` | previous pipeline deploy task for `deployment` events | `migration` |
|
||||
| `CI_PREV_PIPELINE_STATUS` | previous pipeline status | `success`, `failure` |
|
||||
| `CI_PREV_PIPELINE_CREATED` | previous pipeline created UNIX timestamp | `1722610173` |
|
||||
| `CI_PREV_PIPELINE_STARTED` | previous pipeline started UNIX timestamp | `1722610173` |
|
||||
| `CI_PREV_PIPELINE_FINISHED` | previous pipeline finished UNIX timestamp | `1722610383` |
|
||||
| `CI_PREV_PIPELINE_AUTHOR` | previous pipeline author username | `octocat` |
|
||||
| `CI_PREV_PIPELINE_AVATAR` | previous pipeline author avatar | `https://git.example.com/avatars/5dcbcadbce6f87f8abef` |
|
||||
| |   | |
|
||||
| `CI_WORKSPACE` | Path of the workspace where source code gets cloned to | `/woodpecker/src/git.example.com/john-doe/my-repo` |
|
||||
| | **System** | |
|
||||
| `CI_SYSTEM_NAME` | name of the CI system | `woodpecker` |
|
||||
| `CI_SYSTEM_URL` | link to CI system | `https://ci.example.com` |
|
||||
| `CI_SYSTEM_HOST` | hostname of CI server | `ci.example.com` |
|
||||
| `CI_SYSTEM_VERSION` | version of the server | `2.7.0` |
|
||||
| | **Forge** | |
|
||||
| `CI_FORGE_TYPE` | name of forge | `bitbucket` , `bitbucket_dc` , `forgejo` , `gitea` , `github` , `gitlab` |
|
||||
| `CI_FORGE_URL` | root URL of configured forge | `https://git.example.com` |
|
||||
| | **Internal** - Please don't use! | |
|
||||
| `CI_SCRIPT` | Internal script path. Used to call pipeline step commands. | |
|
||||
| `CI_NETRC_USERNAME` | Credentials for private repos to be able to clone data. (Only available for specific images) | |
|
||||
| `CI_NETRC_PASSWORD` | Credentials for private repos to be able to clone data. (Only available for specific images) | |
|
||||
| `CI_NETRC_MACHINE` | Credentials for private repos to be able to clone data. (Only available for specific images) | |
|
||||
|
||||
## Global environment variables
|
||||
|
||||
If you want specific environment variables to be available in all of your pipelines use the `WOODPECKER_ENVIRONMENT` setting on the Woodpecker server. Note that these can't overwrite any existing, built-in variables.
|
||||
|
||||
```ini
|
||||
WOODPECKER_ENVIRONMENT=first_var:value1,second_var:value2
|
||||
```
|
||||
|
||||
These can be used, for example, to manage the image tag used by multiple projects.
|
||||
|
||||
```ini
|
||||
WOODPECKER_ENVIRONMENT=GOLANG_VERSION:1.18
|
||||
```
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: build
|
||||
- image: golang:1.18
|
||||
+ image: golang:${GOLANG_VERSION}
|
||||
commands:
|
||||
- [...]
|
||||
```
|
||||
|
||||
## String Substitution
|
||||
|
||||
Woodpecker provides the ability to substitute environment variables at runtime. This gives us the ability to use dynamic settings, commands and filters in our pipeline configuration.
|
||||
|
||||
Example commit substitution:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: s3
|
||||
image: woodpeckerci/plugin-s3
|
||||
settings:
|
||||
+ target: /target/${CI_COMMIT_SHA}
|
||||
```
|
||||
|
||||
Example tag substitution:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: s3
|
||||
image: woodpeckerci/plugin-s3
|
||||
settings:
|
||||
+ target: /target/${CI_COMMIT_TAG}
|
||||
```
|
||||
|
||||
## String Operations
|
||||
|
||||
Woodpecker also emulates bash string operations. This gives us the ability to manipulate the strings prior to substitution. Example use cases might include substring and stripping prefix or suffix values.
|
||||
|
||||
| OPERATION | DESCRIPTION |
|
||||
| ------------------ | ------------------------------------------------ |
|
||||
| `${param}` | parameter substitution |
|
||||
| `${param,}` | parameter substitution with lowercase first char |
|
||||
| `${param,,}` | parameter substitution with lowercase |
|
||||
| `${param^}` | parameter substitution with uppercase first char |
|
||||
| `${param^^}` | parameter substitution with uppercase |
|
||||
| `${param:pos}` | parameter substitution with substring |
|
||||
| `${param:pos:len}` | parameter substitution with substring and length |
|
||||
| `${param=default}` | parameter substitution with default |
|
||||
| `${param##prefix}` | parameter substitution with prefix removal |
|
||||
| `${param%%suffix}` | parameter substitution with suffix removal |
|
||||
| `${param/old/new}` | parameter substitution with find and replace |
|
||||
|
||||
Example variable substitution with substring:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: s3
|
||||
image: woodpeckerci/plugin-s3
|
||||
settings:
|
||||
+ target: /target/${CI_COMMIT_SHA:0:8}
|
||||
```
|
||||
|
||||
Example variable substitution strips `v` prefix from `v.1.0.0`:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: s3
|
||||
image: woodpeckerci/plugin-s3
|
||||
settings:
|
||||
+ target: /target/${CI_COMMIT_TAG##v}
|
||||
```
|
||||
|
||||
## `pull_request_metadata` specific event reason values
|
||||
|
||||
For the `pull_request_metadata` event, the exact reason a metadata change was detected is passe through in `CI_PIPELINE_EVENT_REASON`.
|
||||
|
||||
**GitLab** merges metadata updates into one webhook. Event reasons are separated by `,` as a list.
|
||||
|
||||
:::note
|
||||
Event reason values are forge-specific and may change between versions.
|
||||
:::
|
||||
|
||||
| Event | GitHub | Gitea | Forgejo | GitLab | Bitbucket | Bitbucket Datacenter | Description |
|
||||
| -------------------- | ------------------ | ------------------ | ------------------ | ------------------ | --------- | -------------------- | ------------------------------------------------------------------------------ |
|
||||
| `assigned` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | Pull request was assigned to a user |
|
||||
| `converted_to_draft` | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | Pull request was converted to a draft |
|
||||
| `demilestoned` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | Pull request was removed from a milestone |
|
||||
| `description_edited` | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | Description edited |
|
||||
| `edited` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | The title or body of a pull request was edited, or the base branch was changed |
|
||||
| `label_added` | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | Pull had no labels and now got label(s) added |
|
||||
| `label_cleared` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | All labels removed |
|
||||
| `label_updated` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | New label(s) added / label(s) changed |
|
||||
| `locked` | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | Conversation on a pull request was locked |
|
||||
| `milestoned` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | Pull request was added to a milestone |
|
||||
| `ready_for_review` | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | Draft pull request was marked as ready for review |
|
||||
| `review_requested` | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | New review was requested |
|
||||
| `title_edited` | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | Title edited |
|
||||
| `unassigned` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | User was unassigned from a pull request |
|
||||
| `unlabeled` | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | Label was removed from a pull request |
|
||||
| `unlocked` | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | Conversation on a pull request was unlocked |
|
||||
|
||||
**Bitbucket** and **Bitbucket Datacenter** [are not supported at the moment](https://github.com/woodpecker-ci/woodpecker/pull/5214).
|
||||
@@ -0,0 +1,160 @@
|
||||
# Configuration extension
|
||||
|
||||
The configuration extension can be used to modify or generate Woodpeckers pipeline configurations. You can configure an HTTP endpoint in the repository settings in the extensions tab.
|
||||
|
||||
Using such an extension can be useful if you want to:
|
||||
|
||||
<!-- cSpell:words templating,Starlark,Jsonnet -->
|
||||
|
||||
- Preprocess the original configuration file with something like Go templating
|
||||
- Convert custom attributes to Woodpecker attributes
|
||||
- Add defaults to the configuration like default steps
|
||||
- Convert configuration files from a totally different format like Gitlab CI config, Starlark, Jsonnet, ...
|
||||
- Centralize configuration for multiple repositories in one place
|
||||
|
||||
## Security
|
||||
|
||||
:::warning
|
||||
As Woodpecker will pass private information like tokens and will execute the returned configuration, it is extremely important to secure the external extension. Therefore Woodpecker signs every request. Read more about it in the [security section](./index.md#security).
|
||||
:::
|
||||
|
||||
## Global configuration
|
||||
|
||||
In addition to the ability to configure the extension per repository, you can also configure a global endpoint in the Woodpecker server configuration. This can be useful if you want to use the extension for all repositories. Be careful if
|
||||
you share your Woodpecker server with others as they will also use your configuration extension.
|
||||
|
||||
The global configuration will be called before the repository specific configuration extension if both are configured.
|
||||
|
||||
```ini title="Server"
|
||||
WOODPECKER_CONFIG_SERVICE_ENDPOINT=https://example.com/ciconfig
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
When a pipeline is triggered Woodpecker will fetch the pipeline configuration from the repository, then make a HTTP POST request to the configured extension with a JSON payload containing some data like the repository, pipeline information and the current config files retrieved from the repository. The extension can then send back modified or even new pipeline configurations following Woodpeckers official yaml format that should be used.
|
||||
|
||||
### Request
|
||||
|
||||
The extension receives an HTTP POST request with the following JSON payload:
|
||||
|
||||
```ts
|
||||
class Request {
|
||||
repo: Repo;
|
||||
pipeline: Pipeline;
|
||||
netrc: Netrc;
|
||||
configuration: {
|
||||
name: string; // filename of the configuration file
|
||||
data: string; // content of the configuration file
|
||||
}[];
|
||||
}
|
||||
```
|
||||
|
||||
Checkout the following models for more information:
|
||||
|
||||
- [repo model](https://github.com/woodpecker-ci/woodpecker/blob/main/server/model/repo.go)
|
||||
- [pipeline model](https://github.com/woodpecker-ci/woodpecker/blob/main/server/model/pipeline.go)
|
||||
- [netrc model](https://github.com/woodpecker-ci/woodpecker/blob/main/server/model/netrc.go)
|
||||
|
||||
:::tip
|
||||
The `netrc` data is pretty powerful as it contains credentials to access the repository. You can use this to clone the repository or even use the forge (Github or Gitlab, ...) API to get more information about the repository.
|
||||
:::
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": {
|
||||
"id": 100,
|
||||
"uid": "",
|
||||
"user_id": 0,
|
||||
"namespace": "",
|
||||
"name": "woodpecker-test-pipeline",
|
||||
"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-filename.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
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": ".woodpecker.yaml",
|
||||
"data": "steps:\n - name: backend\n image: alpine\n commands:\n - echo \"Hello there from Repo (.woodpecker.yaml)\"\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
The extension should respond with a JSON payload containing the new configuration files in Woodpecker's official YAML format.
|
||||
If the extension wants to keep the existing configuration files, it can respond with HTTP status `204 No Content`.
|
||||
|
||||
```ts
|
||||
class Response {
|
||||
configs: {
|
||||
name: string; // filename of the configuration file
|
||||
data: string; // content of the configuration file
|
||||
}[];
|
||||
}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"configs": [
|
||||
{
|
||||
"name": "central-override",
|
||||
"data": "steps:\n - name: backend\n image: alpine\n commands:\n - echo \"Hello there from ConfigAPI\"\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
label: 'Extensions'
|
||||
# position: 3
|
||||
collapsible: true
|
||||
collapsed: true
|
||||
link:
|
||||
type: 'doc'
|
||||
id: 'index'
|
||||
@@ -0,0 +1,34 @@
|
||||
# Extensions
|
||||
|
||||
Woodpecker allows you to replace internal logic with external extensions by using pre-defined http endpoints.
|
||||
|
||||
There is currently one type of extension available:
|
||||
|
||||
- [Configuration extension](./40-configuration-extension.md) to modify or generate pipeline configurations on the fly.
|
||||
|
||||
## Security
|
||||
|
||||
:::warning
|
||||
You need to trust the extensions as they are receiving private information like secrets and tokens and might return harmful
|
||||
data like malicious pipeline configurations that could be executed.
|
||||
:::
|
||||
|
||||
To prevent your extensions from such attacks, Woodpecker is signing all HTTP requests using [HTTP signatures](https://tools.ietf.org/html/draft-cavage-http-signatures). Woodpecker therefore uses a public-private ed25519 key pair.
|
||||
To verify the requests your extension has to verify the signature of all request using the public key with some library like [httpsign](https://github.com/yaronf/httpsign).
|
||||
You can get the public Woodpecker key by opening `http://my-woodpecker.tld/api/signature/public-key` or by visiting the Woodpecker UI, going to you repo settings and opening the extensions page.
|
||||
|
||||
## Example extensions
|
||||
|
||||
A simplistic service providing endpoints for a config and secrets extension can be found here: [https://github.com/woodpecker-ci/example-extensions](https://github.com/woodpecker-ci/example-extensions)
|
||||
|
||||
## Configuration
|
||||
|
||||
To prevent extensions from calling local services by default only external hosts / ip-addresses are allowed. You can change this behavior by setting the `WOODPECKER_EXTENSIONS_ALLOWED_HOSTS` environment variable. You can use a comma separated list of:
|
||||
|
||||
- Built-in networks:
|
||||
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
|
||||
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
|
||||
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
|
||||
- `*`: All hosts are allowed.
|
||||
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
|
||||
- (Wildcard) hosts: `example.com`, `*.example.com`, `192.168.100.*`
|
||||
@@ -114,7 +114,7 @@ steps:
|
||||
- name: debug
|
||||
image: bash
|
||||
commands:
|
||||
- source envvars
|
||||
- source ./envvars
|
||||
- echo $FOO
|
||||
```
|
||||
|
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 430 KiB After Width: | Height: | Size: 430 KiB |
|
Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 353 KiB |
|
Before Width: | Height: | Size: 351 KiB After Width: | Height: | Size: 351 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@@ -3,26 +3,11 @@
|
||||
Woodpecker provides a [Helm chart](https://github.com/woodpecker-ci/helm) for Kubernetes environments:
|
||||
|
||||
```bash
|
||||
helm install woodpecker oci://ghcr.io/woodpecker-ci/helm/woodpecker
|
||||
helm repo add woodpecker oci://ghcr.io/woodpecker-ci/helm
|
||||
helm install woodpecker woodpecker/woodpecker
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
To fetch all configurable options with detailed comments:
|
||||
|
||||
```bash
|
||||
helm show values oci://ghcr.io/woodpecker-ci/helm/woodpecker > values.yaml
|
||||
```
|
||||
|
||||
Install using custom values:
|
||||
|
||||
```bash
|
||||
helm install woodpecker \
|
||||
oci://ghcr.io/woodpecker-ci/helm/woodpecker \
|
||||
-f values.yaml
|
||||
```
|
||||
|
||||
### Metrics
|
||||
## Metrics
|
||||
|
||||
To enable metrics gathering, set the following in values.yml:
|
||||
|
||||
@@ -91,6 +91,7 @@ Woodpecker itself is not responsible for creating these packages. Please reach o
|
||||
- [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)
|
||||
- [Easypanel](https://easypanel.io/docs/templates/woodpeckerci)
|
||||
|
||||
### NixOS
|
||||
|
||||
@@ -808,6 +808,15 @@ The default setting for allowing pull requests on a repo.
|
||||
|
||||
---
|
||||
|
||||
### DEFAULT_APPROVAL_MODE
|
||||
|
||||
- Name: `WOODPECKER_DEFAULT_APPROVAL_MODE`
|
||||
- Default: `forks`
|
||||
|
||||
The default setting for the approval mode on a repo. Possible values: `none`, `forks`, `pull_requests` or `all_events`.
|
||||
|
||||
---
|
||||
|
||||
### DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS
|
||||
|
||||
- Name: `WOODPECKER_DEFAULT_CANCEL_PREVIOUS_PIPELINE_EVENTS`
|
||||
@@ -1062,6 +1071,15 @@ Specify a configuration service endpoint, see [Configuration Extension](#externa
|
||||
|
||||
---
|
||||
|
||||
### EXTENSIONS_ALLOWED_HOSTS
|
||||
|
||||
- Name: `WOODPECKER_EXTENSIONS_ALLOWED_HOSTS`
|
||||
- Default: `external`
|
||||
|
||||
Comma-separated list of hosts that are allowed to be contacted by extensions. Possible values are `loopback`, `private`, `external`, `*` or CIDR list.
|
||||
|
||||
---
|
||||
|
||||
### FORGE_TIMEOUT
|
||||
|
||||
- Name: `WOODPECKER_FORGE_TIMEOUT`
|
||||
@@ -1103,7 +1121,11 @@ Disable version check in admin web UI.
|
||||
- Name: `WOODPECKER_LOG_STORE`
|
||||
- Default: `database`
|
||||
|
||||
Where to store logs. Possible values: `database` or `file`.
|
||||
Where to store logs. Possible values:
|
||||
|
||||
- `database`: stores the logs in the database
|
||||
- `file`: stores logs in JSON files on the files system
|
||||
- `addon`: uses an [addon](./100-addons.md#log) to store logs
|
||||
|
||||
---
|
||||
|
||||
@@ -1112,7 +1134,10 @@ Where to store logs. Possible values: `database` or `file`.
|
||||
- Name: `WOODPECKER_LOG_STORE_FILE_PATH`
|
||||
- Default: none
|
||||
|
||||
Directory to store logs in if [`WOODPECKER_LOG_STORE`](#log_store) is `file`.
|
||||
If [`WOODPECKER_LOG_STORE`](#log_store) is:
|
||||
|
||||
- `file`: Directory to store logs in
|
||||
- `addon`: The path to the addon executable
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Addons
|
||||
|
||||
Addons can be used to extend the Woodpecker server. Currently, they can be used for forges and the log service.
|
||||
|
||||
:::warning
|
||||
Addon forges are still experimental. Their implementation can change and break at any time.
|
||||
:::
|
||||
|
||||
:::danger
|
||||
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
|
||||
|
||||
To use an addon forge, download the correct addon version.
|
||||
|
||||
### Forge
|
||||
|
||||
Use this in your `.env`:
|
||||
|
||||
```ini
|
||||
WOODPECKER_ADDON_FORGE=/path/to/your/addon/forge/file
|
||||
```
|
||||
|
||||
In case you run Woodpecker as container, you probably want to mount the addon binary to `/opt/addons/`.
|
||||
|
||||
#### List of addon forges
|
||||
|
||||
- [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).
|
||||
|
||||
### Log
|
||||
|
||||
Use this in your `.env`:
|
||||
|
||||
```ini
|
||||
WOODPECKER_LOG_STORE=addon
|
||||
WOODPECKER_LOG_STORE_FILE_PATH=/path/to/your/addon/forge/file
|
||||
```
|
||||
|
||||
## Developing addon forges
|
||||
|
||||
See [Addons](../../92-development/100-addons.md).
|
||||
@@ -19,6 +19,8 @@ The following metadata labels are supported:
|
||||
- `woodpecker-ci.org/repo-full-name`
|
||||
- `woodpecker-ci.org/branch`
|
||||
- `woodpecker-ci.org/org-id`
|
||||
- `woodpecker-ci.org/task-uuid`
|
||||
- `woodpecker-ci.org/step`
|
||||
|
||||
## Private registries
|
||||
|
||||
@@ -250,6 +252,15 @@ backend_options:
|
||||
localhostProfile: k8s-apparmor-example-deny-write
|
||||
```
|
||||
|
||||
or configure a specific `fsGroupChangePolicy` (Kubernetes defaults to 'Always')
|
||||
|
||||
```yaml
|
||||
backend_options:
|
||||
kubernetes:
|
||||
securityContext:
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
```
|
||||
|
||||
:::note
|
||||
The feature requires Kubernetes v1.30 or above.
|
||||
:::
|
||||
@@ -380,6 +391,24 @@ Determines if Pod annotations can be defined from a step's backend options.
|
||||
|
||||
---
|
||||
|
||||
### BACKEND_K8S_POD_TOLERATIONS
|
||||
|
||||
- Name: `WOODPECKER_BACKEND_K8S_POD_TOLERATIONS`
|
||||
- Default: none
|
||||
|
||||
Additional tolerations to apply to worker Pods. Must be a YAML object, e.g. `[{"effect":"NoSchedule","key":"jobs","operator":"Exists"}]`.
|
||||
|
||||
---
|
||||
|
||||
### BACKEND_K8S_POD_TOLERATIONS_ALLOW_FROM_STEP
|
||||
|
||||
- Name: `WOODPECKER_BACKEND_K8S_POD_TOLERATIONS_ALLOW_FROM_STEP`
|
||||
- Default: `true`
|
||||
|
||||
Determines if Pod tolerations can be defined from a step's backend options.
|
||||
|
||||
---
|
||||
|
||||
### BACKEND_K8S_POD_NODE_SELECTOR
|
||||
|
||||
- Name: `WOODPECKER_BACKEND_K8S_POD_NODE_SELECTOR`
|
||||
@@ -404,3 +433,12 @@ Determines if containers must be required to run as non-root users.
|
||||
- Default: none
|
||||
|
||||
Secret names to pull images from private repositories. See, how to [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).
|
||||
|
||||
---
|
||||
|
||||
### BACKEND_K8S_PRIORITY_CLASS
|
||||
|
||||
- Name: `WOODPECKER_BACKEND_K8S_PRIORITY_CLASS`
|
||||
- Default: none, which will use the default priority class configured in Kubernetes
|
||||
|
||||
Which [Kubernetes PriorityClass](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/priority-class-v1/) to assign to created job pods.
|
||||
@@ -0,0 +1,18 @@
|
||||
# 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: |
|
||||
| [Event: Pull-Request-Metadata](../../../20-usage/50-environment.md#pull_request_metadata-specific-event-reason-values) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :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: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
¹ The deployment event can be triggered for all forges from Woodpecker directly. However, only GitHub can trigger them using webhooks.
|
||||
|
||||
In addition to this, Woodpecker supports [addon forges](../100-addons.md) 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.
|
||||
@@ -84,6 +84,10 @@ Configures the Bitbucket OAuth client secret. This is used to authorize access.
|
||||
|
||||
Read the value for `WOODPECKER_BITBUCKET_SECRET` from the specified filepath
|
||||
|
||||
## Known Issues
|
||||
|
||||
Bitbucket build keys are limited to 40 characters: [issue #5176](https://github.com/woodpecker-ci/woodpecker/issues/5176). If a job exceeds this limit, you can adjust the key by modifying the `WOODPECKER_STATUS_CONTEXT` or `WOODPECKER_STATUS_CONTEXT_FORMAT` variables. See the [environment variables documentation](../10-server.md#environment-variables) for more details.
|
||||
|
||||
## Missing Features
|
||||
|
||||
Path filters for pull requests are not supported. We are interested in patches to include this functionality.
|
||||
@@ -22,6 +22,7 @@ To enable Bitbucket Server you should configure the Woodpecker container using t
|
||||
+ - WOODPECKER_BITBUCKET_DC_CLIENT_ID=xxx
|
||||
+ - WOODPECKER_BITBUCKET_DC_CLIENT_SECRET=yyy
|
||||
+ - WOODPECKER_BITBUCKET_DC_URL=http://stash.mycompany.com
|
||||
+ - WOODPECKER_BITBUCKET_DC_ENABLE_OAUTH2_SCOPE_PROJECT_ADMIN=true
|
||||
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
@@ -124,3 +125,12 @@ Read the value for `WOODPECKER_BITBUCKET_DC_GIT_PASSWORD` from the specified fil
|
||||
- Default: `false`
|
||||
|
||||
Configure if SSL verification should be skipped.
|
||||
|
||||
---
|
||||
|
||||
### BITBUCKET_DC_ENABLE_OAUTH2_SCOPE_PROJECT_ADMIN
|
||||
|
||||
- Name: `WOODPECKER_BITBUCKET_DC_ENABLE_OAUTH2_SCOPE_PROJECT_ADMIN`
|
||||
- Default: `false`
|
||||
|
||||
When enabled, the Bitbucket Application Link for Woodpecker should include the `PROJECT_ADMIN` scope. Enabling this feature flag will allow the users of Bitbucket Datacenter to use organization secrets and properly list repositories within the organization.
|
||||
|
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 |
@@ -155,7 +155,8 @@ 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.
|
||||
If you use `!` as key prefix it is mandatory for the workflow to have that label set (without !) set and matched.
|
||||
By default, agents provide four additional labels `platform=os/arch`, `hostname=my-agent`, `backend=my-backend` 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).
|
||||
|
||||
---
|
||||
|
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 |