mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-02-18 04:15:15 +00:00
Merge branch 'main' into arrange-pipeline-list
This commit is contained in:
commit
2e76c671fa
337 changed files with 12747 additions and 10461 deletions
11
.cspell.json
11
.cspell.json
|
@ -15,6 +15,7 @@
|
|||
"apimachinery",
|
||||
"Archlinux",
|
||||
"autoincr",
|
||||
"automerge",
|
||||
"autoscaler",
|
||||
"backporting",
|
||||
"backports",
|
||||
|
@ -71,6 +72,8 @@
|
|||
"gomod",
|
||||
"gonic",
|
||||
"GOPATH",
|
||||
"Gource",
|
||||
"handlebargh",
|
||||
"HEALTHCHECK",
|
||||
"healthz",
|
||||
"Hetzner",
|
||||
|
@ -159,8 +162,10 @@
|
|||
"seccomp",
|
||||
"secprofile",
|
||||
"securecookie",
|
||||
"selfhosted",
|
||||
"sess",
|
||||
"shellescape",
|
||||
"sigstore",
|
||||
"Sonatype",
|
||||
"SSHURL",
|
||||
"sslmode",
|
||||
|
@ -184,6 +189,7 @@
|
|||
"Traefik",
|
||||
"tseslint",
|
||||
"ttlcache",
|
||||
"TUNEIT",
|
||||
"Tunnelmole",
|
||||
"typecheck",
|
||||
"Typeflag",
|
||||
|
@ -195,6 +201,7 @@
|
|||
"varz",
|
||||
"Vieter",
|
||||
"virtualisation",
|
||||
"visualisation",
|
||||
"vite",
|
||||
"vueuse",
|
||||
"waivable",
|
||||
|
@ -230,7 +237,7 @@
|
|||
"Makefile",
|
||||
"flake.nix",
|
||||
"go.mod",
|
||||
"pipeline/rpc/proto/woodpecker.pb.go",
|
||||
"**/*.pb.go",
|
||||
"server/store/datastore/migration/**/*",
|
||||
"web/components.d.ts",
|
||||
"web/src/assets/locales/**/*",
|
||||
|
@ -238,13 +245,13 @@
|
|||
"**/testdata/**",
|
||||
"docs/versioned_docs/",
|
||||
"package.json",
|
||||
"91-migrations.md",
|
||||
// generated
|
||||
"go.sum",
|
||||
"flake.lock",
|
||||
"pnpm-lock.yaml",
|
||||
"**/node_modules/**/*",
|
||||
"cmd/server/docs/docs.go",
|
||||
"renovate.json",
|
||||
// TODO: remove the following
|
||||
"docs/**/*.js",
|
||||
"docs/**/*.ts"
|
||||
|
|
11
.github/pull_request_template.md
vendored
Normal file
11
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!--
|
||||
|
||||
Please check the following tips:
|
||||
1. Avoid using force-push and commands that require it (such as `commit --amend` and `rebase origin/main`). This makes it more difficult for the maintainers to review your work. Add new commits on top of the current branch, and merge the new state of `main` into your branch with plain `merge`.
|
||||
2. Provide a meaningful title for this pull request. It will be used as the commit message when this pull request is merged. Add as many commits as you like with any messages you like, they will be squashed into one commit.
|
||||
3. If this pull request fixes an issue, refer to the issue with messages like `Closes #1234`, or `Fixes #1234` in the pull description.
|
||||
4. Please check that you are targeting the `main` branch. Pull requests on release branches are only allowed for backports.
|
||||
5. Make sure you have read contribution guidelines: https://woodpecker-ci.org/docs/development/getting-started
|
||||
6. It is recommended to enable "Allow edits by maintainers", so maintainers can help you more easily.
|
||||
|
||||
-->
|
13
.github/renovate.json
vendored
13
.github/renovate.json
vendored
|
@ -1,12 +1,14 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>woodpecker-ci/renovate-config"],
|
||||
"automergeType": "pr",
|
||||
"enabledManagers": ["woodpecker"],
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"fileMatch": ["shared/constant/constant.go"],
|
||||
"matchStrings": [
|
||||
"//\\s*renovate:\\s*datasource=(?<datasource>.*?) depName=(?<depName>.*?)( versioning=(?<versioning>.*?))?\\s+DefaultCloneImage = \"docker.io/woodpeckerci/plugin-git:(?<currentValue>.*)\""
|
||||
"//\\s*renovate:\\s*datasource=(?<datasource>.*?) depName=(?<depName>.*?)( versioning=(?<versioning>.*?))?\\s+DefaultClonePlugin = \"docker.io/woodpeckerci/plugin-git:(?<currentValue>.*)\""
|
||||
],
|
||||
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}"
|
||||
}
|
||||
|
@ -29,8 +31,8 @@
|
|||
},
|
||||
{
|
||||
"groupName": "golang-lang",
|
||||
"matchPackagePatterns": ["^golang$", "xgo"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchPackageNames": ["/^golang$/", "/xgo/"]
|
||||
},
|
||||
{
|
||||
"groupName": "golang-packages",
|
||||
|
@ -60,9 +62,10 @@
|
|||
"matchFileNames": ["docs/**/package.json"]
|
||||
},
|
||||
{
|
||||
"description": "Extract version from xgo container tags",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchPackagePatterns": ["xgo"],
|
||||
"versioning": "regex:^go-(?<major>\\d+)?(\\.(?<minor>\\d+))?(\\.(?<patch>\\d+))$"
|
||||
"versioning": "regex:^go-(?<major>\\d+)\\.(?<minor>\\d+)\\.x$",
|
||||
"matchPackageNames": ["/techknowlogick/xgo/"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
1
.lycheeignore
Normal file
1
.lycheeignore
Normal file
|
@ -0,0 +1 @@
|
|||
https://stackoverflow.com/*
|
|
@ -5,16 +5,16 @@ repos:
|
|||
- id: check-hooks-apply
|
||||
- id: check-useless-excludes
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.59.1
|
||||
rev: v1.61.0
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.41.0
|
||||
rev: v0.42.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
exclude: '^(docs/versioned_docs/.*|CHANGELOG.md)$'
|
||||
|
@ -24,7 +24,7 @@ repos:
|
|||
- id: checkmake
|
||||
exclude: '^docker/Dockerfile.make$' # actually a Dockerfile and not a makefile
|
||||
- repo: https://github.com/hadolint/hadolint
|
||||
rev: v2.13.0-beta
|
||||
rev: v2.13.1-beta
|
||||
hooks:
|
||||
- id: hadolint
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
|
|
|
@ -2,12 +2,14 @@ when:
|
|||
- event: tag
|
||||
- event: pull_request
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
path: Makefile
|
||||
path:
|
||||
- Makefile
|
||||
- .woodpecker/binaries.yaml
|
||||
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:22-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.x'
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.23.1'
|
||||
|
||||
# cspell:words bindata netgo
|
||||
|
||||
|
@ -97,7 +99,7 @@ steps:
|
|||
release:
|
||||
depends_on:
|
||||
- checksums
|
||||
image: woodpeckerci/plugin-release:0.1.0
|
||||
image: woodpeckerci/plugin-release:0.2.1
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: github_token
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:22-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.x'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:4.1.0'
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.23.1'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:5.0.0'
|
||||
- &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,7 +1,7 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:21-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.19'
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.20'
|
||||
- path: &when_path
|
||||
- 'docs/**'
|
||||
- '.woodpecker/docs.yaml'
|
||||
|
@ -60,7 +60,7 @@ steps:
|
|||
- event: manual
|
||||
|
||||
deploy-preview:
|
||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.0
|
||||
image: docker.io/woodpeckerci/plugin-surge-preview:1.3.2
|
||||
settings:
|
||||
path: 'docs/build/'
|
||||
surge_token:
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
steps:
|
||||
release-helper:
|
||||
image: woodpeckerci/plugin-ready-release-go:1.2.0
|
||||
pull: true
|
||||
- name: release-helper
|
||||
image: woodpeckerci/plugin-ready-release-go:2.0.0
|
||||
settings:
|
||||
release_branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
release_branch: ${CI_COMMIT_BRANCH}
|
||||
forge_type: github
|
||||
git_email: woodpecker-bot@obermui.de
|
||||
github_token:
|
||||
|
@ -11,6 +10,8 @@ steps:
|
|||
|
||||
when:
|
||||
- event: push
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
- release/*
|
||||
- event: manual
|
||||
evaluate: 'TASK == "release-helper"'
|
||||
|
|
|
@ -6,19 +6,21 @@ when:
|
|||
- renovate/*
|
||||
|
||||
variables:
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.1.0
|
||||
- &trivy_plugin docker.io/woodpeckerci/plugin-trivy:1.2.0
|
||||
|
||||
steps:
|
||||
backend:
|
||||
depends_on: []
|
||||
image: *trivy_plugin
|
||||
settings:
|
||||
server: server
|
||||
skip-dirs: web/,docs/
|
||||
|
||||
docs:
|
||||
depends_on: []
|
||||
image: *trivy_plugin
|
||||
settings:
|
||||
server: server
|
||||
skip-dirs: node_modules/,plugins/woodpecker-plugins/node_modules/
|
||||
dir: docs/
|
||||
|
||||
|
@ -26,5 +28,18 @@ steps:
|
|||
depends_on: []
|
||||
image: *trivy_plugin
|
||||
settings:
|
||||
server: server
|
||||
skip-dirs: node_modules/
|
||||
dir: web/
|
||||
|
||||
services:
|
||||
server:
|
||||
image: *trivy_plugin
|
||||
# settings:
|
||||
# service: true
|
||||
# db-repository: docker.io/aquasec/trivy-db:2
|
||||
environment:
|
||||
PLUGIN_SERVICE: 'true'
|
||||
PLUGIN_DB_REPOSITORY: 'docker.io/aquasec/trivy-db:2'
|
||||
ports:
|
||||
- 10000
|
||||
|
|
|
@ -13,7 +13,7 @@ steps:
|
|||
branch: renovate/*
|
||||
|
||||
- name: spellcheck
|
||||
image: docker.io/node:22-alpine
|
||||
image: docker.io/node:23-alpine
|
||||
depends_on: []
|
||||
commands:
|
||||
- corepack enable
|
||||
|
@ -23,15 +23,15 @@ steps:
|
|||
- tree --gitignore -I 012_columns_rename_procs_to_steps.go -I versioned_docs -I '*opensource.svg'| pnpx cspell lint --no-progress stdin
|
||||
|
||||
- name: prettier
|
||||
image: docker.io/woodpeckerci/plugin-prettier:0.1.0
|
||||
image: docker.io/woodpeckerci/plugin-prettier:0.2.0
|
||||
depends_on: []
|
||||
settings:
|
||||
version: 3.2.5
|
||||
version: 3.3.3
|
||||
|
||||
- name: links
|
||||
image: docker.io/lycheeverse/lychee:0.15.1
|
||||
depends_on: []
|
||||
commands:
|
||||
- lychee pipeline/frontend/yaml/linter/schema/schema.json
|
||||
- lychee --exclude localhost docs/docs/
|
||||
- lychee --exclude localhost docs/src/pages/
|
||||
- lychee --user-agent "curl/8.4.0" --exclude localhost docs/docs/
|
||||
- lychee --user-agent "curl/8.4.0" --exclude localhost docs/src/pages/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &when
|
||||
- path: &when_path # related config files
|
||||
- '.woodpecker/test.yaml'
|
||||
|
@ -40,6 +40,7 @@ steps:
|
|||
- go run go.woodpecker-ci.org/woodpecker/v2/cmd/cli lint
|
||||
environment:
|
||||
WOODPECKER_DISABLE_UPDATE_CHECK: true
|
||||
WOODPECKER_PLUGINS_PRIVILEGED: 'docker.io/woodpeckerci/plugin-docker-buildx:5.0.0'
|
||||
when:
|
||||
- event: pull_request
|
||||
path:
|
||||
|
@ -128,7 +129,7 @@ steps:
|
|||
- test
|
||||
- sqlite
|
||||
pull: true
|
||||
image: docker.io/woodpeckerci/plugin-codecov:2.1.2
|
||||
image: docker.io/woodpeckerci/plugin-codecov:2.1.5
|
||||
settings:
|
||||
files:
|
||||
- agent-coverage.out
|
||||
|
@ -144,7 +145,7 @@ steps:
|
|||
|
||||
services:
|
||||
postgres:
|
||||
image: docker.io/postgres:16
|
||||
image: docker.io/postgres:17
|
||||
ports: ['5432']
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
|
@ -152,7 +153,7 @@ services:
|
|||
when: *when
|
||||
|
||||
mysql:
|
||||
image: docker.io/mysql:8.2.0
|
||||
image: docker.io/mysql:9.1.0
|
||||
ports: ['3306']
|
||||
environment:
|
||||
MYSQL_DATABASE: test
|
||||
|
|
|
@ -6,7 +6,7 @@ when:
|
|||
- renovate/*
|
||||
|
||||
variables:
|
||||
- &node_image 'docker.io/node:22-alpine'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &when
|
||||
path:
|
||||
# related config files
|
||||
|
@ -58,6 +58,7 @@ steps:
|
|||
test:
|
||||
depends_on:
|
||||
- install-dependencies
|
||||
- format-check # wait for it else test artifacts are falsely detected as wrong
|
||||
image: *node_image
|
||||
directory: web/
|
||||
commands:
|
||||
|
|
66
CHANGELOG.md
66
CHANGELOG.md
|
@ -1,5 +1,71 @@
|
|||
# Changelog
|
||||
|
||||
## [2.7.2](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.7.2) - 2024-11-03
|
||||
|
||||
### Important
|
||||
|
||||
To secure your instance, set `WOODPECKER_PLUGINS_PRIVILEGED` to only allow specific versions of the `woodpeckerci/plugin-docker-buildx` plugin, use version 5.0.0 or above. This prevents older, potentially unstable versions from being privileged.
|
||||
|
||||
For example, to allow only version 5.0.0, use:
|
||||
|
||||
```bash
|
||||
WOODPECKER_PLUGINS_PRIVILEGED=woodpeckerci/plugin-docker-buildx:5.0.0
|
||||
```
|
||||
|
||||
To allow multiple versions, you can separate them with commas:
|
||||
|
||||
```bash
|
||||
WOODPECKER_PLUGINS_PRIVILEGED=woodpeckerci/plugin-docker-buildx:5.0.0,woodpeckerci/plugin-docker-buildx:5.1.0
|
||||
```
|
||||
|
||||
This setup ensures only specified, stable plugin versions are given privileged access.
|
||||
|
||||
Read more about it in [#4213](https://github.com/woodpecker-ci/woodpecker/pull/4213)
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@6543, @anbraten, @j04n-f, @pat-s, @qwerty287
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- Chore(deps): update dependency vite to v5.4.6 [security] ([#4163](https://github.com/woodpecker-ci/woodpecker/pull/4163)) [[#4187](https://github.com/woodpecker-ci/woodpecker/pull/4187)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Don't parse forge config files multiple times if no error occured ([#4272](https://github.com/woodpecker-ci/woodpecker/pull/4272)) [[#4273](https://github.com/woodpecker-ci/woodpecker/pull/4273)]
|
||||
- Fix repo/owner parsing for gitlab ([#4255](https://github.com/woodpecker-ci/woodpecker/pull/4255)) [[#4261](https://github.com/woodpecker-ci/woodpecker/pull/4261)]
|
||||
- Run queue.process() in background [[#4115](https://github.com/woodpecker-ci/woodpecker/pull/4115)]
|
||||
- Only update agent.LastWork if not done recently ([#4031](https://github.com/woodpecker-ci/woodpecker/pull/4031)) [[#4100](https://github.com/woodpecker-ci/woodpecker/pull/4100)]
|
||||
|
||||
### Misc
|
||||
|
||||
- Backport JS dependency updates [[#4189](https://github.com/woodpecker-ci/woodpecker/pull/4189)]
|
||||
|
||||
## [2.7.1](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.7.1) - 2024-09-07
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@6543, @anbraten, @j04n-f, @qwerty287
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- Lint privileged plugin match and allow to be set empty [[#4084](https://github.com/woodpecker-ci/woodpecker/pull/4084)]
|
||||
- Allow admins to specify privileged plugins by name **and tag** [[#4076](https://github.com/woodpecker-ci/woodpecker/pull/4076)]
|
||||
- Warn if using secrets/env with plugin [[#4039](https://github.com/woodpecker-ci/woodpecker/pull/4039)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Set refspec for gitlab MR [[#4021](https://github.com/woodpecker-ci/woodpecker/pull/4021)]
|
||||
- Change Bitbucket PR hook to point the source branch, commit & ref [[#3965](https://github.com/woodpecker-ci/woodpecker/pull/3965)]
|
||||
- Add updated, merged and declined events to bb webhook activation [[#3963](https://github.com/woodpecker-ci/woodpecker/pull/3963)]
|
||||
- Fix login via navbar [[#3962](https://github.com/woodpecker-ci/woodpecker/pull/3962)]
|
||||
- Fix panic if forge is unreachable [[#3944](https://github.com/woodpecker-ci/woodpecker/pull/3944)]
|
||||
- Fix org settings page [[#4093](https://github.com/woodpecker-ci/woodpecker/pull/4093)]
|
||||
|
||||
### Misc
|
||||
|
||||
- Bump github.com/docker/docker from v24.0.9 to v24.0.9+30 [[#4077](https://github.com/woodpecker-ci/woodpecker/pull/4077)]
|
||||
|
||||
## [2.7.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.7.0) - 2024-07-18
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
|
3
Makefile
3
Makefile
|
@ -39,7 +39,8 @@ 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)
|
||||
XGO_VERSION ?= go-1.20.x
|
||||
# renovate: datasource=docker depName=docker.io/techknowlogick/xgo
|
||||
XGO_VERSION ?= go-1.22.x
|
||||
CGO_CFLAGS ?= $(shell go env CGO_CFLAGS)
|
||||
endif
|
||||
CGO_CFLAGS ?=
|
||||
|
|
57
README.md
57
README.md
|
@ -43,55 +43,48 @@
|
|||
</p>
|
||||
<br/>
|
||||
|
||||
Woodpecker is a simple yet powerful CI/CD engine with great extensibility.
|
||||
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
|
||||
|
||||
![woodpecker](docs/docs/woodpecker.png)
|
||||
![woodpecker](docs/woodpecker.png)
|
||||
|
||||
## 🫶 Support
|
||||
## Installation & Resources
|
||||
|
||||
Please consider donating and become a backer. 🙏 [[Become a backer](https://opencollective.com/woodpecker-ci#category-CONTRIBUTE)]
|
||||
Woodpecker can be installed in various ways (see the [Installation Instructions](https://woodpecker-ci.org/docs/administration/getting-started)) and runs with SQLite as database by default.
|
||||
It requires around 100 MB of RAM (Server) and 30 MB (Agent) at runtime in idle mode.
|
||||
|
||||
## Support
|
||||
|
||||
You can support the project by becoming a backer on [Open Collective](https://opencollective.com/woodpecker-ci#category-CONTRIBUTE) or via [GitHub Sponsors](https://github.com/sponsors/woodpecker-ci).
|
||||
|
||||
<a href="https://opencollective.com/woodpecker-ci" target="_blank"><img src="https://opencollective.com/woodpecker-ci/backers.svg?width=890" alt="Open Collective backers"></a>
|
||||
|
||||
## 📖 Documentation
|
||||
## Documentation
|
||||
|
||||
<https://woodpecker-ci.org/>
|
||||
Our documentation can be found at <https://woodpecker-ci.org/docs/intro>.
|
||||
|
||||
## ✨ Contribute
|
||||
## Translation
|
||||
|
||||
See [Contributing Guide](https://github.com/woodpecker-ci/.github/blob/main/CONTRIBUTING.md)
|
||||
We have a self-hosted [Weblate](https://weblate.org/en/) instance at [translate.woodpecker-ci.org](https://translate.woodpecker-ci.org).
|
||||
|
||||
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://woodpecker-ci.org/docs/next/development/getting-started#gitpod)
|
||||
An overview of the current translation state is available at <https://translate.woodpecker-ci.org/projects/woodpecker-ci/#languages>.
|
||||
|
||||
## 📣 Translate
|
||||
## Public Woodpecker Instances
|
||||
|
||||
We use an own [Weblate](https://weblate.org/en/) instance at [translate.woodpecker-ci.org](https://translate.woodpecker-ci.org).
|
||||
Woodpecker is used as the main CI/CD engine at [Codeberg](https://codeberg.org), an alternative Git hosting platform with a focus on privacy and free software development.
|
||||
|
||||
<a href="https://translate.woodpecker-ci.org/engage/woodpecker-ci/">
|
||||
<img src="https://translate.woodpecker-ci.org/widgets/woodpecker-ci/-/ui/multi-blue.svg" alt="Translation status" />
|
||||
</a>
|
||||
## Plugins
|
||||
|
||||
## 👋 Who uses Woodpecker?
|
||||
Woodpecker can be extended via plugins.
|
||||
The [plugin overview website](https://woodpecker-ci.org/plugins) helps browsing available plugins.
|
||||
It combines both plugins by the Woodpecker core team and community-maintained ones.
|
||||
|
||||
Woodpecker is used by [itself](https://ci.woodpecker-ci.org/woodpecker/woodpecker-ci/), multiple well-known companies, organizations like [Codeberg](https://codeberg.org), hobbyists and many others.
|
||||
## Star History
|
||||
|
||||
Leave a [comment](https://github.com/woodpecker-ci/woodpecker/discussions/2149) if you're using it as well.
|
||||
|
||||
Also consider using the topic `WoodpeckerCI` in your repository, so others can learn from your config and use the hashtag `#WoodpeckerCI` when talking about the project on social media!
|
||||
|
||||
Here are some places where people mention Woodpecker:
|
||||
|
||||
- [GitHub](https://github.com/topics/WoodpeckerCI)
|
||||
- [Codeberg](https://codeberg.org/explore/repos?q=woodpeckerci&topic=1)
|
||||
- [Twitter](https://twitter.com/search?q=%23WoodpeckerCI&src=typed_query)
|
||||
- [Fediverse](https://mastodon.social/tags/WoodpeckerCI)
|
||||
|
||||
## ✨ Stars over time
|
||||
|
||||
[![Stargazers over time](https://starchart.cc/woodpecker-ci/woodpecker.svg)](https://starchart.cc/woodpecker-ci/woodpecker)
|
||||
[![Star History Chart](https://api.star-history.com/svg?repos=woodpecker-ci/woodpecker&type=Date)](https://star-history.com/#woodpecker-ci/woodpecker&Date)
|
||||
|
||||
## License
|
||||
|
||||
Woodpecker is Apache 2.0 licensed with the source files in this repository having a header indicating which license they are under and what copyrights apply.
|
||||
Woodpecker is Apache 2.0 licensed.
|
||||
The source files have a header indicating which license they are under and what copyrights apply.
|
||||
|
||||
Files under the `docs/` folder are licensed under Creative Commons Attribution-ShareAlike 4.0 International Public License.
|
||||
Everything in `docs/` is licensed under the Creative Commons Attribution-ShareAlike 4.0 International Public License.
|
||||
|
|
|
@ -26,19 +26,12 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
|
||||
)
|
||||
|
||||
const (
|
||||
// Store not more than 1mb in a log-line as 4mb is the limit of a grpc message
|
||||
// and log-lines needs to be parsed by the browsers later on.
|
||||
maxLogLineLength = 1024 * 1024 // 1mb
|
||||
)
|
||||
|
||||
func (r *Runner) createLogger(_logger zerolog.Logger, uploads *sync.WaitGroup, workflow *rpc.Workflow) pipeline.Logger {
|
||||
return func(step *backend.Step, rc io.ReadCloser) error {
|
||||
defer rc.Close()
|
||||
|
||||
logger := _logger.With().
|
||||
Str("image", step.Image).
|
||||
Str("workflow_id", workflow.ID).
|
||||
Logger()
|
||||
|
||||
uploads.Add(1)
|
||||
|
@ -51,7 +44,7 @@ func (r *Runner) createLogger(_logger zerolog.Logger, uploads *sync.WaitGroup, w
|
|||
logger.Debug().Msg("log stream opened")
|
||||
|
||||
logStream := log.NewLineWriter(r.client, step.UUID, secrets...)
|
||||
if err := log.CopyLineByLine(logStream, rc, maxLogLineLength); err != nil {
|
||||
if err := log.CopyLineByLine(logStream, rc, pipeline.MaxLogLineLength); err != nil {
|
||||
logger.Error().Err(err).Msg("copy limited logStream part")
|
||||
}
|
||||
|
||||
|
|
|
@ -25,29 +25,44 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
grpcproto "google.golang.org/protobuf/proto"
|
||||
|
||||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/proto"
|
||||
)
|
||||
|
||||
// Set grpc version on compile time to compare against server version response.
|
||||
const ClientGrpcVersion int32 = proto.Version
|
||||
const (
|
||||
// Set grpc version on compile time to compare against server version response.
|
||||
ClientGrpcVersion int32 = proto.Version
|
||||
|
||||
// Maximum size of an outgoing log message.
|
||||
// Picked to prevent it from going over GRPC size limit (4 MiB) with a large safety margin.
|
||||
maxLogBatchSize int = 1 * 1024 * 1024
|
||||
|
||||
// Maximum amount of time between sending consecutive batched log messages.
|
||||
// Controls the delay between the CI job generating a log record, and web users receiving it.
|
||||
maxLogFlushPeriod time.Duration = time.Second
|
||||
)
|
||||
|
||||
type client struct {
|
||||
client proto.WoodpeckerClient
|
||||
conn *grpc.ClientConn
|
||||
logs chan *proto.LogEntry
|
||||
}
|
||||
|
||||
// NewGrpcClient returns a new grpc Client.
|
||||
func NewGrpcClient(conn *grpc.ClientConn) rpc.Peer {
|
||||
func NewGrpcClient(ctx context.Context, conn *grpc.ClientConn) rpc.Peer {
|
||||
client := new(client)
|
||||
client.client = proto.NewWoodpeckerClient(conn)
|
||||
client.conn = conn
|
||||
client.logs = make(chan *proto.LogEntry, 10) // max memory use: 10 lines * 1 MiB
|
||||
go client.processLogs(ctx)
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *client) Close() error {
|
||||
close(c.logs)
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
|
@ -72,13 +87,13 @@ func (c *client) Version(ctx context.Context) (*rpc.Version, error) {
|
|||
}
|
||||
|
||||
// Next returns the next workflow in the queue.
|
||||
func (c *client) Next(ctx context.Context, f rpc.Filter) (*rpc.Workflow, error) {
|
||||
func (c *client) Next(ctx context.Context, filter rpc.Filter) (*rpc.Workflow, error) {
|
||||
var res *proto.NextResponse
|
||||
var err error
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.NextRequest)
|
||||
req.Filter = new(proto.Filter)
|
||||
req.Filter.Labels = f.Labels
|
||||
req.Filter.Labels = filter.Labels
|
||||
for {
|
||||
res, err = c.client.Next(ctx, req)
|
||||
if err == nil {
|
||||
|
@ -135,10 +150,10 @@ func (c *client) Next(ctx context.Context, f rpc.Filter) (*rpc.Workflow, error)
|
|||
}
|
||||
|
||||
// Wait blocks until the workflow is complete.
|
||||
func (c *client) Wait(ctx context.Context, id string) (err error) {
|
||||
func (c *client) Wait(ctx context.Context, workflowID string) (err error) {
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.WaitRequest)
|
||||
req.Id = id
|
||||
req.Id = workflowID
|
||||
for {
|
||||
_, err = c.client.Wait(ctx, req)
|
||||
if err == nil {
|
||||
|
@ -273,10 +288,10 @@ func (c *client) Done(ctx context.Context, workflowID string, state rpc.Workflow
|
|||
}
|
||||
|
||||
// Extend extends the workflow deadline.
|
||||
func (c *client) Extend(ctx context.Context, id string) (err error) {
|
||||
func (c *client) Extend(ctx context.Context, workflowID string) (err error) {
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.ExtendRequest)
|
||||
req.Id = id
|
||||
req.Id = workflowID
|
||||
for {
|
||||
_, err = c.client.Extend(ctx, req)
|
||||
if err == nil {
|
||||
|
@ -317,10 +332,10 @@ func (c *client) Extend(ctx context.Context, id string) (err error) {
|
|||
}
|
||||
|
||||
// Update updates the workflow state.
|
||||
func (c *client) Update(ctx context.Context, id string, state rpc.StepState) (err error) {
|
||||
func (c *client) Update(ctx context.Context, workflowID string, state rpc.StepState) (err error) {
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.UpdateRequest)
|
||||
req.Id = id
|
||||
req.Id = workflowID
|
||||
req.State = new(proto.StepState)
|
||||
req.State.StepUuid = state.StepUUID
|
||||
req.State.Started = state.Started
|
||||
|
@ -367,18 +382,69 @@ func (c *client) Update(ctx context.Context, id string, state rpc.StepState) (er
|
|||
return nil
|
||||
}
|
||||
|
||||
// Log writes the workflow log entry.
|
||||
func (c *client) Log(ctx context.Context, logEntry *rpc.LogEntry) (err error) {
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.LogRequest)
|
||||
req.LogEntry = new(proto.LogEntry)
|
||||
req.LogEntry.StepUuid = logEntry.StepUUID
|
||||
req.LogEntry.Data = logEntry.Data
|
||||
req.LogEntry.Line = int32(logEntry.Line)
|
||||
req.LogEntry.Time = logEntry.Time
|
||||
req.LogEntry.Type = int32(logEntry.Type)
|
||||
// EnqueueLog queues the log entry to be written in a batch later.
|
||||
func (c *client) EnqueueLog(logEntry *rpc.LogEntry) {
|
||||
c.logs <- &proto.LogEntry{
|
||||
StepUuid: logEntry.StepUUID,
|
||||
Data: logEntry.Data,
|
||||
Line: int32(logEntry.Line),
|
||||
Time: logEntry.Time,
|
||||
Type: int32(logEntry.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *client) processLogs(ctx context.Context) {
|
||||
var entries []*proto.LogEntry
|
||||
var bytes int
|
||||
|
||||
send := func() {
|
||||
if len(entries) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Int("entries", len(entries)).
|
||||
Int("bytes", bytes).
|
||||
Msg("log drain: sending queued logs")
|
||||
|
||||
if err := c.sendLogs(ctx, entries); err != nil {
|
||||
log.Error().Err(err).Msg("log drain: could not send logs to server")
|
||||
}
|
||||
|
||||
// even if send failed, we don't have infinite memory; retry has already been used
|
||||
entries = entries[:0]
|
||||
bytes = 0
|
||||
}
|
||||
|
||||
// ctx.Done() is covered by the log channel being closed
|
||||
for {
|
||||
_, err = c.client.Log(ctx, req)
|
||||
select {
|
||||
case entry, ok := <-c.logs:
|
||||
if !ok {
|
||||
log.Info().Msg("log drain: channel closed")
|
||||
send()
|
||||
return
|
||||
}
|
||||
|
||||
entries = append(entries, entry)
|
||||
bytes += grpcproto.Size(entry) // cspell:words grpcproto
|
||||
|
||||
if bytes >= maxLogBatchSize {
|
||||
send()
|
||||
}
|
||||
|
||||
case <-time.After(maxLogFlushPeriod):
|
||||
send()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *client) sendLogs(ctx context.Context, entries []*proto.LogEntry) error {
|
||||
req := &proto.LogRequest{LogEntries: entries}
|
||||
retry := c.newBackOff()
|
||||
|
||||
for {
|
||||
_, err := c.client.Log(ctx, req)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
@ -414,12 +480,15 @@ func (c *client) Log(ctx context.Context, logEntry *rpc.LogEntry) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *client) RegisterAgent(ctx context.Context, platform, backend, version string, capacity int) (int64, error) {
|
||||
func (c *client) RegisterAgent(ctx context.Context, info rpc.AgentInfo) (int64, error) {
|
||||
req := new(proto.RegisterAgentRequest)
|
||||
req.Platform = platform
|
||||
req.Backend = backend
|
||||
req.Version = version
|
||||
req.Capacity = int32(capacity)
|
||||
req.Info = &proto.AgentInfo{
|
||||
Platform: info.Platform,
|
||||
Backend: info.Backend,
|
||||
Version: info.Version,
|
||||
Capacity: int32(info.Capacity),
|
||||
CustomLabels: info.CustomLabels,
|
||||
}
|
||||
|
||||
res, err := c.client.RegisterAgent(ctx, req)
|
||||
return res.GetAgentId(), err
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline"
|
||||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||
)
|
||||
|
||||
|
@ -105,7 +106,6 @@ func (r *Runner) Run(runnerCtx, shutdownCtx context.Context) error { //nolint:co
|
|||
if err := r.client.Wait(workflowCtx, workflow.ID); err != nil {
|
||||
canceled = true
|
||||
logger.Warn().Err(err).Msg("cancel signal received")
|
||||
|
||||
cancel()
|
||||
} else {
|
||||
logger.Debug().Msg("done listening for cancel signal")
|
||||
|
@ -117,11 +117,10 @@ func (r *Runner) Run(runnerCtx, shutdownCtx context.Context) error { //nolint:co
|
|||
select {
|
||||
case <-workflowCtx.Done():
|
||||
logger.Debug().Msg("pipeline done")
|
||||
|
||||
return
|
||||
case <-time.After(time.Minute):
|
||||
logger.Debug().Msg("pipeline lease renewed")
|
||||
|
||||
case <-time.After(constant.TaskTimeout / 3):
|
||||
logger.Debug().Msg("pipeline lease renewed")
|
||||
if err := r.client.Extend(workflowCtx, workflow.ID); err != nil {
|
||||
log.Error().Err(err).Msg("extending pipeline deadline failed")
|
||||
}
|
||||
|
@ -144,7 +143,7 @@ func (r *Runner) Run(runnerCtx, shutdownCtx context.Context) error { //nolint:co
|
|||
pipeline.WithContext(workflowCtx),
|
||||
pipeline.WithTaskUUID(fmt.Sprint(workflow.ID)),
|
||||
pipeline.WithLogger(r.createLogger(logger, &uploads, workflow)),
|
||||
pipeline.WithTracer(r.createTracer(ctxMeta, logger, workflow)),
|
||||
pipeline.WithTracer(r.createTracer(ctxMeta, &uploads, logger, workflow)),
|
||||
pipeline.WithBackend(*r.backend),
|
||||
pipeline.WithDescription(map[string]string{
|
||||
"workflow_id": workflow.ID,
|
||||
|
@ -170,9 +169,9 @@ func (r *Runner) Run(runnerCtx, shutdownCtx context.Context) error { //nolint:co
|
|||
Bool("canceled", canceled).
|
||||
Msg("workflow finished")
|
||||
|
||||
logger.Debug().Msg("uploading logs ...")
|
||||
logger.Debug().Msg("uploading logs and traces / states ...")
|
||||
uploads.Wait()
|
||||
logger.Debug().Msg("uploaded logs")
|
||||
logger.Debug().Msg("uploaded logs and traces / states")
|
||||
|
||||
logger.Debug().
|
||||
Str("error", state.Error).
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -26,11 +27,13 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc"
|
||||
)
|
||||
|
||||
func (r *Runner) createTracer(ctxMeta context.Context, logger zerolog.Logger, workflow *rpc.Workflow) pipeline.TraceFunc {
|
||||
func (r *Runner) createTracer(ctxMeta context.Context, uploads *sync.WaitGroup, logger zerolog.Logger, workflow *rpc.Workflow) pipeline.TraceFunc {
|
||||
return func(state *pipeline.State) error {
|
||||
uploads.Add(1)
|
||||
|
||||
stepLogger := logger.With().
|
||||
Str("image", state.Pipeline.Step.Image).
|
||||
Str("workflowID", workflow.ID).
|
||||
Str("workflow_id", workflow.ID).
|
||||
Err(state.Process.Error).
|
||||
Int("exit_code", state.Process.ExitCode).
|
||||
Bool("exited", state.Process.Exited).
|
||||
|
@ -57,6 +60,7 @@ func (r *Runner) createTracer(ctxMeta context.Context, logger zerolog.Logger, wo
|
|||
}
|
||||
|
||||
stepLogger.Debug().Msg("update step status complete")
|
||||
uploads.Done()
|
||||
}()
|
||||
if state.Process.Exited {
|
||||
return nil
|
||||
|
@ -68,21 +72,12 @@ func (r *Runner) createTracer(ctxMeta context.Context, logger zerolog.Logger, wo
|
|||
// TODO: find better way to update this state and move it to pipeline to have the same env in cli-exec
|
||||
state.Pipeline.Step.Environment["CI_MACHINE"] = r.hostname
|
||||
|
||||
state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "success"
|
||||
state.Pipeline.Step.Environment["CI_PIPELINE_STARTED"] = strconv.FormatInt(state.Pipeline.Started, 10)
|
||||
state.Pipeline.Step.Environment["CI_PIPELINE_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "success"
|
||||
state.Pipeline.Step.Environment["CI_STEP_STARTED"] = strconv.FormatInt(state.Pipeline.Started, 10)
|
||||
state.Pipeline.Step.Environment["CI_STEP_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
state.Pipeline.Step.Environment["CI_SYSTEM_PLATFORM"] = runtime.GOOS + "/" + runtime.GOARCH
|
||||
|
||||
if state.Pipeline.Error != nil {
|
||||
state.Pipeline.Step.Environment["CI_PIPELINE_STATUS"] = "failure"
|
||||
state.Pipeline.Step.Environment["CI_STEP_STATUS"] = "failure"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/drone/envsubst"
|
||||
"github.com/oklog/ulid/v2"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
|
@ -36,11 +37,13 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/kubernetes"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/local"
|
||||
backend_types "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/metadata"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/compiler"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/linter"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/matrix"
|
||||
pipelineLog "go.woodpecker-ci.org/woodpecker/v2/pipeline/log"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||
)
|
||||
|
||||
|
@ -74,6 +77,7 @@ func execDir(ctx context.Context, c *cli.Command, dir string) error {
|
|||
if runtime.GOOS == "windows" {
|
||||
repoPath = convertPathForWindows(repoPath)
|
||||
}
|
||||
// TODO: respect depends_on and do parallel runs with output to multiple _windows_ e.g. tmux like
|
||||
return filepath.Walk(dir, func(path string, info os.FileInfo, e error) error {
|
||||
if e != nil {
|
||||
return e
|
||||
|
@ -82,7 +86,7 @@ func execDir(ctx context.Context, c *cli.Command, dir string) error {
|
|||
// check if it is a regular file (not dir)
|
||||
if info.Mode().IsRegular() && (strings.HasSuffix(info.Name(), ".yaml") || strings.HasSuffix(info.Name(), ".yml")) {
|
||||
fmt.Println("#", info.Name())
|
||||
_ = runExec(ctx, c, path, repoPath) // TODO: should we drop errors or store them and report back?
|
||||
_ = runExec(ctx, c, path, repoPath, false) // TODO: should we drop errors or store them and report back?
|
||||
fmt.Println("")
|
||||
return nil
|
||||
}
|
||||
|
@ -101,10 +105,10 @@ func execFile(ctx context.Context, c *cli.Command, file string) error {
|
|||
if runtime.GOOS == "windows" {
|
||||
repoPath = convertPathForWindows(repoPath)
|
||||
}
|
||||
return runExec(ctx, c, file, repoPath)
|
||||
return runExec(ctx, c, file, repoPath, true)
|
||||
}
|
||||
|
||||
func runExec(ctx context.Context, c *cli.Command, file, repoPath string) error {
|
||||
func runExec(ctx context.Context, c *cli.Command, file, repoPath string, singleExec bool) error {
|
||||
dat, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -119,7 +123,7 @@ func runExec(ctx context.Context, c *cli.Command, file, repoPath string) error {
|
|||
axes = append(axes, matrix.Axis{})
|
||||
}
|
||||
for _, axis := range axes {
|
||||
err := execWithAxis(ctx, c, file, repoPath, axis)
|
||||
err := execWithAxis(ctx, c, file, repoPath, axis, singleExec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -127,8 +131,20 @@ func runExec(ctx context.Context, c *cli.Command, file, repoPath string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, axis matrix.Axis) error {
|
||||
metadata := metadataFromContext(ctx, c, axis)
|
||||
func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, axis matrix.Axis, singleExec bool) error {
|
||||
metadataWorkflow := &metadata.Workflow{}
|
||||
if !singleExec {
|
||||
// TODO: proper try to use the engine to generate the same metadata for workflows
|
||||
// https://github.com/woodpecker-ci/woodpecker/pull/3967
|
||||
metadataWorkflow.Name = strings.TrimSuffix(strings.TrimSuffix(file, ".yaml"), ".yml")
|
||||
}
|
||||
metadata, err := metadataFromContext(ctx, c, axis, metadataWorkflow)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create metadata: %w", err)
|
||||
} else if metadata == nil {
|
||||
return fmt.Errorf("metadata is nil")
|
||||
}
|
||||
|
||||
environ := metadata.Environ()
|
||||
var secrets []compiler.Secret
|
||||
for key, val := range metadata.Workflow.Matrix {
|
||||
|
@ -166,6 +182,9 @@ func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, ax
|
|||
return err
|
||||
}
|
||||
|
||||
// emulate server behavior https://github.com/woodpecker-ci/woodpecker/blob/eebaa10d104cbc3fa7ce4c0e344b0b7978405135/server/pipeline/stepbuilder/stepBuilder.go#L289-L295
|
||||
prefix := "wp_" + ulid.Make().String()
|
||||
|
||||
// configure volumes for local execution
|
||||
volumes := c.StringSlice("volumes")
|
||||
if c.Bool("local") {
|
||||
|
@ -180,12 +199,22 @@ func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, ax
|
|||
workspacePath = c.String("workspace-path")
|
||||
}
|
||||
|
||||
volumes = append(volumes, c.String("prefix")+"_default:"+workspaceBase)
|
||||
volumes = append(volumes, prefix+"_default:"+workspaceBase)
|
||||
volumes = append(volumes, repoPath+":"+path.Join(workspaceBase, workspacePath))
|
||||
}
|
||||
|
||||
privilegedPlugins := c.StringSlice("plugins-privileged")
|
||||
|
||||
// lint the yaml file
|
||||
err = linter.New(linter.WithTrusted(true)).Lint([]*linter.WorkflowConfig{{
|
||||
err = linter.New(
|
||||
linter.WithTrusted(linter.TrustedConfiguration{
|
||||
Security: c.Bool("repo-trusted-security"),
|
||||
Network: c.Bool("repo-trusted-network"),
|
||||
Volumes: c.Bool("repo-trusted-volumes"),
|
||||
}),
|
||||
linter.PrivilegedPlugins(privilegedPlugins),
|
||||
linter.WithTrustedClonePlugins(constant.TrustedClonePlugins),
|
||||
).Lint([]*linter.WorkflowConfig{{
|
||||
File: path.Base(file),
|
||||
RawConfig: confStr,
|
||||
Workflow: conf,
|
||||
|
@ -201,7 +230,7 @@ func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, ax
|
|||
// compiles the yaml file
|
||||
compiled, err := compiler.New(
|
||||
compiler.WithEscalated(
|
||||
c.StringSlice("privileged")...,
|
||||
privilegedPlugins...,
|
||||
),
|
||||
compiler.WithVolumes(volumes...),
|
||||
compiler.WithWorkspace(
|
||||
|
@ -211,9 +240,7 @@ func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, ax
|
|||
compiler.WithNetworks(
|
||||
c.StringSlice("network")...,
|
||||
),
|
||||
compiler.WithPrefix(
|
||||
c.String("prefix"),
|
||||
),
|
||||
compiler.WithPrefix(prefix),
|
||||
compiler.WithProxy(compiler.ProxyOptions{
|
||||
NoProxy: c.String("backend-no-proxy"),
|
||||
HTTPProxy: c.String("backend-http-proxy"),
|
||||
|
@ -227,7 +254,7 @@ func execWithAxis(ctx context.Context, c *cli.Command, file, repoPath string, ax
|
|||
c.String("netrc-password"),
|
||||
c.String("netrc-machine"),
|
||||
),
|
||||
compiler.WithMetadata(metadata),
|
||||
compiler.WithMetadata(*metadata),
|
||||
compiler.WithSecret(secrets...),
|
||||
compiler.WithEnviron(pipelineEnv),
|
||||
).Compile(conf)
|
||||
|
@ -281,8 +308,7 @@ func convertPathForWindows(path string) string {
|
|||
return filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
const maxLogLineLength = 1024 * 1024 // 1mb
|
||||
var defaultLogger = pipeline.Logger(func(step *backend_types.Step, rc io.ReadCloser) error {
|
||||
logWriter := NewLineWriter(step.Name, step.UUID)
|
||||
return pipelineLog.CopyLineByLine(logWriter, rc, maxLogLineLength)
|
||||
return pipelineLog.CopyLineByLine(logWriter, rc, pipeline.MaxLogLineLength)
|
||||
})
|
||||
|
|
|
@ -18,8 +18,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
|
||||
)
|
||||
|
||||
var flags = []cli.Flag{
|
||||
|
@ -34,6 +32,11 @@ var flags = []cli.Flag{
|
|||
Name: "repo-path",
|
||||
Usage: "path to local repository",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_METADATA_FILE"),
|
||||
Name: "metadata-file",
|
||||
Usage: "path to pipeline metadata file (normally downloaded from UI). Parameters can be adjusted by applying additional cli flags",
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_TIMEOUT"),
|
||||
Name: "timeout",
|
||||
|
@ -50,17 +53,10 @@ var flags = []cli.Flag{
|
|||
Name: "network",
|
||||
Usage: "external networks",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PREFIX"),
|
||||
Name: "prefix",
|
||||
Value: "woodpecker",
|
||||
Usage: "prefix used for containers, volumes, networks, ... created by woodpecker",
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "privileged",
|
||||
Usage: "privileged plugins",
|
||||
Value: constant.PrivilegedPlugins,
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
||||
Name: "plugins-privileged",
|
||||
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_BACKEND"),
|
||||
|
@ -127,201 +123,287 @@ var flags = []cli.Flag{
|
|||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_SYSTEM_PLATFORM"),
|
||||
Name: "system-platform",
|
||||
Usage: "Set the metadata environment variable \"CI_SYSTEM_PLATFORM\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_SYSTEM_HOST"),
|
||||
Name: "system-host",
|
||||
Usage: "Set the metadata environment variable \"CI_SYSTEM_HOST\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_SYSTEM_NAME"),
|
||||
Name: "system-name",
|
||||
Usage: "Set the metadata environment variable \"CI_SYSTEM_NAME\".",
|
||||
Value: "woodpecker",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_SYSTEM_URL"),
|
||||
Name: "system-url",
|
||||
Usage: "Set the metadata environment variable \"CI_SYSTEM_URL\".",
|
||||
Value: "https://github.com/woodpecker-ci/woodpecker",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO"),
|
||||
Name: "repo",
|
||||
Usage: "full repo name",
|
||||
Usage: "Set the full name to derive metadata environment variables \"CI_REPO\", \"CI_REPO_NAME\" and \"CI_REPO_OWNER\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_REMOTE_ID"),
|
||||
Name: "repo-remote-id",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_REMOTE_ID\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_URL"),
|
||||
Name: "repo-url",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_URL\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_SCM"),
|
||||
Name: "repo-scm",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_SCM\".",
|
||||
Value: "git",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_DEFAULT_BRANCH"),
|
||||
Name: "repo-default-branch",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_DEFAULT_BRANCH\".",
|
||||
Value: "main",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_CLONE_URL"),
|
||||
Name: "repo-clone-url",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_CLONE_URL\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_CLONE_SSH_URL"),
|
||||
Name: "repo-clone-ssh-url",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_CLONE_SSH_URL\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_PRIVATE"),
|
||||
Name: "repo-private",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_PRIVATE\".",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_TRUSTED"),
|
||||
Name: "repo-trusted",
|
||||
Sources: cli.EnvVars("CI_REPO_TRUSTED_NETWORK"),
|
||||
Name: "repo-trusted-network",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_TRUSTED_NETWORK\".",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_TRUSTED_VOLUMES"),
|
||||
Name: "repo-trusted-volumes",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_TRUSTED_VOLUMES\".",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("CI_REPO_TRUSTED_SECURITY"),
|
||||
Name: "repo-trusted-security",
|
||||
Usage: "Set the metadata environment variable \"CI_REPO_TRUSTED_SECURITY\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_NUMBER"),
|
||||
Name: "pipeline-number",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_NUMBER\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_PARENT"),
|
||||
Name: "pipeline-parent",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_PARENT\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_CREATED"),
|
||||
Name: "pipeline-created",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_CREATED\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_STARTED"),
|
||||
Name: "pipeline-started",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_FINISHED"),
|
||||
Name: "pipeline-finished",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_STATUS"),
|
||||
Name: "pipeline-status",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_STARTED\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_EVENT"),
|
||||
Name: "pipeline-event",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_EVENT\".",
|
||||
Value: "manual",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_URL"),
|
||||
Sources: cli.EnvVars("CI_PIPELINE_FORGE_URL"),
|
||||
Name: "pipeline-url",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_FORGE_URL\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TARGET", "CI_PIPELINE_TARGET"), // TODO: remove CI_PIPELINE_TARGET in 3.x
|
||||
Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TARGET"),
|
||||
Name: "pipeline-deploy-to",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_DEPLOY_TARGET\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TASK", "CI_PIPELINE_TASK"), // TODO: remove CI_PIPELINE_TASK in 3.x
|
||||
Sources: cli.EnvVars("CI_PIPELINE_DEPLOY_TASK"),
|
||||
Name: "pipeline-deploy-task",
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_DEPLOY_TASK\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PIPELINE_FILES"),
|
||||
Usage: "Set the metadata environment variable \"CI_PIPELINE_FILES\", either json formatted list of strings, or comma separated string list.",
|
||||
Name: "pipeline-changed-files",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_SHA"),
|
||||
Name: "commit-sha",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_SHA\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_REF"),
|
||||
Name: "commit-ref",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_REF\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_REFSPEC"),
|
||||
Name: "commit-refspec",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_REFSPEC\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_BRANCH"),
|
||||
Name: "commit-branch",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_BRANCH\".",
|
||||
Value: "main",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_MESSAGE"),
|
||||
Name: "commit-message",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_MESSAGE\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_AUTHOR_NAME"),
|
||||
Sources: cli.EnvVars("CI_COMMIT_AUTHOR"),
|
||||
Name: "commit-author-name",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_AUTHOR\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_AUTHOR_AVATAR"),
|
||||
Name: "commit-author-avatar",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_AUTHOR_AVATAR\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_AUTHOR_EMAIL"),
|
||||
Name: "commit-author-email",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_AUTHOR_EMAIL\".",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_PULL_REQUEST_LABELS"),
|
||||
Name: "commit-pull-labels",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_PULL_REQUEST_LABELS\".",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("CI_COMMIT_PRERELEASE"),
|
||||
Name: "commit-release-is-pre",
|
||||
Usage: "Set the metadata environment variable \"CI_COMMIT_PRERELEASE\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_NUMBER"),
|
||||
Name: "prev-pipeline-number",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_NUMBER\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_CREATED"),
|
||||
Name: "prev-pipeline-created",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_CREATED\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_STARTED"),
|
||||
Name: "prev-pipeline-started",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_STARTED\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_FINISHED"),
|
||||
Name: "prev-pipeline-finished",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_FINISHED\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_STATUS"),
|
||||
Name: "prev-pipeline-status",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_STATUS\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_EVENT"),
|
||||
Name: "prev-pipeline-event",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_EVENT\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_URL"),
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_FORGE_URL"),
|
||||
Name: "prev-pipeline-url",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_FORGE_URL\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_DEPLOY_TARGET"),
|
||||
Name: "prev-pipeline-deploy-to",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_DEPLOY_TARGET\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_PIPELINE_DEPLOY_TASK"),
|
||||
Name: "prev-pipeline-deploy-task",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_PIPELINE_DEPLOY_TASK\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_SHA"),
|
||||
Name: "prev-commit-sha",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_SHA\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_REF"),
|
||||
Name: "prev-commit-ref",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_REF\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_REFSPEC"),
|
||||
Name: "prev-commit-refspec",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_REFSPEC\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_BRANCH"),
|
||||
Name: "prev-commit-branch",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_BRANCH\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_MESSAGE"),
|
||||
Name: "prev-commit-message",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_MESSAGE\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_NAME"),
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR"),
|
||||
Name: "prev-commit-author-name",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_AUTHOR\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_AVATAR"),
|
||||
Name: "prev-commit-author-avatar",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_AUTHOR_AVATAR\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_PREV_COMMIT_AUTHOR_EMAIL"),
|
||||
Name: "prev-commit-author-email",
|
||||
Usage: "Set the metadata environment variable \"CI_PREV_COMMIT_AUTHOR_EMAIL\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_WORKFLOW_NAME"),
|
||||
Name: "workflow-name",
|
||||
Usage: "Set the metadata environment variable \"CI_WORKFLOW_NAME\".",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_WORKFLOW_NUMBER"),
|
||||
Name: "workflow-number",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("CI_STEP_NAME"),
|
||||
Name: "step-name",
|
||||
Usage: "Set the metadata environment variable \"CI_WORKFLOW_NUMBER\".",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("CI_ENV"),
|
||||
Name: "env",
|
||||
Usage: "Set the metadata environment variable \"CI_ENV\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_FORGE_TYPE"),
|
||||
Name: "forge-type",
|
||||
Usage: "Set the metadata environment variable \"CI_FORGE_TYPE\".",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("CI_FORGE_URL"),
|
||||
Name: "forge-url",
|
||||
Usage: "Set the metadata environment variable \"CI_FORGE_URL\".",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ package exec
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
|
@ -27,94 +30,133 @@ import (
|
|||
)
|
||||
|
||||
// return the metadata from the cli context.
|
||||
func metadataFromContext(_ context.Context, c *cli.Command, axis matrix.Axis) metadata.Metadata {
|
||||
func metadataFromContext(_ context.Context, c *cli.Command, axis matrix.Axis, w *metadata.Workflow) (*metadata.Metadata, error) {
|
||||
m := &metadata.Metadata{}
|
||||
|
||||
if c.IsSet("metadata-file") {
|
||||
metadataFile, err := os.Open(c.String("metadata-file"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer metadataFile.Close()
|
||||
|
||||
if err := json.NewDecoder(metadataFile).Decode(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
platform := c.String("system-platform")
|
||||
if platform == "" {
|
||||
platform = runtime.GOOS + "/" + runtime.GOARCH
|
||||
}
|
||||
|
||||
fullRepoName := c.String("repo-name")
|
||||
repoOwner := ""
|
||||
repoName := ""
|
||||
if idx := strings.LastIndex(fullRepoName, "/"); idx != -1 {
|
||||
repoOwner = fullRepoName[:idx]
|
||||
repoName = fullRepoName[idx+1:]
|
||||
metadataFileAndOverrideOrDefault(c, "repo-name", func(fullRepoName string) {
|
||||
if idx := strings.LastIndex(fullRepoName, "/"); idx != -1 {
|
||||
m.Repo.Owner = fullRepoName[:idx]
|
||||
m.Repo.Name = fullRepoName[idx+1:]
|
||||
}
|
||||
}, c.String)
|
||||
|
||||
var err error
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-changed-files", func(changedFilesRaw string) {
|
||||
var changedFiles []string
|
||||
if len(changedFilesRaw) != 0 && changedFilesRaw[0] == '[' {
|
||||
if jsonErr := json.Unmarshal([]byte(changedFilesRaw), &changedFiles); jsonErr != nil {
|
||||
err = fmt.Errorf("pipeline-changed-files detected json but could not parse it: %w", jsonErr)
|
||||
}
|
||||
} else {
|
||||
for _, file := range strings.Split(changedFilesRaw, ",") {
|
||||
changedFiles = append(changedFiles, strings.TrimSpace(file))
|
||||
}
|
||||
}
|
||||
m.Curr.Commit.ChangedFiles = changedFiles
|
||||
}, c.String)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return metadata.Metadata{
|
||||
Repo: metadata.Repo{
|
||||
Name: repoName,
|
||||
Owner: repoOwner,
|
||||
RemoteID: c.String("repo-remote-id"),
|
||||
ForgeURL: c.String("repo-url"),
|
||||
CloneURL: c.String("repo-clone-url"),
|
||||
CloneSSHURL: c.String("repo-clone-ssh-url"),
|
||||
Private: c.Bool("repo-private"),
|
||||
Trusted: c.Bool("repo-trusted"),
|
||||
},
|
||||
Curr: metadata.Pipeline{
|
||||
Number: c.Int("pipeline-number"),
|
||||
Parent: c.Int("pipeline-parent"),
|
||||
Created: c.Int("pipeline-created"),
|
||||
Started: c.Int("pipeline-started"),
|
||||
Finished: c.Int("pipeline-finished"),
|
||||
Status: c.String("pipeline-status"),
|
||||
Event: c.String("pipeline-event"),
|
||||
ForgeURL: c.String("pipeline-url"),
|
||||
DeployTo: c.String("pipeline-deploy-to"),
|
||||
DeployTask: c.String("pipeline-deploy-task"),
|
||||
Commit: metadata.Commit{
|
||||
Sha: c.String("commit-sha"),
|
||||
Ref: c.String("commit-ref"),
|
||||
Refspec: c.String("commit-refspec"),
|
||||
Branch: c.String("commit-branch"),
|
||||
Message: c.String("commit-message"),
|
||||
Author: metadata.Author{
|
||||
Name: c.String("commit-author-name"),
|
||||
Email: c.String("commit-author-email"),
|
||||
Avatar: c.String("commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Prev: metadata.Pipeline{
|
||||
Number: c.Int("prev-pipeline-number"),
|
||||
Created: c.Int("prev-pipeline-created"),
|
||||
Started: c.Int("prev-pipeline-started"),
|
||||
Finished: c.Int("prev-pipeline-finished"),
|
||||
Status: c.String("prev-pipeline-status"),
|
||||
Event: c.String("prev-pipeline-event"),
|
||||
ForgeURL: c.String("prev-pipeline-url"),
|
||||
Commit: metadata.Commit{
|
||||
Sha: c.String("prev-commit-sha"),
|
||||
Ref: c.String("prev-commit-ref"),
|
||||
Refspec: c.String("prev-commit-refspec"),
|
||||
Branch: c.String("prev-commit-branch"),
|
||||
Message: c.String("prev-commit-message"),
|
||||
Author: metadata.Author{
|
||||
Name: c.String("prev-commit-author-name"),
|
||||
Email: c.String("prev-commit-author-email"),
|
||||
Avatar: c.String("prev-commit-author-avatar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Workflow: metadata.Workflow{
|
||||
Name: c.String("workflow-name"),
|
||||
Number: int(c.Int("workflow-number")),
|
||||
Matrix: axis,
|
||||
},
|
||||
Step: metadata.Step{
|
||||
Name: c.String("step-name"),
|
||||
Number: int(c.Int("step-number")),
|
||||
},
|
||||
Sys: metadata.System{
|
||||
Name: c.String("system-name"),
|
||||
URL: c.String("system-url"),
|
||||
Platform: platform,
|
||||
Version: version.Version,
|
||||
},
|
||||
Forge: metadata.Forge{
|
||||
Type: c.String("forge-type"),
|
||||
URL: c.String("forge-url"),
|
||||
},
|
||||
// Repo
|
||||
metadataFileAndOverrideOrDefault(c, "repo-remote-id", func(s string) { m.Repo.RemoteID = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-url", func(s string) { m.Repo.ForgeURL = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-scm", func(s string) { m.Repo.SCM = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-default-branch", func(s string) { m.Repo.Branch = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-clone-url", func(s string) { m.Repo.CloneURL = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-clone-ssh-url", func(s string) { m.Repo.CloneSSHURL = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-private", func(b bool) { m.Repo.Private = b }, c.Bool)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-trusted-network", func(b bool) { m.Repo.Trusted.Network = b }, c.Bool)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-trusted-security", func(b bool) { m.Repo.Trusted.Security = b }, c.Bool)
|
||||
metadataFileAndOverrideOrDefault(c, "repo-trusted-volumes", func(b bool) { m.Repo.Trusted.Volumes = b }, c.Bool)
|
||||
|
||||
// Current Pipeline
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-number", func(i int64) { m.Curr.Number = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-parent", func(i int64) { m.Curr.Parent = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-created", func(i int64) { m.Curr.Created = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-started", func(i int64) { m.Curr.Started = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-finished", func(i int64) { m.Curr.Finished = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-status", func(s string) { m.Curr.Status = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-event", func(s string) { m.Curr.Event = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-url", func(s string) { m.Curr.ForgeURL = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-deploy-to", func(s string) { m.Curr.DeployTo = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "pipeline-deploy-task", func(s string) { m.Curr.DeployTask = s }, c.String)
|
||||
|
||||
// Current Pipeline Commit
|
||||
metadataFileAndOverrideOrDefault(c, "commit-sha", func(s string) { m.Curr.Commit.Sha = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-ref", func(s string) { m.Curr.Commit.Ref = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-refspec", func(s string) { m.Curr.Commit.Refspec = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-branch", func(s string) { m.Curr.Commit.Branch = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-message", func(s string) { m.Curr.Commit.Message = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-author-name", func(s string) { m.Curr.Commit.Author.Name = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-author-email", func(s string) { m.Curr.Commit.Author.Email = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-author-avatar", func(s string) { m.Curr.Commit.Author.Avatar = s }, c.String)
|
||||
|
||||
metadataFileAndOverrideOrDefault(c, "commit-pull-labels", func(sl []string) { m.Curr.Commit.PullRequestLabels = sl }, c.StringSlice)
|
||||
metadataFileAndOverrideOrDefault(c, "commit-release-is-pre", func(b bool) { m.Curr.Commit.IsPrerelease = b }, c.Bool)
|
||||
|
||||
// Previous Pipeline
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-number", func(i int64) { m.Prev.Number = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-created", func(i int64) { m.Prev.Created = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-started", func(i int64) { m.Prev.Started = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-finished", func(i int64) { m.Prev.Finished = i }, c.Int)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-status", func(s string) { m.Prev.Status = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-event", func(s string) { m.Prev.Event = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-pipeline-url", func(s string) { m.Prev.ForgeURL = s }, c.String)
|
||||
|
||||
// Previous Pipeline Commit
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-sha", func(s string) { m.Prev.Commit.Sha = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-ref", func(s string) { m.Prev.Commit.Ref = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-refspec", func(s string) { m.Prev.Commit.Refspec = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-branch", func(s string) { m.Prev.Commit.Branch = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-message", func(s string) { m.Prev.Commit.Message = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-author-name", func(s string) { m.Prev.Commit.Author.Name = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-author-email", func(s string) { m.Prev.Commit.Author.Email = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "prev-commit-author-avatar", func(s string) { m.Prev.Commit.Author.Avatar = s }, c.String)
|
||||
|
||||
// Workflow
|
||||
metadataFileAndOverrideOrDefault(c, "workflow-name", func(s string) { m.Workflow.Name = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "workflow-number", func(i int64) { m.Workflow.Number = int(i) }, c.Int)
|
||||
m.Workflow.Matrix = axis
|
||||
|
||||
// System
|
||||
metadataFileAndOverrideOrDefault(c, "system-name", func(s string) { m.Sys.Name = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "system-url", func(s string) { m.Sys.URL = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "system-host", func(s string) { m.Sys.Host = s }, c.String)
|
||||
m.Sys.Platform = platform
|
||||
m.Sys.Version = version.Version
|
||||
|
||||
// Forge
|
||||
metadataFileAndOverrideOrDefault(c, "forge-type", func(s string) { m.Forge.Type = s }, c.String)
|
||||
metadataFileAndOverrideOrDefault(c, "forge-url", func(s string) { m.Forge.URL = s }, c.String)
|
||||
|
||||
if w != nil {
|
||||
m.Workflow = *w
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// metadataFileAndOverrideOrDefault will either use the flag default or if metadata file is set only overload if explicit set.
|
||||
func metadataFileAndOverrideOrDefault[T any](c *cli.Command, flag string, setter func(T), getter func(string) T) {
|
||||
if !c.IsSet("metadata-file") || c.IsSet(flag) {
|
||||
setter(getter(flag))
|
||||
}
|
||||
}
|
||||
|
|
142
cli/exec/metadata_test.go
Normal file
142
cli/exec/metadata_test.go
Normal file
|
@ -0,0 +1,142 @@
|
|||
// Copyright 2024 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/metadata"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/matrix"
|
||||
)
|
||||
|
||||
func TestMetadataFromContext(t *testing.T) {
|
||||
sampleMetadata := &metadata.Metadata{
|
||||
Repo: metadata.Repo{Owner: "test-user", Name: "test-repo"},
|
||||
Curr: metadata.Pipeline{Number: 5},
|
||||
}
|
||||
|
||||
runCommand := func(flags []cli.Flag, fn func(c *cli.Command)) {
|
||||
c := &cli.Command{
|
||||
Flags: flags,
|
||||
Action: func(_ context.Context, c *cli.Command) error {
|
||||
fn(c)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
assert.NoError(t, c.Run(context.Background(), []string{"woodpecker-cli"}))
|
||||
}
|
||||
|
||||
t.Run("LoadFromFile", func(t *testing.T) {
|
||||
tempFileName := createTempFile(t, sampleMetadata)
|
||||
|
||||
flags := []cli.Flag{
|
||||
&cli.StringFlag{Name: "metadata-file"},
|
||||
}
|
||||
|
||||
runCommand(flags, func(c *cli.Command) {
|
||||
_ = c.Set("metadata-file", tempFileName)
|
||||
|
||||
m, err := metadataFromContext(context.Background(), c, nil, nil)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "test-repo", m.Repo.Name)
|
||||
assert.Equal(t, int64(5), m.Curr.Number)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("OverrideFromFlags", func(t *testing.T) {
|
||||
tempFileName := createTempFile(t, sampleMetadata)
|
||||
|
||||
flags := []cli.Flag{
|
||||
&cli.StringFlag{Name: "metadata-file"},
|
||||
&cli.StringFlag{Name: "repo-name"},
|
||||
&cli.IntFlag{Name: "pipeline-number"},
|
||||
}
|
||||
|
||||
runCommand(flags, func(c *cli.Command) {
|
||||
_ = c.Set("metadata-file", tempFileName)
|
||||
_ = c.Set("repo-name", "aUser/override-repo")
|
||||
_ = c.Set("pipeline-number", "10")
|
||||
|
||||
m, err := metadataFromContext(context.Background(), c, nil, nil)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "override-repo", m.Repo.Name)
|
||||
assert.Equal(t, int64(10), m.Curr.Number)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("InvalidFile", func(t *testing.T) {
|
||||
tempFile, err := os.CreateTemp("", "invalid.json")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.Remove(tempFile.Name()) })
|
||||
|
||||
_, err = tempFile.Write([]byte("invalid json"))
|
||||
require.NoError(t, err)
|
||||
|
||||
flags := []cli.Flag{
|
||||
&cli.StringFlag{Name: "metadata-file"},
|
||||
}
|
||||
|
||||
runCommand(flags, func(c *cli.Command) {
|
||||
_ = c.Set("metadata-file", tempFile.Name())
|
||||
|
||||
_, err = metadataFromContext(context.Background(), c, nil, nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("DefaultValues", func(t *testing.T) {
|
||||
flags := []cli.Flag{
|
||||
&cli.StringFlag{Name: "repo-name", Value: "test/default-repo"},
|
||||
&cli.IntFlag{Name: "pipeline-number", Value: 1},
|
||||
}
|
||||
|
||||
runCommand(flags, func(c *cli.Command) {
|
||||
m, err := metadataFromContext(context.Background(), c, nil, nil)
|
||||
require.NoError(t, err)
|
||||
if assert.NotNil(t, m) {
|
||||
assert.Equal(t, "test", m.Repo.Owner)
|
||||
assert.Equal(t, "default-repo", m.Repo.Name)
|
||||
assert.Equal(t, int64(1), m.Curr.Number)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("MatrixAxis", func(t *testing.T) {
|
||||
runCommand([]cli.Flag{}, func(c *cli.Command) {
|
||||
axis := matrix.Axis{"go": "1.16", "os": "linux"}
|
||||
m, err := metadataFromContext(context.Background(), c, axis, nil)
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, map[string]string{"go": "1.16", "os": "linux"}, m.Workflow.Matrix)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func createTempFile(t *testing.T, content any) string {
|
||||
t.Helper()
|
||||
tempFile, err := os.CreateTemp("", "metadata.json")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.Remove(tempFile.Name()) })
|
||||
|
||||
err = json.NewEncoder(tempFile).Encode(content)
|
||||
require.NoError(t, err)
|
||||
return tempFile.Name()
|
||||
}
|
|
@ -27,6 +27,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/common"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/frontend/yaml/linter"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
|
||||
)
|
||||
|
||||
// Command exports the info command.
|
||||
|
@ -35,6 +36,19 @@ var Command = &cli.Command{
|
|||
Usage: "lint a pipeline configuration file",
|
||||
ArgsUsage: "[path/to/.woodpecker.yaml]",
|
||||
Action: lint,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
||||
Name: "plugins-privileged",
|
||||
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_TRUSTED_CLONE"),
|
||||
Name: "plugins-trusted-clone",
|
||||
Usage: "Plugins which are trusted to handle the netrc info in clone steps",
|
||||
Value: constant.TrustedClonePlugins,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func lint(ctx context.Context, c *cli.Command) error {
|
||||
|
@ -69,7 +83,7 @@ func lintDir(ctx context.Context, c *cli.Command, dir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func lintFile(_ context.Context, _ *cli.Command, file string) error {
|
||||
func lintFile(_ context.Context, c *cli.Command, file string) error {
|
||||
fi, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -83,7 +97,7 @@ func lintFile(_ context.Context, _ *cli.Command, file string) error {
|
|||
|
||||
rawConfig := string(buf)
|
||||
|
||||
c, err := yaml.ParseString(rawConfig)
|
||||
parsedConfig, err := yaml.ParseString(rawConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -91,11 +105,19 @@ func lintFile(_ context.Context, _ *cli.Command, file string) error {
|
|||
config := &linter.WorkflowConfig{
|
||||
File: path.Base(file),
|
||||
RawConfig: rawConfig,
|
||||
Workflow: c,
|
||||
Workflow: parsedConfig,
|
||||
}
|
||||
|
||||
// TODO: lint multiple files at once to allow checks for sth like "depends_on" to work
|
||||
err = linter.New(linter.WithTrusted(true)).Lint([]*linter.WorkflowConfig{config})
|
||||
err = linter.New(
|
||||
linter.WithTrusted(linter.TrustedConfiguration{
|
||||
Network: true,
|
||||
Volumes: true,
|
||||
Security: true,
|
||||
}),
|
||||
linter.PrivilegedPlugins(c.StringSlice("plugins-privileged")),
|
||||
linter.WithTrustedClonePlugins(c.StringSlice("plugins-trusted-clone")),
|
||||
).Lint([]*linter.WorkflowConfig{config})
|
||||
if err != nil {
|
||||
str, err := FormatLintError(config.File, err)
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ package secret
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
|
@ -51,6 +52,11 @@ func secretInfo(ctx context.Context, c *cli.Command) error {
|
|||
secretName = c.String("name")
|
||||
format = c.String("format") + "\n"
|
||||
)
|
||||
|
||||
if secretName == "" {
|
||||
return fmt.Errorf("secret name is missing")
|
||||
}
|
||||
|
||||
client, err := internal.NewClient(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -156,7 +157,7 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
|||
}
|
||||
defer conn.Close()
|
||||
|
||||
client := agent_rpc.NewGrpcClient(conn)
|
||||
client := agent_rpc.NewGrpcClient(ctx, conn)
|
||||
agentConfigPersisted := atomic.Bool{}
|
||||
|
||||
grpcCtx := metadata.NewOutgoingContext(grpcClientCtx, metadata.Pairs("hostname", hostname))
|
||||
|
@ -198,7 +199,22 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
|||
log.Debug().Msgf("loaded %s backend engine", backendEngine.Name())
|
||||
|
||||
maxWorkflows := int(c.Int("max-workflows"))
|
||||
agentConfig.AgentID, err = client.RegisterAgent(grpcCtx, engInfo.Platform, backendEngine.Name(), version.String(), maxWorkflows) //nolint:contextcheck
|
||||
|
||||
customLabels := make(map[string]string)
|
||||
if err := stringSliceAddToMap(c.StringSlice("labels"), customLabels); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(customLabels) != 0 {
|
||||
log.Debug().Msgf("custom labels detected: %#v", customLabels)
|
||||
}
|
||||
|
||||
agentConfig.AgentID, err = client.RegisterAgent(grpcCtx, rpc.AgentInfo{ //nolint:contextcheck
|
||||
Version: version.String(),
|
||||
Backend: backendEngine.Name(),
|
||||
Platform: engInfo.Platform,
|
||||
Capacity: maxWorkflows,
|
||||
CustomLabels: customLabels,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -210,7 +226,7 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
|||
<-agentCtx.Done()
|
||||
// Remove stateless agents from server
|
||||
if !agentConfigPersisted.Load() {
|
||||
log.Debug().Msg("unregistering agent from server ...")
|
||||
log.Debug().Msg("unregister agent from server ...")
|
||||
// we want to run it explicit run when context got canceled so run it in background
|
||||
err := client.UnregisterAgent(grpcClientCtx)
|
||||
if err != nil {
|
||||
|
@ -228,16 +244,17 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
|||
}
|
||||
}
|
||||
|
||||
// set default labels ...
|
||||
labels := map[string]string{
|
||||
"hostname": hostname,
|
||||
"platform": engInfo.Platform,
|
||||
"backend": backendEngine.Name(),
|
||||
"repo": "*", // allow all repos by default
|
||||
}
|
||||
// ... and let it overwrite by custom ones
|
||||
maps.Copy(labels, customLabels)
|
||||
|
||||
if err := stringSliceAddToMap(c.StringSlice("filter"), labels); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug().Any("labels", labels).Msgf("agent configured with labels")
|
||||
|
||||
filter := rpc.Filter{
|
||||
Labels: labels,
|
||||
|
|
|
@ -60,8 +60,9 @@ var flags = []cli.Flag{
|
|||
Value: "/etc/woodpecker/agent.conf",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_FILTER_LABELS"),
|
||||
Name: "filter",
|
||||
Sources: cli.EnvVars("WOODPECKER_AGENT_LABELS", "WOODPECKER_FILTER_LABELS"), // remove WOODPECKER_FILTER_LABELS in v4.x
|
||||
Name: "labels",
|
||||
Aliases: []string{"filter"}, // remove in v4.x
|
||||
Usage: "List of labels to filter tasks on. An agent must be assigned every tag listed in a task to be selected.",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/cli/org"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/pipeline"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/repo"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/repo/registry"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/secret"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/setup"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/update"
|
||||
|
@ -57,8 +56,6 @@ func newApp() *cli.Command {
|
|||
deploy.Command,
|
||||
exec.Command,
|
||||
info.Command,
|
||||
// TODO: Remove in 3.x
|
||||
registry.Command,
|
||||
secret.Command,
|
||||
user.Command,
|
||||
lint.Command,
|
||||
|
|
|
@ -101,7 +101,7 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/agents/{agent}": {
|
||||
"/agents/{agent_id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -211,7 +211,7 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/agents/{agent}/tasks": {
|
||||
"/agents/{agent_id}/tasks": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -1063,6 +1063,193 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/orgs/{org_id}/agents": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Agents"
|
||||
],
|
||||
"summary": "List agents for an organization",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cpersonal access token\u003e",
|
||||
"description": "Insert your personal access token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the organization's id",
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"default": 1,
|
||||
"description": "for response pagination, page offset number",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"default": 50,
|
||||
"description": "for response pagination, max items per page",
|
||||
"name": "perPage",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Creates a new agent with a random token, scoped to the specified organization",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Agents"
|
||||
],
|
||||
"summary": "Create a new organization-scoped agent",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cpersonal access token\u003e",
|
||||
"description": "Insert your personal access token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the organization's id",
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "the agent's data (only 'name' and 'no_schedule' are read)",
|
||||
"name": "agent",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Agent"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/orgs/{org_id}/agents/{agent_id}": {
|
||||
"delete": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"Agents"
|
||||
],
|
||||
"summary": "Delete an organization-scoped agent",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cpersonal access token\u003e",
|
||||
"description": "Insert your personal access token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the organization's id",
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the agent's id",
|
||||
"name": "agent_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Agents"
|
||||
],
|
||||
"summary": "Update an organization-scoped agent",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cpersonal access token\u003e",
|
||||
"description": "Insert your personal access token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the organization's id",
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the agent's id",
|
||||
"name": "agent_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "the agent's updated data",
|
||||
"name": "agent",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Agent"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/orgs/{org_id}/permissions": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
@ -3144,6 +3331,49 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{repo_id}/pipelines/{number}/metadata": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Pipelines"
|
||||
],
|
||||
"summary": "Get metadata for a pipeline or a specific workflow, including previous pipeline info",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cpersonal access token\u003e",
|
||||
"description": "Insert your personal access token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the repository id",
|
||||
"name": "repo_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "the number of the pipeline",
|
||||
"name": "number",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/metadata.Metadata"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{repo_id}/pull_requests": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
@ -4359,6 +4589,12 @@ const docTemplate = `{
|
|||
"created": {
|
||||
"type": "integer"
|
||||
},
|
||||
"custom_labels": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -4375,6 +4611,10 @@ const docTemplate = `{
|
|||
"no_schedule": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"org_id": {
|
||||
"description": "OrgID is counted as unset if set to -1, this is done to ensure a new(Agent) still enforce the OrgID check by default",
|
||||
"type": "integer"
|
||||
},
|
||||
"owner_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -4415,8 +4655,7 @@ const docTemplate = `{
|
|||
"branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "TODO change JSON field to \"created\" in 3.0",
|
||||
"created": {
|
||||
"type": "integer"
|
||||
},
|
||||
"creator_id": {
|
||||
|
@ -4458,15 +4697,13 @@ const docTemplate = `{
|
|||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "TODO change JSON field to \"created\" in 3.0",
|
||||
"created": {
|
||||
"type": "integer"
|
||||
},
|
||||
"event": {
|
||||
"type": "string"
|
||||
},
|
||||
"finished_at": {
|
||||
"description": "TODO change JSON field to \"finished\" in 3.0",
|
||||
"finished": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
|
@ -4487,8 +4724,7 @@ const docTemplate = `{
|
|||
"repo_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"started_at": {
|
||||
"description": "TODO change JSON field to \"started\" in 3.0",
|
||||
"started": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
|
@ -4645,8 +4881,7 @@ const docTemplate = `{
|
|||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "TODO change JSON field to \"created\" in 3.0",
|
||||
"created": {
|
||||
"type": "integer"
|
||||
},
|
||||
"deploy_task": {
|
||||
|
@ -4664,8 +4899,7 @@ const docTemplate = `{
|
|||
"event": {
|
||||
"$ref": "#/definitions/WebhookEvent"
|
||||
},
|
||||
"finished_at": {
|
||||
"description": "TODO change JSON field to \"finished\" in 3.0",
|
||||
"finished": {
|
||||
"type": "integer"
|
||||
},
|
||||
"forge_url": {
|
||||
|
@ -4698,8 +4932,7 @@ const docTemplate = `{
|
|||
"refspec": {
|
||||
"type": "string"
|
||||
},
|
||||
"reviewed_at": {
|
||||
"description": "TODO change JSON field to \"reviewed\" in 3.0",
|
||||
"reviewed": {
|
||||
"type": "integer"
|
||||
},
|
||||
"reviewed_by": {
|
||||
|
@ -4709,8 +4942,7 @@ const docTemplate = `{
|
|||
"description": "uses reported user for webhooks and name of cron for cron pipelines",
|
||||
"type": "string"
|
||||
},
|
||||
"started_at": {
|
||||
"description": "TODO change JSON field to \"started\" in 3.0",
|
||||
"started": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
|
@ -4722,8 +4954,7 @@ const docTemplate = `{
|
|||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "TODO change JSON field to \"updated\" in 3.0",
|
||||
"updated": {
|
||||
"type": "integer"
|
||||
},
|
||||
"variables": {
|
||||
|
@ -4868,7 +5099,7 @@ const docTemplate = `{
|
|||
"type": "integer"
|
||||
},
|
||||
"trusted": {
|
||||
"type": "boolean"
|
||||
"$ref": "#/definitions/model.TrustedConfiguration"
|
||||
},
|
||||
"visibility": {
|
||||
"$ref": "#/definitions/RepoVisibility"
|
||||
|
@ -4903,7 +5134,7 @@ const docTemplate = `{
|
|||
"type": "integer"
|
||||
},
|
||||
"trusted": {
|
||||
"type": "boolean"
|
||||
"$ref": "#/definitions/model.TrustedConfigurationPatch"
|
||||
},
|
||||
"visibility": {
|
||||
"type": "string"
|
||||
|
@ -5012,15 +5243,15 @@ const docTemplate = `{
|
|||
"Step": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "integer"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"exit_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"finished": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -5036,7 +5267,7 @@ const docTemplate = `{
|
|||
"ppid": {
|
||||
"type": "integer"
|
||||
},
|
||||
"start_time": {
|
||||
"started": {
|
||||
"type": "integer"
|
||||
},
|
||||
"state": {
|
||||
|
@ -5073,12 +5304,6 @@ const docTemplate = `{
|
|||
"agent_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"dep_status": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
|
@ -5163,6 +5388,239 @@ const docTemplate = `{
|
|||
"EventManual"
|
||||
]
|
||||
},
|
||||
"metadata.Author": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Commit": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/metadata.Author"
|
||||
},
|
||||
"branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"changed_files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"is_prerelease": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"ref": {
|
||||
"type": "string"
|
||||
},
|
||||
"refspec": {
|
||||
"type": "string"
|
||||
},
|
||||
"sha": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Forge": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Metadata": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"curr": {
|
||||
"$ref": "#/definitions/metadata.Pipeline"
|
||||
},
|
||||
"forge": {
|
||||
"$ref": "#/definitions/metadata.Forge"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"prev": {
|
||||
"$ref": "#/definitions/metadata.Pipeline"
|
||||
},
|
||||
"repo": {
|
||||
"$ref": "#/definitions/metadata.Repo"
|
||||
},
|
||||
"step": {
|
||||
"$ref": "#/definitions/metadata.Step"
|
||||
},
|
||||
"sys": {
|
||||
"$ref": "#/definitions/metadata.System"
|
||||
},
|
||||
"workflow": {
|
||||
"$ref": "#/definitions/metadata.Workflow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Pipeline": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"commit": {
|
||||
"$ref": "#/definitions/metadata.Commit"
|
||||
},
|
||||
"created": {
|
||||
"type": "integer"
|
||||
},
|
||||
"cron": {
|
||||
"type": "string"
|
||||
},
|
||||
"event": {
|
||||
"type": "string"
|
||||
},
|
||||
"finished": {
|
||||
"type": "integer"
|
||||
},
|
||||
"forge_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "integer"
|
||||
},
|
||||
"parent": {
|
||||
"type": "integer"
|
||||
},
|
||||
"started": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"target": {
|
||||
"type": "string"
|
||||
},
|
||||
"task": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Repo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"clone_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"clone_url_ssh": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"forge_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"private": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"remote_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"scm": {
|
||||
"type": "string"
|
||||
},
|
||||
"trusted": {
|
||||
"$ref": "#/definitions/metadata.TrustedConfiguration"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Step": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.System": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"arch": {
|
||||
"type": "string"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.TrustedConfiguration": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"network": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"security": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata.Workflow": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"matrix": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.ForgeType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
@ -5184,6 +5642,34 @@ const docTemplate = `{
|
|||
"ForgeTypeAddon"
|
||||
]
|
||||
},
|
||||
"model.TrustedConfiguration": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"network": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"security": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.TrustedConfigurationPatch": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"network": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"security": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.Workflow": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -5196,9 +5682,6 @@ const docTemplate = `{
|
|||
"$ref": "#/definitions/Step"
|
||||
}
|
||||
},
|
||||
"end_time": {
|
||||
"type": "integer"
|
||||
},
|
||||
"environ": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
|
@ -5208,6 +5691,9 @@ const docTemplate = `{
|
|||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"finished": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -5223,7 +5709,7 @@ const docTemplate = `{
|
|||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"start_time": {
|
||||
"started": {
|
||||
"type": "integer"
|
||||
},
|
||||
"state": {
|
||||
|
|
|
@ -27,14 +27,34 @@ import (
|
|||
|
||||
var flags = append([]cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LOG_XORM"),
|
||||
Name: "log-xorm",
|
||||
Usage: "enable xorm logging",
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_LOG", "WOODPECKER_LOG_XORM"),
|
||||
Name: "db-log",
|
||||
Aliases: []string{"log-xorm"}, // TODO: remove in v4.0.0
|
||||
Usage: "enable logging in database engine (currently xorm)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LOG_XORM_SQL"),
|
||||
Name: "log-xorm-sql",
|
||||
Usage: "enable xorm sql command logging",
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_LOG_SQL", "WOODPECKER_LOG_XORM_SQL"),
|
||||
Name: "db-log-sql",
|
||||
Aliases: []string{"log-xorm-sql"}, // TODO: remove in v4.0.0
|
||||
Usage: "enable logging of sql commands",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_MAX_CONNECTIONS"),
|
||||
Name: "db-max-open-connections",
|
||||
Usage: "max connections xorm is allowed create",
|
||||
Value: 100,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_IDLE_CONNECTIONS"),
|
||||
Name: "db-max-idle-connections",
|
||||
Usage: "amount of connections xorm will hold open",
|
||||
Value: 2,
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_CONNECTION_TIMEOUT"),
|
||||
Name: "db-max-connection-timeout",
|
||||
Usage: "time an active connection is allowed to stay open",
|
||||
Value: 3 * time.Second,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_HOST"),
|
||||
|
@ -135,10 +155,11 @@ var flags = append([]cli.Flag{
|
|||
Value: []string{"push", "pull_request"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_CLONE_IMAGE"),
|
||||
Name: "default-clone-image",
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_CLONE_PLUGIN", "WOODPECKER_DEFAULT_CLONE_IMAGE"),
|
||||
Name: "default-clone-plugin",
|
||||
Aliases: []string{"default-clone-image"},
|
||||
Usage: "The default docker image to be used when cloning the repo",
|
||||
Value: constant.DefaultCloneImage,
|
||||
Value: constant.DefaultClonePlugin,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DEFAULT_PIPELINE_TIMEOUT"),
|
||||
|
@ -159,10 +180,15 @@ var flags = append([]cli.Flag{
|
|||
Value: time.Hour * 72,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_ESCALATE"),
|
||||
Name: "escalate",
|
||||
Usage: "images to run in privileged mode",
|
||||
Value: constant.PrivilegedPlugins,
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_PRIVILEGED"),
|
||||
Name: "plugins-privileged",
|
||||
Usage: "Allow plugins to run in privileged mode, if environment variable is defined but empty there will be none",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_PLUGINS_TRUSTED_CLONE"),
|
||||
Name: "plugins-trusted-clone",
|
||||
Usage: "Plugins which are trusted to handle the netrc info in clone steps",
|
||||
Value: constant.TrustedClonePlugins,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_VOLUME"),
|
||||
|
@ -199,7 +225,8 @@ var flags = append([]cli.Flag{
|
|||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_DATABASE_DRIVER"),
|
||||
Name: "driver",
|
||||
Name: "db-driver",
|
||||
Aliases: []string{"driver"}, // TODO: remove in v4.0.0
|
||||
Usage: "database driver",
|
||||
Value: "sqlite3",
|
||||
},
|
||||
|
@ -207,9 +234,10 @@ var flags = append([]cli.Flag{
|
|||
Sources: cli.NewValueSourceChain(
|
||||
cli.File(os.Getenv("WOODPECKER_DATABASE_DATASOURCE_FILE")),
|
||||
cli.EnvVar("WOODPECKER_DATABASE_DATASOURCE")),
|
||||
Name: "datasource",
|
||||
Usage: "database driver configuration string",
|
||||
Value: datasourceDefaultValue(),
|
||||
Name: "db-datasource",
|
||||
Aliases: []string{"datasource"}, // TODO: remove in v4.0.0
|
||||
Usage: "database driver configuration string",
|
||||
Value: datasourceDefaultValue(),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.NewValueSourceChain(
|
||||
|
@ -281,7 +309,7 @@ var flags = append([]cli.Flag{
|
|||
Sources: cli.EnvVars("WOODPECKER_FORGE_TIMEOUT"),
|
||||
Name: "forge-timeout",
|
||||
Usage: "how many seconds before timeout when fetching the Woodpecker configuration from a Forge",
|
||||
Value: time.Second * 3,
|
||||
Value: time.Second * 5,
|
||||
},
|
||||
&cli.UintFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_FORGE_RETRY"),
|
||||
|
@ -289,36 +317,8 @@ var flags = append([]cli.Flag{
|
|||
Usage: "How many retries of fetching the Woodpecker configuration from a forge are done before we fail",
|
||||
Value: 3,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_MEM_SWAP"),
|
||||
Name: "limit-mem-swap",
|
||||
Usage: "maximum memory used for swap in bytes",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_MEM"),
|
||||
Name: "limit-mem",
|
||||
Usage: "maximum memory allowed in bytes",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_SHM_SIZE"),
|
||||
Name: "limit-shm-size",
|
||||
Usage: "docker compose /dev/shm allowed in bytes",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_QUOTA"),
|
||||
Name: "limit-cpu-quota",
|
||||
Usage: "impose a cpu quota",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_SHARES"),
|
||||
Name: "limit-cpu-shares",
|
||||
Usage: "change the cpu shares",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LIMIT_CPU_SET"),
|
||||
Name: "limit-cpu-set",
|
||||
Usage: "set the cpus allowed to execute containers",
|
||||
},
|
||||
//
|
||||
// generic forge settings
|
||||
//
|
||||
&cli.StringFlag{
|
||||
Name: "forge-url",
|
||||
|
@ -477,7 +477,7 @@ var flags = append([]cli.Flag{
|
|||
// expert flags
|
||||
//
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_EXPERT_WEBHOOK_HOST", "WOODPECKER_WEBHOOK_HOST"), // TODO: remove WOODPECKER_WEBHOOK_HOST in next major release
|
||||
Sources: cli.EnvVars("WOODPECKER_EXPERT_WEBHOOK_HOST"),
|
||||
Name: "server-webhook-host",
|
||||
Usage: "!!!for experts!!! fully qualified woodpecker server url called by forge's webhooks. Format: <scheme>://<host>[/<prefix path>]",
|
||||
},
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
func runGrpcServer(ctx context.Context, c *cli.Command, _store store.Store) error {
|
||||
lis, err := net.Listen("tcp", c.String("grpc-addr"))
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to listen on grpc-addr") //nolint:forbidigo
|
||||
return fmt.Errorf("failed to listen on grpc-addr: %w", err)
|
||||
}
|
||||
|
||||
jwtSecret := c.String("grpc-secret")
|
||||
|
|
|
@ -43,7 +43,6 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/store"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/store/datastore"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/store/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -52,11 +51,14 @@ const (
|
|||
)
|
||||
|
||||
func setupStore(ctx context.Context, c *cli.Command) (store.Store, error) {
|
||||
datasource := c.String("datasource")
|
||||
driver := c.String("driver")
|
||||
datasource := c.String("db-datasource")
|
||||
driver := c.String("db-driver")
|
||||
xorm := store.XORM{
|
||||
Log: c.Bool("log-xorm"),
|
||||
ShowSQL: c.Bool("log-xorm-sql"),
|
||||
Log: c.Bool("db-log"),
|
||||
ShowSQL: c.Bool("db-log-sql"),
|
||||
MaxOpenConns: int(c.Int("db-max-open-connections")),
|
||||
MaxIdleConns: int(c.Int("db-max-idle-connections")),
|
||||
ConnMaxLifetime: c.Duration("db-max-connection-timeout"),
|
||||
}
|
||||
|
||||
if driver == "sqlite3" {
|
||||
|
@ -104,8 +106,11 @@ func checkSqliteFileExist(path string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func setupQueue(ctx context.Context, s store.Store) queue.Queue {
|
||||
return queue.WithTaskStore(ctx, queue.New(ctx), s)
|
||||
func setupQueue(ctx context.Context, s store.Store) (queue.Queue, error) {
|
||||
return queue.New(ctx, queue.Config{
|
||||
Backend: queue.TypeMemory,
|
||||
Store: s,
|
||||
})
|
||||
}
|
||||
|
||||
func setupMembershipService(_ context.Context, _store store.Store) cache.MembershipService {
|
||||
|
@ -144,18 +149,19 @@ func setupJWTSecret(_store store.Store) (string, error) {
|
|||
return jwtSecret, nil
|
||||
}
|
||||
|
||||
func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error {
|
||||
func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) (err error) {
|
||||
// services
|
||||
server.Config.Services.Queue = setupQueue(ctx, s)
|
||||
server.Config.Services.Logs = logging.New()
|
||||
server.Config.Services.Pubsub = pubsub.New()
|
||||
server.Config.Services.Membership = setupMembershipService(ctx, s)
|
||||
serviceManager, err := services.NewManager(c, s, setup.Forge)
|
||||
server.Config.Services.Queue, err = setupQueue(ctx, s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not setup queue: %w", err)
|
||||
}
|
||||
server.Config.Services.Manager, err = services.NewManager(c, s, setup.Forge)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not setup service manager: %w", err)
|
||||
}
|
||||
server.Config.Services.Manager = serviceManager
|
||||
|
||||
server.Config.Services.LogStore, err = setupLogStore(c, s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not setup log store: %w", err)
|
||||
|
@ -165,8 +171,9 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error
|
|||
server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos")
|
||||
|
||||
// Cloning
|
||||
server.Config.Pipeline.DefaultCloneImage = c.String("default-clone-image")
|
||||
constant.TrustedCloneImages = append(constant.TrustedCloneImages, server.Config.Pipeline.DefaultCloneImage)
|
||||
server.Config.Pipeline.DefaultClonePlugin = c.String("default-clone-plugin")
|
||||
server.Config.Pipeline.TrustedClonePlugins = c.StringSlice("plugins-trusted-clone")
|
||||
server.Config.Pipeline.TrustedClonePlugins = append(server.Config.Pipeline.TrustedClonePlugins, server.Config.Pipeline.DefaultClonePlugin)
|
||||
|
||||
// Execution
|
||||
_events := c.StringSlice("default-cancel-previous-pipeline-events")
|
||||
|
@ -178,14 +185,6 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error
|
|||
server.Config.Pipeline.DefaultTimeout = c.Int("default-pipeline-timeout")
|
||||
server.Config.Pipeline.MaxTimeout = c.Int("max-pipeline-timeout")
|
||||
|
||||
// limits
|
||||
server.Config.Pipeline.Limits.MemSwapLimit = c.Int("limit-mem-swap")
|
||||
server.Config.Pipeline.Limits.MemLimit = c.Int("limit-mem")
|
||||
server.Config.Pipeline.Limits.ShmSize = c.Int("limit-shm-size")
|
||||
server.Config.Pipeline.Limits.CPUQuota = c.Int("limit-cpu-quota")
|
||||
server.Config.Pipeline.Limits.CPUShares = c.Int("limit-cpu-shares")
|
||||
server.Config.Pipeline.Limits.CPUSet = c.String("limit-cpu-set")
|
||||
|
||||
// backend options for pipeline compiler
|
||||
server.Config.Pipeline.Proxy.No = c.String("backend-no-proxy")
|
||||
server.Config.Pipeline.Proxy.HTTP = c.String("backend-http-proxy")
|
||||
|
@ -222,9 +221,9 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) error
|
|||
server.Config.Server.CustomJsFile = strings.TrimSpace(c.String("custom-js-file"))
|
||||
server.Config.Pipeline.Networks = c.StringSlice("network")
|
||||
server.Config.Pipeline.Volumes = c.StringSlice("volume")
|
||||
server.Config.Pipeline.Privileged = c.StringSlice("escalate")
|
||||
server.Config.WebUI.EnableSwagger = c.Bool("enable-swagger")
|
||||
server.Config.WebUI.SkipVersionCheck = c.Bool("skip-version-check")
|
||||
server.Config.Pipeline.PrivilegedPlugins = c.StringSlice("plugins-privileged")
|
||||
|
||||
// prometheus
|
||||
server.Config.Prometheus.AuthToken = c.String("prometheus-auth-token")
|
||||
|
|
|
@ -33,7 +33,7 @@ func setupSwaggerStaticConfig() {
|
|||
docs.SwaggerInfo.InfoInstanceName = "api"
|
||||
docs.SwaggerInfo.Title = "Woodpecker CI API"
|
||||
docs.SwaggerInfo.Version = version.String()
|
||||
docs.SwaggerInfo.Description = "Woodpecker is a simple yet powerful CI/CD engine with great extensibility.\n" +
|
||||
docs.SwaggerInfo.Description = "Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.\n" +
|
||||
"To get a personal access token (PAT) for authentication, please log in your Woodpecker server,\n" +
|
||||
"and go to you personal profile page, by clicking the user icon at the top right."
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
|
@ -57,6 +58,7 @@ func main() {
|
|||
|
||||
// convert to OpenApi3
|
||||
if err := toOpenApi3(filePath, filePath); err != nil {
|
||||
fmt.Printf("converting '%s' from openapi v2 to v3 failed\n", filePath)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -77,18 +79,18 @@ func removeHost(jsonIn string) (string, error) {
|
|||
func toOpenApi3(input, output string) error {
|
||||
data2, err := os.ReadFile(input)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("read input: %w", err)
|
||||
}
|
||||
|
||||
var doc2 openapi2.T
|
||||
err = json.Unmarshal(data2, &doc2)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unmarshal input: %w", err)
|
||||
}
|
||||
|
||||
doc3, err := openapi2conv.ToV3(&doc2)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("convert openapi v2 to v3: %w", err)
|
||||
}
|
||||
err = doc3.Validate(context.Background())
|
||||
if err != nil {
|
||||
|
@ -97,8 +99,12 @@ func toOpenApi3(input, output string) error {
|
|||
|
||||
data, err := json.Marshal(doc3)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("Marshal converted: %w", err)
|
||||
}
|
||||
|
||||
return os.WriteFile(output, data, 0o644)
|
||||
if err = os.WriteFile(output, data, 0o644); err != nil {
|
||||
return fmt.Errorf("write output: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ version: '3'
|
|||
|
||||
services:
|
||||
gitea-database:
|
||||
image: postgres:16.3-alpine
|
||||
image: postgres:17.0-alpine
|
||||
environment:
|
||||
POSTGRES_USER: gitea
|
||||
POSTGRES_PASSWORD: 123456
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.22 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -10,6 +10,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||
FROM docker.io/alpine:3.20
|
||||
RUN apk add -U --no-cache ca-certificates
|
||||
ENV GODEBUG=netdns=go
|
||||
# Internal setting do NOT change! Signals that woodpecker is running inside a container
|
||||
ENV WOODPECKER_IN_CONTAINER=true
|
||||
EXPOSE 3000
|
||||
|
||||
COPY --from=build /src/dist/woodpecker-agent /bin/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.22 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -10,6 +10,8 @@ RUN mkdir -p /etc/woodpecker
|
|||
|
||||
FROM scratch
|
||||
ENV GODEBUG=netdns=go
|
||||
# Internal setting do NOT change! Signals that woodpecker is running inside a container
|
||||
ENV WOODPECKER_IN_CONTAINER=true
|
||||
EXPOSE 3000
|
||||
|
||||
# copy certs from build image
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.22 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -8,7 +8,10 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||
make build-cli
|
||||
|
||||
FROM docker.io/alpine:3.20
|
||||
WORKDIR /woodpecker
|
||||
|
||||
RUN apk add -U --no-cache ca-certificates
|
||||
|
||||
ENV GODEBUG=netdns=go
|
||||
ENV WOODPECKER_DISABLE_UPDATE_CHECK=true
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.22 AS build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
@ -8,6 +8,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||
make build-cli
|
||||
|
||||
FROM scratch
|
||||
WORKDIR /woodpecker
|
||||
|
||||
ENV GODEBUG=netdns=go
|
||||
ENV WOODPECKER_DISABLE_UPDATE_CHECK=true
|
||||
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
||||
FROM docker.io/golang:1.22-alpine3.19 as golang_image
|
||||
FROM docker.io/node:22-alpine3.19
|
||||
FROM docker.io/golang:1.23-alpine as golang_image
|
||||
FROM docker.io/node:23-alpine
|
||||
|
||||
# renovate: datasource=repology depName=alpine_3_19/make versioning=loose
|
||||
ENV MAKE_VERSION="4.4.1-r2"
|
||||
# renovate: datasource=repology depName=alpine_3_19/gcc versioning=loose
|
||||
ENV GCC_VERSION="13.2.1_git20231014-r0"
|
||||
# renovate: datasource=repology depName=alpine_3_19/binutils-gold versioning=loose
|
||||
ENV BINUTILS_GOLD_VERSION="2.41-r0"
|
||||
# renovate: datasource=repology depName=alpine_3_19/musl-dev versioning=loose
|
||||
ENV MUSL_DEV_VERSION="1.2.4_git20230717-r4"
|
||||
# renovate: datasource=repology depName=alpine_3_19/protoc versioning=loose
|
||||
ENV PROTOC_VERSION="24.4-r0"
|
||||
|
||||
RUN apk add --no-cache --update make=${MAKE_VERSION} gcc=${GCC_VERSION} binutils-gold=${BINUTILS_GOLD_VERSION} musl-dev=${MUSL_DEV_VERSION} protoc=${PROTOC_VERSION} && \
|
||||
RUN apk add --no-cache --update make gcc binutils-gold musl-dev protoc && \
|
||||
corepack enable
|
||||
|
||||
# Build packages.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.22 AS certs
|
||||
FROM --platform=$BUILDPLATFORM docker.io/golang:1.23 AS certs
|
||||
|
||||
FROM scratch
|
||||
ARG TARGETOS TARGETARCH
|
||||
|
|
|
@ -53,7 +53,7 @@ Security is pretty important to us and we want to make sure that no one can stea
|
|||
|
||||
## Migration notes
|
||||
|
||||
There have been a few more breaking changes. [Read more about what you need to do when upgrading!](../docs/migrations#200)
|
||||
There have been a few more breaking changes. [Read more about what you need to do when upgrading!](/migrations#200)
|
||||
|
||||
## New features
|
||||
|
||||
|
|
60
docs/blog/2023-12-12-podman-image-builds/index.md
Normal file
60
docs/blog/2023-12-12-podman-image-builds/index.md
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: '[Community] Podman-in-Podman image builds'
|
||||
description: Build images in Podman with buildah
|
||||
slug: podman-image-builds
|
||||
authors:
|
||||
- name: handlebargh
|
||||
url: https://github.com/handlebargh
|
||||
image_url: https://github.com/handlebargh.png
|
||||
hide_table_of_contents: true
|
||||
tags: [community, image, podman]
|
||||
---
|
||||
|
||||
<!-- cspell:ignore buildah Containerfile roundcube -->
|
||||
|
||||
I run Woodpecker CI with podman backend instead of docker and just figured out how to build images with buildah. Since I couldn't find this anywhere documented, I thought I might as well just share it here.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
It's actually pretty straight forward. Here's what my repository structure looks like:
|
||||
|
||||
```bash
|
||||
.
|
||||
├── roundcube
|
||||
│ ├── Containerfile
|
||||
│ ├── docker-entrypoint.sh
|
||||
│ └── php.ini
|
||||
└── .woodpecker
|
||||
└── .build_roundcube.yml
|
||||
```
|
||||
|
||||
As you can see I'm building a roundcube mail image.
|
||||
|
||||
This is the `.woodpecker/.build_roundcube.yaml`
|
||||
|
||||
```yaml
|
||||
when:
|
||||
event: [cron, manual]
|
||||
cron: build_roundcube
|
||||
|
||||
steps:
|
||||
build-image:
|
||||
image: quay.io/buildah/stable:latest
|
||||
pull: true
|
||||
privileged: true
|
||||
commands:
|
||||
- echo $REGISTRY_LOGIN_TOKEN | buildah login -u <username> --password-stdin registry.gitlab.com
|
||||
- cd roundcube
|
||||
- buildah build --tag registry.gitlab.com/<namespace>/<repository_name>/roundcube:latest .
|
||||
- buildah push registry.gitlab.com/<namespace>/<repository_name>/roundcube:latest
|
||||
|
||||
secrets: [registry_login_token]
|
||||
```
|
||||
|
||||
As you can see, I'm using this workflow over at gitlab.com. It should work with GitHub as well, with adjusting the registry login.
|
||||
|
||||
You may have to adjust the `when:` to your needs. Furthermore, you must check the `trusted` checkbox in project settings. Therefore, be sure to run trusted code only in this setup.
|
||||
|
||||
This seems to work fine so far. I wonder if anybody else made this work a different way.
|
||||
|
||||
EDIT: Removed the additional step that would run buildah in a podman container. I didn't know it could be that easy to be honest.
|
31
docs/blog/2023-12-13-debug-pipeline-steps/index.md
Normal file
31
docs/blog/2023-12-13-debug-pipeline-steps/index.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
title: '[Community] Debug pipeline steps'
|
||||
description: Debug pipeline steps using sshx
|
||||
slug: debug-pipeline-steps
|
||||
authors:
|
||||
- name: anbraten
|
||||
url: https://github.com/anbraten
|
||||
image_url: https://github.com/anbraten.png
|
||||
hide_table_of_contents: true
|
||||
tags: [community, debug]
|
||||
---
|
||||
|
||||
<!-- cspell:ignore sshx -->
|
||||
|
||||
Sometimes you want to debug a pipeline.
|
||||
Therefore I recently discovered: <https://github.com/ekzhang/sshx>
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
A simple step like should allow you to debug:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: debug
|
||||
image: alpine
|
||||
commands:
|
||||
- curl -sSf https://sshx.io/get | sh && sshx
|
||||
# ^
|
||||
# └ This will open a remote terminal session and print the URL. It
|
||||
# should take under a second.
|
||||
```
|
140
docs/blog/2023-12-15-podman-sigstore/index.md
Normal file
140
docs/blog/2023-12-15-podman-sigstore/index.md
Normal file
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
title: '[Community] Podman image build with sigstore'
|
||||
description: Build images in Podman with sigstore signature checking and signing
|
||||
slug: podman-image-build-sigstore
|
||||
authors:
|
||||
- name: handlebargh
|
||||
url: https://github.com/handlebargh
|
||||
image_url: https://github.com/handlebargh.png
|
||||
hide_table_of_contents: false
|
||||
tags: [community, image, podman, sigstore, signature]
|
||||
---
|
||||
|
||||
<!-- cspell:ignore BQVUJ Containerfile cosing distroless fulcio keypair nonroot QVRFLS rekor skopeo -->
|
||||
|
||||
This example shows how to build a container image with podman while verifying the base image and signing the resulting image.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
The image being pulled uses a keyless signature, while the image being built will be signed by a pre-generated private key.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Generate signing keypair
|
||||
|
||||
You can use cosing or skopeo to generate the keypair.
|
||||
|
||||
Using skopeo:
|
||||
|
||||
```bash
|
||||
skopeo generate-sigstore-key --output-prefix myKey
|
||||
```
|
||||
|
||||
This command will generate a `myKey.private` and a `myKey.pub` keyfile.
|
||||
|
||||
Store the `myKey.private` as secret in Woodpecker. In the example below, the secret is called `sigstore_private_key`
|
||||
|
||||
### Configure hosts pulling the resulting image
|
||||
|
||||
See [here](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/assembly_signing-container-images_building-running-and-managing-containers#proc_verifying-sigstore-image-signatures-using-a-public-key_assembly_signing-container-images) on how to configure the hosts pulling the built and signed image.
|
||||
|
||||
## Repository structure
|
||||
|
||||
Consider the `Makefile` having a `build` target that will be used in the following workflow.
|
||||
This target yields a Go binary with the filename `app` that will be placed in the root directory.
|
||||
|
||||
```bash
|
||||
.
|
||||
├── Containerfile
|
||||
├── main.go
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .woodpecker.yml
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
### Containerfile
|
||||
|
||||
The Containerfile refers to the base image that will be verified when pulled.
|
||||
|
||||
```dockerfile
|
||||
FROM gcr.io/distroless/static-debian12:nonroot
|
||||
COPY app /app
|
||||
CMD ["/app"]
|
||||
```
|
||||
|
||||
### Woodpecker workflow
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
build:
|
||||
image: docker.io/library/golang:1.21
|
||||
pull: true
|
||||
commands:
|
||||
- make build
|
||||
|
||||
publish:
|
||||
image: quay.io/podman/stable:latest
|
||||
# Caution: This image is built daily. It might fill up your image store quickly.
|
||||
pull: true
|
||||
# Fill in the trusted checkbox in Woodpecker's settings as well
|
||||
privileged: true
|
||||
commands:
|
||||
# Configure podman to use sigstore attachments for both, the registry you pull from and the registry you push to.
|
||||
- |
|
||||
printf "docker:
|
||||
registry.gitlab.com:
|
||||
use-sigstore-attachments: true
|
||||
gcr.io:
|
||||
use-sigstore-attachments: true" >> /etc/containers/registries.d/default.yaml
|
||||
|
||||
# At pull, check the keyless sigstore signature of the distroless image.
|
||||
# This is a very strict container policy. It allows pulling from gcr.io/distroless only. Every other registry will be rejected.
|
||||
# See https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md for more information.
|
||||
|
||||
# fulcio CA crt obtained from https://github.com/sigstore/sigstore/blob/main/pkg/tuf/repository/targets/fulcio_v1.crt.pem
|
||||
# rekor public key obtained from https://github.com/sigstore/sigstore/blob/main/pkg/tuf/repository/targets/rekor.pub
|
||||
# crt/key data is base64 encoded. --> echo "$CERT" | base64
|
||||
- |
|
||||
printf '{
|
||||
"default": [
|
||||
{
|
||||
"type": "reject"
|
||||
}
|
||||
],
|
||||
"transports": {
|
||||
"docker": {
|
||||
"gcr.io/distroless": [
|
||||
{
|
||||
"type": "sigstoreSigned",
|
||||
"fulcio": {
|
||||
"caData": "LS0tLS1CRUdJTiBDR...QVRFLS0tLS0K",
|
||||
"oidcIssuer": "https://accounts.google.com",
|
||||
"subjectEmail": "keyless@distroless.iam.gserviceaccount.com"
|
||||
},
|
||||
"rekorPublicKeyData": "LS0tLS1CRUdJTiBQVUJ...lDIEtFWS0tLS0tCg==",
|
||||
"signedIdentity": { "type": "matchRepository" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"docker-daemon": {
|
||||
"": [
|
||||
{
|
||||
"type": "reject"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}' > /etc/containers/policy.json
|
||||
|
||||
# Use this key to sign the built image at push.
|
||||
- echo "$SIGSTORE_PRIVATE_KEY" > key.private
|
||||
# Login at the registry
|
||||
- echo $REGISTRY_LOGIN_TOKEN | podman login -u <username> --password-stdin registry.gitlab.com
|
||||
# Build the container image
|
||||
- podman build --tag registry.gitlab.com/<namespace>/<repository_name>/<image_name>:latest .
|
||||
# Sign and push the image
|
||||
- podman push --sign-by-sigstore-private-key ./key.private registry.gitlab.com/<namespace>/<repository_name>/<image_name>:latest
|
||||
|
||||
secrets: [sigstore_private_key, registry_login_token]
|
||||
```
|
|
@ -87,4 +87,4 @@ be removed in the next major release:
|
|||
- Use `WOODPECKER_EXPERT_FORGE_OAUTH_HOST` instead of `WOODPECKER_DEV_GITEA_OAUTH_URL` or `WOODPECKER_DEV_OAUTH_HOST`
|
||||
- Deprecated `WOODPECKER_WEBHOOK_HOST` in favor of `WOODPECKER_EXPERT_WEBHOOK_HOST`
|
||||
|
||||
For a full list of deprecations that will be dropped in the `next` major release `3.0.0` (no eta yet), please check the [migrations](/docs/migrations#next) section.
|
||||
For a full list of deprecations that will be dropped in the `next` major release `3.0.0` (no eta yet), please check the [migrations](/migrations#next) section.
|
||||
|
|
|
@ -86,16 +86,17 @@ Sometimes you have some tasks that you need to do in every project. For example,
|
|||
If you want to get a Slack notification after your pipeline has finished, you can add a Slack plugin to your pipeline:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: notify me on Slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: developers
|
||||
username: woodpecker
|
||||
password:
|
||||
from_secret: slack_token
|
||||
when:
|
||||
status: [success, failure] # This will execute the step on success and failure
|
||||
steps:
|
||||
# ...
|
||||
- name: notify me on Slack
|
||||
image: plugins/slack
|
||||
settings:
|
||||
channel: developers
|
||||
username: woodpecker
|
||||
password:
|
||||
from_secret: slack_token
|
||||
when:
|
||||
status: [success, failure] # This will execute the step on success and failure
|
||||
```
|
||||
|
||||
To configure a plugin you can use the `settings` section.
|
||||
|
|
|
@ -7,18 +7,18 @@
|
|||
- **Server**: The component of Woodpecker that handles webhooks from forges, orchestrates agents, and sends status back. It also serves the API and web UI for administration and configuration.
|
||||
- **Agent**: A component of Woodpecker that executes [pipelines][Pipeline] (specifically one or more [workflows][Workflow]) with a specific backend (e.g. [Docker][], Kubernetes, [local][Local]). It connects to the server via GRPC.
|
||||
- **CLI**: The Woodpecker command-line interface (CLI) is a terminal tool used to administer the server, to execute pipelines locally for debugging / testing purposes, and to perform tasks like linting pipelines.
|
||||
- **Pipeline**: A sequence of [workflows][Workflow] that are executed on the code. [Pipelines][Pipeline] are triggered by events.
|
||||
- **Workflow**: A sequence of steps and services that are executed as part of a [pipeline][Pipeline]. Workflows are represented by YAML files. Each [workflow][Workflow] has its own isolated [workspace][Workspace], and often additional resources like a shared network (docker).
|
||||
- **[Pipeline][Pipeline]**: A sequence of [workflows][Workflow] that are executed on the code. Pipelines are triggered by events.
|
||||
- **[Workflow][Workflow]**: A sequence of steps and services that are executed as part of a [pipeline][Pipeline]. Workflows are represented by YAML files. Each workflow has its own isolated [workspace][Workspace], and often additional resources like a shared network (docker).
|
||||
- **Steps**: Individual commands, actions or tasks within a [workflow][Workflow].
|
||||
- **Code**: Refers to the files tracked by the version control system used by the [forge][Forge].
|
||||
- **Repos**: Short for repositories, these are storage locations where code is stored.
|
||||
- **Forge**: The hosting platform or service where the repositories are hosted.
|
||||
- **Workspace**: A folder shared between all steps of a [workflow][Workflow] containing the repository and all the generated data from previous steps.
|
||||
- **Event**: Triggers the execution of a [pipeline][Pipeline], such as a [forge][Forge] event like `push`, or `manual` triggered manually from the UI.
|
||||
- **[Forge][Forge]**: The hosting platform or service where the repositories are hosted.
|
||||
- **[Workspace][workspace]**: A folder shared between all steps of a [workflow][Workflow] containing the repository and all the generated data from previous steps.
|
||||
- **[Event][Event]**: Triggers the execution of a [pipeline][Pipeline], such as a [forge][Forge] event like `push`, or `manual` triggered manually from the UI.
|
||||
- **Commit**: A defined state of the code, usually associated with a version control system like Git.
|
||||
- **Matrix**: A configuration option that allows the execution of [workflows][Workflow] for each value in the [matrix][Matrix].
|
||||
- **[Matrix][Matrix]**: A configuration option that allows the execution of [workflows][Workflow] for each value in the matrix.
|
||||
- **Service**: A service is a step that is executed from the start of a [workflow][Workflow] until its end. It can be accessed by name via the network from other steps within the same [workflow][Workflow].
|
||||
- **Plugins**: [Plugins][Plugin] are extensions that provide pre-defined actions or commands for a step in a [workflow][Workflow]. They can be configured via settings.
|
||||
- **[Plugins][Plugin]**: Plugins are extensions that provide pre-defined actions or commands for a step in a [workflow][Workflow]. They can be configured via settings.
|
||||
- **Container**: A lightweight and isolated environment where commands are executed.
|
||||
- **YAML File**: A file format used to define and configure [workflows][Workflow].
|
||||
- **Dependency**: [Workflows][Workflow] can depend on each other, and if possible, they are executed in parallel.
|
||||
|
@ -33,16 +33,6 @@
|
|||
|
||||
![Relation between pipelines, workflows and steps](pipeline-workflow-step.svg)
|
||||
|
||||
## Pipeline events
|
||||
|
||||
- `push`: A push event is triggered when a commit is pushed to a branch.
|
||||
- `pull_request`: A pull request event is triggered when a pull request is opened or a new commit is pushed to it.
|
||||
- `pull_request_closed`: A pull request closed event is triggered when a pull request is closed or merged.
|
||||
- `tag`: A tag event is triggered when a tag is pushed.
|
||||
- `release`: A release event is triggered when a release, pre-release or draft is created. (You can apply further filters using [evaluate](../20-workflow-syntax.md#evaluate) with [environment variables](../50-environment.md#built-in-environment-variables).)
|
||||
- `manual`: A manual event is triggered when a user manually triggers a pipeline.
|
||||
- `cron`: A cron event is triggered when a cron job is executed.
|
||||
|
||||
## Conventions
|
||||
|
||||
Sometimes there are multiple terms that can be used to describe something. This section lists the preferred terms to use in Woodpecker:
|
||||
|
@ -54,6 +44,7 @@ Sometimes there are multiple terms that can be used to describe something. This
|
|||
|
||||
<!-- References -->
|
||||
|
||||
[Event]: ../20-workflow-syntax.md#event
|
||||
[Pipeline]: ../20-workflow-syntax.md
|
||||
[Workflow]: ../25-workflows.md
|
||||
[Forge]: ../../30-administration/11-forges/11-overview.md
|
||||
|
|
|
@ -104,7 +104,7 @@ When using the `local` backend, the `image` entry is used to specify the shell,
|
|||
- go test
|
||||
|
||||
- name: publish
|
||||
+ image: plugins/docker
|
||||
+ image: woodpeckerci/plugin-kaniko
|
||||
repo: foo/bar
|
||||
|
||||
services:
|
||||
|
@ -179,12 +179,6 @@ Woodpecker provides the ability to pass environment variables to individual step
|
|||
|
||||
For more details, check the [environment docs](./50-environment.md).
|
||||
|
||||
### `secrets`
|
||||
|
||||
Woodpecker provides the ability to store named parameters external to the YAML configuration file, in a central secret store. These secrets can be passed to individual steps of the workflow at runtime.
|
||||
|
||||
For more details, check the [secrets docs](./40-secrets.md).
|
||||
|
||||
### `failure`
|
||||
|
||||
Some of the steps may be allowed to fail without causing the whole workflow and therefore pipeline to report a failure (e.g., a step executing a linting check). To enable this, add `failure: ignore` to your step. If Woodpecker encounters an error while executing the step, it will report it as failed but still executes the next steps of the workflow, if any, without affecting the status of the workflow.
|
||||
|
@ -288,7 +282,16 @@ when:
|
|||
|
||||
#### `event`
|
||||
|
||||
Available events: `push`, `pull_request`, `pull_request_closed`, `tag`, `release`, `deployment`, `cron`, `manual`
|
||||
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.
|
||||
- `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` (only available for GitHub): triggered when a deployment is created in the repository.
|
||||
- `cron`: triggered when a cron job is executed.
|
||||
- `manual`: triggered when a user manually triggers a pipeline.
|
||||
|
||||
Execute a step if the build event is a `tag`:
|
||||
|
||||
|
@ -475,7 +478,7 @@ Normally steps of a workflow are executed serially in the order in which they ar
|
|||
- go build
|
||||
|
||||
- name: deploy
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
repo: foo/bar
|
||||
+ depends_on: [build, test] # deploy will be executed after build and test finished
|
||||
|
@ -601,7 +604,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_filter_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/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.
|
||||
|
||||
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.
|
||||
|
|
|
@ -23,13 +23,13 @@ If you still need to pass artifacts between the workflows you need use some stor
|
|||
|
||||
```bash
|
||||
.woodpecker/
|
||||
├── .build.yaml
|
||||
├── .deploy.yaml
|
||||
├── .lint.yaml
|
||||
└── .test.yaml
|
||||
├── build.yaml
|
||||
├── deploy.yaml
|
||||
├── lint.yaml
|
||||
└── test.yaml
|
||||
```
|
||||
|
||||
```yaml title=".woodpecker/.build.yaml"
|
||||
```yaml title=".woodpecker/build.yaml"
|
||||
steps:
|
||||
- name: build
|
||||
image: debian:stable-slim
|
||||
|
@ -38,7 +38,7 @@ steps:
|
|||
- sleep 5
|
||||
```
|
||||
|
||||
```yaml title=".woodpecker/.deploy.yaml"
|
||||
```yaml title=".woodpecker/deploy.yaml"
|
||||
steps:
|
||||
- name: deploy
|
||||
image: debian:stable-slim
|
||||
|
@ -51,7 +51,7 @@ depends_on:
|
|||
- test
|
||||
```
|
||||
|
||||
```yaml title=".woodpecker/.test.yaml"
|
||||
```yaml title=".woodpecker/test.yaml"
|
||||
steps:
|
||||
- name: test
|
||||
image: debian:stable-slim
|
||||
|
@ -63,7 +63,7 @@ depends_on:
|
|||
- build
|
||||
```
|
||||
|
||||
```yaml title=".woodpecker/.lint.yaml"
|
||||
```yaml title=".woodpecker/lint.yaml"
|
||||
steps:
|
||||
- name: lint
|
||||
image: debian:stable-slim
|
||||
|
|
|
@ -11,26 +11,7 @@ Woodpecker provides three different levels to add secrets to your pipeline. The
|
|||
|
||||
## Usage
|
||||
|
||||
### Use secrets in commands
|
||||
|
||||
Secrets are exposed to your pipeline steps and plugins as uppercase environment variables and can therefore be referenced in the commands section of your pipeline,
|
||||
once their usage is declared in the `secrets` section:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: docker
|
||||
commands:
|
||||
+ - echo $docker_username
|
||||
+ - echo $DOCKER_PASSWORD
|
||||
+ secrets: [ docker_username, DOCKER_PASSWORD ]
|
||||
```
|
||||
|
||||
The case of the environment variables is not changed, but secret matching is done case-insensitively. In the example above, `DOCKER_PASSWORD` would also match if the secret is called `docker_password`.
|
||||
|
||||
### Use secrets in settings and environment
|
||||
|
||||
You can set an setting or environment value from secrets using the `from_secret` syntax.
|
||||
You can set a setting or an environment value from secrets using the `from_secret` syntax.
|
||||
|
||||
In this example, the secret named `secret_token` would be passed to the setting named `token`,which will be available in the plugin as environment variable named `PLUGIN_TOKEN` (See [plugins](./51-plugins/20-creating-plugins.md#settings) for details), and to the environment variable `TOKEN_ENV`.
|
||||
|
||||
|
@ -55,11 +36,11 @@ Please note parameter expressions are subject to pre-processing. When using secr
|
|||
- name: docker
|
||||
image: docker
|
||||
commands:
|
||||
- - echo ${docker_username}
|
||||
- - echo ${DOCKER_PASSWORD}
|
||||
+ - echo $${docker_username}
|
||||
+ - echo $${DOCKER_PASSWORD}
|
||||
secrets: [ docker_username, DOCKER_PASSWORD ]
|
||||
- - echo ${TOKEN_ENV}
|
||||
+ - echo $${TOKEN_ENV}
|
||||
environment:
|
||||
TOKEN_ENV:
|
||||
from_secret: secret_token
|
||||
```
|
||||
|
||||
### Use in Pull Requests events
|
||||
|
@ -70,9 +51,16 @@ Secrets are not exposed to pull requests by default. You can override this behav
|
|||
Please be careful when exposing secrets to pull requests. If your repository is open source and accepts pull requests your secrets are not safe. A bad actor can submit a malicious pull request that exposes your secrets.
|
||||
:::
|
||||
|
||||
## Image filter
|
||||
## Plugins filter
|
||||
|
||||
To prevent abusing your secrets from malicious usage, you can limit a secret to a list of images. If enabled they are not available to any other plugin (steps without user-defined commands). If you or an attacker defines explicit commands, the secrets will not be available to the container to prevent leaking them.
|
||||
To prevent abusing your secrets from malicious usage, you can limit a secret to a list of plugins. If enabled they are not available to any other plugin (steps without user-defined commands). If you or an attacker defines explicit commands, the secrets will not be available to the container to prevent leaking them.
|
||||
|
||||
:::note
|
||||
If you specify a tag, the filter will respect it.
|
||||
Just make sure you don't specify the same image without one, otherwise it will be ignored again.
|
||||
:::
|
||||
|
||||
![plugins filter](./secrets-plugins-filter.png)
|
||||
|
||||
## Adding Secrets
|
||||
|
||||
|
|
|
@ -35,10 +35,6 @@ Example registry hostname matching logic:
|
|||
- Hostname `docker.io` matches `bradrydzewski/golang`
|
||||
- Hostname `docker.io` matches `bradrydzewski/golang:latest`
|
||||
|
||||
:::note
|
||||
The flow above doesn't work in Kubernetes. There is [workaround](../30-administration/22-backends/40-kubernetes.md#images-from-private-registries).
|
||||
:::
|
||||
|
||||
## Global registry support
|
||||
|
||||
To make a private registry globally available, check the [server configuration docs](../30-administration/10-server-config.md#global-registry-setting).
|
||||
|
|
|
@ -23,12 +23,6 @@ To configure cron jobs you need at least push access to the repository.
|
|||
|
||||
![cron settings](./cron-settings.png)
|
||||
|
||||
The supported schedule syntax can be found at <https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc#hdr-CRON_Expression_Format>. If you need general understanding of the cron syntax <https://it-tools.tech/crontab-generator> is a good place to start and experiment.
|
||||
The supported schedule syntax can be found at <https://pkg.go.dev/github.com/gdgvda/cron#hdr-CRON_Expression_Format>. If you need general understanding of the cron syntax <https://it-tools.tech/crontab-generator> is a good place to start and experiment.
|
||||
|
||||
Examples: `@every 5m`, `@daily`, `0 30 * * * *` ...
|
||||
|
||||
:::info
|
||||
Woodpeckers cron syntax starts with seconds instead of minutes as used by most linux cron schedulers.
|
||||
|
||||
Example: "At minute 30 every hour" would be `0 30 * * * *` instead of `30 * * * *`
|
||||
:::
|
||||
Examples: `@every 5m`, `@daily`, `30 * * * *` ...
|
||||
|
|
|
@ -48,97 +48,95 @@ Please note that the environment section is not able to expand environment varia
|
|||
|
||||
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 |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| `CI` | CI environment name (value: `woodpecker`) |
|
||||
| | **Repository** |
|
||||
| `CI_REPO` | repository full name `<owner>/<name>` |
|
||||
| `CI_REPO_OWNER` | repository owner |
|
||||
| `CI_REPO_NAME` | repository name |
|
||||
| `CI_REPO_REMOTE_ID` | repository remote ID, is the UID it has in the forge |
|
||||
| `CI_REPO_SCM` | repository SCM (git) |
|
||||
| `CI_REPO_URL` | repository web URL |
|
||||
| `CI_REPO_CLONE_URL` | repository clone URL |
|
||||
| `CI_REPO_CLONE_SSH_URL` | repository SSH clone URL |
|
||||
| `CI_REPO_DEFAULT_BRANCH` | repository default branch (main) |
|
||||
| `CI_REPO_PRIVATE` | repository is private |
|
||||
| `CI_REPO_TRUSTED` | repository is trusted |
|
||||
| | **Current Commit** |
|
||||
| `CI_COMMIT_SHA` | commit SHA |
|
||||
| `CI_COMMIT_REF` | commit ref |
|
||||
| `CI_COMMIT_REFSPEC` | commit ref spec |
|
||||
| `CI_COMMIT_BRANCH` | commit branch (equals target branch for pull requests) |
|
||||
| `CI_COMMIT_SOURCE_BRANCH` | commit source branch (empty if event is not `pull_request` or `pull_request_closed`) |
|
||||
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (empty if event is not `pull_request` or `pull_request_closed`) |
|
||||
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) |
|
||||
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (empty if event is not `pull_request` or `pull_request_closed`) |
|
||||
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (empty if event is not `pull_request` or `pull_request_closed`) |
|
||||
| `CI_COMMIT_MESSAGE` | commit message |
|
||||
| `CI_COMMIT_AUTHOR` | commit author username |
|
||||
| `CI_COMMIT_AUTHOR_EMAIL` | commit author email address |
|
||||
| `CI_COMMIT_AUTHOR_AVATAR` | commit author avatar |
|
||||
| `CI_COMMIT_PRERELEASE` | release is a pre-release (empty if event is not `release`) |
|
||||
| | **Current pipeline** |
|
||||
| `CI_PIPELINE_NUMBER` | pipeline number |
|
||||
| `CI_PIPELINE_PARENT` | number of parent pipeline |
|
||||
| `CI_PIPELINE_EVENT` | pipeline event (see [pipeline events](../20-usage/15-terminology/index.md#pipeline-events)) |
|
||||
| `CI_PIPELINE_URL` | link to the web UI for the pipeline |
|
||||
| `CI_PIPELINE_FORGE_URL` | link to the forge's web UI for the commit(s) or tag that triggered the pipeline |
|
||||
| `CI_PIPELINE_DEPLOY_TARGET` | pipeline deploy target for `deployment` events (i.e. production) |
|
||||
| `CI_PIPELINE_DEPLOY_TASK` | pipeline deploy task for `deployment` events (i.e. migration) |
|
||||
| `CI_PIPELINE_STATUS` | pipeline status (success, failure) |
|
||||
| `CI_PIPELINE_CREATED` | pipeline created UNIX timestamp |
|
||||
| `CI_PIPELINE_STARTED` | pipeline started UNIX timestamp |
|
||||
| `CI_PIPELINE_FINISHED` | pipeline finished UNIX timestamp |
|
||||
| `CI_PIPELINE_FILES` | changed files (empty if event is not `push` or `pull_request`), it is undefined if more than 500 files are touched |
|
||||
| | **Current workflow** |
|
||||
| `CI_WORKFLOW_NAME` | workflow name |
|
||||
| | **Current step** |
|
||||
| `CI_STEP_NAME` | step name |
|
||||
| `CI_STEP_NUMBER` | step number |
|
||||
| `CI_STEP_STATUS` | step status (success, failure) |
|
||||
| `CI_STEP_STARTED` | step started UNIX timestamp |
|
||||
| `CI_STEP_FINISHED` | step finished UNIX timestamp |
|
||||
| `CI_STEP_URL` | URL to step in UI |
|
||||
| | **Previous commit** |
|
||||
| `CI_PREV_COMMIT_SHA` | previous commit SHA |
|
||||
| `CI_PREV_COMMIT_REF` | previous commit ref |
|
||||
| `CI_PREV_COMMIT_REFSPEC` | previous commit ref spec |
|
||||
| `CI_PREV_COMMIT_BRANCH` | previous commit branch |
|
||||
| `CI_PREV_COMMIT_SOURCE_BRANCH` | previous commit source branch |
|
||||
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch |
|
||||
| `CI_PREV_COMMIT_URL` | previous commit link in forge |
|
||||
| `CI_PREV_COMMIT_MESSAGE` | previous commit message |
|
||||
| `CI_PREV_COMMIT_AUTHOR` | previous commit author username |
|
||||
| `CI_PREV_COMMIT_AUTHOR_EMAIL` | previous commit author email address |
|
||||
| `CI_PREV_COMMIT_AUTHOR_AVATAR` | previous commit author avatar |
|
||||
| | **Previous pipeline** |
|
||||
| `CI_PREV_PIPELINE_NUMBER` | previous pipeline number |
|
||||
| `CI_PREV_PIPELINE_PARENT` | previous pipeline number of parent pipeline |
|
||||
| `CI_PREV_PIPELINE_EVENT` | previous pipeline event (see [pipeline events](../20-usage/15-terminology/index.md#pipeline-events)) |
|
||||
| `CI_PREV_PIPELINE_URL` | previous pipeline link in CI |
|
||||
| `CI_PREV_PIPELINE_FORGE_URL` | previous pipeline link to event in forge |
|
||||
| `CI_PREV_PIPELINE_DEPLOY_TARGET` | previous pipeline deploy target for `deployment` events (ie production) |
|
||||
| `CI_PREV_PIPELINE_DEPLOY_TASK` | previous pipeline deploy task for `deployment` events (ie migration) |
|
||||
| `CI_PREV_PIPELINE_STATUS` | previous pipeline status (success, failure) |
|
||||
| `CI_PREV_PIPELINE_CREATED` | previous pipeline created UNIX timestamp |
|
||||
| `CI_PREV_PIPELINE_STARTED` | previous pipeline started UNIX timestamp |
|
||||
| `CI_PREV_PIPELINE_FINISHED` | previous pipeline finished UNIX timestamp |
|
||||
| |   |
|
||||
| `CI_WORKSPACE` | Path of the workspace where source code gets cloned to |
|
||||
| | **System** |
|
||||
| `CI_SYSTEM_NAME` | name of the CI system: `woodpecker` |
|
||||
| `CI_SYSTEM_URL` | link to CI system |
|
||||
| `CI_SYSTEM_HOST` | hostname of CI server |
|
||||
| `CI_SYSTEM_VERSION` | version of the server |
|
||||
| | **Forge** |
|
||||
| `CI_FORGE_TYPE` | name of forge (gitea, github, ...) |
|
||||
| `CI_FORGE_URL` | root URL of configured forge |
|
||||
| | **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) |
|
||||
| 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_SCM` | repository SCM | `git` |
|
||||
| `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 (empty if event is not `pull_request` or `pull_request_closed`) | `issue-branch` |
|
||||
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (empty if event is not `pull_request` or `pull_request_closed`) | `main` |
|
||||
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) | `v1.10.3` |
|
||||
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (empty if event is not `pull_request` or `pull_request_closed`) | `1` |
|
||||
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (empty if event is not `pull_request` or `pull_request_closed`) | `server` |
|
||||
| `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_AUTHOR_AVATAR` | commit author avatar | `https://git.example.com/avatars/5dcbcadbce6f87f8abef` |
|
||||
| `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`, `tag`, `release`, `manual`, `cron` |
|
||||
| `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"]` |
|
||||
| | **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 | `issue-branch` |
|
||||
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch | `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` |
|
||||
| `CI_PREV_COMMIT_AUTHOR_AVATAR` | previous commit author avatar | `https://git.example.com/avatars/12` |
|
||||
| | **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`, `tag`, `release`, `manual`, `cron` |
|
||||
| `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_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
|
||||
|
||||
|
@ -172,7 +170,7 @@ Example commit substitution:
|
|||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
+ tags: ${CI_COMMIT_SHA}
|
||||
```
|
||||
|
@ -182,7 +180,7 @@ Example tag substitution:
|
|||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
+ tags: ${CI_COMMIT_TAG}
|
||||
```
|
||||
|
@ -210,7 +208,7 @@ Example variable substitution with substring:
|
|||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
+ tags: ${CI_COMMIT_SHA:0:8}
|
||||
```
|
||||
|
@ -220,7 +218,7 @@ Example variable substitution strips `v` prefix from `v.1.0.0`:
|
|||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
+ tags: ${CI_COMMIT_TAG##v}
|
||||
```
|
||||
|
|
|
@ -42,7 +42,7 @@ Values like this are converted to JSON and then passed to your plugin. In the ex
|
|||
|
||||
### Secrets
|
||||
|
||||
Secrets should be passed as settings too. Therefore, users should use [`from_secret`](../40-secrets.md#use-secrets-in-settings-and-environment).
|
||||
Secrets should be passed as settings too. Therefore, users should use [`from_secret`](../40-secrets.md#usage).
|
||||
|
||||
## Plugin library
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ steps:
|
|||
- go test
|
||||
|
||||
- name: publish
|
||||
image: plugins/docker
|
||||
image: woodpeckerci/plugin-kaniko
|
||||
settings:
|
||||
repo: foo/bar
|
||||
tags: latest
|
||||
|
@ -50,9 +50,10 @@ steps:
|
|||
Plugins are just pipeline steps. They share the build workspace, mounted as a volume, and therefore have access to your source tree.
|
||||
While normal steps are all about arbitrary code execution, plugins should only allow the functions intended by the plugin author.
|
||||
|
||||
So there are a few limitations, like the workspace base is always mounted at `/woodpecker`, but the working directory is dynamically adjusted accordingly. So as user of a plugin you should not have to care about this.
|
||||
|
||||
Also instead of using environment variables the plugin should only care about one prefixed with `PLUGIN_` witch are the internal representation of the **settings** ([read more](./20-creating-plugins.md)).
|
||||
That's why there are a few limitations. The workspace base is always mounted at `/woodpecker`, but the working directory is dynamically
|
||||
adjusted accordingly, as user of a plugin you should not have to care about this. Also, you cannot use the plugin together with `commands`
|
||||
or `entrypoint` which will fail. Using `environment` is possible, but in this case, the plugin is internally not treated as plugin
|
||||
anymore. The container then cannot access secrets with plugin filter anymore and the containers won't be privileged without explicit definition.
|
||||
|
||||
## Finding Plugins
|
||||
|
||||
|
|
BIN
docs/docs/20-usage/secrets-plugins-filter.png
Normal file
BIN
docs/docs/20-usage/secrets-plugins-filter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -32,9 +32,9 @@ In addition you need at least some kind of database which requires additional re
|
|||
|
||||
## 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:
|
||||
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 [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)
|
||||
|
@ -55,5 +55,5 @@ Check the [server configuration](./10-server-config.md) and [agent configuration
|
|||
|
||||
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.
|
||||
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,12 +1,10 @@
|
|||
# docker-compose
|
||||
# docker compose
|
||||
|
||||
The below [docker-compose](https://docs.docker.com/compose/) configuration can be used to start a Woodpecker server with a single agent.
|
||||
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.
|
||||
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"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
image: woodpeckerci/woodpecker-server:latest
|
||||
|
@ -43,8 +41,6 @@ volumes:
|
|||
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"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -53,11 +49,10 @@ Woodpecker needs to know its own address. You must therefore provide the public
|
|||
+ - WOODPECKER_HOST=${WOODPECKER_HOST}
|
||||
```
|
||||
|
||||
Woodpecker can also have its port's configured. It uses a separate port for gRPC and for HTTP. The agent performs gRPC calls and connects to the gRPC port.
|
||||
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"
|
||||
version: '3'
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -70,7 +65,6 @@ They can be configured with `*_ADDR` variables:
|
|||
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"
|
||||
version: '3'
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -83,8 +77,6 @@ Reverse proxying can also be [configured for gRPC](../40-advanced/10-proxy.md#ca
|
|||
As agents run pipeline steps as docker containers they require access to the host machine's Docker daemon:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
[...]
|
||||
woodpecker-agent:
|
||||
|
@ -96,8 +88,6 @@ As agents run pipeline steps as docker containers they require access to the hos
|
|||
Agents require the server address for agent-to-server communication. The agent connects to the server's gRPC port:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-agent:
|
||||
[...]
|
||||
|
@ -108,8 +98,6 @@ Agents require the server address for agent-to-server communication. The agent c
|
|||
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"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Third-party installation methods
|
||||
# Distribution packages
|
||||
|
||||
:::info
|
||||
These installation methods are not officially supported. If you experience issues with them, please open issues in the specific repositories.
|
||||
Woodpecker itself is not responsible for creating these packages. Please reach out to the people responsible for packaging Woodpecker for the individual distributions.
|
||||
:::
|
||||
|
||||
- [Using NixOS](./40-nixos.md) via the [NixOS module](https://search.nixos.org/options?channel=unstable&size=200&sort=relevance&query=woodpecker)
|
||||
- [On Alpine Edge](https://pkgs.alpinelinux.org/packages?name=woodpecker&branch=edge&repo=&arch=&maintainer=)
|
||||
- [On Arch Linux](https://archlinux.org/packages/?q=woodpecker)
|
||||
- [On openSUSE](https://software.opensuse.org/package/woodpecker)
|
||||
- [Using YunoHost](https://apps.yunohost.org/app/woodpecker)
|
||||
- [On Cloudron](https://www.cloudron.io/store/org.woodpecker_ci.cloudronapp.html)
|
||||
- [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)
|
||||
|
|
|
@ -87,4 +87,4 @@ All configuration options can be found via [NixOS Search](https://search.nixos.o
|
|||
|
||||
## Tips and tricks
|
||||
|
||||
There are some resources on how to utilize Woodpecker more effectively with NixOS on the [Awesome Woodpecker](../../92-awesome.md) page, like using the runners nix-store in the pipeline.
|
||||
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.
|
||||
|
|
|
@ -7,8 +7,6 @@ The default database engine of Woodpecker is an embedded SQLite database which r
|
|||
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"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
|
|
@ -63,17 +63,15 @@ Point it to your server's docker config.
|
|||
WOODPECKER_DOCKER_CONFIG=/root/.docker/config.json
|
||||
```
|
||||
|
||||
## Handling sensitive data in docker-compose and docker-swarm
|
||||
## Handling sensitive data in **docker compose** and **docker swarm**
|
||||
|
||||
To handle sensitive data in docker-compose or docker-swarm configurations there are several options:
|
||||
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.
|
||||
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"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -161,17 +159,35 @@ Configures the logging level. Possible values are `trace`, `debug`, `info`, `war
|
|||
Output destination for logs.
|
||||
'stdout' and 'stderr' can be used as special keywords.
|
||||
|
||||
### `WOODPECKER_LOG_XORM`
|
||||
### `WOODPECKER_DATABASE_LOG`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable XORM logs.
|
||||
Enable logging in database engine (currently xorm).
|
||||
|
||||
### `WOODPECKER_LOG_XORM_SQL`
|
||||
### `WOODPECKER_DATABASE_LOG_SQL`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Enable XORM SQL command logs.
|
||||
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`
|
||||
|
||||
|
@ -197,14 +213,6 @@ Examples:
|
|||
- `WOODPECKER_HOST=http://example.org/woodpecker`
|
||||
- `WOODPECKER_HOST=http://example.org:1234/woodpecker`
|
||||
|
||||
### `WOODPECKER_WEBHOOK_HOST`
|
||||
|
||||
> Default: value from `WOODPECKER_HOST` config env
|
||||
|
||||
Server fully qualified URL of the Webhook-facing hostname and path prefix.
|
||||
|
||||
Example: `WOODPECKER_WEBHOOK_HOST=http://woodpecker-server.cicd.svc.cluster.local:8000`
|
||||
|
||||
### `WOODPECKER_SERVER_ADDR`
|
||||
|
||||
> Default: `:8000`
|
||||
|
@ -327,11 +335,13 @@ Always use authentication to clone repositories even if they are public. Needed
|
|||
|
||||
List of event names that will be canceled when a new pipeline for the same context (tag, branch) is created.
|
||||
|
||||
### `WOODPECKER_DEFAULT_CLONE_IMAGE`
|
||||
### `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
|
||||
The default docker image to be used when cloning the repo.
|
||||
|
||||
It is also added to the trusted clone plugin list.
|
||||
|
||||
### `WOODPECKER_DEFAULT_PIPELINE_TIMEOUT`
|
||||
|
||||
|
@ -354,11 +364,20 @@ Context: when someone does log into Woodpecker, a temporary session token is cre
|
|||
As long as the session is valid (until it expires or log-out),
|
||||
a user can log into Woodpecker, without re-authentication.
|
||||
|
||||
### `WOODPECKER_ESCALATE`
|
||||
### `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)
|
||||
|
||||
Docker images to run in privileged mode. Only change if you are sure what you do!
|
||||
Plugins which are trusted to handle the netrc info in clone steps.
|
||||
If a clone step use an image not in this list, the netrc will not be injected and an user has 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`
|
||||
|
@ -475,44 +494,6 @@ Supported variables:
|
|||
|
||||
---
|
||||
|
||||
### `WOODPECKER_LIMIT_MEM_SWAP`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory a single pipeline container is allowed to swap to disk, configured in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_LIMIT_MEM`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory a single pipeline container can use, configured in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_LIMIT_SHM_SIZE`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory of `/dev/shm` allowed in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_LIMIT_CPU_QUOTA`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The number of microseconds per CPU period that the container is limited to before throttled. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_LIMIT_CPU_SHARES`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The relative weight vs. other containers.
|
||||
|
||||
### `WOODPECKER_LIMIT_CPU_SET`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list to limit the specific CPUs or cores a pipeline container can use.
|
||||
|
||||
Example: `WOODPECKER_LIMIT_CPU_SET=1,2`
|
||||
|
||||
### `WOODPECKER_CONFIG_SERVICE_ENDPOINT`
|
||||
|
||||
> Default: empty
|
||||
|
@ -521,7 +502,7 @@ Specify a configuration service endpoint, see [Configuration Extension](./40-adv
|
|||
|
||||
### `WOODPECKER_FORGE_TIMEOUT`
|
||||
|
||||
> Default: 3s
|
||||
> Default: 5s
|
||||
|
||||
Specify timeout when fetching the Woodpecker configuration from forge. See <https://pkg.go.dev/time#ParseDuration> for syntax reference.
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@ Otherwise, the communication should go via the `docker0` gateway (usually 172.17
|
|||
To configure the Docker network if the network's name is `gitea`, configure it like this:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
[...]
|
||||
woodpecker-agent:
|
||||
|
@ -97,11 +95,3 @@ Read the value for `WOODPECKER_GITEA_SECRET` from the specified filepath
|
|||
> Default: `false`
|
||||
|
||||
Configure if SSL verification should be skipped.
|
||||
|
||||
## Advanced options
|
||||
|
||||
### `WOODPECKER_DEV_GITEA_OAUTH_URL`
|
||||
|
||||
> Default: value of `WOODPECKER_GITEA_URL`
|
||||
|
||||
Configures the user-facing Gitea server address. Should be used if `WOODPECKER_GITEA_URL` points to an internal URL used for API requests.
|
||||
|
|
|
@ -4,10 +4,6 @@ toc_max_heading_level: 2
|
|||
|
||||
# Forgejo
|
||||
|
||||
:::warning
|
||||
Forgejo support is experimental.
|
||||
:::
|
||||
|
||||
Woodpecker comes with built-in support for Forgejo. To enable Forgejo you should configure the Woodpecker container using the following environment variables:
|
||||
|
||||
```ini
|
||||
|
|
|
@ -11,8 +11,6 @@ Woodpecker comes with experimental support for Bitbucket Datacenter / Server, fo
|
|||
To enable Bitbucket Server you should configure the Woodpecker container using the following environment variables:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
|
|
@ -120,11 +120,14 @@ Configures the path of the agent config file.
|
|||
|
||||
Configures the number of parallel workflows.
|
||||
|
||||
### `WOODPECKER_FILTER_LABELS`
|
||||
### `WOODPECKER_AGENT_LABELS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Configures labels to filter pipeline pick up. 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).
|
||||
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).
|
||||
|
||||
### `WOODPECKER_HEALTHCHECK`
|
||||
|
||||
|
|
|
@ -64,3 +64,41 @@ Enable IPv6 for the networks used by pipeline containers (steps). Make sure you
|
|||
|
||||
List of default volumes separated by comma to be mounted to all pipeline containers (steps). For example to use custom CA
|
||||
certificates installed on host and host timezone use `/etc/ssl/certs:/etc/ssl/certs:ro,/etc/timezone:/etc/timezone`.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_MEM_SWAP`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory a single pipeline container is allowed to swap to disk, configured in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_MEM`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory a single pipeline container can use, configured in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_SHM_SIZE`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The maximum amount of memory of `/dev/shm` allowed in bytes. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_QUOTA`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The number of microseconds per CPU period that the container is limited to before throttled. There is no limit if `0`.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SHARES`
|
||||
|
||||
> Default: `0`
|
||||
|
||||
The relative weight vs. other containers.
|
||||
|
||||
### `WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SET`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Comma-separated list to limit the specific CPUs or cores a pipeline container can use.
|
||||
|
||||
Example: `WOODPECKER_BACKEND_DOCKER_LIMIT_CPU_SET=1,2`
|
||||
|
|
|
@ -8,9 +8,9 @@ The Kubernetes backend executes steps inside standalone Pods. A temporary PVC is
|
|||
|
||||
## Images from private registries
|
||||
|
||||
In order to pull private container images defined in your pipeline YAML you must provide [registry credentials in Kubernetes Secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).
|
||||
As the Secret is Agent-wide, it has to be placed in namespace defined by `WOODPECKER_BACKEND_K8S_NAMESPACE`.
|
||||
Besides, you need to provide the Secret name to Agent via `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES`.
|
||||
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`.
|
||||
|
||||
## Job specific configuration
|
||||
|
||||
|
@ -197,7 +197,7 @@ backend_options:
|
|||
```
|
||||
|
||||
:::note
|
||||
AppArmor syntax follows [KEP-24](https://github.com/kubernetes/enhancements/blob/fddcbb9cbf3df39ded03bad71228265ac6e5215f/keps/sig-node/24-apparmor/README.md).
|
||||
The feature requires Kubernetes v1.30 or above.
|
||||
:::
|
||||
|
||||
### Annotations and labels
|
||||
|
|
|
@ -137,8 +137,6 @@ To install the Woodpecker server behind a [Traefik](https://traefik.io/) load ba
|
|||
<!-- cspell:words redirectscheme certresolver -->
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
server:
|
||||
image: woodpeckerci/woodpecker-server:latest
|
||||
|
|
|
@ -81,12 +81,11 @@ WOODPECKER_CONFIG_SERVICE_ENDPOINT=https://example.com/ciconfig
|
|||
"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"
|
||||
}
|
||||
]
|
||||
"netrc": {
|
||||
"machine": "https://example.com",
|
||||
"login": "user",
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ SSL support is provided using the [ListenAndServeTLS](https://golang.org/pkg/net
|
|||
Update your configuration to expose the following ports:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -66,8 +64,6 @@ Update your configuration to expose the following ports:
|
|||
Update your configuration to mount your certificate and key:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
@ -79,8 +75,6 @@ Update your configuration to mount your certificate and key:
|
|||
Update your configuration to provide the paths of your certificate and key:
|
||||
|
||||
```diff title="docker-compose.yaml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
[...]
|
||||
|
|
|
@ -6,13 +6,11 @@ Please note that the autoscaler is not feature-complete yet. You can follow the
|
|||
|
||||
## Setup
|
||||
|
||||
### docker-compose
|
||||
### docker compose
|
||||
|
||||
If you are using docker-compose you can add the following to your `docker-compose.yaml` file:
|
||||
If you are using docker compose you can add the following to your `docker-compose.yaml` file:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
woodpecker-server:
|
||||
image: woodpeckerci/woodpecker-server:next
|
||||
|
|
|
@ -54,8 +54,7 @@ A common config for debugging would look like this:
|
|||
WOODPECKER_OPEN=true
|
||||
WOODPECKER_ADMIN=your-username
|
||||
|
||||
# if you want to test webhooks with an online forge like GitHub this address needs to be accessible from public server
|
||||
WOODPECKER_HOST=http://your-dev-address.com
|
||||
WOODPECKER_HOST=http://localhost:8000
|
||||
|
||||
# github (sample for a forge config - see /docs/administration/forge/overview for other forges)
|
||||
WOODPECKER_GITHUB=true
|
||||
|
@ -70,8 +69,8 @@ WOODPECKER_MAX_WORKFLOWS=1
|
|||
# enable if you want to develop the UI
|
||||
# WOODPECKER_DEV_WWW_PROXY=http://localhost:8010
|
||||
|
||||
# used so you can login without using a public address
|
||||
WOODPECKER_DEV_OAUTH_HOST=http://localhost:8000
|
||||
# if you want to test webhooks with an online forge like GitHub this address needs to be set and accessible from public server
|
||||
WOODPECKER_EXPERT_WEBHOOK_HOST=http://your-address.com
|
||||
|
||||
# disable health-checks while debugging (normally not needed while developing)
|
||||
WOODPECKER_HEALTHCHECK=false
|
||||
|
@ -82,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). If you set `WOODPECKER_DEV_OAUTH_HOST=http://localhost:8000` you can use that address with the path as explained for the specific forge to login without the need for a public address. For example for GitHub you would use `http://localhost:8000/authorize` as authorization callback URL.
|
||||
Create an OAuth app for your forge as described in the [forges documentation](../30-administration/11-forges/11-overview.md).
|
||||
|
||||
## Developing with VS Code
|
||||
|
||||
|
|
|
@ -21,3 +21,49 @@ To automatically execute the migration after the start of the server, the new mi
|
|||
## Constants of official images
|
||||
|
||||
All official default images, are saved in [shared/constant/constant.go](https://github.com/woodpecker-ci/woodpecker/blob/main/shared/constant/constant.go) and must be pinned by an exact tag.
|
||||
|
||||
## Building images locally
|
||||
|
||||
### Server
|
||||
|
||||
```sh
|
||||
### build web component
|
||||
make vendor
|
||||
cd web/
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm build
|
||||
cd ..
|
||||
|
||||
### define the platforms to build for (e.g. linux/amd64)
|
||||
# (the | is not a typo here)
|
||||
export PLATFORMS='linux|amd64'
|
||||
make cross-compile-server
|
||||
|
||||
### build the image
|
||||
docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.server.multiarch --push .
|
||||
```
|
||||
|
||||
:::info
|
||||
The `cross-compile-server` rule makes use of `xgo`, a go cross-compiler. You need to be on a `amd64` host to do this, as `xgo` is only available for `amd64` (see [xgo#213](https://github.com/techknowlogick/xgo/issues/213)).
|
||||
You can try to use the `build-server` rule instead, however this one fails for some OS (e.g. macOS).
|
||||
:::
|
||||
|
||||
### Agent
|
||||
|
||||
```sh
|
||||
### build the agent
|
||||
make build-agent
|
||||
|
||||
### build the image
|
||||
docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.agent.multiarch --push .
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
```sh
|
||||
### build the CLI
|
||||
make build-cli
|
||||
|
||||
### build the image
|
||||
docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.cli.multiarch --push .
|
||||
```
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 209 KiB |
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
|
@ -5,7 +5,7 @@ import * as path from 'path';
|
|||
|
||||
const config: Config = {
|
||||
title: 'Woodpecker CI',
|
||||
tagline: 'Woodpecker is a simple yet powerful CI/CD engine with great extensibility.',
|
||||
tagline: 'Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.',
|
||||
url: 'https://woodpecker-ci.org',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
|
@ -50,13 +50,13 @@ const config: Config = {
|
|||
position: 'left',
|
||||
items: [
|
||||
{
|
||||
to: '/docs/next/migrations', // Always point to newest migration guide
|
||||
activeBaseRegex: 'docs/(next/)?migrations',
|
||||
to: '/migrations', // Always point to newest migration guide
|
||||
activeBaseRegex: 'migrations',
|
||||
label: 'Migrations',
|
||||
},
|
||||
{
|
||||
to: '/docs/next/awesome', // Always point to newest awesome list
|
||||
activeBaseRegex: 'docs/(next/)?awesome',
|
||||
to: '/awesome', // Always point to newest awesome list
|
||||
activeBaseRegex: 'awesome',
|
||||
label: 'Awesome',
|
||||
},
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ const config: Config = {
|
|||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Woodpecker CI. Built with Docusaurus.`,
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Woodpecker Authors. Built with Docusaurus.`,
|
||||
},
|
||||
prism: {
|
||||
theme: themes.github,
|
||||
|
@ -264,6 +264,7 @@ const config: Config = {
|
|||
blog: {
|
||||
blogTitle: 'Blog',
|
||||
blogDescription: 'A blog for release announcements, turorials...',
|
||||
onInlineAuthors: 'ignore',
|
||||
// postsPerPage: 'ALL',
|
||||
// blogSidebarCount: 0,
|
||||
},
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.1.0",
|
||||
"@docusaurus/plugin-content-blog": "^3.1.0",
|
||||
"@docusaurus/preset-classic": "^3.1.0",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.44.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"@docusaurus/core": "^3.5.2",
|
||||
"@docusaurus/plugin-content-blog": "^3.5.2",
|
||||
"@docusaurus/preset-classic": "^3.5.2",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.45.0",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"clsx": "^2.1.0",
|
||||
"esbuild-loader": "^4.1.0",
|
||||
"clsx": "^2.1.1",
|
||||
"esbuild-loader": "^4.2.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"redocusaurus": "^2.0.2",
|
||||
"react-dom": "^18.3.1",
|
||||
"redocusaurus": "^2.1.2",
|
||||
"url-loader": "^4.1.1"
|
||||
},
|
||||
"browserslist": {
|
||||
|
@ -42,18 +42,20 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.1.0",
|
||||
"@docusaurus/tsconfig": "3.4.0",
|
||||
"@docusaurus/types": "^3.1.0",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "^18.2.67",
|
||||
"@docusaurus/module-type-aliases": "^3.5.2",
|
||||
"@docusaurus/tsconfig": "3.5.2",
|
||||
"@docusaurus/types": "^3.5.2",
|
||||
"@types/node": "^20.17.1",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"typescript": "^5.4.3"
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"got": "^14.0.0"
|
||||
"got": "^14.0.0",
|
||||
"path-to-regexp": "^3.3.0",
|
||||
"cookie": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"@tsconfig/docusaurus": "^2.0.3",
|
||||
"@types/node": "^20.12.13",
|
||||
"axios": "^1.7.2",
|
||||
"concurrently": "^8.2.2",
|
||||
"concurrently": "^9.0.0",
|
||||
"isomorphic-dompurify": "^2.11.0",
|
||||
"marked": "^13.0.0",
|
||||
"marked": "^14.0.0",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
|
|
|
@ -40,11 +40,6 @@
|
|||
"docs": "https://raw.githubusercontent.com/woodpecker-ci/plugin-extend-env/main/docs.md",
|
||||
"verified": true
|
||||
},
|
||||
{
|
||||
"name": "Block Git changes",
|
||||
"docs": "https://codeberg.org/qwerty287/woodpecker-block-git-changes/raw/branch/main/docs.md",
|
||||
"verified": false
|
||||
},
|
||||
{
|
||||
"name": "Regex check",
|
||||
"docs": "https://codeberg.org/qwerty287/woodpecker-regex-check/raw/branch/main/docs.md",
|
||||
|
@ -219,6 +214,11 @@
|
|||
"name": "Docker Tags",
|
||||
"docs": "https://raw.githubusercontent.com/dvjn/woodpecker-docker-tags-plugin/main/docs.md",
|
||||
"verified": false
|
||||
},
|
||||
{
|
||||
"name": "Telegram",
|
||||
"docs": "https://raw.githubusercontent.com/appleboy/drone-telegram/refs/heads/master/DOCS.md",
|
||||
"verified": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
4892
docs/pnpm-lock.yaml
4892
docs/pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
18
docs/src/pages/about.md
Normal file
18
docs/src/pages/about.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# About
|
||||
|
||||
Woodpecker has been originally forked from Drone 0.8 as the Drone CI license was changed after the 0.8 release from Apache 2.0 to a proprietary license. Woodpecker is based on this latest freely available version.
|
||||
|
||||
## History
|
||||
|
||||
Woodpecker was originally forked by [@laszlocph](https://github.com/laszlocph) in 2019.
|
||||
|
||||
A few important time points:
|
||||
|
||||
- [`2fbaa56`](https://github.com/woodpecker-ci/woodpecker/commit/2fbaa56eee0f4be7a3ca4be03dbd00c1bf5d1274) is the first commit of the fork, made on Apr 3, 2019.
|
||||
- The first release [v0.8.91](https://github.com/woodpecker-ci/woodpecker/releases/tag/v0.8.91) was published on Apr 6, 2019.
|
||||
- On Aug 27, 2019, the project was renamed to "Woodpecker" ([`630c383`](https://github.com/woodpecker-ci/woodpecker/commit/630c383181b10c4ec375e500c812c4b76b3c52b8)).
|
||||
- The first release under the name "Woodpecker" was published on Sep 9, 2019 ([v0.8.104](https://github.com/woodpecker-ci/woodpecker/releases/tag/v0.8.104)).
|
||||
|
||||
## Differences to Drone
|
||||
|
||||
Woodpecker is a community-focused software that still stay free and open source forever, while Drone is managed by [Harness](https://harness.io/) and published under [Polyform Small Business](https://polyformproject.org/licenses/small-business/1.0.0/) license.
|
|
@ -55,12 +55,18 @@ If you have some missing resources, please feel free to [open a pull-request](ht
|
|||
- [Deploying mdbook to codeberg pages using woodpecker CI](https://www.markpitblado.me/blog/deploying-mdbook-to-codeberg-pages-using-woodpecker-ci/)
|
||||
- [Deploy a Fly app with Woodpecker CI](https://joeroe.io/2024/01/09/deploy-fly-woodpecker-ci.html)
|
||||
- [Ansible - using Woodpecker as an alternative to Semaphore](https://pat-s.me/ansible-using-woodpecker-as-an-alternative-to-semaphore/)
|
||||
- [Simple selfhosted CI/CD with Woodpecker](https://xyquadrat.ch/blog/simple-ci-with-woodpecker/)
|
||||
- [Notes to self on Woodpecker-CI](https://jpmens.net/2023/09/22/notes-to-self-on-woodpecker-ci/)
|
||||
- [CI/CD with Woodpecker and Gitea](https://wilw.dev/blog/2023/04/23/woodpecker-ci/)
|
||||
|
||||
## Videos
|
||||
|
||||
- [Replace Ansible Semaphore with Woodpecker CI](https://www.youtube.com/watch?v=d610YPvCB0E)
|
||||
- ["unexpected EOF" error when trying to pair Woodpecker CI served through the Caddy with Gitea](https://www.youtube.com/watch?v=n7Hyvt71Np0)
|
||||
- [CICD Environment in Docker Swarm behind Caddy Server - Part 2 Woodpeckerci](https://www.youtube.com/watch?v=rkbw_k7JvS0)
|
||||
- [How to Build & Publish Custom Docker Container using Gitea & Woodpecker behind Caddy Server | TUNEIT](https://www.youtube.com/watch?v=9m7DbgL1mNk)
|
||||
- [Radicle Woodpecker CI Integration](https://www.youtube.com/watch?v=Ks1nbYLn4P8)
|
||||
- [woodpecker-ci/woodpecker - Gource visualisation](https://www.youtube.com/watch?v=38JuakZ6m5s)
|
||||
|
||||
## Plugins
|
||||
|
|
@ -14,7 +14,7 @@ function HomepageHeader() {
|
|||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link className="button button--secondary button--lg" to="/docs/intro">
|
||||
<Link className="button button--lg button--secondary" to="/docs/intro">
|
||||
Woodpecker Tutorial - 5min ⏱️
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@ export default function Home() {
|
|||
return (
|
||||
<Layout
|
||||
title={`${siteConfig.title}`}
|
||||
description="Woodpecker is a simple yet powerful CI/CD engine with great extensibility."
|
||||
description="Woodpecker is a simple, yet powerful CI/CD engine with great extensibility."
|
||||
>
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
|
|
|
@ -1,33 +1,80 @@
|
|||
# Migrations
|
||||
|
||||
Some versions need some changes to the server configuration or the pipeline configuration files.
|
||||
|
||||
<!--
|
||||
## 3.0.0
|
||||
|
||||
- Update all webhooks by pressing the "Repair all" button in the admin settings as the webhook token claims have changed
|
||||
|
||||
-->
|
||||
Some versions need some changes to the server configuration or the pipeline configuration files. If you are an user check the `User migrations` section of an version. As an admin of a Woodpecker server or agent check the `Admin migrations` section.
|
||||
|
||||
## `next`
|
||||
|
||||
- Removed `WOODPECKER_DEV_OAUTH_HOST` and `WOODPECKER_DEV_GITEA_OAUTH_URL` use `WOODPECKER_EXPERT_FORGE_OAUTH_HOST`
|
||||
:::info
|
||||
This will be the next version of Woodpecker.
|
||||
:::
|
||||
|
||||
## User migrations
|
||||
|
||||
- Removed built-in environment variables:
|
||||
- `CI_COMMIT_URL` use `CI_PIPELINE_FORGE_URL`
|
||||
- `CI_STEP_FINISHED` as empty during execution
|
||||
- `CI_PIPELINE_FINISHED` as empty during execution
|
||||
- `CI_PIPELINE_STATUS` was always `success`
|
||||
- `CI_STEP_STATUS` was always `success`
|
||||
- Set `/woodpecker` as default workdir for the **woodpecker-cli** container
|
||||
- Secret filters for plugins now check against tag if specified
|
||||
- Compatibility mode of deprecated `pipeline:`, `platform:` and `branches:` pipeline config options are now removed and pipeline will now fail if still in use.
|
||||
- Deprecated `steps.[name].group` in favor of `steps.[name].depends_on` (see [workflow syntax](./20-usage/20-workflow-syntax.md#depends_on) to learn how to set dependencies)
|
||||
- Removed `WOODPECKER_ROOT_PATH` and `WOODPECKER_ROOT_URL` config variables. Use `WOODPECKER_HOST` with a path instead
|
||||
- Removed `steps.[name].group` in favor of `steps.[name].depends_on` (see [workflow syntax](/docs/usage/workflow-syntax#depends_on) to learn how to set dependencies)
|
||||
- Pipelines without a config file will now be skipped instead of failing
|
||||
- Deprecated `includes` and `excludes` support from **event** filter
|
||||
- Deprecated uppercasing all secret env vars, instead, the value of the `secrets` property is used. [Read more](./20-usage/40-secrets.md#use-secrets-in-commands)
|
||||
- Deprecated alternative names for secrets, use `environment` with `from_secret`
|
||||
- Deprecated slice definition for env vars
|
||||
- Deprecated `environment` filter, use `when.evaluate`
|
||||
- Deprecated `WOODPECKER_WEBHOOK_HOST` in favor of `WOODPECKER_EXPERT_WEBHOOK_HOST`
|
||||
- Removed `includes` and `excludes` support from **event** filter
|
||||
- Removed upper-casing all secret env vars, instead, the value of the `secrets` property is used. [Read more](/docs/usage/secrets#usage)
|
||||
- Removed alternative names for secrets, use `environment` with `from_secret`
|
||||
- Removed `environment` filter, use `when.evaluate`
|
||||
- Removed `WOODPECKER_WEBHOOK_HOST` in favor of `WOODPECKER_EXPERT_WEBHOOK_HOST`
|
||||
- Renamed `start_time`, `end_time`, `created_at`, `started_at`, `finished_at` and `reviewed_at` JSON fields to `started`, `finished`, `created`, `started`, `finished`, `reviewed`
|
||||
- JSON field `trusted` on repo model was changed from boolean to object
|
||||
- Update all webhooks by pressing the "Repair all" button in the admin settings as the webhook token claims have changed
|
||||
- Crons now use standard Linux syntax without seconds
|
||||
- Removed old API routes: `registry/` -> `registries`, `/authorize/token`
|
||||
- Replaced `registry` command with `repo registry` in cli
|
||||
- Deprecated `secrets`, use `environment` with `from_secret`
|
||||
|
||||
## Admin migrations
|
||||
|
||||
- Deprecate `WOODPECKER_LOG_XORM` and `WOODPECKER_LOG_XORM_SQL` use `"WOODPECKER_DATABASE_LOG` and `"WOODPECKER_DATABASE_LOG_SQL`
|
||||
- Deprecate `WOODPECKER_FILTER_LABELS` use `WOODPECKER_AGENT_LABELS`
|
||||
- Move docker resource limit settings from server into agent configuration
|
||||
- Rename server environment variable `WOODPECKER_ESCALATE` to `WOODPECKER_PLUGINS_PRIVILEGED`
|
||||
- All default privileged plugins (like `woodpeckerci/plugin-docker-buildx`) were removed. Please carefully [re-add those plugins](/docs/next/administration/server-config#woodpecker_plugins_privileged) you trust and rely on.
|
||||
- `WOODPECKER_DEFAULT_CLONE_IMAGE` got deprecated use `WOODPECKER_DEFAULT_CLONE_PLUGIN`
|
||||
- Check trusted-clone- and privileged-plugins by image name and tag (if tag is set)
|
||||
- Removed `WOODPECKER_DEV_OAUTH_HOST` and `WOODPECKER_DEV_GITEA_OAUTH_URL` use `WOODPECKER_EXPERT_FORGE_OAUTH_HOST`
|
||||
- Removed `WOODPECKER_ROOT_PATH` and `WOODPECKER_ROOT_URL` config variables. Use `WOODPECKER_HOST` with a path instead
|
||||
- Removed implicitly defined `regcred` image pull secret name. Set it explicitly via `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES`
|
||||
- Removed slice definition for env vars
|
||||
- Migrated to rfc9421 for webhook signatures
|
||||
- Replaced `configs` object by `netrc` in external configuration APIs
|
||||
- Disallow upgrades from 1.x, upgrade to 2.x first
|
||||
|
||||
## 2.7.2
|
||||
|
||||
To secure your instance, set `WOODPECKER_PLUGINS_PRIVILEGED` to only allow specific versions of the `woodpeckerci/plugin-docker-buildx` plugin, use version 5.0.0 or above. This prevents older, potentially unstable versions from being privileged.
|
||||
|
||||
For example, to allow only version 5.0.0, use:
|
||||
|
||||
```bash
|
||||
WOODPECKER_PLUGINS_PRIVILEGED=woodpeckerci/plugin-docker-buildx:5.0.0
|
||||
```
|
||||
|
||||
To allow multiple versions, you can separate them with commas:
|
||||
|
||||
```bash
|
||||
WOODPECKER_PLUGINS_PRIVILEGED=woodpeckerci/plugin-docker-buildx:5.0.0,woodpeckerci/plugin-docker-buildx:5.1.0
|
||||
```
|
||||
|
||||
This setup ensures only specified, stable plugin versions are given privileged access.
|
||||
|
||||
Read more about it in [#4213](https://github.com/woodpecker-ci/woodpecker/pull/4213)
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- Dropped deprecated `CI_BUILD_*`, `CI_PREV_BUILD_*`, `CI_JOB_*`, `*_LINK`, `CI_SYSTEM_ARCH`, `CI_REPO_REMOTE` built-in environment variables
|
||||
- Deprecated `platform:` filter in favor of `labels:`, [read more](./20-usage/20-workflow-syntax.md#filter-by-platform)
|
||||
- Deprecated `platform:` filter in favor of `labels:`, [read more](/docs/usage/workflow-syntax#filter-by-platform)
|
||||
- Secrets `event` property was renamed to `events` and `image` to `images` as both are lists. The new property `events` / `images` has to be used in the api. The old properties `event` and `image` were removed.
|
||||
- The secrets `plugin_only` option was removed. Secrets with images are now always only available for plugins using listed by the `images` property. Existing secrets with a list of `images` will now only be available to the listed images if they are used as a plugin.
|
||||
- Removed `build` alias for `pipeline` command in CLI
|
||||
|
@ -39,8 +86,8 @@ Some versions need some changes to the server configuration or the pipeline conf
|
|||
|
||||
## 1.0.0
|
||||
|
||||
- The signature used to verify extension calls (like those used for the [config-extension](./30-administration/40-advanced/100-external-configuration-api.md)) done by the Woodpecker server switched from using a shared-secret HMac to an ed25519 key-pair. Read more about it at the [config-extensions](./30-administration/40-advanced/100-external-configuration-api.md) documentation.
|
||||
- Refactored support for old agent filter labels and expressions. Learn how to use the new [filter](./20-usage/20-workflow-syntax.md#labels)
|
||||
- The signature used to verify extension calls (like those used for the [config-extension](/docs/administration/advanced/external-configuration-api)) done by the Woodpecker server switched from using a shared-secret HMac to an ed25519 key-pair. Read more about it at the [config-extensions](/docs/administration/advanced/external-configuration-api) documentation.
|
||||
- Refactored support for old agent filter labels and expressions. Learn how to use the new [filter](/docs/usage/workflow-syntax#labels)
|
||||
- Renamed step environment variable `CI_SYSTEM_ARCH` to `CI_SYSTEM_PLATFORM`. Same applies for the cli exec variable.
|
||||
- Renamed environment variables `CI_BUILD_*` and `CI_PREV_BUILD_*` to `CI_PIPELINE_*` and `CI_PREV_PIPELINE_*`, old ones are still available but deprecated
|
||||
- Renamed environment variables `CI_JOB_*` to `CI_STEP_*`, old ones are still available but deprecated
|
||||
|
@ -49,7 +96,7 @@ Some versions need some changes to the server configuration or the pipeline conf
|
|||
- Renamed API endpoints for pipelines (`<owner>/<repo>/builds/<buildId>` -> `<owner>/<repo>/pipelines/<pipelineId>`), old ones are still available but deprecated
|
||||
- Updated Prometheus gauge `build_*` to `pipeline_*`
|
||||
- Updated Prometheus gauge `*_job_*` to `*_step_*`
|
||||
- Renamed config env `WOODPECKER_MAX_PROCS` to `WOODPECKER_MAX_WORKFLOWS` (still available as fallback)
|
||||
- Renamed config env `WOODPECKER_MAX_PROCS` to `WOODPECKER_MAX_WORKFLOWS` (still available as fallback) <!-- cspell:ignore PROCS -->
|
||||
- The pipelines are now also read from `.yaml` files, the new default order is `.woodpecker/*.yml` and `.woodpecker/*.yaml` (without any prioritization) -> `.woodpecker.yml` -> `.woodpecker.yaml`
|
||||
- Dropped support for [Coding](https://coding.net/), [Gogs](https://gogs.io) and Bitbucket Server (Stash).
|
||||
- `/api/queue/resume` & `/api/queue/pause` endpoint methods were changed from `GET` to `POST`
|
||||
|
@ -78,7 +125,7 @@ Some versions need some changes to the server configuration or the pipeline conf
|
|||
|
||||
Only projects created after updating will have an empty value by default. Existing projects will stick to the current pipeline path which is `.drone.yml` in most cases.
|
||||
|
||||
Read more about it at the [Project Settings](./20-usage/75-project-settings.md#pipeline-path)
|
||||
Read more about it at the [Project Settings](/docs/usage/project-settings#pipeline-path)
|
||||
|
||||
- From version `0.15.0` ongoing there will be three types of docker images: `latest`, `next` and `x.x.x` with an alpine variant for each type like `latest-alpine`.
|
||||
If you used `latest` before to try pre-release features you should switch to `next` after this release.
|
||||
|
@ -113,7 +160,7 @@ Some versions need some changes to the server configuration or the pipeline conf
|
|||
- CI_SOURCE_BRANCH => use CI_COMMIT_SOURCE_BRANCH
|
||||
- CI_TARGET_BRANCH => use CI_COMMIT_TARGET_BRANCH
|
||||
|
||||
For all available variables and their descriptions have a look at [built-in-environment-variables](./20-usage/50-environment.md#built-in-environment-variables).
|
||||
For all available variables and their descriptions have a look at [built-in-environment-variables](/docs/usage/environment#built-in-environment-variables).
|
||||
|
||||
- Prometheus metrics have been changed from `drone_*` to `woodpecker_*`
|
||||
|
|
@ -19,7 +19,7 @@ the actual release will be about a week later.
|
|||
|
||||
### Deprecations & migrations
|
||||
|
||||
All deprecations and migrations for Woodpecker users and instance admins are documented in the [migration guide](/docs/next/migrations).
|
||||
All deprecations and migrations for Woodpecker users and instance admins are documented in the [migration guide](/migrations).
|
||||
|
||||
## Next version (current state of the `main` branch)
|
||||
|
||||
|
@ -33,7 +33,11 @@ Here you can find documentation for previous versions of Woodpecker.
|
|||
|
||||
| | | |
|
||||
| ------- | ---------- | ------------------------------------------------------------------------------------- |
|
||||
| 2.6.0 | 2024-07-18 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.6.0/docs/docs/) |
|
||||
| 2.7.2 | 2024-11-03 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.7.2/docs/docs/) |
|
||||
| 2.7.1 | 2024-09-07 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.7.1/docs/docs/) |
|
||||
| 2.7.0 | 2024-07-18 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.7.0/docs/docs/) |
|
||||
| 2.6.1 | 2024-07-19 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.6.1/docs/docs/) |
|
||||
| 2.6.0 | 2024-06-13 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.6.0/docs/docs/) |
|
||||
| 2.5.0 | 2024-06-01 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.5.0/docs/docs/) |
|
||||
| 2.4.1 | 2024-03-20 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.4.1/docs/docs/) |
|
||||
| 2.4.0 | 2024-03-19 | [Documentation](https://github.com/woodpecker-ci/woodpecker/tree/v2.4.0/docs/docs/) |
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Welcome to Woodpecker
|
||||
|
||||
Woodpecker is a simple yet powerful CI/CD engine with great extensibility. It focuses on executing pipelines inside [containers](https://opencontainers.org/).
|
||||
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility. It focuses on executing pipelines inside [containers](https://opencontainers.org/).
|
||||
If you are already using containers in your daily workflow, you'll for sure love Woodpecker.
|
||||
|
||||
![woodpecker](woodpecker.png)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Welcome to Woodpecker
|
||||
|
||||
Woodpecker is a simple yet powerful CI/CD engine with great extensibility. It focuses on executing pipelines inside [containers](https://opencontainers.org/).
|
||||
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility. It focuses on executing pipelines inside [containers](https://opencontainers.org/).
|
||||
If you are already using containers in your daily workflow, you'll for sure love Woodpecker.
|
||||
|
||||
![woodpecker](woodpecker.png)
|
||||
|
|
BIN
docs/woodpecker.png
Normal file
BIN
docs/woodpecker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 728 KiB |
12
flake.lock
12
flake.lock
|
@ -5,11 +5,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -20,11 +20,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1720542800,
|
||||
"narHash": "sha256-ZgnNHuKV6h2+fQ5LuqnUaqZey1Lqqt5dTUAiAnqH0QQ=",
|
||||
"lastModified": 1729665710,
|
||||
"narHash": "sha256-AlcmCXJZPIlO5dmFzV3V2XF6x/OpNWUV8Y/FMPGd8Z4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "feb2849fdeb70028c70d73b848214b00d324a497",
|
||||
"rev": "2768c7d042a37de65bb1b5b3268fc987e534c49d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
go-mockery
|
||||
protobuf
|
||||
sqlite
|
||||
go-swag # for generate-swagger
|
||||
addlicense
|
||||
protoc-gen-go
|
||||
protoc-gen-go-grpc
|
||||
];
|
||||
CFLAGS = "-I${pkgs.glibc.dev}/include";
|
||||
LDFLAGS = "-L${pkgs.glibc}/lib";
|
||||
|
|
129
go.mod
129
go.mod
|
@ -2,78 +2,78 @@ module go.woodpecker-ci.org/woodpecker/v2
|
|||
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.22.5
|
||||
toolchain go1.23.2
|
||||
|
||||
require (
|
||||
al.essio.dev/pkg/shellescape v1.5.0
|
||||
code.gitea.io/sdk/gitea v0.18.0
|
||||
al.essio.dev/pkg/shellescape v1.5.1
|
||||
code.gitea.io/sdk/gitea v0.19.0
|
||||
codeberg.org/6543/go-yaml2json v1.0.0
|
||||
codeberg.org/6543/xyaml v1.1.0
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.1.1
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.2.0
|
||||
github.com/6543/logfile-open v1.2.1
|
||||
github.com/adrg/xdg v0.5.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||
github.com/caddyserver/certmagic v0.21.3
|
||||
github.com/adrg/xdg v0.5.2
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1
|
||||
github.com/caddyserver/certmagic v0.21.4
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/charmbracelet/huh v0.5.1
|
||||
github.com/charmbracelet/huh v0.6.0
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240327025511-ec643317aa10
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v27.1.1+incompatible
|
||||
github.com/docker/docker v27.1.1+incompatible
|
||||
github.com/docker/cli v27.3.1+incompatible
|
||||
github.com/docker/docker v27.3.1+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/drone/envsubst v1.0.3
|
||||
github.com/expr-lang/expr v1.16.9
|
||||
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/getkin/kin-openapi v0.126.0
|
||||
github.com/gdgvda/cron v0.3.0
|
||||
github.com/getkin/kin-openapi v0.127.0
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/gitsight/go-vcsurl v1.0.1
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/go-github/v63 v63.0.0
|
||||
github.com/google/go-github/v66 v66.0.0
|
||||
github.com/google/tink/go v1.7.0
|
||||
github.com/gorilla/securecookie v1.1.2
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-plugin v1.6.1
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0
|
||||
github.com/hashicorp/go-plugin v1.6.2
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/kinbiko/jsonassert v1.1.1
|
||||
github.com/kinbiko/jsonassert v1.2.0
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/moby v27.1.1+incompatible
|
||||
github.com/moby/moby v27.3.1+incompatible
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/muesli/termenv v0.15.2
|
||||
github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257
|
||||
github.com/neticdk/go-bitbucket v1.0.0
|
||||
github.com/oklog/ulid/v2 v2.1.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/robfig/cron v1.2.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.3
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1
|
||||
github.com/xanzy/go-gitlab v0.107.0
|
||||
github.com/swaggo/swag v1.16.4
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20241004184838-20ef97b2155a
|
||||
github.com/xanzy/go-gitlab v0.112.0
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/yaronf/httpsign v0.3.1
|
||||
github.com/zalando/go-keyring v0.2.5
|
||||
github.com/zalando/go-keyring v0.2.6
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/oauth2 v0.21.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/term v0.22.0
|
||||
golang.org/x/text v0.16.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/term v0.25.0
|
||||
golang.org/x/text v0.19.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.30.3
|
||||
k8s.io/apimachinery v0.30.3
|
||||
k8s.io/client-go v0.30.3
|
||||
k8s.io/api v0.31.2
|
||||
k8s.io/apimachinery v0.31.2
|
||||
k8s.io/client-go v0.31.2
|
||||
src.techknowlogick.com/xormigrate v1.7.1
|
||||
xorm.io/builder v0.3.13
|
||||
xorm.io/xorm v1.3.9
|
||||
|
@ -81,10 +81,10 @@ require (
|
|||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/42wim/httpsig v1.2.2 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/alessio/shellescape v1.4.1 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
|
@ -93,20 +93,18 @@ require (
|
|||
github.com/caddyserver/zerossl v0.1.3 // indirect
|
||||
github.com/catppuccin/go v0.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charmbracelet/bubbles v0.18.0 // indirect
|
||||
github.com/charmbracelet/bubbletea v0.26.4 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.11.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.1.2 // indirect
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1 // indirect
|
||||
github.com/charmbracelet/x/input v0.1.2 // indirect
|
||||
github.com/charmbracelet/x/term v0.1.1 // indirect
|
||||
github.com/charmbracelet/x/windows v0.1.2 // indirect
|
||||
github.com/charmbracelet/bubbles v0.20.0 // indirect
|
||||
github.com/charmbracelet/bubbletea v1.1.0 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.13.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.2.3 // indirect
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/danieljoos/wincred v1.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/danieljoos/wincred v1.2.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.0 // indirect
|
||||
|
@ -116,6 +114,7 @@ require (
|
|||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
|
@ -147,7 +146,8 @@ require (
|
|||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
|
@ -161,10 +161,9 @@ require (
|
|||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mholt/acmez/v2 v2.0.1 // indirect
|
||||
github.com/miekg/dns v1.1.59 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mholt/acmez/v2 v2.0.3 // indirect
|
||||
github.com/miekg/dns v1.1.62 // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
|
@ -179,10 +178,10 @@ require (
|
|||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
|
@ -192,10 +191,10 @@ require (
|
|||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect
|
||||
|
@ -204,18 +203,18 @@ require (
|
|||
go.opentelemetry.io/otel/trace v1.28.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gotest.tools/v3 v3.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
|
|
276
go.sum
276
go.sum
|
@ -1,18 +1,20 @@
|
|||
al.essio.dev/pkg/shellescape v1.5.0 h1:7oTvSsQ5kg9WksA9O58y9wjYnY4jP0CL82/Q8WLUGKk=
|
||||
al.essio.dev/pkg/shellescape v1.5.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
|
||||
code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI=
|
||||
code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI=
|
||||
al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho=
|
||||
al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
|
||||
code.gitea.io/sdk/gitea v0.19.0 h1:8I6s1s4RHgzxiPHhOQdgim1RWIRcr0LVMbHBjBFXq4Y=
|
||||
code.gitea.io/sdk/gitea v0.19.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI=
|
||||
codeberg.org/6543/go-yaml2json v1.0.0 h1:heGqo9VEi7gY2yNqjj7X4ADs5nzlFIbGsJtgYDLrnig=
|
||||
codeberg.org/6543/go-yaml2json v1.0.0/go.mod h1:mz61q14LWF4ZABrgMEDMmk3t9dPi6zgR1uBh2VKV2RQ=
|
||||
codeberg.org/6543/xyaml v1.1.0 h1:0PWTy8OUqshshjrrnAXFWXSPUEa8R49DIh2ah07SxFc=
|
||||
codeberg.org/6543/xyaml v1.1.0/go.mod h1:jI7afXLZUxeL4rNNsG1SlHh78L+gma9lK1bIebyFZwA=
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.1.1 h1:WEI3FZdoQjaiaR15TRmyGfY091R7o+NAaso65ckbsq0=
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.1.1/go.mod h1:09wAYX9H0+wBo1baX9DdSqdfreZc6ji5aELsnu9m14M=
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.2.0 h1:/z7iYYHgTuP+BnJY5qnWj6UjlA1YsAFYhi36JZY1S7Y=
|
||||
codeberg.org/mvdkleijn/forgejo-sdk/forgejo v1.2.0/go.mod h1:qGzzS6EYParzgmXvnf1QANdnQmHFSyAlJN3SiRZp7e8=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
||||
github.com/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA=
|
||||
github.com/42wim/httpsig v1.2.2/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY=
|
||||
github.com/6543/logfile-open v1.2.1 h1:az+TtNHclTAKaHfFCTSbuduMllANox1gM9qLQr7LV5I=
|
||||
github.com/6543/logfile-open v1.2.1/go.mod h1:ZoEy7pW2mexmQxiZIqPCeh8vUxVuiHYXmSZNbvEb51g=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
||||
|
@ -23,13 +25,13 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
|
||||
github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4=
|
||||
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/adrg/xdg v0.5.2 h1:HNeVffMIG56GLMaoKTcTcyFhD2xS/dhyuBlKSNCM6Ug=
|
||||
github.com/adrg/xdg v0.5.2/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
|
@ -38,16 +40,16 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
|
|||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/caddyserver/certmagic v0.21.3 h1:pqRRry3yuB4CWBVq9+cUqu+Y6E2z8TswbhNx1AZeYm0=
|
||||
github.com/caddyserver/certmagic v0.21.3/go.mod h1:Zq6pklO9nVRl3DIFUw9gVUfXKdpc/0qwTUAQMBlfgtI=
|
||||
github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0=
|
||||
github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE=
|
||||
github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
|
||||
github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
|
||||
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
|
||||
|
@ -56,28 +58,22 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
|
|||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
|
||||
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
|
||||
github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
|
||||
github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
|
||||
github.com/charmbracelet/huh v0.5.1 h1:t5j6g9sMjAE2a9AQuc4lNL7pf/0X4WdHiiMGkL8v/aM=
|
||||
github.com/charmbracelet/huh v0.5.1/go.mod h1:gs7b2brpzXkY0PBWUqJrlzvOowTCL0vNAR6OTItc+kA=
|
||||
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
|
||||
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
||||
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
|
||||
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
|
||||
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=
|
||||
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240327025511-ec643317aa10 h1:/HZJSyFVH5rB1MlCDfkhQhRbLPD2Er29ngWXiUQ8bik=
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240327025511-ec643317aa10/go.mod h1:nrBG0YEHaxdbqHXW1xvG1hPqkuac9Eg7RTMvogiXuz0=
|
||||
github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
|
||||
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
|
||||
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
|
||||
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1 h1:VZIQzjwFE0EamzG2v8HfemeisB8X02Tl0BZBnJ0PeU8=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
|
||||
github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a h1:k/s6UoOSVynWiw7PlclyGO2VdVs5ZLbMIHiGp4shFZE=
|
||||
github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a/go.mod h1:YBotIGhfoWhHDlnUpJMkjebGV2pdGRCn1Y4/Nk/vVcU=
|
||||
github.com/charmbracelet/x/input v0.1.2 h1:QJAZr33eOhDowkkEQ24rsJy4Llxlm+fRDf/cQrmqJa0=
|
||||
github.com/charmbracelet/x/input v0.1.2/go.mod h1:LGBim0maUY4Pitjn/4fHnuXb4KirU3DODsyuHuXdOyA=
|
||||
github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
|
||||
github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
|
||||
github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg=
|
||||
github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
|
||||
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
|
||||
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
|
||||
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
|
||||
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
|
||||
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
|
||||
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
@ -96,11 +92,12 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
|||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE=
|
||||
github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec=
|
||||
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
|
||||
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
|
@ -110,10 +107,10 @@ github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDror
|
|||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
|
||||
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ=
|
||||
github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
|
||||
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
|
||||
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
|
@ -143,10 +140,14 @@ github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf/go.mod h1:VzmDKDJVZ
|
|||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/getkin/kin-openapi v0.126.0 h1:c2cSgLnAsS0xYfKsgt5oBV6MYRM/giU8/RtwUY4wyfY=
|
||||
github.com/getkin/kin-openapi v0.126.0/go.mod h1:7mONz8IwmSRg6RttPu6v8U/OJ+gr+J99qSFNjPGSQqw=
|
||||
github.com/gdgvda/cron v0.3.0 h1:Wjj9NSYGzvtjkdZxOjpU749OuJGpcqr/tSxzeeBQGVI=
|
||||
github.com/gdgvda/cron v0.3.0/go.mod h1:caBF+mzTZGtQqFE05T1m6u9OmCASY3EK51XAICf3wio=
|
||||
github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY=
|
||||
github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
|
@ -184,8 +185,8 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
|
|||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
|
@ -221,15 +222,16 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE=
|
||||
github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA=
|
||||
github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M=
|
||||
github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
|
@ -246,8 +248,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
|
|||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI=
|
||||
github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0=
|
||||
github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog=
|
||||
github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
|
||||
|
@ -300,8 +302,8 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f
|
|||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4=
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc=
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw=
|
||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
|
@ -315,14 +317,15 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d
|
|||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kinbiko/jsonassert v1.1.1 h1:DB12divY+YB+cVpHULLuKePSi6+ui4M/shHSzJISkSE=
|
||||
github.com/kinbiko/jsonassert v1.1.1/go.mod h1:NO4lzrogohtIdNUNzx8sdzB55M4R4Q1bsrWVdqQ7C+A=
|
||||
github.com/kinbiko/jsonassert v1.2.0 h1:+/JthIVXdIrThrOtSN9ry0mNtWKXMWuvxR0nU7gQ+tI=
|
||||
github.com/kinbiko/jsonassert v1.2.0/go.mod h1:pCc3uudOt+lVAbkji9O0uw8MSVt4s+1ZJ0y8Ux2F1Og=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
@ -334,6 +337,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
|
||||
|
@ -377,26 +382,24 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
|||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
|
||||
github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
|
||||
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
||||
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw=
|
||||
github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/moby v27.1.1+incompatible h1:WdCIKJ4WIxhrKti5c+Z7sj2SLADbsuB/reEBpQ4rtOQ=
|
||||
github.com/moby/moby v27.1.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/moby v27.3.1+incompatible h1:KQbXBjo7PavKpzIl7UkHT31y9lw/e71Uvrqhr4X+zMA=
|
||||
github.com/moby/moby v27.3.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -413,8 +416,8 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D
|
|||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257 h1:RNw/zu+CJemcRlDFPjElZUbY2UlI/MA2B3I6PM3Isiw=
|
||||
github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/neticdk/go-bitbucket v1.0.0 h1:FPvHEgPHoDwD2VHbpyu2R2gnoWQ867RxZd2FivS4wSw=
|
||||
|
@ -426,11 +429,11 @@ github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNs
|
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE=
|
||||
github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
|
@ -444,23 +447,22 @@ github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef
|
|||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
|
@ -511,20 +513,22 @@ github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
|||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||
github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg=
|
||||
github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk=
|
||||
github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
|
||||
github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4 h1:exFN/ZOxXslYr9t2AjrniP7wPjp/VLLAJhgazj92EBg=
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5.0.20240714105325-1da00919bcb4/go.mod h1:AIqom6Q60U4tiqHp41i7+/AB2XHgi1WvQ7jOFlccmZ4=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1 h1:oxO/Jem1QPy4lxbDtX8PMiFbL79dNMA6CNAfbC06rn4=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20240711030030-937cfe918cb1/go.mod h1:Z1ItyMma7t6I7zHG9OpbExhHQOSkFf/96n+mAZ9MtVI=
|
||||
github.com/xanzy/go-gitlab v0.107.0 h1:P2CT9Uy9yN9lJo3FLxpMZ4xj6uWcpnigXsjvqJ6nd2Y=
|
||||
github.com/xanzy/go-gitlab v0.107.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY=
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5 h1:H1oWnR2/GN0dNm2PVylws+GxSOD6YOwW/jI5l78YfPk=
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha5/go.mod h1:AIqom6Q60U4tiqHp41i7+/AB2XHgi1WvQ7jOFlccmZ4=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20241004184838-20ef97b2155a h1:ipFw/N7kumxX+CA9UoKXX86MNfYsfsom8YOdUC+Rsfw=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.0.20241004184838-20ef97b2155a/go.mod h1:Z1ItyMma7t6I7zHG9OpbExhHQOSkFf/96n+mAZ9MtVI=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/go-gitlab v0.112.0 h1:6Z0cqEooCvBMfBIHw+CgO4AKGRV8na/9781xOb0+DKw=
|
||||
github.com/xanzy/go-gitlab v0.112.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
|
@ -532,19 +536,17 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
|
|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
github.com/yaronf/httpsign v0.3.1 h1:A4pqjwOVCwlExyy/mPTTryCHcXn+xhq4+wxq4BKhi2k=
|
||||
github.com/yaronf/httpsign v0.3.1/go.mod h1:+7d6GccMcoljvE3QtU00NCmR1iTXCVNfbMe5nqaxRG4=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8=
|
||||
github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
|
||||
github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s=
|
||||
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
|
||||
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
|
||||
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
|
@ -599,18 +601,16 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
|||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -624,17 +624,17 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -664,14 +664,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -679,8 +679,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -697,22 +697,22 @@ golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade h1:WxZOF2yayUHpHSbUE6NMzumUzBxYc3YGwo0YHnbzsJY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a h1:hqK4+jJZXCU4pW7jsAdGOVFIfLHQeV7LaizZKnZ84HI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
@ -737,18 +737,18 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
|
||||
k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
|
||||
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
|
||||
k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k=
|
||||
k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
|
||||
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
|
||||
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
|
||||
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
|
||||
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
|
|
|
@ -10,3 +10,7 @@ section: daemon/system
|
|||
contents:
|
||||
- src: ./dist/agent/linux_amd64/woodpecker-agent
|
||||
dst: /usr/local/bin/woodpecker-agent
|
||||
- src: ./nfpm/woodpecker-agent.service
|
||||
dst: /usr/local/lib/systemd/system/
|
||||
- src: ./nfpm/woodpecker-agent.env.example
|
||||
dst: /etc/woodpecker/
|
||||
|
|
|
@ -10,3 +10,7 @@ section: daemon/system
|
|||
contents:
|
||||
- src: ./dist/server/linux_amd64/woodpecker-server
|
||||
dst: /usr/local/bin/woodpecker-server
|
||||
- src: ./nfpm/woodpecker-server.service
|
||||
dst: /usr/local/lib/systemd/system/
|
||||
- src: ./nfpm/woodpecker-server.env.example
|
||||
dst: /etc/woodpecker/
|
||||
|
|
7
nfpm/woodpecker-agent.env.example
Normal file
7
nfpm/woodpecker-agent.env.example
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Example for a woodpecker-agent.env file
|
||||
|
||||
# Check the documentation for the agent:
|
||||
# https://woodpecker-ci.org/docs/administration/agent-config
|
||||
|
||||
# Add all required environment variables for your setup in the form of VARIABLE=value
|
||||
VARIABLE=value
|
19
nfpm/woodpecker-agent.service
Normal file
19
nfpm/woodpecker-agent.service
Normal file
|
@ -0,0 +1,19 @@
|
|||
[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
|
7
nfpm/woodpecker-server.env.example
Normal file
7
nfpm/woodpecker-server.env.example
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Example for a woodpecker-server.env file
|
||||
|
||||
# Check the documentation for the server:
|
||||
# https://woodpecker-ci.org/docs/administration/server-config
|
||||
|
||||
# Add all required environment variables for your setup in the form of VARIABLE=value
|
||||
VARIABLE=value
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue