mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-18 14:36:30 +00:00
Merge branch 'main' into fix/code-highlight-colors
This commit is contained in:
commit
c6d78971ff
95 changed files with 3973 additions and 2589 deletions
|
@ -2,7 +2,7 @@ variables:
|
|||
- &golang_image 'docker.io/golang:1.23'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.23.x'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:5.0.0'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:5.1.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.23'
|
||||
- &node_image 'docker.io/node:23-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.20'
|
||||
- &alpine_image 'docker.io/alpine:3.21'
|
||||
- path: &when_path
|
||||
- 'docs/**'
|
||||
- '.woodpecker/docs.yaml'
|
||||
|
|
31
.woodpecker/links.yaml
Normal file
31
.woodpecker/links.yaml
Normal file
|
@ -0,0 +1,31 @@
|
|||
when:
|
||||
- event: cron
|
||||
cron: links
|
||||
|
||||
steps:
|
||||
- name: links
|
||||
image: docker.io/lycheeverse/lychee:0.15.1
|
||||
failure: ignore
|
||||
depends_on: []
|
||||
commands:
|
||||
- lychee pipeline/frontend/yaml/linter/schema/schema.json > links.md
|
||||
- lychee --exclude localhost docs/docs/ >> links.md
|
||||
- lychee --exclude localhost docs/src/pages/ >> links.md
|
||||
- echo -e "\nLast checked:$(date)" >> links.md
|
||||
|
||||
- name: Update issue
|
||||
image: docker.io/alpine:3.21
|
||||
depends_on: links
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: github_token
|
||||
commands:
|
||||
- apk add -q --no-cache jq curl
|
||||
- export ISSUE_NUMBER=4514
|
||||
- export DESCRIPTION=$(cat links.md)
|
||||
- |
|
||||
curl -X PATCH \
|
||||
-H "Authorization: token $GITHUB_TOKEN" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/${CI_REPO}/issues/$ISSUE_NUMBER \
|
||||
-d "$(jq -n --arg body "$DESCRIPTION" '{body: $body}')"
|
|
@ -1,15 +1,15 @@
|
|||
when:
|
||||
- event: push
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
- release/*
|
||||
|
||||
steps:
|
||||
- name: release-helper
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:2.1.1
|
||||
image: docker.io/woodpeckerci/plugin-ready-release-go:3.1.0
|
||||
settings:
|
||||
release_branch: ${CI_COMMIT_BRANCH}
|
||||
forge_type: github
|
||||
git_email: woodpecker-bot@obermui.de
|
||||
github_token:
|
||||
from_secret: GITHUB_TOKEN
|
||||
|
||||
when:
|
||||
- event: push
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
- release/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
when:
|
||||
- event: [pull_request, cron]
|
||||
- event: [pull_request]
|
||||
- event: push
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
|
|
|
@ -19,15 +19,7 @@ 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.2.0
|
||||
image: docker.io/woodpeckerci/plugin-prettier:1.0.0
|
||||
depends_on: []
|
||||
settings:
|
||||
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 --user-agent "curl/8.4.0" --exclude localhost docs/docs/
|
||||
- lychee --user-agent "curl/8.4.0" --exclude localhost docs/src/pages/
|
||||
|
|
|
@ -36,7 +36,7 @@ steps:
|
|||
environment:
|
||||
WOODPECKER_DISABLE_UPDATE_CHECK: true
|
||||
WOODPECKER_LINT_STRICT: true
|
||||
WOODPECKER_PLUGINS_PRIVILEGED: 'docker.io/woodpeckerci/plugin-docker-buildx:5.0.0'
|
||||
WOODPECKER_PLUGINS_PRIVILEGED: 'docker.io/woodpeckerci/plugin-docker-buildx'
|
||||
when:
|
||||
- event: pull_request
|
||||
path:
|
||||
|
@ -125,7 +125,7 @@ steps:
|
|||
- test
|
||||
- sqlite
|
||||
pull: true
|
||||
image: docker.io/woodpeckerci/plugin-codecov:2.1.5
|
||||
image: docker.io/woodpeckerci/plugin-codecov:2.1.6
|
||||
settings:
|
||||
files:
|
||||
- agent-coverage.out
|
||||
|
|
315
CHANGELOG.md
315
CHANGELOG.md
|
@ -1,5 +1,320 @@
|
|||
# Changelog
|
||||
|
||||
## [3.0.0](https://github.com/woodpecker-ci/woodpecker/releases/tag/v3.0.0) - 2024-12-13
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@6543, @Fishbowler, @M0Rf30, @anbraten, @cduchenoy, @fernandrone, @gnowland, @greenaar, @hg, @j04n-f, @jenrik, @johanneskastl, @jolheiser, @lafriks, @lukashass, @meln5674, @not-my-profile, @pat-s, @qwerty287, @smainz, @tori-27, @tsufeki, @xoxys, @xtexChooser, @zc-devs
|
||||
|
||||
### 💥 Breaking changes
|
||||
|
||||
- Drop native Let's Encrypt support [[#4541](https://github.com/woodpecker-ci/woodpecker/pull/4541)]
|
||||
- Set new default approval mode based on repo visibility [[#4456](https://github.com/woodpecker-ci/woodpecker/pull/4456)]
|
||||
- Do not set empty environment variables [[#4193](https://github.com/woodpecker-ci/woodpecker/pull/4193)]
|
||||
- Unify cli commands and flags [[#4481](https://github.com/woodpecker-ci/woodpecker/pull/4481)]
|
||||
- Move pipeline logs command [[#4480](https://github.com/woodpecker-ci/woodpecker/pull/4480)]
|
||||
- Fix woodpecker-go repo model to match server [[#4479](https://github.com/woodpecker-ci/woodpecker/pull/4479)]
|
||||
- Restructure cli commands [[#4467](https://github.com/woodpecker-ci/woodpecker/pull/4467)]
|
||||
- Add pagination options to all supported endpoints in sdk [[#4463](https://github.com/woodpecker-ci/woodpecker/pull/4463)]
|
||||
- Allow to set custom trusted clone plugins [[#4352](https://github.com/woodpecker-ci/woodpecker/pull/4352)]
|
||||
- Add PipelineListsOptions to woodpecker-go [[#3652](https://github.com/woodpecker-ci/woodpecker/pull/3652)]
|
||||
- Remove `secrets` in favor of `from_secret` [[#4363](https://github.com/woodpecker-ci/woodpecker/pull/4363)]
|
||||
- Kubernetes | Docker: Add support for rootless images [[#4151](https://github.com/woodpecker-ci/woodpecker/pull/4151)]
|
||||
- Split repo trusted setting [[#4025](https://github.com/woodpecker-ci/woodpecker/pull/4025)]
|
||||
- Move docker resource limit settings from server to agent [[#3174](https://github.com/woodpecker-ci/woodpecker/pull/3174)]
|
||||
- Set `/woodpecker` as default workdir for the **woodpecker-cli** container [[#4130](https://github.com/woodpecker-ci/woodpecker/pull/4130)]
|
||||
- Require upgrade from 2.x [[#4112](https://github.com/woodpecker-ci/woodpecker/pull/4112)]
|
||||
- Don't expose task data via api [[#4108](https://github.com/woodpecker-ci/woodpecker/pull/4108)]
|
||||
- Remove some ci environment variables [[#3846](https://github.com/woodpecker-ci/woodpecker/pull/3846)]
|
||||
- Remove all default privileged plugins [[#4053](https://github.com/woodpecker-ci/woodpecker/pull/4053)]
|
||||
- Add option to filter secrets by plugins with specific tags [[#4069](https://github.com/woodpecker-ci/woodpecker/pull/4069)]
|
||||
- Remove old pipeline options [[#4016](https://github.com/woodpecker-ci/woodpecker/pull/4016)]
|
||||
- Remove various deprecations [[#4017](https://github.com/woodpecker-ci/woodpecker/pull/4017)]
|
||||
- Drop repo name fallback for hooks [[#4013](https://github.com/woodpecker-ci/woodpecker/pull/4013)]
|
||||
- Improve local backend detection [[#4006](https://github.com/woodpecker-ci/woodpecker/pull/4006)]
|
||||
- Refactor JSON and SDK fields [[#3968](https://github.com/woodpecker-ci/woodpecker/pull/3968)]
|
||||
- Migrate to maintained cron lib and remove seconds [[#3785](https://github.com/woodpecker-ci/woodpecker/pull/3785)]
|
||||
- Switch to profile-based AppArmor configuration [[#4008](https://github.com/woodpecker-ci/woodpecker/pull/4008)]
|
||||
- Remove Kubernetes default image pull secret name `regcred` [[#4005](https://github.com/woodpecker-ci/woodpecker/pull/4005)]
|
||||
- Drop "WOODPECKER_WEBHOOK_HOST" env var and adjust docs [[#3969](https://github.com/woodpecker-ci/woodpecker/pull/3969)]
|
||||
- Drop version in schema [[#3970](https://github.com/woodpecker-ci/woodpecker/pull/3970)]
|
||||
- Update docker to v27 [[#3972](https://github.com/woodpecker-ci/woodpecker/pull/3972)]
|
||||
- Require gitlab 12.4 [[#3966](https://github.com/woodpecker-ci/woodpecker/pull/3966)]
|
||||
- Migrate to maintained httpsign library [[#3839](https://github.com/woodpecker-ci/woodpecker/pull/3839)]
|
||||
- Remove `WOODPECKER_DEV_OAUTH_HOST` and `WOODPECKER_DEV_GITEA_OAUTH_URL` [[#3961](https://github.com/woodpecker-ci/woodpecker/pull/3961)]
|
||||
- Remove deprecated pipeline keywords: `pipeline:`, `platform:`, `branches:` [[#3916](https://github.com/woodpecker-ci/woodpecker/pull/3916)]
|
||||
- server: remove old unused routes [[#3845](https://github.com/woodpecker-ci/woodpecker/pull/3845)]
|
||||
- CLI: remove step-id and add step-number as option to logs [[#3927](https://github.com/woodpecker-ci/woodpecker/pull/3927)]
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- Add server config to disable user registered agents [[#4206](https://github.com/woodpecker-ci/woodpecker/pull/4206)]
|
||||
- chore: fix `http-proxy-middleware` CVE [[#4257](https://github.com/woodpecker-ci/woodpecker/pull/4257)]
|
||||
- Allow altering trusted clone plugins and filter them via tag [[#4074](https://github.com/woodpecker-ci/woodpecker/pull/4074)]
|
||||
- Update gitea sdk [[#4012](https://github.com/woodpecker-ci/woodpecker/pull/4012)]
|
||||
- Update Forgejo SDK [[#3948](https://github.com/woodpecker-ci/woodpecker/pull/3948)]
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- Add user as docker backend_option [[#4526](https://github.com/woodpecker-ci/woodpecker/pull/4526)]
|
||||
- Implement org/user agents [[#3539](https://github.com/woodpecker-ci/woodpecker/pull/3539)]
|
||||
- Replay pipeline using `cli exec` by downloading metadata [[#4103](https://github.com/woodpecker-ci/woodpecker/pull/4103)]
|
||||
- Update clone plugin to support sha256 [[#4136](https://github.com/woodpecker-ci/woodpecker/pull/4136)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Fix BB ambiguous commit status key [[#4544](https://github.com/woodpecker-ci/woodpecker/pull/4544)]
|
||||
- fix: addon JSON pointers [[#4508](https://github.com/woodpecker-ci/woodpecker/pull/4508)]
|
||||
- Fix apparmorProfile being ignored when it's the only field [[#4507](https://github.com/woodpecker-ci/woodpecker/pull/4507)]
|
||||
- Sanitize strings in table output [[#4466](https://github.com/woodpecker-ci/woodpecker/pull/4466)]
|
||||
- Cleanup openapi generation [[#4331](https://github.com/woodpecker-ci/woodpecker/pull/4331)]
|
||||
- Support github refresh tokens [[#3811](https://github.com/woodpecker-ci/woodpecker/pull/3811)]
|
||||
- Fix not working overflow on repo list message [[#4420](https://github.com/woodpecker-ci/woodpecker/pull/4420)]
|
||||
- Fix avatar column type [[#4340](https://github.com/woodpecker-ci/woodpecker/pull/4340)]
|
||||
- fix `error="io: read/write on closed pipe"` on k8s backend [[#4281](https://github.com/woodpecker-ci/woodpecker/pull/4281)]
|
||||
- Move update notifier dot into settings button [[#4334](https://github.com/woodpecker-ci/woodpecker/pull/4334)]
|
||||
- gitea: add check if pull_request webhook is missing pull info [[#4305](https://github.com/woodpecker-ci/woodpecker/pull/4305)]
|
||||
- Refresh token before loading branches [[#4284](https://github.com/woodpecker-ci/woodpecker/pull/4284)]
|
||||
- Delete GitLab webhooks with partial URL match [[#4259](https://github.com/woodpecker-ci/woodpecker/pull/4259)]
|
||||
- Increase `WOODPECKER_FORGE_TIMEOUT` to fix config fetching for GitLab [[#4262](https://github.com/woodpecker-ci/woodpecker/pull/4262)]
|
||||
- Ensure cli exec has by default not the same prefix [[#4132](https://github.com/woodpecker-ci/woodpecker/pull/4132)]
|
||||
- Fix repo add loading spinner [[#4135](https://github.com/woodpecker-ci/woodpecker/pull/4135)]
|
||||
- Fix migration registries table [[#4111](https://github.com/woodpecker-ci/woodpecker/pull/4111)]
|
||||
- Wait for tracer to be done before finishing workflow [[#4068](https://github.com/woodpecker-ci/woodpecker/pull/4068)]
|
||||
- Fix schema with detached steps [[#4066](https://github.com/woodpecker-ci/woodpecker/pull/4066)]
|
||||
- Fix schema with commands and entrypoint [[#4065](https://github.com/woodpecker-ci/woodpecker/pull/4065)]
|
||||
- Read long log lines from file storage correctly [[#4048](https://github.com/woodpecker-ci/woodpecker/pull/4048)]
|
||||
- Set refspec for gitlab MR [[#4021](https://github.com/woodpecker-ci/woodpecker/pull/4021)]
|
||||
- Set `CI_PREV_COMMIT_{SOURCE,TARGET}_BRANCH` as mentioned in the documentation [[#4001](https://github.com/woodpecker-ci/woodpecker/pull/4001)]
|
||||
- [Bitbucket Datacenter] Return empty list instead of null [[#4010](https://github.com/woodpecker-ci/woodpecker/pull/4010)]
|
||||
- Fix BB PR pipeline ref [[#3985](https://github.com/woodpecker-ci/woodpecker/pull/3985)]
|
||||
- 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)]
|
||||
- Truncate creation in list [[#3952](https://github.com/woodpecker-ci/woodpecker/pull/3952)]
|
||||
- Fix panic if forge is unreachable [[#3944](https://github.com/woodpecker-ci/woodpecker/pull/3944)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Show client flags [[#4542](https://github.com/woodpecker-ci/woodpecker/pull/4542)]
|
||||
- chore(deps): update react monorepo to v19 (major) [[#4523](https://github.com/woodpecker-ci/woodpecker/pull/4523)]
|
||||
- chore(deps): update docs npm deps non-major [[#4519](https://github.com/woodpecker-ci/woodpecker/pull/4519)]
|
||||
- chore(deps): lock file maintenance [[#4502](https://github.com/woodpecker-ci/woodpecker/pull/4502)]
|
||||
- chore(deps): lock file maintenance [[#4501](https://github.com/woodpecker-ci/woodpecker/pull/4501)]
|
||||
- chore(deps): update dependency isomorphic-dompurify to v2.18.0 [[#4493](https://github.com/woodpecker-ci/woodpecker/pull/4493)]
|
||||
- fix(deps): update docs npm deps non-major [[#4484](https://github.com/woodpecker-ci/woodpecker/pull/4484)]
|
||||
- Add migration notes for restructured cli commands [[#4476](https://github.com/woodpecker-ci/woodpecker/pull/4476)]
|
||||
- Various fixes for `awesome.md` [[#4448](https://github.com/woodpecker-ci/woodpecker/pull/4448)]
|
||||
- chore(deps): lock file maintenance [[#4453](https://github.com/woodpecker-ci/woodpecker/pull/4453)]
|
||||
- chore(deps): update dependency isomorphic-dompurify to v2.17.0 [[#4449](https://github.com/woodpecker-ci/woodpecker/pull/4449)]
|
||||
- fix(deps): update docs npm deps non-major [[#4441](https://github.com/woodpecker-ci/woodpecker/pull/4441)]
|
||||
- chore(deps): update dependency @docusaurus/tsconfig to v3.6.2 [[#4433](https://github.com/woodpecker-ci/woodpecker/pull/4433)]
|
||||
- chore(deps): lock file maintenance [[#4435](https://github.com/woodpecker-ci/woodpecker/pull/4435)]
|
||||
- Bump minimum nodejs to v20 [[#4417](https://github.com/woodpecker-ci/woodpecker/pull/4417)]
|
||||
- chore(deps): lock file maintenance [[#4402](https://github.com/woodpecker-ci/woodpecker/pull/4402)]
|
||||
- Add microsoft teams plugin [[#4400](https://github.com/woodpecker-ci/woodpecker/pull/4400)]
|
||||
- fix(deps): update docs npm deps non-major [[#4394](https://github.com/woodpecker-ci/woodpecker/pull/4394)]
|
||||
- chore(deps): update dependency @types/node to v22 [[#4395](https://github.com/woodpecker-ci/woodpecker/pull/4395)]
|
||||
- chore(deps): update dependency marked to v15 [[#4396](https://github.com/woodpecker-ci/woodpecker/pull/4396)]
|
||||
- Podman is not (official) supported [[#4367](https://github.com/woodpecker-ci/woodpecker/pull/4367)]
|
||||
- Add EditorConfig-Checker Plugin to docs [[#4371](https://github.com/woodpecker-ci/woodpecker/pull/4371)]
|
||||
- Update netrc option description [[#4342](https://github.com/woodpecker-ci/woodpecker/pull/4342)]
|
||||
- Fix deployment event note [[#4283](https://github.com/woodpecker-ci/woodpecker/pull/4283)]
|
||||
- Improve migration notes [[#4291](https://github.com/woodpecker-ci/woodpecker/pull/4291)]
|
||||
- Add instructions how to build images locally [[#4277](https://github.com/woodpecker-ci/woodpecker/pull/4277)]
|
||||
- chore(deps): update docs npm deps non-major [[#4238](https://github.com/woodpecker-ci/woodpecker/pull/4238)]
|
||||
- Correct spelling [[#4279](https://github.com/woodpecker-ci/woodpecker/pull/4279)]
|
||||
- Add Telegram plugin [[#4229](https://github.com/woodpecker-ci/woodpecker/pull/4229)]
|
||||
- Remove archived plugin [[#4227](https://github.com/woodpecker-ci/woodpecker/pull/4227)]
|
||||
- Use "Woodpecker Authors" as copyright on website [[#4225](https://github.com/woodpecker-ci/woodpecker/pull/4225)]
|
||||
- chore(deps): update dependency cookie to v1 [[#4224](https://github.com/woodpecker-ci/woodpecker/pull/4224)]
|
||||
- fix(deps): update docs npm deps non-major [[#4221](https://github.com/woodpecker-ci/woodpecker/pull/4221)]
|
||||
- Fix errant apostrophe in docker-compose documentation [[#4203](https://github.com/woodpecker-ci/woodpecker/pull/4203)]
|
||||
- chore(deps): lock file maintenance [[#4186](https://github.com/woodpecker-ci/woodpecker/pull/4186)]
|
||||
- chore(deps): update dependency concurrently to v9 [[#4176](https://github.com/woodpecker-ci/woodpecker/pull/4176)]
|
||||
- chore(deps): update docs npm deps non-major [[#4164](https://github.com/woodpecker-ci/woodpecker/pull/4164)]
|
||||
- Update image filter error message [[#4143](https://github.com/woodpecker-ci/woodpecker/pull/4143)]
|
||||
- Docs: reference to built-in docker compose and remove deprecated version from compose examples [[#4123](https://github.com/woodpecker-ci/woodpecker/pull/4123)]
|
||||
- directory key is allowed for services [[#4127](https://github.com/woodpecker-ci/woodpecker/pull/4127)]
|
||||
- [docs] Removes dot prefix from pipeline configuration filenames [[#4105](https://github.com/woodpecker-ci/woodpecker/pull/4105)]
|
||||
- Use kaniko plugin in docs as example [[#4072](https://github.com/woodpecker-ci/woodpecker/pull/4072)]
|
||||
- Add some posts and videos [[#4070](https://github.com/woodpecker-ci/woodpecker/pull/4070)]
|
||||
- Move event type descriptions from Terminology to Workflow Syntax [[#4062](https://github.com/woodpecker-ci/woodpecker/pull/4062)]
|
||||
- Add community posts from discussions [[#4058](https://github.com/woodpecker-ci/woodpecker/pull/4058)]
|
||||
- Add a pull request template with some basic guidelines [[#4055](https://github.com/woodpecker-ci/woodpecker/pull/4055)]
|
||||
- Add examples of CI environment variable values [[#4009](https://github.com/woodpecker-ci/woodpecker/pull/4009)]
|
||||
- Fix inline author warning [[#4040](https://github.com/woodpecker-ci/woodpecker/pull/4040)]
|
||||
- Updated Secrets image filter docs [[#4028](https://github.com/woodpecker-ci/woodpecker/pull/4028)]
|
||||
- Update dependency marked to v14 [[#4036](https://github.com/woodpecker-ci/woodpecker/pull/4036)]
|
||||
- Update docs npm deps non-major [[#4033](https://github.com/woodpecker-ci/woodpecker/pull/4033)]
|
||||
- Overhaul README [[#3995](https://github.com/woodpecker-ci/woodpecker/pull/3995)]
|
||||
- fix(deps): update docs npm deps non-major [[#3990](https://github.com/woodpecker-ci/woodpecker/pull/3990)]
|
||||
- Add spellchecking for docs [[#3787](https://github.com/woodpecker-ci/woodpecker/pull/3787)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- Use docusaurus faster [[#4528](https://github.com/woodpecker-ci/woodpecker/pull/4528)]
|
||||
- Use pagination helper to list pipelines in cli [[#4478](https://github.com/woodpecker-ci/woodpecker/pull/4478)]
|
||||
- Some UI improvements [[#4497](https://github.com/woodpecker-ci/woodpecker/pull/4497)]
|
||||
- Add status filter to list pipeline API [[#4494](https://github.com/woodpecker-ci/woodpecker/pull/4494)]
|
||||
- Use JS-native date/time formatting [[#4488](https://github.com/woodpecker-ci/woodpecker/pull/4488)]
|
||||
- Add pipeline purge command to cli [[#4470](https://github.com/woodpecker-ci/woodpecker/pull/4470)]
|
||||
- Add option to limit the resultset returned by paginate helper [[#4475](https://github.com/woodpecker-ci/woodpecker/pull/4475)]
|
||||
- Add filter to list repository pipelines API [[#4416](https://github.com/woodpecker-ci/woodpecker/pull/4416)]
|
||||
- Increase log level when failing to fetch YAML [[#4107](https://github.com/woodpecker-ci/woodpecker/pull/4107)]
|
||||
- Trim space to all config flags that allow to read value from file [[#4468](https://github.com/woodpecker-ci/woodpecker/pull/4468)]
|
||||
- Change default icon size to 20 [[#4458](https://github.com/woodpecker-ci/woodpecker/pull/4458)]
|
||||
- Add visibility icon to repo list [[#4460](https://github.com/woodpecker-ci/woodpecker/pull/4460)]
|
||||
- Unify pipeline status icons [[#4414](https://github.com/woodpecker-ci/woodpecker/pull/4414)]
|
||||
- Improve project settings descriptions [[#4410](https://github.com/woodpecker-ci/woodpecker/pull/4410)]
|
||||
- Add count badge to visualize counters in tab title [[#4419](https://github.com/woodpecker-ci/woodpecker/pull/4419)]
|
||||
- Redesign repo list and include last pipeline [[#4386](https://github.com/woodpecker-ci/woodpecker/pull/4386)]
|
||||
- Use KeyValueEditor for DeployPipelinePopup too [[#4412](https://github.com/woodpecker-ci/woodpecker/pull/4412)]
|
||||
- Use separate routes instead of anchors [[#4285](https://github.com/woodpecker-ci/woodpecker/pull/4285)]
|
||||
- Untangle settings / header slots [[#4403](https://github.com/woodpecker-ci/woodpecker/pull/4403)]
|
||||
- Fix responsiveness of the settings template [[#4383](https://github.com/woodpecker-ci/woodpecker/pull/4383)]
|
||||
- Use squared spinner for active pipelines [[#4379](https://github.com/woodpecker-ci/woodpecker/pull/4379)]
|
||||
- Add server configuration option to add default set of labels for workflows that has no labels specified [[#4326](https://github.com/woodpecker-ci/woodpecker/pull/4326)]
|
||||
- Add `cli lint` option to treat warnings as errors [[#4373](https://github.com/woodpecker-ci/woodpecker/pull/4373)]
|
||||
- Improve error message for wrong secrets / environment config [[#4359](https://github.com/woodpecker-ci/woodpecker/pull/4359)]
|
||||
- Improve linter messages in UI [[#4351](https://github.com/woodpecker-ci/woodpecker/pull/4351)]
|
||||
- Pass settings to services [[#4338](https://github.com/woodpecker-ci/woodpecker/pull/4338)]
|
||||
- Inline model types for migrations [[#4293](https://github.com/woodpecker-ci/woodpecker/pull/4293)]
|
||||
- Add options to control the database connections (open,idle,timeout) [[#4212](https://github.com/woodpecker-ci/woodpecker/pull/4212)]
|
||||
- Move Queue creation behind new func that evaluates queue type [[#4252](https://github.com/woodpecker-ci/woodpecker/pull/4252)]
|
||||
- Add additional error message on swagger v2 to v3 convert [[#4254](https://github.com/woodpecker-ci/woodpecker/pull/4254)]
|
||||
- Deprecate `secrets` [[#4235](https://github.com/woodpecker-ci/woodpecker/pull/4235)]
|
||||
- Agent edit/detail view: change the help url based on the backend [[#4219](https://github.com/woodpecker-ci/woodpecker/pull/4219)]
|
||||
- Use middleware to load org [[#4208](https://github.com/woodpecker-ci/woodpecker/pull/4208)]
|
||||
- Assign workflows to agents with the best label matches [[#4201](https://github.com/woodpecker-ci/woodpecker/pull/4201)]
|
||||
- Report custom labels set by agent admins back [[#4141](https://github.com/woodpecker-ci/woodpecker/pull/4141)]
|
||||
- Highlight invalid entries in manual pipeline trigger [[#4153](https://github.com/woodpecker-ci/woodpecker/pull/4153)]
|
||||
- Print agent labels in debug mode [[#4155](https://github.com/woodpecker-ci/woodpecker/pull/4155)]
|
||||
- Implement registries for Kubernetes backend [[#4092](https://github.com/woodpecker-ci/woodpecker/pull/4092)]
|
||||
- Correct cli exec flags and remove ineffective ones [[#4129](https://github.com/woodpecker-ci/woodpecker/pull/4129)]
|
||||
- Set repo user to repairing user when old user is missing [[#4128](https://github.com/woodpecker-ci/woodpecker/pull/4128)]
|
||||
- Restart tasks on dead agents sooner [[#4114](https://github.com/woodpecker-ci/woodpecker/pull/4114)]
|
||||
- Adjust cli exec metadata structure to equal server metadata [[#4119](https://github.com/woodpecker-ci/woodpecker/pull/4119)]
|
||||
- Allow to restart declined pipelines [[#4109](https://github.com/woodpecker-ci/woodpecker/pull/4109)]
|
||||
- Add indices to repo table [[#4087](https://github.com/woodpecker-ci/woodpecker/pull/4087)]
|
||||
- Add systemd unit files to the RPM/DEB packages [[#3986](https://github.com/woodpecker-ci/woodpecker/pull/3986)]
|
||||
- Duplicate key `workflow_id` in the agent logs [[#4046](https://github.com/woodpecker-ci/woodpecker/pull/4046)]
|
||||
- Improve error on config loading [[#4024](https://github.com/woodpecker-ci/woodpecker/pull/4024)]
|
||||
- Show error if secret name is missing [[#4014](https://github.com/woodpecker-ci/woodpecker/pull/4014)]
|
||||
- Show error returned from API [[#3980](https://github.com/woodpecker-ci/woodpecker/pull/3980)]
|
||||
- Move manual popup to own page [[#3981](https://github.com/woodpecker-ci/woodpecker/pull/3981)]
|
||||
- Fail on InvalidImageName [[#4007](https://github.com/woodpecker-ci/woodpecker/pull/4007)]
|
||||
- Use Bitbucket PR title for pipeline message [[#3984](https://github.com/woodpecker-ci/woodpecker/pull/3984)]
|
||||
- Show logs if step has error [[#3979](https://github.com/woodpecker-ci/woodpecker/pull/3979)]
|
||||
- Refactor docker backend and add more test coverage [[#2700](https://github.com/woodpecker-ci/woodpecker/pull/2700)]
|
||||
- Make cli plugin log purge recognize steps by name [[#3953](https://github.com/woodpecker-ci/woodpecker/pull/3953)]
|
||||
- Pin page size [[#3946](https://github.com/woodpecker-ci/woodpecker/pull/3946)]
|
||||
- Improve cron list [[#3947](https://github.com/woodpecker-ci/woodpecker/pull/3947)]
|
||||
- Add PULLREQUEST_DRONE_PULL_REQUEST drone env [[#3939](https://github.com/woodpecker-ci/woodpecker/pull/3939)]
|
||||
- Make agent gRPC errors distinguishable [[#3936](https://github.com/woodpecker-ci/woodpecker/pull/3936)]
|
||||
|
||||
### 📦️ Dependency
|
||||
|
||||
- fix(deps): update module google.golang.org/grpc to v1.69.0 [[#4563](https://github.com/woodpecker-ci/woodpecker/pull/4563)]
|
||||
- fix(deps): update golang-packages [[#4553](https://github.com/woodpecker-ci/woodpecker/pull/4553)]
|
||||
- Update kin-openapi [[#4560](https://github.com/woodpecker-ci/woodpecker/pull/4560)]
|
||||
- fix(deps): update module golang.org/x/crypto to v0.31.0 [security] [[#4557](https://github.com/woodpecker-ci/woodpecker/pull/4557)]
|
||||
- fix(deps): update golang-packages [[#4546](https://github.com/woodpecker-ci/woodpecker/pull/4546)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-ready-release-go docker tag to v3.1.0 [[#4536](https://github.com/woodpecker-ci/woodpecker/pull/4536)]
|
||||
- chore(deps): update docker.io/curlimages/curl docker tag to v8.11.0 [[#4530](https://github.com/woodpecker-ci/woodpecker/pull/4530)]
|
||||
- fix(deps): update golang-packages [[#4496](https://github.com/woodpecker-ci/woodpecker/pull/4496)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-docker-buildx docker tag to v5.1.0 [[#4524](https://github.com/woodpecker-ci/woodpecker/pull/4524)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-prettier docker tag to v1 [[#4522](https://github.com/woodpecker-ci/woodpecker/pull/4522)]
|
||||
- chore(deps): update docker.io/alpine docker tag to v3.21 [[#4520](https://github.com/woodpecker-ci/woodpecker/pull/4520)]
|
||||
- chore(deps): update dependency vite to v6 [[#4485](https://github.com/woodpecker-ci/woodpecker/pull/4485)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-ready-release-go docker tag to v3 [[#4506](https://github.com/woodpecker-ci/woodpecker/pull/4506)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-surge-preview docker tag to v1.3.3 [[#4495](https://github.com/woodpecker-ci/woodpecker/pull/4495)]
|
||||
- fix(deps): update golang-packages [[#4477](https://github.com/woodpecker-ci/woodpecker/pull/4477)]
|
||||
- fix(deps): update dependency @vueuse/core to v12 [[#4486](https://github.com/woodpecker-ci/woodpecker/pull/4486)]
|
||||
- fix(deps): update module github.com/google/go-github/v66 to v67 [[#4487](https://github.com/woodpecker-ci/woodpecker/pull/4487)]
|
||||
- chore(deps): update woodpeckerci/plugin-release docker tag to v0.2.2 [[#4483](https://github.com/woodpecker-ci/woodpecker/pull/4483)]
|
||||
- chore(deps): update pre-commit hook golangci/golangci-lint to v1.62.2 [[#4482](https://github.com/woodpecker-ci/woodpecker/pull/4482)]
|
||||
- fix(deps): update golang-packages [[#4452](https://github.com/woodpecker-ci/woodpecker/pull/4452)]
|
||||
- fix(deps): update golang-packages [[#4411](https://github.com/woodpecker-ci/woodpecker/pull/4411)]
|
||||
- chore(deps): update pre-commit hook igorshubovych/markdownlint-cli to v0.43.0 [[#4443](https://github.com/woodpecker-ci/woodpecker/pull/4443)]
|
||||
- chore(deps): update postgres docker tag to v17.2 [[#4442](https://github.com/woodpecker-ci/woodpecker/pull/4442)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-trivy docker tag to v1.3.0 [[#4434](https://github.com/woodpecker-ci/woodpecker/pull/4434)]
|
||||
- chore(deps): update web npm deps non-major [[#4432](https://github.com/woodpecker-ci/woodpecker/pull/4432)]
|
||||
- fix(deps): update golang-packages [[#4401](https://github.com/woodpecker-ci/woodpecker/pull/4401)]
|
||||
- chore(deps): update web npm deps non-major [[#4391](https://github.com/woodpecker-ci/woodpecker/pull/4391)]
|
||||
- fix(deps): update dependency @intlify/unplugin-vue-i18n to v6 [[#4397](https://github.com/woodpecker-ci/woodpecker/pull/4397)]
|
||||
- chore(deps): update pre-commit hook golangci/golangci-lint to v1.62.0 [[#4390](https://github.com/woodpecker-ci/woodpecker/pull/4390)]
|
||||
- chore(deps): update postgres docker tag to v17.1 [[#4389](https://github.com/woodpecker-ci/woodpecker/pull/4389)]
|
||||
- chore(deps): update docker.io/techknowlogick/xgo docker tag to go-1.23.x [[#4388](https://github.com/woodpecker-ci/woodpecker/pull/4388)]
|
||||
- chore(config): migrate renovate config [[#4296](https://github.com/woodpecker-ci/woodpecker/pull/4296)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-trivy docker tag to v1.2.0 [[#4289](https://github.com/woodpecker-ci/woodpecker/pull/4289)]
|
||||
- chore(deps): update docker.io/techknowlogick/xgo docker tag to go-1.23.x [[#4282](https://github.com/woodpecker-ci/woodpecker/pull/4282)]
|
||||
- fix(deps): update golang-packages [[#4251](https://github.com/woodpecker-ci/woodpecker/pull/4251)]
|
||||
- fix(deps): update web npm deps non-major [[#4258](https://github.com/woodpecker-ci/woodpecker/pull/4258)]
|
||||
- chore(deps): update web npm deps non-major [[#4250](https://github.com/woodpecker-ci/woodpecker/pull/4250)]
|
||||
- chore(deps): update node.js to v23 [[#4239](https://github.com/woodpecker-ci/woodpecker/pull/4239)]
|
||||
- chore(deps): update web npm deps non-major [[#4237](https://github.com/woodpecker-ci/woodpecker/pull/4237)]
|
||||
- chore(deps): update docker.io/mysql docker tag to v9.1.0 [[#4236](https://github.com/woodpecker-ci/woodpecker/pull/4236)]
|
||||
- fix(deps): update dependency simple-icons to v13.14.0 [[#4226](https://github.com/woodpecker-ci/woodpecker/pull/4226)]
|
||||
- fix(deps): update web npm deps non-major [[#4223](https://github.com/woodpecker-ci/woodpecker/pull/4223)]
|
||||
- fix(deps): update golang-packages [[#4215](https://github.com/woodpecker-ci/woodpecker/pull/4215)]
|
||||
- fix(deps): update golang-packages [[#4210](https://github.com/woodpecker-ci/woodpecker/pull/4210)]
|
||||
- fix(deps): update module github.com/google/go-github/v65 to v66 [[#4205](https://github.com/woodpecker-ci/woodpecker/pull/4205)]
|
||||
- fix(deps): update dependency vue-i18n to v10.0.4 [[#4200](https://github.com/woodpecker-ci/woodpecker/pull/4200)]
|
||||
- chore(deps): update pre-commit hook pre-commit/pre-commit-hooks to v5 [[#4192](https://github.com/woodpecker-ci/woodpecker/pull/4192)]
|
||||
- fix(deps): update dependency simple-icons to v13.13.0 [[#4196](https://github.com/woodpecker-ci/woodpecker/pull/4196)]
|
||||
- chore(deps): update web npm deps non-major [[#4174](https://github.com/woodpecker-ci/woodpecker/pull/4174)]
|
||||
- chore(deps): update docker.io/postgres docker tag to v17 [[#4179](https://github.com/woodpecker-ci/woodpecker/pull/4179)]
|
||||
- fix(deps): update dependency @intlify/unplugin-vue-i18n to v5 [[#4183](https://github.com/woodpecker-ci/woodpecker/pull/4183)]
|
||||
- fix(deps): update dependency @vueuse/core to v11 [[#4184](https://github.com/woodpecker-ci/woodpecker/pull/4184)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-codecov docker tag to v2.1.5 [[#4167](https://github.com/woodpecker-ci/woodpecker/pull/4167)]
|
||||
- fix(deps): update module github.com/google/go-github/v64 to v65 [[#4185](https://github.com/woodpecker-ci/woodpecker/pull/4185)]
|
||||
- chore(deps): update docker.io/mysql docker tag to v9 [[#4178](https://github.com/woodpecker-ci/woodpecker/pull/4178)]
|
||||
- chore(deps): update docker.io/alpine docker tag to v3.20 [[#4169](https://github.com/woodpecker-ci/woodpecker/pull/4169)]
|
||||
- fix(deps): update github.com/urfave/cli/v3 digest to 20ef97b [[#4166](https://github.com/woodpecker-ci/woodpecker/pull/4166)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-surge-preview docker tag to v1.3.2 [[#4168](https://github.com/woodpecker-ci/woodpecker/pull/4168)]
|
||||
- chore(deps): update woodpeckerci/plugin-release docker tag to v0.2.1 [[#4175](https://github.com/woodpecker-ci/woodpecker/pull/4175)]
|
||||
- chore(deps): update woodpeckerci/plugin-ready-release-go docker tag to v2 [[#4182](https://github.com/woodpecker-ci/woodpecker/pull/4182)]
|
||||
- fix(deps): update github.com/muesli/termenv digest to 82936c5 [[#4165](https://github.com/woodpecker-ci/woodpecker/pull/4165)]
|
||||
- chore(deps): update postgres docker tag to v17 [[#4181](https://github.com/woodpecker-ci/woodpecker/pull/4181)]
|
||||
- chore(deps): update pre-commit non-major [[#4173](https://github.com/woodpecker-ci/woodpecker/pull/4173)]
|
||||
- chore(deps): update docker.io/golang docker tag to v1.23 [[#4170](https://github.com/woodpecker-ci/woodpecker/pull/4170)]
|
||||
- chore(deps): update node.js to v22 [[#4180](https://github.com/woodpecker-ci/woodpecker/pull/4180)]
|
||||
- fix(deps): update golang-packages [[#4161](https://github.com/woodpecker-ci/woodpecker/pull/4161)]
|
||||
- chore(deps): update dependency @antfu/eslint-config to v3 [[#4095](https://github.com/woodpecker-ci/woodpecker/pull/4095)]
|
||||
- chore(deps): update dependency jsdom to v25 [[#4094](https://github.com/woodpecker-ci/woodpecker/pull/4094)]
|
||||
- chore(deps): update docker.io/golang docker tag to v1.23 [[#4081](https://github.com/woodpecker-ci/woodpecker/pull/4081)]
|
||||
- chore(deps): update docker.io/woodpeckerci/plugin-prettier docker tag to v0.2.0 [[#4082](https://github.com/woodpecker-ci/woodpecker/pull/4082)]
|
||||
- fix(deps): update module github.com/google/go-github/v63 to v64 [[#4073](https://github.com/woodpecker-ci/woodpecker/pull/4073)]
|
||||
- fix(deps): update golang-packages [[#4059](https://github.com/woodpecker-ci/woodpecker/pull/4059)]
|
||||
- Update github.com/urfave/cli/v3 digest to fc07a8c [[#4043](https://github.com/woodpecker-ci/woodpecker/pull/4043)]
|
||||
- Update woodpeckerci/plugin-git Docker tag to v2.5.2 [[#4041](https://github.com/woodpecker-ci/woodpecker/pull/4041)]
|
||||
- Update web npm deps non-major [[#4034](https://github.com/woodpecker-ci/woodpecker/pull/4034)]
|
||||
- Update dependency simple-icons to v13 [[#4037](https://github.com/woodpecker-ci/woodpecker/pull/4037)]
|
||||
- chore(deps): lock file maintenance [[#3991](https://github.com/woodpecker-ci/woodpecker/pull/3991)]
|
||||
- fix(deps): update golang-packages [[#3958](https://github.com/woodpecker-ci/woodpecker/pull/3958)]
|
||||
|
||||
### Misc
|
||||
|
||||
- Move link checks into cron-curated issue dashboard [[#4515](https://github.com/woodpecker-ci/woodpecker/pull/4515)]
|
||||
- Add settings title action [[#4499](https://github.com/woodpecker-ci/woodpecker/pull/4499)]
|
||||
- Use same default sort for repo and org repo list [[#4461](https://github.com/woodpecker-ci/woodpecker/pull/4461)]
|
||||
- Add dns config option to official feature set [[#4418](https://github.com/woodpecker-ci/woodpecker/pull/4418)]
|
||||
- Remove `renovate` branch triggers [[#4437](https://github.com/woodpecker-ci/woodpecker/pull/4437)]
|
||||
- Improve tab layout and add hover effect [[#4431](https://github.com/woodpecker-ci/woodpecker/pull/4431)]
|
||||
- Dont run pipeline on push events to renovate branches [[#4406](https://github.com/woodpecker-ci/woodpecker/pull/4406)]
|
||||
- Harden and correct fifo task queue tests [[#4377](https://github.com/woodpecker-ci/woodpecker/pull/4377)]
|
||||
- Kubernetes documentation enhancements [[#4374](https://github.com/woodpecker-ci/woodpecker/pull/4374)]
|
||||
- Use release-helper for release/* branches [[#4301](https://github.com/woodpecker-ci/woodpecker/pull/4301)]
|
||||
- Fix wording for privileged plugins linter error [[#4280](https://github.com/woodpecker-ci/woodpecker/pull/4280)]
|
||||
- Fix renovate support for `xgo` [[#4276](https://github.com/woodpecker-ci/woodpecker/pull/4276)]
|
||||
- Improve nix development environment [[#4256](https://github.com/woodpecker-ci/woodpecker/pull/4256)]
|
||||
- [pre-commit.ci] pre-commit autoupdate [[#4209](https://github.com/woodpecker-ci/woodpecker/pull/4209)]
|
||||
- Add `.lycheeignore` [[#4154](https://github.com/woodpecker-ci/woodpecker/pull/4154)]
|
||||
- Add eslint-plugin-promise back [[#4022](https://github.com/woodpecker-ci/woodpecker/pull/4022)]
|
||||
- Improve wording [[#3951](https://github.com/woodpecker-ci/woodpecker/pull/3951)]
|
||||
- Fix typos and optimize wording [[#3940](https://github.com/woodpecker-ci/woodpecker/pull/3940)]
|
||||
|
||||
## [2.7.2](https://github.com/woodpecker-ci/woodpecker/releases/tag/v2.7.2) - 2024-11-03
|
||||
|
||||
### Important
|
||||
|
|
|
@ -48,19 +48,16 @@ var GlobalFlags = append([]cli.Flag{
|
|||
Sources: cli.EnvVars("WOODPECKER_SKIP_VERIFY"),
|
||||
Name: "skip-verify",
|
||||
Usage: "skip ssl verification",
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("SOCKS_PROXY"),
|
||||
Name: "socks-proxy",
|
||||
Usage: "socks proxy address",
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("SOCKS_PROXY_OFF"),
|
||||
Name: "socks-proxy-off",
|
||||
Usage: "socks proxy ignored",
|
||||
Hidden: true,
|
||||
},
|
||||
}, logger.GlobalLoggerFlags...)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"text/tabwriter"
|
||||
"unicode"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
// NewTable creates a new Table.
|
||||
|
|
|
@ -74,5 +74,5 @@ func pipelineCreate(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
||||
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||
}
|
||||
|
|
|
@ -58,5 +58,5 @@ func pipelineLast(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
||||
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/common"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
|
||||
shared_utils "go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
|
@ -77,60 +78,51 @@ func List(ctx context.Context, c *cli.Command) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resources, err := pipelineList(c, client)
|
||||
pipelines, err := pipelineList(c, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pipelineOutput(c, resources)
|
||||
return pipelineOutput(c, pipelines)
|
||||
}
|
||||
|
||||
func pipelineList(c *cli.Command, client woodpecker.Client) ([]woodpecker.Pipeline, error) {
|
||||
resources := make([]woodpecker.Pipeline, 0)
|
||||
|
||||
func pipelineList(c *cli.Command, client woodpecker.Client) ([]*woodpecker.Pipeline, error) {
|
||||
repoIDOrFullName := c.Args().First()
|
||||
repoID, err := internal.ParseRepo(client, repoIDOrFullName)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opt := woodpecker.PipelineListOptions{}
|
||||
before := c.Timestamp("before")
|
||||
after := c.Timestamp("after")
|
||||
|
||||
if !before.IsZero() {
|
||||
if before := c.Timestamp("before"); !before.IsZero() {
|
||||
opt.Before = before
|
||||
}
|
||||
if !after.IsZero() {
|
||||
if after := c.Timestamp("after"); !after.IsZero() {
|
||||
opt.After = after
|
||||
}
|
||||
|
||||
pipelines, err := client.PipelineList(repoID, opt)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
|
||||
branch := c.String("branch")
|
||||
event := c.String("event")
|
||||
status := c.String("status")
|
||||
limit := int(c.Int("limit"))
|
||||
|
||||
var count int
|
||||
for _, pipeline := range pipelines {
|
||||
if count >= limit {
|
||||
break
|
||||
}
|
||||
if branch != "" && pipeline.Branch != branch {
|
||||
continue
|
||||
}
|
||||
if event != "" && pipeline.Event != event {
|
||||
continue
|
||||
}
|
||||
if status != "" && pipeline.Status != status {
|
||||
continue
|
||||
}
|
||||
resources = append(resources, *pipeline)
|
||||
count++
|
||||
pipelines, err := shared_utils.Paginate(func(page int) ([]*woodpecker.Pipeline, error) {
|
||||
return client.PipelineList(repoID,
|
||||
woodpecker.PipelineListOptions{
|
||||
ListOptions: woodpecker.ListOptions{
|
||||
Page: page,
|
||||
},
|
||||
Before: opt.Before,
|
||||
After: opt.After,
|
||||
Branch: branch,
|
||||
Events: []string{event},
|
||||
Status: status,
|
||||
},
|
||||
)
|
||||
}, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resources, nil
|
||||
return pipelines, nil
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func TestPipelineList(t *testing.T) {
|
|||
pipelines []*woodpecker.Pipeline
|
||||
pipelineErr error
|
||||
args []string
|
||||
expected []woodpecker.Pipeline
|
||||
expected []*woodpecker.Pipeline
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
|
@ -34,53 +34,12 @@ func TestPipelineList(t *testing.T) {
|
|||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
args: []string{"ls", "repo/name"},
|
||||
expected: []woodpecker.Pipeline{
|
||||
expected: []*woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter by branch",
|
||||
repoID: 1,
|
||||
pipelines: []*woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
args: []string{"ls", "--branch", "main", "repo/name"},
|
||||
expected: []woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter by event",
|
||||
repoID: 1,
|
||||
pipelines: []*woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
args: []string{"ls", "--event", "push", "repo/name"},
|
||||
expected: []woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter by status",
|
||||
repoID: 1,
|
||||
pipelines: []*woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
args: []string{"ls", "--status", "success", "repo/name"},
|
||||
expected: []woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "limit results",
|
||||
repoID: 1,
|
||||
|
@ -90,7 +49,7 @@ func TestPipelineList(t *testing.T) {
|
|||
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
|
||||
},
|
||||
args: []string{"ls", "--limit", "2", "repo/name"},
|
||||
expected: []woodpecker.Pipeline{
|
||||
expected: []*woodpecker.Pipeline{
|
||||
{ID: 1, Branch: "main", Event: "push", Status: "success"},
|
||||
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
|
||||
},
|
||||
|
@ -107,7 +66,15 @@ func TestPipelineList(t *testing.T) {
|
|||
for _, tt := range testtases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockClient := mocks.NewClient(t)
|
||||
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(tt.pipelines, tt.pipelineErr)
|
||||
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(func(_ int64, opt woodpecker.PipelineListOptions) ([]*woodpecker.Pipeline, error) {
|
||||
if tt.pipelineErr != nil {
|
||||
return nil, tt.pipelineErr
|
||||
}
|
||||
if opt.Page == 1 {
|
||||
return tt.pipelines, nil
|
||||
}
|
||||
return []*woodpecker.Pipeline{}, nil
|
||||
}).Maybe()
|
||||
mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil)
|
||||
|
||||
command := buildPipelineListCmd()
|
||||
|
|
|
@ -50,7 +50,7 @@ var Command = &cli.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Writer) error {
|
||||
func pipelineOutput(c *cli.Command, pipelines []*woodpecker.Pipeline, fd ...io.Writer) error {
|
||||
outFmt, outOpt := output.ParseOutputOptions(c.String("output"))
|
||||
noHeader := c.Bool("output-no-headers")
|
||||
|
||||
|
@ -74,7 +74,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tmpl.Execute(out, resources); err != nil {
|
||||
if err := tmpl.Execute(out, pipelines); err != nil {
|
||||
return err
|
||||
}
|
||||
case "table":
|
||||
|
@ -89,7 +89,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
|
|||
if !noHeader {
|
||||
table.WriteHeader(cols)
|
||||
}
|
||||
for _, resource := range resources {
|
||||
for _, resource := range pipelines {
|
||||
if err := table.Write(cols, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func TestPipelineOutput(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
pipelines := []woodpecker.Pipeline{
|
||||
pipelines := []*woodpecker.Pipeline{
|
||||
{
|
||||
Number: 1,
|
||||
Status: "success",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2022 Woodpecker Authors
|
||||
// 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.
|
||||
|
@ -16,7 +16,9 @@ package pipeline
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
@ -96,13 +98,13 @@ func pipelinePurge(c *cli.Command, client woodpecker.Client) (err error) {
|
|||
// Create a map of pipeline IDs to keep
|
||||
keepMap := make(map[int64]struct{})
|
||||
for _, p := range pipelinesKeep {
|
||||
keepMap[p.ID] = struct{}{}
|
||||
keepMap[p.Number] = struct{}{}
|
||||
}
|
||||
|
||||
// Filter pipelines to only include those not in keepMap
|
||||
var pipelinesToPurge []*woodpecker.Pipeline
|
||||
for _, p := range pipelines {
|
||||
if _, exists := keepMap[p.ID]; !exists {
|
||||
if _, exists := keepMap[p.Number]; !exists {
|
||||
pipelinesToPurge = append(pipelinesToPurge, p)
|
||||
}
|
||||
}
|
||||
|
@ -114,13 +116,18 @@ func pipelinePurge(c *cli.Command, client woodpecker.Client) (err error) {
|
|||
|
||||
for i, p := range pipelinesToPurge {
|
||||
// cspell:words spurge
|
||||
log.Debug().Msgf("%spurge %v/%v pipelines from repo '%v'", msgPrefix, i+1, len(pipelinesToPurge), repoIDOrFullName)
|
||||
log.Debug().Msgf("%spurge %v/%v pipelines from repo '%v' (pipeline %v)", msgPrefix, i+1, len(pipelinesToPurge), repoIDOrFullName, p.Number)
|
||||
if dryRun {
|
||||
continue
|
||||
}
|
||||
|
||||
err := client.PipelineDelete(repoID, p.ID)
|
||||
err := client.PipelineDelete(repoID, p.Number)
|
||||
if err != nil {
|
||||
var clientErr *woodpecker.ClientError
|
||||
if errors.As(err, &clientErr) && clientErr.StatusCode == http.StatusUnprocessableEntity {
|
||||
log.Error().Err(err).Msgf("failed to delete pipeline %d", p.Number)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +157,7 @@ func fetchPipelines(client woodpecker.Client, repoID int64, duration time.Durati
|
|||
ListOptions: woodpecker.ListOptions{
|
||||
Page: page,
|
||||
},
|
||||
After: time.Now().Add(-duration),
|
||||
Before: time.Now().Add(-duration),
|
||||
},
|
||||
)
|
||||
}, -1)
|
||||
|
|
|
@ -16,20 +16,21 @@ import (
|
|||
|
||||
func TestPipelinePurge(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repoID int64
|
||||
args []string
|
||||
pipelinesKeep []*woodpecker.Pipeline
|
||||
pipelines []*woodpecker.Pipeline
|
||||
wantDelete int
|
||||
wantErr error
|
||||
name string
|
||||
repoID int64
|
||||
args []string
|
||||
pipelinesKeep []*woodpecker.Pipeline
|
||||
pipelines []*woodpecker.Pipeline
|
||||
mockDeleteError error
|
||||
wantDelete int
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "success with no pipelines to purge",
|
||||
repoID: 1,
|
||||
args: []string{"purge", "--older-than", "1h", "repo/name"},
|
||||
pipelinesKeep: []*woodpecker.Pipeline{
|
||||
{ID: 1},
|
||||
{Number: 1},
|
||||
},
|
||||
pipelines: []*woodpecker.Pipeline{},
|
||||
},
|
||||
|
@ -38,12 +39,12 @@ func TestPipelinePurge(t *testing.T) {
|
|||
repoID: 1,
|
||||
args: []string{"purge", "--older-than", "1h", "repo/name"},
|
||||
pipelinesKeep: []*woodpecker.Pipeline{
|
||||
{ID: 1},
|
||||
{Number: 1},
|
||||
},
|
||||
pipelines: []*woodpecker.Pipeline{
|
||||
{ID: 1},
|
||||
{ID: 2},
|
||||
{ID: 3},
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
{Number: 3},
|
||||
},
|
||||
wantDelete: 2,
|
||||
},
|
||||
|
@ -53,6 +54,24 @@ func TestPipelinePurge(t *testing.T) {
|
|||
args: []string{"purge", "--older-than", "invalid", "repo/name"},
|
||||
wantErr: errors.New("time: invalid duration \"invalid\""),
|
||||
},
|
||||
{
|
||||
name: "continue on 422 error",
|
||||
repoID: 1,
|
||||
args: []string{"purge", "--older-than", "1h", "repo/name"},
|
||||
pipelinesKeep: []*woodpecker.Pipeline{
|
||||
{Number: 1},
|
||||
},
|
||||
pipelines: []*woodpecker.Pipeline{
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
{Number: 3},
|
||||
},
|
||||
wantDelete: 2,
|
||||
mockDeleteError: &woodpecker.ClientError{
|
||||
StatusCode: 422,
|
||||
Message: "test error",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -62,15 +81,15 @@ func TestPipelinePurge(t *testing.T) {
|
|||
|
||||
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(func(_ int64, opt woodpecker.PipelineListOptions) ([]*woodpecker.Pipeline, error) {
|
||||
// Return keep pipelines for first call
|
||||
if opt.After.IsZero() {
|
||||
if opt.Before.IsZero() {
|
||||
if opt.Page == 1 {
|
||||
return tt.pipelinesKeep, nil
|
||||
}
|
||||
return []*woodpecker.Pipeline{}, nil
|
||||
}
|
||||
|
||||
// Return pipelines to purge for calls with After filter
|
||||
if !opt.After.IsZero() {
|
||||
// Return pipelines to purge for calls with Before filter
|
||||
if !opt.Before.IsZero() {
|
||||
if opt.Page == 1 {
|
||||
return tt.pipelines, nil
|
||||
}
|
||||
|
@ -80,7 +99,9 @@ func TestPipelinePurge(t *testing.T) {
|
|||
return []*woodpecker.Pipeline{}, nil
|
||||
}).Maybe()
|
||||
|
||||
if tt.wantDelete > 0 {
|
||||
if tt.mockDeleteError != nil {
|
||||
mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(tt.mockDeleteError)
|
||||
} else if tt.wantDelete > 0 {
|
||||
mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(nil).Times(tt.wantDelete)
|
||||
}
|
||||
|
||||
|
|
|
@ -65,5 +65,5 @@ func pipelineShow(ctx context.Context, c *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline})
|
||||
return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ var repoUpdateCmd = &cli.Command{
|
|||
Usage: "repository is trusted",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "gated",
|
||||
Usage: "repository is gated",
|
||||
Name: "gated", // TODO: remove in next release
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "require-approval",
|
||||
|
@ -82,7 +82,6 @@ func repoUpdate(ctx context.Context, c *cli.Command) error {
|
|||
config = c.String("config")
|
||||
timeout = c.Duration("timeout")
|
||||
trusted = c.Bool("trusted")
|
||||
gated = c.Bool("gated")
|
||||
requireApproval = c.String("require-approval")
|
||||
pipelineCounter = int(c.Int("pipeline-counter"))
|
||||
unsafe = c.Bool("unsafe")
|
||||
|
@ -92,29 +91,18 @@ func repoUpdate(ctx context.Context, c *cli.Command) error {
|
|||
if c.IsSet("trusted") {
|
||||
patch.IsTrusted = &trusted
|
||||
}
|
||||
// TODO: remove isGated in next major release
|
||||
|
||||
// TODO: remove in next release
|
||||
if c.IsSet("gated") {
|
||||
if gated {
|
||||
patch.RequireApproval = &woodpecker.RequireApprovalAllEvents
|
||||
} else {
|
||||
patch.RequireApproval = &woodpecker.RequireApprovalNone
|
||||
}
|
||||
return fmt.Errorf("'gated' option has been set in version 2.8, use 'require-approval' in >= 3.0")
|
||||
}
|
||||
|
||||
if c.IsSet("require-approval") {
|
||||
if mode := woodpecker.ApprovalMode(requireApproval); mode.Valid() {
|
||||
patch.RequireApproval = &mode
|
||||
} else {
|
||||
return fmt.Errorf("update approval mode failed: '%s' is no valid mode", mode)
|
||||
}
|
||||
|
||||
// TODO: remove isGated in next major release
|
||||
if requireApproval == string(woodpecker.RequireApprovalAllEvents) {
|
||||
trueBool := true
|
||||
patch.IsGated = &trueBool
|
||||
} else if requireApproval == string(woodpecker.RequireApprovalNone) {
|
||||
falseBool := false
|
||||
patch.IsGated = &falseBool
|
||||
}
|
||||
}
|
||||
if c.IsSet("timeout") {
|
||||
v := int64(timeout / time.Minute)
|
||||
|
|
|
@ -93,16 +93,6 @@ var flags = append([]cli.Flag{
|
|||
Name: "custom-js-file",
|
||||
Usage: "file path for the server to serve a custom .JS file, used for customizing the UI",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LETS_ENCRYPT_EMAIL"),
|
||||
Name: "lets-encrypt-email",
|
||||
Usage: "let's encrypt email",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_LETS_ENCRYPT"),
|
||||
Name: "lets-encrypt",
|
||||
Usage: "enable let's encrypt",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Sources: cli.EnvVars("WOODPECKER_GRPC_ADDR"),
|
||||
Name: "grpc-addr",
|
||||
|
|
|
@ -39,7 +39,7 @@ func pinger(_ context.Context, c *cli.Command) error {
|
|||
}
|
||||
|
||||
// if woodpecker do ssl on it's own
|
||||
if c.String("server-cert") != "" || c.Bool("lets-encrypt") {
|
||||
if c.String("server-cert") != "" {
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/gin-gonic/gin"
|
||||
prometheus_http "github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -167,8 +166,7 @@ func run(ctx context.Context, c *cli.Command) error {
|
|||
middleware.Store(_store),
|
||||
)
|
||||
|
||||
switch {
|
||||
case c.String("server-cert") != "":
|
||||
if c.String("server-cert") != "" {
|
||||
// start the server with tls enabled
|
||||
serviceWaitingGroup.Go(func() error {
|
||||
tlsServer := &http.Server{
|
||||
|
@ -234,32 +232,7 @@ func run(ctx context.Context, c *cli.Command) error {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
case c.Bool("lets-encrypt"):
|
||||
// start the server with lets-encrypt
|
||||
certmagic.DefaultACME.Email = c.String("lets-encrypt-email")
|
||||
certmagic.DefaultACME.Agreed = true
|
||||
|
||||
address, err := url.Parse(strings.TrimSuffix(c.String("server-host"), "/"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceWaitingGroup.Go(func() error {
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
log.Error().Msg("there is no certmagic.HTTPS alternative who is context aware we will fail in 2 seconds")
|
||||
time.Sleep(time.Second * 2)
|
||||
log.Fatal().Msg("we kill certmagic by fail") //nolint:forbidigo
|
||||
}()
|
||||
|
||||
log.Info().Msg("starting certmagic server ...")
|
||||
if err := certmagic.HTTPS([]string{address.Host}, handler); err != nil {
|
||||
log.Error().Err(err).Msg("certmagic does not work")
|
||||
stopServerFunc(fmt.Errorf("certmagic failed: %w", err))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
default:
|
||||
} else {
|
||||
// start the server without tls
|
||||
serviceWaitingGroup.Go(func() error {
|
||||
httpServer := &http.Server{
|
||||
|
|
|
@ -7,7 +7,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||
--mount=type=cache,target=/go/pkg \
|
||||
make build-agent
|
||||
|
||||
FROM docker.io/alpine:3.20
|
||||
FROM docker.io/alpine:3.21
|
||||
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
|
||||
|
|
|
@ -7,7 +7,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||
--mount=type=cache,target=/go/pkg \
|
||||
make build-cli
|
||||
|
||||
FROM docker.io/alpine:3.20
|
||||
FROM docker.io/alpine:3.21
|
||||
WORKDIR /woodpecker
|
||||
|
||||
RUN apk add -U --no-cache ca-certificates
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
||||
FROM docker.io/golang:1.23-alpine as golang_image
|
||||
# docker build --rm -f docker/Dockerfile.make -t woodpecker/make:local .
|
||||
FROM docker.io/golang:1.23-alpine AS golang_image
|
||||
FROM docker.io/node:23-alpine
|
||||
|
||||
RUN apk add --no-cache --update make gcc binutils-gold musl-dev protoc && \
|
||||
|
@ -10,6 +10,7 @@ COPY --from=golang_image /usr/local/go /usr/local/go
|
|||
COPY Makefile /
|
||||
ENV PATH=$PATH:/usr/local/go/bin
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
ENV COREPACK_ENABLE_AUTO_PIN=0
|
||||
|
||||
# Cache tools
|
||||
RUN GOBIN=/usr/local/go/bin make install-tools && \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM docker.io/alpine:3.20
|
||||
FROM docker.io/alpine:3.21
|
||||
|
||||
ARG TARGETOS TARGETARCH
|
||||
RUN apk add -U --no-cache ca-certificates
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
|
@ -11,17 +11,27 @@ Woodpecker provides three different levels to add secrets to your pipeline. The
|
|||
|
||||
## Usage
|
||||
|
||||
You can set a setting or an environment value from secrets using the `from_secret` syntax.
|
||||
You can set a setting or 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`.
|
||||
The example below passes a secret called `secret_token` as an environment variable that will be called `TOKEN_ENV`:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: my-plugin
|
||||
env-secret-example:
|
||||
image: alpine
|
||||
commands:
|
||||
+ - echo "The secret is $TOKEN_ENV"
|
||||
+ environment:
|
||||
+ TOKEN_ENV:
|
||||
+ from_secret: secret_token
|
||||
```
|
||||
|
||||
You can use the same syntax to pass secrets to settings. For example, you can pass a secret named `secret_token` to the settings called `token`, which will then be available in the plugin as environment variable named `PLUGIN_TOKEN` (See [plugins](./51-plugins/20-creating-plugins.md#settings) for details).
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: settings-secret-example
|
||||
image: my-plugin
|
||||
+ settings:
|
||||
+ token:
|
||||
+ from_secret: secret_token
|
||||
|
|
|
@ -70,11 +70,11 @@ This is the reference list of all environment variables available to your pipeli
|
|||
| `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_SOURCE_BRANCH` | commit source branch (set only for `pull_request` and `pull_request_closed` events) | `issue-branch` |
|
||||
| `CI_COMMIT_TARGET_BRANCH` | commit target branch (set only for `pull_request` and `pull_request_closed` events) | `main` |
|
||||
| `CI_COMMIT_TAG` | commit tag name (empty if event is not `tag`) | `v1.10.3` |
|
||||
| `CI_COMMIT_PULL_REQUEST` | commit pull request number (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_PULL_REQUEST` | commit pull request number (set only for `pull_request` and `pull_request_closed` events) | `1` |
|
||||
| `CI_COMMIT_PULL_REQUEST_LABELS` | labels assigned to pull request (set only for `pull_request` and `pull_request_closed` events) | `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` |
|
||||
|
@ -103,8 +103,8 @@ This is the reference list of all environment variables available to your pipeli
|
|||
| `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_SOURCE_BRANCH` | previous commit source branch (set only for `pull_request` and `pull_request_closed` events) | `issue-branch` |
|
||||
| `CI_PREV_COMMIT_TARGET_BRANCH` | previous commit target branch (set only for `pull_request` and `pull_request_closed` events) | `main` |
|
||||
| `CI_PREV_COMMIT_URL` | previous commit link in forge | `https://git.example.com/john-doe/my-repo/commit/15784117e4e103f36cba75a9e29da48046eb82c4` |
|
||||
| `CI_PREV_COMMIT_MESSAGE` | previous commit message | `test` |
|
||||
| `CI_PREV_COMMIT_AUTHOR` | previous commit author username | `john-doe` |
|
||||
|
|
|
@ -275,12 +275,6 @@ The file must be UTF-8 encoded, to ensure all special characters are preserved.
|
|||
|
||||
Example: `WOODPECKER_CUSTOM_JS_FILE=/usr/local/www/woodpecker.js`
|
||||
|
||||
### `WOODPECKER_LETS_ENCRYPT`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Automatically generates an SSL certificate using Let's Encrypt, and configures the server to accept HTTPS requests.
|
||||
|
||||
### `WOODPECKER_GRPC_ADDR`
|
||||
|
||||
> Default: `:9000`
|
||||
|
|
|
@ -38,7 +38,7 @@ Addons use RPC to communicate to the server and are implemented using the [`go-p
|
|||
|
||||
This example will use the Go language.
|
||||
|
||||
Directly import Woodpecker's Go packages (`go.woodpecker-ci.org/woodpecker/woodpecker/v2`) and use the interfaces and types defined there.
|
||||
Directly import Woodpecker's Go packages (`go.woodpecker-ci.org/woodpecker/v2`) and use the interfaces and types defined there.
|
||||
|
||||
In the `main` function, just call `"go.woodpecker-ci.org/woodpecker/v2/server/forge/addon".Serve` with a `"go.woodpecker-ci.org/woodpecker/v2/server/forge".Forge` as argument.
|
||||
This will take care of connecting the addon forge to the server.
|
||||
|
|
|
@ -18,6 +18,25 @@ FROM woodpeckerci/woodpecker-server:latest-alpine
|
|||
RUN apk add -U --no-cache docker-credential-ecr-login
|
||||
```
|
||||
|
||||
## Step specific configuration
|
||||
|
||||
### Run user
|
||||
|
||||
By default the docker backend starts the step container without the `--user` flag. This means the step container will use the default user of the container. To change this behavior you can set the `user` backend option to the preferred user/group:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: example
|
||||
image: alpine
|
||||
commands:
|
||||
- whoami
|
||||
backend_options:
|
||||
docker:
|
||||
user: 65534:65534
|
||||
```
|
||||
|
||||
The syntax is the same as the [docker run](https://docs.docker.com/engine/reference/run/#user) `--user` flag.
|
||||
|
||||
## Image cleanup
|
||||
|
||||
The agent **will not** automatically remove images from the host. This task should be managed by the host system. For example, you can use a cron job to periodically do clean-up tasks for the CI runner.
|
||||
|
|
|
@ -12,7 +12,7 @@ In addition to [registries specified in the UI](../../20-usage/41-registries.md)
|
|||
|
||||
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
|
||||
## Step specific configuration
|
||||
|
||||
### Resources
|
||||
|
||||
|
@ -67,7 +67,7 @@ To give steps access to the Kubernetes API via service account, take a look at [
|
|||
|
||||
### Node selector
|
||||
|
||||
`nodeSelector` specifies the labels which are used to select the node on which the job will be executed.
|
||||
`nodeSelector` specifies the labels which are used to select the node on which the step will be executed.
|
||||
|
||||
Labels defined here will be appended to a list which already contains `"kubernetes.io/arch"`.
|
||||
By default `"kubernetes.io/arch"` is inferred from the agents' platform. One can override it by setting that label in the `nodeSelector` section of the `backend_options`.
|
||||
|
|
|
@ -1,35 +1,5 @@
|
|||
# SSL
|
||||
|
||||
Woodpecker supports two ways of enabling SSL communication. You can either use Let's Encrypt to get automated SSL support with
|
||||
renewal or provide your own SSL certificates.
|
||||
|
||||
## Let's Encrypt
|
||||
|
||||
Woodpecker supports automated SSL configuration and updates using Let's Encrypt.
|
||||
|
||||
You can enable Let's Encrypt by making the following modifications to your server configuration:
|
||||
|
||||
```ini
|
||||
WOODPECKER_LETS_ENCRYPT=true
|
||||
WOODPECKER_LETS_ENCRYPT_EMAIL=ssl-admin@example.tld
|
||||
```
|
||||
|
||||
Note that Woodpecker uses the hostname from the `WOODPECKER_HOST` environment variable when requesting certificates. For example, if `WOODPECKER_HOST=https://example.com` is set the certificate is requested for `example.com`. To receive emails before certificates expire Let's Encrypt requires an email address. You can set it with `WOODPECKER_LETS_ENCRYPT_EMAIL=ssl-admin@example.tld`.
|
||||
|
||||
The SSL certificates are stored in `$HOME/.local/share/certmagic` for binary versions of Woodpecker and in `/var/lib/woodpecker` for the Container versions of it. You can set a custom path by setting `XDG_DATA_HOME` if required.
|
||||
|
||||
> Once enabled you can visit the Woodpecker UI with http and the HTTPS address. HTTP will be redirected to HTTPS.
|
||||
|
||||
### Certificate Cache
|
||||
|
||||
Woodpecker writes the certificates to `/var/lib/woodpecker/certmagic/`.
|
||||
|
||||
### Certificate Updates
|
||||
|
||||
Woodpecker uses the official Go acme library which will handle certificate upgrades. There should be no addition configuration or management required.
|
||||
|
||||
## SSL with own certificates
|
||||
|
||||
Woodpecker supports SSL configuration by mounting certificates into your container.
|
||||
|
||||
```ini
|
||||
|
@ -37,17 +7,17 @@ WOODPECKER_SERVER_CERT=/etc/certs/woodpecker.example.com/server.crt
|
|||
WOODPECKER_SERVER_KEY=/etc/certs/woodpecker.example.com/server.key
|
||||
```
|
||||
|
||||
### Certificate Chain
|
||||
## Certificate Chain
|
||||
|
||||
The most common problem encountered is providing a certificate file without the intermediate chain.
|
||||
|
||||
> LoadX509KeyPair reads and parses a public/private key pair from a pair of files. The files must contain PEM encoded data. The certificate file may contain intermediate certificates following the leaf certificate to form a certificate chain.
|
||||
|
||||
### Certificate Errors
|
||||
## Certificate Errors
|
||||
|
||||
SSL support is provided using the [ListenAndServeTLS](https://golang.org/pkg/net/http/#ListenAndServeTLS) function from the Go standard library. If you receive certificate errors or warnings please examine your configuration more closely.
|
||||
|
||||
### Running in containers
|
||||
## Running in containers
|
||||
|
||||
Update your configuration to expose the following ports:
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# 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.
|
||||
Woodpecker is a community-driven open source CI/CD tool. It is lightweight, fast and simple to use. It can be used with many different Git providers and runners.
|
||||
|
||||
## History
|
||||
|
||||
Woodpecker was originally forked by [@laszlocph](https://github.com/laszlocph) in 2019.
|
||||
Woodpecker was originally forked from Drone 0.8 by [@laszlocph](https://github.com/laszlocph) in 2019 after its license model was changed.
|
||||
|
||||
A few important time points:
|
||||
|
||||
|
@ -15,4 +15,5 @@ A few important time points:
|
|||
|
||||
## 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.
|
||||
Woodpecker is a community-driven open source software published under the Apache License 2.0 and will always remain so. Drone CI is managed by [Harness](https://harness.io/) and is available in two editions: [Open Source under Apache License 2.0 and Enterprise under Polyform Small Business license](https://docs.drone.io/enterprise/#is-drone-open-source).
|
||||
In terms of Drone's feature set, Woodpecker is somewhere between [Drone Enterprise and OSS](https://docs.drone.io/enterprise/#what-is-the-difference-between-open-source-and-enterprise), but also has some unique features.
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { Config } from '@docusaurus/types';
|
|||
import type * as Preset from '@docusaurus/preset-classic';
|
||||
import * as path from 'path';
|
||||
|
||||
const config: Config = {
|
||||
const config = {
|
||||
title: 'Woodpecker CI',
|
||||
tagline: 'Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.',
|
||||
url: 'https://woodpecker-ci.org',
|
||||
|
@ -248,7 +248,7 @@ const config: Config = {
|
|||
label: '2.8.x',
|
||||
},
|
||||
'2.7': {
|
||||
label: '2.7.x',
|
||||
label: '2.7.x 💀',
|
||||
banner: 'unmaintained',
|
||||
},
|
||||
'2.6': {
|
||||
|
@ -265,8 +265,6 @@ const config: Config = {
|
|||
blogTitle: 'Blog',
|
||||
blogDescription: 'A blog for release announcements, turorials...',
|
||||
onInlineAuthors: 'ignore',
|
||||
// postsPerPage: 'ALL',
|
||||
// blogSidebarCount: 0,
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
|
@ -291,19 +289,12 @@ const config: Config = {
|
|||
},
|
||||
],
|
||||
],
|
||||
webpack: {
|
||||
jsLoader: (isServer) => ({
|
||||
loader: require.resolve('esbuild-loader'),
|
||||
options: {
|
||||
loader: 'tsx',
|
||||
target: isServer ? 'node12' : 'es2017',
|
||||
supported: { 'dynamic-import': false },
|
||||
},
|
||||
}),
|
||||
},
|
||||
markdown: {
|
||||
format: 'detect',
|
||||
},
|
||||
};
|
||||
future: {
|
||||
experimental_faster: true,
|
||||
},
|
||||
} satisfies Config;
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -15,19 +15,15 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.6.3",
|
||||
"@docusaurus/faster": "^3.6.3",
|
||||
"@docusaurus/plugin-content-blog": "^3.6.3",
|
||||
"@docusaurus/preset-classic": "^3.6.3",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.46.0",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"clsx": "^2.1.1",
|
||||
"esbuild-loader": "^4.2.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"redocusaurus": "^2.2.0",
|
||||
"url-loader": "^4.1.1"
|
||||
"redocusaurus": "^2.2.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
@ -46,16 +42,9 @@
|
|||
"@docusaurus/tsconfig": "3.6.3",
|
||||
"@docusaurus/types": "^3.6.3",
|
||||
"@types/node": "^22.9.3",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"got": "^14.0.0",
|
||||
"path-to-regexp": "^3.3.0",
|
||||
"cookie": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
"typescript": "^5.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.2 || ^18.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0"
|
||||
"react": "^17.0.2 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fuse.js": "^7.0.0",
|
||||
|
|
2708
docs/pnpm-lock.yaml
2708
docs/pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,66 +1,171 @@
|
|||
# Migrations
|
||||
|
||||
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`
|
||||
|
||||
:::info
|
||||
This will be the next version of Woodpecker.
|
||||
:::
|
||||
- No changes
|
||||
|
||||
## User migrations
|
||||
## 3.0.0
|
||||
|
||||
- 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.
|
||||
- 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
|
||||
- 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`
|
||||
- CLI commands got restructured to provide a simplified structure:
|
||||
- `woodpecker-cli secret [add|rm|...] --global` is now `woodpecker-cli admin secret [add|rm|...]`
|
||||
- `woodpecker-cli user` is now `woodpecker-cli admin user`
|
||||
- `woodpecker-cli log-level` is now `woodpecker-cli admin log-level`
|
||||
- `woodpecker-cli secret [add|rm|...] --organization` is now `woodpecker-cli org secret [add|rm|...]`
|
||||
- `woodpecker-cli deploy` is now `woodpecker-cli pipeline deploy`
|
||||
- `woodpecker-cli log` is now `woodpecker-cli pipeline log`
|
||||
- `woodpecker-cli cron` is now `woodpecker-cli repo cron`
|
||||
- `woodpecker-cli secret [add|rm|...] --repository` is now `woodpecker-cli repo secret [add|rm|...]`
|
||||
- `woodpecker-cli pipeline logs` is now `woodpecker-cli pipeline log show`
|
||||
- `woodpecker-cli [registry|secret|...] info` is now `woodpecker-cli [registry|secret|...] show`
|
||||
### User-facing migrations
|
||||
|
||||
## Admin migrations
|
||||
#### Security
|
||||
|
||||
- The "gated" option, which restricted which pipelines can start right away without requiring approval, has been replaced by "require-approval" option. Even though this feature ([#3348](https://github.com/woodpecker-ci/woodpecker/pull/3348)) was backported to 2.8, no default is explicitly set.
|
||||
The new default in 3.0 is to require approval only for forked repositories.
|
||||
This allows easier management of dependency bots and other trusted entities having write access to the repository.
|
||||
|
||||
#### Environment variables
|
||||
|
||||
- Environment variables must now be defined as maps. List definitions are disallowed. ([#4016](https://github.com/woodpecker-ci/woodpecker/pull/4016))
|
||||
|
||||
2.x:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- ENV1=value1
|
||||
```
|
||||
|
||||
3.x:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
ENV1: value1
|
||||
```
|
||||
|
||||
The following built-in environment variables have been removed/replaced:
|
||||
|
||||
- `CI_COMMIT_URL` has been deprecated in favor of `CI_PIPELINE_FORGE_URL`
|
||||
- `CI_STEP_FINISHED` as it was empty during execution
|
||||
- `CI_PIPELINE_FINISHED` as it was empty during execution
|
||||
- `CI_PIPELINE_STATUS` due to always being set to `success`
|
||||
- `CI_STEP_STATUS` due to always being set to `success`
|
||||
- `WOODPECKER_WEBHOOK_HOST` in favor of `WOODPECKER_EXPERT_WEBHOOK_HOST`
|
||||
|
||||
Environment variables which are empty after workflow parsing are not being injected into the build but filtered out beforehand ([#4193](https://github.com/woodpecker-ci/woodpecker/pull/4193))
|
||||
|
||||
#### Former deprecations
|
||||
|
||||
The following syntax deprecations will now result in an error:
|
||||
|
||||
- `pipeline:` ([#3916](https://github.com/woodpecker-ci/woodpecker/pull/3916))
|
||||
- `platform:` ([#3916](https://github.com/woodpecker-ci/woodpecker/pull/3916))
|
||||
- `branches:` ([#3916](https://github.com/woodpecker-ci/woodpecker/pull/3916))
|
||||
|
||||
#### Workflow syntax changes
|
||||
|
||||
- Grouping of steps via `steps.[name].group` should now be done using `steps.[name].depends_on`
|
||||
- The `includes` and `excludes` event filter options have been removed
|
||||
- Previously, env vars have been automatically sanitized to uppercase.
|
||||
As this has been confusing, the type-case of the secret definition is now respected ([#3375](https://github.com/woodpecker-ci/woodpecker/pull/3375)).
|
||||
- `secrets` have been entirely removed in favor of `environment` combined with the `from_secret` syntax.
|
||||
As `secrets` are just normal env vars which are masked, the goal was to allow them to be declared next to normal env vars and at the same time reduce the keyword syntax count.
|
||||
Additionally, the `from_secret` syntax gives more flexibility in naming.
|
||||
Whereas beforehand `secrets` where always named after their initial secret name, the `from_secret` reference can now be different.
|
||||
Last, one can inject multiple different env vars from the same secret reference.
|
||||
|
||||
2.x:
|
||||
|
||||
```yaml
|
||||
secrets: [my_token]
|
||||
```
|
||||
|
||||
3.x:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
MY_TOKEN:
|
||||
from_secret: my_token
|
||||
```
|
||||
|
||||
- The `environment` filter option has been removed in favor of `when.evaluate`
|
||||
|
||||
#### API changes
|
||||
|
||||
- Removed deprecated `registry/` endpoint. Use `registries`, `/authorize/token`
|
||||
|
||||
#### CLI changes
|
||||
|
||||
The following restructuring was done to achieve a more consistent grouping:
|
||||
|
||||
| Old Command | New Command |
|
||||
| ------------------------------------------- | ------------------------------------------- |
|
||||
| `woodpecker-cli registry` | `woodpecker-cli repo registry` |
|
||||
| `woodpecker-cli secret --global` | `woodpecker-cli admin secret` |
|
||||
| `woodpecker-cli user` | `woodpecker-cli admin user` |
|
||||
| `woodpecker-cli log-level` | `woodpecker-cli admin log-level` |
|
||||
| `woodpecker-cli secret --organization` | `woodpecker-cli org secret` |
|
||||
| `woodpecker-cli deploy` | `woodpecker-cli pipeline deploy` |
|
||||
| `woodpecker-cli log` | `woodpecker-cli pipeline log` |
|
||||
| `woodpecker-cli cron` | `woodpecker-cli repo cron` |
|
||||
| `woodpecker-cli secret --repository` | `woodpecker-cli repo secret` |
|
||||
| `woodpecker-cli pipeline logs` | `woodpecker-cli pipeline log show` |
|
||||
| `woodpecker-cli (registry,secret,...) info` | `woodpecker-cli (registry,secret,...) show` |
|
||||
|
||||
#### Miscellaneous
|
||||
|
||||
- For `woodpecker-cli` containers, `/woodpecker` has been set as the default `workdir`
|
||||
|
||||
- Plugin filters for secrets (in the "secrets" repo settings) can now validate against tags.
|
||||
Additionally, the description has been updated to reflect that these filters only apply to plugins ([#4069](https://github.com/woodpecker-ci/woodpecker/pull/4069)).
|
||||
|
||||
- SDK changes:
|
||||
|
||||
- The SDK fields `start_time`, `end_time`, `created_at`, `started_at`, `finished_at` and `reviewed_at` have been renamed to `started`, `finished`, `created`, `started`, `finished`, `reviewed` ([#3968](https://github.com/woodpecker-ci/woodpecker/pull/3968))
|
||||
- The `trusted` field of the repo model was changed from `boolean` to `object`
|
||||
|
||||
- CRON definitions now use standard Linux syntax without seconds.
|
||||
All custom CRON definitions which do not use keywords such as `@daily` or `@weekly` must be updated.
|
||||
|
||||
Example definition for a CRON job running at 8 am daily:
|
||||
|
||||
2.x:
|
||||
|
||||
```sh
|
||||
0 0 8 * * *
|
||||
```
|
||||
|
||||
3.x:
|
||||
|
||||
```sh
|
||||
0 8 * * *
|
||||
```
|
||||
|
||||
- Native Let's Encrypt certificate support has been dropped as it was almost unused and causing frequent issues.
|
||||
Let's Encrypt needs to be set up standalone now. The SSL key pair can still be used in `WOODPECKER_SERVER_CERT` and `WOODPECKER_SERVER_KEY` as an alternative to using a reverse proxy for TLS termination.
|
||||
|
||||
### Admin-facing migrations
|
||||
|
||||
- Previously, some (official) plugins were granted the `privileged` option by default to allow simplified usage.
|
||||
To streamline this process and enhance security transparency, no plugin is granted the `privileged` options by default anymore.
|
||||
To allow the use of these plugins in >= 3.0, they must be set explicitly through `WOODPECKER_PLUGINS_PRIVILEGED` on the admin side.
|
||||
This change mainly impacts the use of the `woodpeckerci/plugin-docker-buildx` plugin, which now will not work anymore unless explicitly listed through this env var ([#4053](https://github.com/woodpecker-ci/woodpecker/pull/4053))
|
||||
|
||||
- Environment variable deprecations:
|
||||
|
||||
| Deprecated Variable | New Variable |
|
||||
| -------------------------------- | ------------------------------------ |
|
||||
| `WOODPECKER_LOG_XORM` | `WOODPECKER_DATABASE_LOG` |
|
||||
| `WOODPECKER_LOG_XORM_SQL` | `WOODPECKER_DATABASE_LOG_SQL` |
|
||||
| `WOODPECKER_FILTER_LABELS` | `WOODPECKER_AGENT_LABELS` |
|
||||
| `WOODPECKER_ESCALATE` | `WOODPECKER_PLUGINS_PRIVILEGED` |
|
||||
| `WOODPECKER_DEFAULT_CLONE_IMAGE` | `WOODPECKER_DEFAULT_CLONE_PLUGIN` |
|
||||
| `WOODPECKER_DEV_OAUTH_HOST` | `WOODPECKER_EXPERT_FORGE_OAUTH_HOST` |
|
||||
| `WOODPECKER_DEV_GITEA_OAUTH_URL` | `WOODPECKER_EXPERT_FORGE_OAUTH_HOST` |
|
||||
| `WOODPECKER_ROOT_PATH` | `WOODPECKER_HOST` |
|
||||
| `WOODPECKER_ROOT_URL` | `WOODPECKER_HOST` |
|
||||
|
||||
- The resource limit settings for the "docker" backend were moved from the server into agent configuration.
|
||||
This allows setting limits on an agent-level which allows greater resource definition granularity ([#3174](https://github.com/woodpecker-ci/woodpecker/pull/3174))
|
||||
|
||||
- "Kubernetes" backend: previously the image pull secret name was hard-coded to `regcred`.
|
||||
To allow more flexibility and specifying multiple pull secrets, the default has been removed.
|
||||
Image pull secrets must now be set explicitly via env var `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES` ([#4005](https://github.com/woodpecker-ci/woodpecker/pull/4005))
|
||||
|
||||
- Webhook signatures now use the `rfc9421` protocol
|
||||
|
||||
- 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
|
||||
|
||||
- Upgrading from 1.x versions to 3.x is disallowed, upgrading to 2.x first is required to ensure proper DB migrations
|
||||
|
||||
## 2.7.2
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ Woodpecker provides three different levels to add secrets to your pipeline. The
|
|||
|
||||
### Use secrets in commands
|
||||
|
||||
:::warning
|
||||
The use of secrets is deprecated as of version 2.8 and planned to be removed with version 3.
|
||||
Instead, you can use the *secrets in settings and environment* approach outlined below.
|
||||
You can already migrate to this strategy with version 2.8.
|
||||
:::
|
||||
|
||||
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:
|
||||
|
||||
|
@ -30,17 +36,27 @@ The case of the environment variables is not changed, but secret matching is don
|
|||
|
||||
### 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 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`.
|
||||
The example below passes a secret called `secret_token` as an environment variable that will be called `TOKEN_ENV`:
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: docker
|
||||
image: my-plugin
|
||||
env-secret-example:
|
||||
image: alpine
|
||||
commands:
|
||||
+ - echo "The secret is $TOKEN_ENV"
|
||||
+ environment:
|
||||
+ TOKEN_ENV:
|
||||
+ from_secret: secret_token
|
||||
```
|
||||
|
||||
You can use the same syntax to pass secrets to settings. For example, you can pass a secret named `secret_token` to the settings called `token`, which will then be available in the plugin as environment variable named `PLUGIN_TOKEN` (See [plugins](./51-plugins/20-creating-plugins.md#settings) for details).
|
||||
|
||||
```diff
|
||||
steps:
|
||||
- name: settings-secret-example
|
||||
image: my-plugin
|
||||
+ settings:
|
||||
+ token:
|
||||
+ from_secret: secret_token
|
||||
|
|
78
go.mod
78
go.mod
|
@ -1,8 +1,6 @@
|
|||
module go.woodpecker-ci.org/woodpecker/v2
|
||||
|
||||
go 1.22.7
|
||||
|
||||
toolchain go1.23.3
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
al.essio.dev/pkg/shellescape v1.5.1
|
||||
|
@ -13,13 +11,12 @@ require (
|
|||
github.com/6543/logfile-open v1.2.1
|
||||
github.com/adrg/xdg v0.5.3
|
||||
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.6.0
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240327025511-ec643317aa10
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v27.3.1+incompatible
|
||||
github.com/docker/docker v27.3.1+incompatible
|
||||
github.com/docker/cli v27.4.0+incompatible
|
||||
github.com/docker/docker v27.4.0+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/drone/envsubst v1.0.3
|
||||
|
@ -27,10 +24,11 @@ require (
|
|||
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
|
||||
github.com/fsnotify/fsnotify v1.8.0
|
||||
github.com/gdgvda/cron v0.3.0
|
||||
github.com/getkin/kin-openapi v0.127.0
|
||||
github.com/getkin/kin-openapi v0.128.1-0.20241211220347-325cecc5e4e1
|
||||
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/go-viper/mapstructure/v2 v2.2.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/go-github/v67 v67.0.0
|
||||
github.com/google/tink/go v1.7.0
|
||||
|
@ -42,10 +40,9 @@ require (
|
|||
github.com/kinbiko/jsonassert v1.2.0
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/moby v27.3.1+incompatible
|
||||
github.com/moby/moby v27.4.0+incompatible
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/muesli/termenv v0.15.3-0.20240912151726-82936c5ea257
|
||||
github.com/muesli/termenv v0.15.3-0.20241212154518-8c990cd6cf4b
|
||||
github.com/neticdk/go-bitbucket v1.0.0
|
||||
github.com/oklog/ulid/v2 v2.1.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
@ -56,24 +53,24 @@ require (
|
|||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.4
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.10
|
||||
github.com/xanzy/go-gitlab v0.114.0
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/yaronf/httpsign v0.3.1
|
||||
github.com/zalando/go-keyring v0.2.6
|
||||
gitlab.com/gitlab-org/api/client-go v0.117.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/crypto v0.31.0
|
||||
golang.org/x/net v0.32.0
|
||||
golang.org/x/oauth2 v0.24.0
|
||||
golang.org/x/sync v0.9.0
|
||||
golang.org/x/term v0.26.0
|
||||
golang.org/x/text v0.20.0
|
||||
google.golang.org/grpc v1.68.0
|
||||
google.golang.org/protobuf v1.35.2
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/term v0.27.0
|
||||
golang.org/x/text v0.21.0
|
||||
google.golang.org/grpc v1.69.0
|
||||
google.golang.org/protobuf v1.36.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.31.3
|
||||
k8s.io/apimachinery v0.31.3
|
||||
k8s.io/client-go v0.31.3
|
||||
k8s.io/api v0.32.0
|
||||
k8s.io/apimachinery v0.32.0
|
||||
k8s.io/client-go v0.32.0
|
||||
src.techknowlogick.com/xormigrate v1.7.1
|
||||
xorm.io/builder v0.3.13
|
||||
xorm.io/xorm v1.3.9
|
||||
|
@ -90,7 +87,6 @@ require (
|
|||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
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.20.0 // indirect
|
||||
|
@ -141,8 +137,6 @@ require (
|
|||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
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
|
||||
|
@ -155,15 +149,12 @@ require (
|
|||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||
github.com/lestrrat-go/jwx/v2 v2.1.0 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/libdns/libdns v0.2.2 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
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.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
|
||||
|
@ -173,10 +164,10 @@ require (
|
|||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect
|
||||
github.com/oklog/run v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo v1.16.4 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
||||
github.com/onsi/gomega v1.34.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
|
@ -199,28 +190,25 @@ require (
|
|||
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/zeebo/blake3 v0.2.4 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.29.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // 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.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // 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
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
|
163
go.sum
163
go.sum
|
@ -48,10 +48,6 @@ github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc
|
|||
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.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=
|
||||
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
|
@ -108,10 +104,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.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/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc=
|
||||
github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A=
|
||||
github.com/docker/docker v27.4.0+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=
|
||||
|
@ -148,8 +144,8 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq
|
|||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
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/getkin/kin-openapi v0.128.1-0.20241211220347-325cecc5e4e1 h1:jIUT6NT0F50dhHXlFWsGfdJI/5OnnzO6HZHSiSh5DfM=
|
||||
github.com/getkin/kin-openapi v0.128.1-0.20241211220347-325cecc5e4e1/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI=
|
||||
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=
|
||||
|
@ -193,6 +189,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
|
|||
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/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
|
@ -243,8 +241,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
|||
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/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
|
||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
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=
|
||||
|
@ -271,10 +269,6 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
|
|||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
|
||||
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
|
@ -372,8 +366,6 @@ github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
|||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
|
@ -400,18 +392,12 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S
|
|||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
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.3.1+incompatible h1:KQbXBjo7PavKpzIl7UkHT31y9lw/e71Uvrqhr4X+zMA=
|
||||
github.com/moby/moby v27.3.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/moby v27.4.0+incompatible h1:jGXXZCMAmFZS9pKsQqUt9yAPHOC450PM9lbQYPSQnuc=
|
||||
github.com/moby/moby v27.4.0+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=
|
||||
|
@ -428,8 +414,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.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/muesli/termenv v0.15.3-0.20241212154518-8c990cd6cf4b h1:gmVbquSG+bANneniKyO7R2DkOlCat7XDaSfXxHKKQBY=
|
||||
github.com/muesli/termenv v0.15.3-0.20241212154518-8c990cd6cf4b/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=
|
||||
|
@ -437,6 +423,10 @@ github.com/neticdk/go-bitbucket v1.0.0/go.mod h1:IrHeWO1CrNi0DlOvfhAA9bGRSeNSUB6
|
|||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU=
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
||||
|
@ -446,13 +436,13 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
|
||||
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
|
||||
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
|
||||
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
||||
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
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=
|
||||
|
@ -545,12 +535,10 @@ github.com/urfave/cli-docs/v3 v3.0.0-alpha6 h1:w/l/N0xw1rO/aHRIGXJ0lDwwYFOzilup1
|
|||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6/go.mod h1:p7Z4lg8FSTrPB9GTaNyTrK3ygffHZcK3w0cU2VE+mzU=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.10 h1:whPwidq9cUh18NBqzSR8N3tts8NiQDsTmt9s7AyX85c=
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9.10/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
|
||||
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.114.0 h1:0wQr/KBckwrZPfEMjRqpUz0HmsKKON9UhCYv9KDy19M=
|
||||
github.com/xanzy/go-gitlab v0.114.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=
|
||||
|
@ -565,28 +553,26 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
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.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=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
gitlab.com/gitlab-org/api/client-go v0.117.0 h1:HsbKxlTjVgfYmyCU+NRQk2G42RlMOKs6gF+/o0DL+TI=
|
||||
gitlab.com/gitlab-org/api/client-go v0.117.0/go.mod h1:E+X2dndIYDuUfKVP0C3jhkWvTSE00BkLbCsXTY3edDo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
|
||||
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
|
||||
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
|
||||
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
||||
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
|
||||
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
@ -604,8 +590,6 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
|
|||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
|
@ -623,8 +607,8 @@ 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.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
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=
|
||||
|
@ -647,8 +631,8 @@ 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.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -656,8 +640,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
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.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.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=
|
||||
|
@ -692,14 +676,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.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.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.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
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=
|
||||
|
@ -707,10 +691,10 @@ 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.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
|
@ -734,25 +718,27 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||
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-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI=
|
||||
google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
|
||||
google.golang.org/protobuf v1.36.0/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=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
|
@ -765,7 +751,6 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@ -774,18 +759,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.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8=
|
||||
k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE=
|
||||
k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4=
|
||||
k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4=
|
||||
k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs=
|
||||
k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
|
||||
k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
|
||||
k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
|
||||
k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
|
||||
k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
|
||||
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-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/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=
|
||||
|
@ -825,10 +810,10 @@ modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|||
modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
src.techknowlogick.com/xormigrate v1.7.1 h1:RKGLLUAqJ+zO8iZ7eOc7oLH7f0cs2gfXSZSvBRBHnlY=
|
||||
|
|
21
pipeline/backend/docker/backend_options.go
Normal file
21
pipeline/backend/docker/backend_options.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
|
||||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
)
|
||||
|
||||
// BackendOptions defines all the advanced options for the docker backend.
|
||||
type BackendOptions struct {
|
||||
User string `mapstructure:"user"`
|
||||
}
|
||||
|
||||
func parseBackendOptions(step *backend.Step) (BackendOptions, error) {
|
||||
var result BackendOptions
|
||||
if step == nil || step.BackendOptions == nil {
|
||||
return result, nil
|
||||
}
|
||||
err := mapstructure.WeakDecode(step.BackendOptions[EngineName], &result)
|
||||
return result, err
|
||||
}
|
56
pipeline/backend/docker/backend_options_test.go
Normal file
56
pipeline/backend/docker/backend_options_test.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
)
|
||||
|
||||
func Test_parseBackendOptions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
step *backend.Step
|
||||
want BackendOptions
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil options",
|
||||
step: &backend.Step{BackendOptions: nil},
|
||||
want: BackendOptions{},
|
||||
},
|
||||
{
|
||||
name: "empty options",
|
||||
step: &backend.Step{BackendOptions: map[string]any{}},
|
||||
want: BackendOptions{},
|
||||
},
|
||||
{
|
||||
name: "with user option",
|
||||
step: &backend.Step{BackendOptions: map[string]any{
|
||||
"docker": map[string]any{
|
||||
"user": "1000:1000",
|
||||
},
|
||||
}},
|
||||
want: BackendOptions{User: "1000:1000"},
|
||||
},
|
||||
{
|
||||
name: "invalid backend options",
|
||||
step: &backend.Step{BackendOptions: map[string]any{"docker": "invalid"}},
|
||||
want: BackendOptions{},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseBackendOptions(tt.step)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ import (
|
|||
const minVolumeComponents = 2
|
||||
|
||||
// returns a container configuration.
|
||||
func (e *docker) toConfig(step *types.Step) *container.Config {
|
||||
func (e *docker) toConfig(step *types.Step, options BackendOptions) *container.Config {
|
||||
e.windowsPathPatch(step)
|
||||
|
||||
config := &container.Config{
|
||||
|
@ -44,6 +44,7 @@ func (e *docker) toConfig(step *types.Step) *container.Config {
|
|||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
Volumes: toVol(step.Volumes),
|
||||
User: options.User,
|
||||
}
|
||||
configEnv := make(map[string]string)
|
||||
maps.Copy(configEnv, step.Environment)
|
||||
|
|
|
@ -131,7 +131,7 @@ func TestToContainerName(t *testing.T) {
|
|||
|
||||
func TestStepToConfig(t *testing.T) {
|
||||
// StepTypeCommands
|
||||
conf := testEngine.toConfig(testCmdStep)
|
||||
conf := testEngine.toConfig(testCmdStep, BackendOptions{})
|
||||
if assert.NotNil(t, conf) {
|
||||
assert.EqualValues(t, []string{"/bin/sh", "-c", "echo $CI_SCRIPT | base64 -d | /bin/sh -e"}, conf.Entrypoint)
|
||||
assert.Nil(t, conf.Cmd)
|
||||
|
@ -139,7 +139,7 @@ func TestStepToConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
// StepTypePlugin
|
||||
conf = testEngine.toConfig(testPluginStep)
|
||||
conf = testEngine.toConfig(testPluginStep, BackendOptions{})
|
||||
if assert.NotNil(t, conf) {
|
||||
assert.Nil(t, conf.Cmd)
|
||||
assert.EqualValues(t, testPluginStep.UUID, conf.Labels["wp_uuid"])
|
||||
|
@ -174,7 +174,7 @@ func TestToConfigSmall(t *testing.T) {
|
|||
Name: "test",
|
||||
UUID: "09238932",
|
||||
Commands: []string{"go test"},
|
||||
})
|
||||
}, BackendOptions{})
|
||||
|
||||
assert.NotNil(t, conf)
|
||||
sort.Strings(conf.Env)
|
||||
|
@ -233,7 +233,7 @@ func TestToConfigFull(t *testing.T) {
|
|||
AuthConfig: backend.Auth{Username: "user", Password: "123456"},
|
||||
NetworkMode: "bridge",
|
||||
Ports: []backend.Port{{Number: 21}, {Number: 22}},
|
||||
})
|
||||
}, BackendOptions{})
|
||||
|
||||
assert.NotNil(t, conf)
|
||||
sort.Strings(conf.Env)
|
||||
|
@ -286,7 +286,7 @@ func TestToWindowsConfig(t *testing.T) {
|
|||
AuthConfig: backend.Auth{Username: "user", Password: "123456"},
|
||||
NetworkMode: "nat",
|
||||
Ports: []backend.Port{{Number: 21}, {Number: 22}},
|
||||
})
|
||||
}, BackendOptions{})
|
||||
|
||||
assert.NotNil(t, conf)
|
||||
sort.Strings(conf.Env)
|
||||
|
|
|
@ -46,6 +46,7 @@ type docker struct {
|
|||
}
|
||||
|
||||
const (
|
||||
EngineName = "docker"
|
||||
networkDriverNAT = "nat"
|
||||
networkDriverBridge = "bridge"
|
||||
volumeDriver = "local"
|
||||
|
@ -59,7 +60,7 @@ func New() backend.Backend {
|
|||
}
|
||||
|
||||
func (e *docker) Name() string {
|
||||
return "docker"
|
||||
return EngineName
|
||||
}
|
||||
|
||||
func (e *docker) IsAvailable(ctx context.Context) bool {
|
||||
|
@ -170,9 +171,14 @@ func (e *docker) SetupWorkflow(ctx context.Context, conf *backend.Config, taskUU
|
|||
}
|
||||
|
||||
func (e *docker) StartStep(ctx context.Context, step *backend.Step, taskUUID string) error {
|
||||
options, err := parseBackendOptions(step)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("could not parse backend options")
|
||||
}
|
||||
|
||||
log.Trace().Str("taskUUID", taskUUID).Msgf("start step %s", step.Name)
|
||||
|
||||
config := e.toConfig(step)
|
||||
config := e.toConfig(step, options)
|
||||
hostConfig := toHostConfig(step, &e.config)
|
||||
containerName := toContainerName(step)
|
||||
|
||||
|
@ -204,7 +210,7 @@ func (e *docker) StartStep(ctx context.Context, step *backend.Step, taskUUID str
|
|||
// add default volumes to the host configuration
|
||||
hostConfig.Binds = utils.DeduplicateStrings(append(hostConfig.Binds, e.config.volumes...))
|
||||
|
||||
_, err := e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, containerName)
|
||||
_, err = e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, containerName)
|
||||
if client.IsErrNotFound(err) {
|
||||
// automatically pull and try to re-create the image if the
|
||||
// failure is caused because the image does not exist.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
|
||||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
)
|
||||
|
@ -86,9 +86,9 @@ const (
|
|||
|
||||
func parseBackendOptions(step *backend.Step) (BackendOptions, error) {
|
||||
var result BackendOptions
|
||||
if step.BackendOptions == nil {
|
||||
if step == nil || step.BackendOptions == nil {
|
||||
return result, nil
|
||||
}
|
||||
err := mapstructure.Decode(step.BackendOptions[EngineName], &result)
|
||||
err := mapstructure.WeakDecode(step.BackendOptions[EngineName], &result)
|
||||
return result, err
|
||||
}
|
||||
|
|
|
@ -9,97 +9,139 @@ import (
|
|||
)
|
||||
|
||||
func Test_parseBackendOptions(t *testing.T) {
|
||||
got, err := parseBackendOptions(&backend.Step{BackendOptions: nil})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, BackendOptions{}, got)
|
||||
got, err = parseBackendOptions(&backend.Step{BackendOptions: map[string]any{}})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, BackendOptions{}, got)
|
||||
got, err = parseBackendOptions(&backend.Step{
|
||||
BackendOptions: map[string]any{
|
||||
"kubernetes": map[string]any{
|
||||
"nodeSelector": map[string]string{"storage": "ssd"},
|
||||
"serviceAccountName": "wp-svc-acc",
|
||||
"labels": map[string]string{"app": "test"},
|
||||
"annotations": map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
"tolerations": []map[string]any{
|
||||
{"key": "net-port", "value": "100Mbit", "effect": TaintEffectNoSchedule},
|
||||
},
|
||||
"resources": map[string]any{
|
||||
"requests": map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
||||
"limits": map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||
},
|
||||
"securityContext": map[string]any{
|
||||
"privileged": newBool(true),
|
||||
"runAsNonRoot": newBool(true),
|
||||
"runAsUser": newInt64(101),
|
||||
"runAsGroup": newInt64(101),
|
||||
"fsGroup": newInt64(101),
|
||||
"seccompProfile": map[string]any{
|
||||
"type": "Localhost",
|
||||
"localhostProfile": "profiles/audit.json",
|
||||
},
|
||||
"apparmorProfile": map[string]any{
|
||||
"type": "Localhost",
|
||||
"localhostProfile": "k8s-apparmor-example-deny-write",
|
||||
},
|
||||
},
|
||||
"secrets": []map[string]any{
|
||||
{
|
||||
"name": "aws",
|
||||
"key": "access-key",
|
||||
"target": map[string]any{
|
||||
"env": "AWS_SECRET_ACCESS_KEY",
|
||||
tests := []struct {
|
||||
name string
|
||||
step *backend.Step
|
||||
want BackendOptions
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil options",
|
||||
step: &backend.Step{BackendOptions: nil},
|
||||
want: BackendOptions{},
|
||||
},
|
||||
{
|
||||
name: "empty options",
|
||||
step: &backend.Step{BackendOptions: map[string]any{}},
|
||||
want: BackendOptions{},
|
||||
},
|
||||
{
|
||||
name: "full k8s options",
|
||||
step: &backend.Step{
|
||||
BackendOptions: map[string]any{
|
||||
"kubernetes": map[string]any{
|
||||
"nodeSelector": map[string]string{"storage": "ssd"},
|
||||
"serviceAccountName": "wp-svc-acc",
|
||||
"labels": map[string]string{"app": "test"},
|
||||
"annotations": map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
"tolerations": []map[string]any{
|
||||
{"key": "net-port", "value": "100Mbit", "effect": TaintEffectNoSchedule},
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "reg-cred",
|
||||
"key": ".dockerconfigjson",
|
||||
"target": map[string]any{
|
||||
"file": "~/.docker/config.json",
|
||||
"resources": map[string]any{
|
||||
"requests": map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
||||
"limits": map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||
},
|
||||
"securityContext": map[string]any{
|
||||
"privileged": newBool(true),
|
||||
"runAsNonRoot": newBool(true),
|
||||
"runAsUser": newInt64(101),
|
||||
"runAsGroup": newInt64(101),
|
||||
"fsGroup": newInt64(101),
|
||||
"seccompProfile": map[string]any{
|
||||
"type": "Localhost",
|
||||
"localhostProfile": "profiles/audit.json",
|
||||
},
|
||||
"apparmorProfile": map[string]any{
|
||||
"type": "Localhost",
|
||||
"localhostProfile": "k8s-apparmor-example-deny-write",
|
||||
},
|
||||
},
|
||||
"secrets": []map[string]any{
|
||||
{
|
||||
"name": "aws",
|
||||
"key": "access-key",
|
||||
"target": map[string]any{
|
||||
"env": "AWS_SECRET_ACCESS_KEY",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "reg-cred",
|
||||
"key": ".dockerconfigjson",
|
||||
"target": map[string]any{
|
||||
"file": "~/.docker/config.json",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, BackendOptions{
|
||||
NodeSelector: map[string]string{"storage": "ssd"},
|
||||
ServiceAccountName: "wp-svc-acc",
|
||||
Labels: map[string]string{"app": "test"},
|
||||
Annotations: map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
|
||||
Resources: Resources{
|
||||
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
||||
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||
},
|
||||
SecurityContext: &SecurityContext{
|
||||
Privileged: newBool(true),
|
||||
RunAsNonRoot: newBool(true),
|
||||
RunAsUser: newInt64(101),
|
||||
RunAsGroup: newInt64(101),
|
||||
FSGroup: newInt64(101),
|
||||
SeccompProfile: &SecProfile{
|
||||
Type: "Localhost",
|
||||
LocalhostProfile: "profiles/audit.json",
|
||||
},
|
||||
ApparmorProfile: &SecProfile{
|
||||
Type: "Localhost",
|
||||
LocalhostProfile: "k8s-apparmor-example-deny-write",
|
||||
want: BackendOptions{
|
||||
NodeSelector: map[string]string{"storage": "ssd"},
|
||||
ServiceAccountName: "wp-svc-acc",
|
||||
Labels: map[string]string{"app": "test"},
|
||||
Annotations: map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
|
||||
Resources: Resources{
|
||||
Requests: map[string]string{"memory": "128Mi", "cpu": "1000m"},
|
||||
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||
},
|
||||
SecurityContext: &SecurityContext{
|
||||
Privileged: newBool(true),
|
||||
RunAsNonRoot: newBool(true),
|
||||
RunAsUser: newInt64(101),
|
||||
RunAsGroup: newInt64(101),
|
||||
FSGroup: newInt64(101),
|
||||
SeccompProfile: &SecProfile{
|
||||
Type: "Localhost",
|
||||
LocalhostProfile: "profiles/audit.json",
|
||||
},
|
||||
ApparmorProfile: &SecProfile{
|
||||
Type: "Localhost",
|
||||
LocalhostProfile: "k8s-apparmor-example-deny-write",
|
||||
},
|
||||
},
|
||||
Secrets: []SecretRef{
|
||||
{
|
||||
Name: "aws",
|
||||
Key: "access-key",
|
||||
Target: SecretTarget{Env: "AWS_SECRET_ACCESS_KEY"},
|
||||
},
|
||||
{
|
||||
Name: "reg-cred",
|
||||
Key: ".dockerconfigjson",
|
||||
Target: SecretTarget{File: "~/.docker/config.json"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Secrets: []SecretRef{
|
||||
{
|
||||
Name: "aws",
|
||||
Key: "access-key",
|
||||
Target: SecretTarget{Env: "AWS_SECRET_ACCESS_KEY"},
|
||||
},
|
||||
{
|
||||
Name: "reg-cred",
|
||||
Key: ".dockerconfigjson",
|
||||
Target: SecretTarget{File: "~/.docker/config.json"},
|
||||
{
|
||||
name: "number options",
|
||||
step: &backend.Step{BackendOptions: map[string]any{
|
||||
"kubernetes": map[string]any{
|
||||
"resources": map[string]any{
|
||||
"requests": map[string]int{"memory": 128, "cpu": 1000},
|
||||
"limits": map[string]int{"memory": 256, "cpu": 2},
|
||||
},
|
||||
},
|
||||
}},
|
||||
want: BackendOptions{
|
||||
Resources: Resources{
|
||||
Requests: map[string]string{"memory": "128", "cpu": "1000"},
|
||||
Limits: map[string]string{"memory": "256", "cpu": "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, got)
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseBackendOptions(tt.step)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ func podSecurityContext(sc *SecurityContext, secCtxConf SecurityContextConfig, s
|
|||
apparmor = apparmorProfile(sc.ApparmorProfile)
|
||||
}
|
||||
|
||||
if nonRoot == nil && user == nil && group == nil && fsGroup == nil && seccomp == nil {
|
||||
if nonRoot == nil && user == nil && group == nil && fsGroup == nil && seccomp == nil && apparmor == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,143 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
pullRegexp = regexp.MustCompile(`\d+`)
|
||||
maxChangedFiles = 500
|
||||
const (
|
||||
initialEnvMapSize = 100
|
||||
maxChangedFiles = 500
|
||||
)
|
||||
|
||||
var pullRegexp = regexp.MustCompile(`\d+`)
|
||||
|
||||
// Environ returns the metadata as a map of environment variables.
|
||||
func (m *Metadata) Environ() map[string]string {
|
||||
params := make(map[string]string, initialEnvMapSize)
|
||||
|
||||
system := m.Sys
|
||||
setNonEmptyEnvVar(params, "CI", system.Name)
|
||||
setNonEmptyEnvVar(params, "CI_SYSTEM_NAME", system.Name)
|
||||
setNonEmptyEnvVar(params, "CI_SYSTEM_URL", system.URL)
|
||||
setNonEmptyEnvVar(params, "CI_SYSTEM_HOST", system.Host)
|
||||
setNonEmptyEnvVar(params, "CI_SYSTEM_PLATFORM", system.Platform) // will be set by pipeline platform option or by agent
|
||||
setNonEmptyEnvVar(params, "CI_SYSTEM_VERSION", system.Version)
|
||||
|
||||
forge := m.Forge
|
||||
setNonEmptyEnvVar(params, "CI_FORGE_TYPE", forge.Type)
|
||||
setNonEmptyEnvVar(params, "CI_FORGE_URL", forge.URL)
|
||||
|
||||
repo := m.Repo
|
||||
setNonEmptyEnvVar(params, "CI_REPO", path.Join(repo.Owner, repo.Name))
|
||||
setNonEmptyEnvVar(params, "CI_REPO_NAME", repo.Name)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_OWNER", repo.Owner)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_REMOTE_ID", repo.RemoteID)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_SCM", repo.SCM)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_URL", repo.ForgeURL)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_CLONE_URL", repo.CloneURL)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_CLONE_SSH_URL", repo.CloneSSHURL)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_DEFAULT_BRANCH", repo.Branch)
|
||||
setNonEmptyEnvVar(params, "CI_REPO_PRIVATE", strconv.FormatBool(repo.Private))
|
||||
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_NETWORK", strconv.FormatBool(repo.Trusted.Network))
|
||||
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_VOLUMES", strconv.FormatBool(repo.Trusted.Volumes))
|
||||
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED_SECURITY", strconv.FormatBool(repo.Trusted.Security))
|
||||
// Deprecated remove in 4.x
|
||||
setNonEmptyEnvVar(params, "CI_REPO_TRUSTED", strconv.FormatBool(m.Repo.Trusted.Security && m.Repo.Trusted.Network && m.Repo.Trusted.Volumes))
|
||||
|
||||
pipeline := m.Curr
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_NUMBER", strconv.FormatInt(pipeline.Number, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_PARENT", strconv.FormatInt(pipeline.Parent, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_EVENT", pipeline.Event)
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_URL", m.getPipelineWebURL(pipeline, 0))
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_FORGE_URL", pipeline.ForgeURL)
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_DEPLOY_TARGET", pipeline.DeployTo)
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_DEPLOY_TASK", pipeline.DeployTask)
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_CREATED", strconv.FormatInt(pipeline.Created, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PIPELINE_STARTED", strconv.FormatInt(pipeline.Started, 10))
|
||||
|
||||
workflow := m.Workflow
|
||||
setNonEmptyEnvVar(params, "CI_WORKFLOW_NAME", workflow.Name)
|
||||
setNonEmptyEnvVar(params, "CI_WORKFLOW_NUMBER", strconv.Itoa(workflow.Number))
|
||||
|
||||
step := m.Step
|
||||
setNonEmptyEnvVar(params, "CI_STEP_NAME", step.Name)
|
||||
setNonEmptyEnvVar(params, "CI_STEP_NUMBER", strconv.Itoa(step.Number))
|
||||
setNonEmptyEnvVar(params, "CI_STEP_URL", m.getPipelineWebURL(pipeline, step.Number))
|
||||
// CI_STEP_STARTED will be set by agent
|
||||
|
||||
commit := pipeline.Commit
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_SHA", commit.Sha)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_REF", commit.Ref)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_REFSPEC", commit.Refspec)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_MESSAGE", commit.Message)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_BRANCH", commit.Branch)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR", commit.Author.Name)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR_EMAIL", commit.Author.Email)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_AUTHOR_AVATAR", commit.Author.Avatar)
|
||||
if pipeline.Event == EventTag || pipeline.Event == EventRelease || strings.HasPrefix(pipeline.Commit.Ref, "refs/tags/") {
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_TAG", strings.TrimPrefix(pipeline.Commit.Ref, "refs/tags/"))
|
||||
}
|
||||
if pipeline.Event == EventRelease {
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_PRERELEASE", strconv.FormatBool(pipeline.Commit.IsPrerelease))
|
||||
}
|
||||
if pipeline.Event == EventPull || pipeline.Event == EventPullClosed {
|
||||
sourceBranch, targetBranch := getSourceTargetBranches(commit.Refspec)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_SOURCE_BRANCH", sourceBranch)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_TARGET_BRANCH", targetBranch)
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_PULL_REQUEST", pullRegexp.FindString(pipeline.Commit.Ref))
|
||||
setNonEmptyEnvVar(params, "CI_COMMIT_PULL_REQUEST_LABELS", strings.Join(pipeline.Commit.PullRequestLabels, ","))
|
||||
}
|
||||
|
||||
// Only export changed files if maxChangedFiles is not exceeded
|
||||
changedFiles := commit.ChangedFiles
|
||||
if len(changedFiles) == 0 {
|
||||
params["CI_PIPELINE_FILES"] = "[]"
|
||||
} else if len(changedFiles) <= maxChangedFiles {
|
||||
// we have to use json, as other separators like ;, or space are valid filename chars
|
||||
changedFiles, err := json.Marshal(changedFiles)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("marshal changed files")
|
||||
}
|
||||
params["CI_PIPELINE_FILES"] = string(changedFiles)
|
||||
}
|
||||
|
||||
prevPipeline := m.Prev
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_NUMBER", strconv.FormatInt(prevPipeline.Number, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_PARENT", strconv.FormatInt(prevPipeline.Parent, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_EVENT", prevPipeline.Event)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_URL", m.getPipelineWebURL(prevPipeline, 0))
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_FORGE_URL", prevPipeline.ForgeURL)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_URL", prevPipeline.ForgeURL) // why commit url?
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_DEPLOY_TARGET", prevPipeline.DeployTo)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_DEPLOY_TASK", prevPipeline.DeployTask)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_STATUS", prevPipeline.Status)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_CREATED", strconv.FormatInt(prevPipeline.Created, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_STARTED", strconv.FormatInt(prevPipeline.Started, 10))
|
||||
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_FINISHED", strconv.FormatInt(prevPipeline.Finished, 10))
|
||||
|
||||
prevCommit := prevPipeline.Commit
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_SHA", prevCommit.Sha)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_REF", prevCommit.Ref)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_REFSPEC", prevCommit.Refspec)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_MESSAGE", prevCommit.Message)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_BRANCH", prevCommit.Branch)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR", prevCommit.Author.Name)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR_EMAIL", prevCommit.Author.Email)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR_AVATAR", prevCommit.Author.Avatar)
|
||||
if prevPipeline.Event == EventPull || prevPipeline.Event == EventPullClosed {
|
||||
prevSourceBranch, prevTargetBranch := getSourceTargetBranches(prevCommit.Refspec)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_SOURCE_BRANCH", prevSourceBranch)
|
||||
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_TARGET_BRANCH", prevTargetBranch)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func (m *Metadata) getPipelineWebURL(pipeline Pipeline, stepNumber int) string {
|
||||
if stepNumber == 0 {
|
||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d", m.Sys.URL, m.Repo.ID, pipeline.Number)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d/%d", m.Sys.URL, m.Repo.ID, pipeline.Number, stepNumber)
|
||||
}
|
||||
|
||||
func getSourceTargetBranches(refspec string) (string, string) {
|
||||
var (
|
||||
sourceBranch string
|
||||
|
@ -45,124 +177,10 @@ func getSourceTargetBranches(refspec string) (string, string) {
|
|||
return sourceBranch, targetBranch
|
||||
}
|
||||
|
||||
// Environ returns the metadata as a map of environment variables.
|
||||
func (m *Metadata) Environ() map[string]string {
|
||||
sourceBranch, targetBranch := getSourceTargetBranches(m.Curr.Commit.Refspec)
|
||||
prevSourceBranch, prevTargetBranch := getSourceTargetBranches(m.Prev.Commit.Refspec)
|
||||
|
||||
params := map[string]string{
|
||||
"CI": m.Sys.Name,
|
||||
"CI_REPO": path.Join(m.Repo.Owner, m.Repo.Name),
|
||||
"CI_REPO_NAME": m.Repo.Name,
|
||||
"CI_REPO_OWNER": m.Repo.Owner,
|
||||
"CI_REPO_REMOTE_ID": m.Repo.RemoteID,
|
||||
"CI_REPO_SCM": m.Repo.SCM,
|
||||
"CI_REPO_URL": m.Repo.ForgeURL,
|
||||
"CI_REPO_CLONE_URL": m.Repo.CloneURL,
|
||||
"CI_REPO_CLONE_SSH_URL": m.Repo.CloneSSHURL,
|
||||
"CI_REPO_DEFAULT_BRANCH": m.Repo.Branch,
|
||||
"CI_REPO_PRIVATE": strconv.FormatBool(m.Repo.Private),
|
||||
"CI_REPO_TRUSTED_NETWORK": strconv.FormatBool(m.Repo.Trusted.Network),
|
||||
"CI_REPO_TRUSTED_VOLUMES": strconv.FormatBool(m.Repo.Trusted.Volumes),
|
||||
"CI_REPO_TRUSTED_SECURITY": strconv.FormatBool(m.Repo.Trusted.Security),
|
||||
// Deprecated remove in 4.x
|
||||
"CI_REPO_TRUSTED": strconv.FormatBool(m.Repo.Trusted.Security && m.Repo.Trusted.Network && m.Repo.Trusted.Volumes),
|
||||
|
||||
"CI_COMMIT_SHA": m.Curr.Commit.Sha,
|
||||
"CI_COMMIT_REF": m.Curr.Commit.Ref,
|
||||
"CI_COMMIT_REFSPEC": m.Curr.Commit.Refspec,
|
||||
"CI_COMMIT_BRANCH": m.Curr.Commit.Branch,
|
||||
"CI_COMMIT_SOURCE_BRANCH": sourceBranch,
|
||||
"CI_COMMIT_TARGET_BRANCH": targetBranch,
|
||||
"CI_COMMIT_MESSAGE": m.Curr.Commit.Message,
|
||||
"CI_COMMIT_AUTHOR": m.Curr.Commit.Author.Name,
|
||||
"CI_COMMIT_AUTHOR_EMAIL": m.Curr.Commit.Author.Email,
|
||||
"CI_COMMIT_AUTHOR_AVATAR": m.Curr.Commit.Author.Avatar,
|
||||
"CI_COMMIT_TAG": "", // will be set if event is tag
|
||||
"CI_COMMIT_PULL_REQUEST": "", // will be set if event is pull_request or pull_request_closed
|
||||
"CI_COMMIT_PULL_REQUEST_LABELS": "", // will be set if event is pull_request or pull_request_closed
|
||||
|
||||
"CI_PIPELINE_NUMBER": strconv.FormatInt(m.Curr.Number, 10),
|
||||
"CI_PIPELINE_PARENT": strconv.FormatInt(m.Curr.Parent, 10),
|
||||
"CI_PIPELINE_EVENT": m.Curr.Event,
|
||||
"CI_PIPELINE_URL": m.getPipelineWebURL(m.Curr, 0),
|
||||
"CI_PIPELINE_FORGE_URL": m.Curr.ForgeURL,
|
||||
"CI_PIPELINE_DEPLOY_TARGET": m.Curr.DeployTo,
|
||||
"CI_PIPELINE_DEPLOY_TASK": m.Curr.DeployTask,
|
||||
"CI_PIPELINE_CREATED": strconv.FormatInt(m.Curr.Created, 10),
|
||||
"CI_PIPELINE_STARTED": strconv.FormatInt(m.Curr.Started, 10),
|
||||
|
||||
"CI_WORKFLOW_NAME": m.Workflow.Name,
|
||||
"CI_WORKFLOW_NUMBER": strconv.Itoa(m.Workflow.Number),
|
||||
|
||||
"CI_STEP_NAME": m.Step.Name,
|
||||
"CI_STEP_NUMBER": strconv.Itoa(m.Step.Number),
|
||||
"CI_STEP_STARTED": "", // will be set by agent
|
||||
"CI_STEP_URL": m.getPipelineWebURL(m.Curr, m.Step.Number),
|
||||
|
||||
"CI_PREV_COMMIT_SHA": m.Prev.Commit.Sha,
|
||||
"CI_PREV_COMMIT_REF": m.Prev.Commit.Ref,
|
||||
"CI_PREV_COMMIT_REFSPEC": m.Prev.Commit.Refspec,
|
||||
"CI_PREV_COMMIT_BRANCH": m.Prev.Commit.Branch,
|
||||
"CI_PREV_COMMIT_URL": m.Prev.ForgeURL,
|
||||
"CI_PREV_COMMIT_MESSAGE": m.Prev.Commit.Message,
|
||||
"CI_PREV_COMMIT_AUTHOR": m.Prev.Commit.Author.Name,
|
||||
"CI_PREV_COMMIT_AUTHOR_EMAIL": m.Prev.Commit.Author.Email,
|
||||
"CI_PREV_COMMIT_AUTHOR_AVATAR": m.Prev.Commit.Author.Avatar,
|
||||
"CI_PREV_COMMIT_SOURCE_BRANCH": prevSourceBranch,
|
||||
"CI_PREV_COMMIT_TARGET_BRANCH": prevTargetBranch,
|
||||
|
||||
"CI_PREV_PIPELINE_NUMBER": strconv.FormatInt(m.Prev.Number, 10),
|
||||
"CI_PREV_PIPELINE_PARENT": strconv.FormatInt(m.Prev.Parent, 10),
|
||||
"CI_PREV_PIPELINE_EVENT": m.Prev.Event,
|
||||
"CI_PREV_PIPELINE_URL": m.getPipelineWebURL(m.Prev, 0),
|
||||
"CI_PREV_PIPELINE_FORGE_URL": m.Prev.ForgeURL,
|
||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": m.Prev.DeployTo,
|
||||
"CI_PREV_PIPELINE_DEPLOY_TASK": m.Prev.DeployTask,
|
||||
"CI_PREV_PIPELINE_STATUS": m.Prev.Status,
|
||||
"CI_PREV_PIPELINE_CREATED": strconv.FormatInt(m.Prev.Created, 10),
|
||||
"CI_PREV_PIPELINE_STARTED": strconv.FormatInt(m.Prev.Started, 10),
|
||||
"CI_PREV_PIPELINE_FINISHED": strconv.FormatInt(m.Prev.Finished, 10),
|
||||
|
||||
"CI_SYSTEM_NAME": m.Sys.Name,
|
||||
"CI_SYSTEM_URL": m.Sys.URL,
|
||||
"CI_SYSTEM_HOST": m.Sys.Host,
|
||||
"CI_SYSTEM_PLATFORM": m.Sys.Platform, // will be set by pipeline platform option or by agent
|
||||
"CI_SYSTEM_VERSION": m.Sys.Version,
|
||||
|
||||
"CI_FORGE_TYPE": m.Forge.Type,
|
||||
"CI_FORGE_URL": m.Forge.URL,
|
||||
func setNonEmptyEnvVar(env map[string]string, key, value string) {
|
||||
if len(value) > 0 {
|
||||
env[key] = value
|
||||
} else {
|
||||
log.Trace().Str("variable", key).Msg("env var is filtered as it's empty")
|
||||
}
|
||||
if m.Curr.Event == EventTag || m.Curr.Event == EventRelease || strings.HasPrefix(m.Curr.Commit.Ref, "refs/tags/") {
|
||||
params["CI_COMMIT_TAG"] = strings.TrimPrefix(m.Curr.Commit.Ref, "refs/tags/")
|
||||
}
|
||||
if m.Curr.Event == EventRelease {
|
||||
params["CI_COMMIT_PRERELEASE"] = strconv.FormatBool(m.Curr.Commit.IsPrerelease)
|
||||
}
|
||||
if m.Curr.Event == EventPull || m.Curr.Event == EventPullClosed {
|
||||
params["CI_COMMIT_PULL_REQUEST"] = pullRegexp.FindString(m.Curr.Commit.Ref)
|
||||
params["CI_COMMIT_PULL_REQUEST_LABELS"] = strings.Join(m.Curr.Commit.PullRequestLabels, ",")
|
||||
}
|
||||
|
||||
// Only export changed files if maxChangedFiles is not exceeded
|
||||
if len(m.Curr.Commit.ChangedFiles) == 0 {
|
||||
params["CI_PIPELINE_FILES"] = "[]"
|
||||
} else if len(m.Curr.Commit.ChangedFiles) <= maxChangedFiles {
|
||||
// we have to use json, as other separators like ;, or space are valid filename chars
|
||||
changedFiles, err := json.Marshal(m.Curr.Commit.ChangedFiles)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("marshal changed files")
|
||||
}
|
||||
params["CI_PIPELINE_FILES"] = string(changedFiles)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func (m *Metadata) getPipelineWebURL(pipeline Pipeline, stepNumber int) string {
|
||||
if stepNumber == 0 {
|
||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d", m.Sys.URL, m.Repo.ID, pipeline.Number)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/repos/%d/pipeline/%d/%d", m.Sys.URL, m.Repo.ID, pipeline.Number, stepNumber)
|
||||
}
|
||||
|
|
|
@ -314,8 +314,8 @@ func TestCompilerCompile(t *testing.T) {
|
|||
for _, st := range backConf.Stages {
|
||||
for _, s := range st.Steps {
|
||||
s.UUID = ""
|
||||
assert.Truef(t, s.Environment["VERBOSE"] == "true", "expect to get value of global set environment")
|
||||
assert.Truef(t, len(s.Environment) > 50, "expect to have a lot of build in variables")
|
||||
assert.Truef(t, s.Environment["VERBOSE"] == "true", "expected to get value of global set environment")
|
||||
assert.Truef(t, len(s.Environment) > 10, "expected to have a lot of built-in variables")
|
||||
s.Environment = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.36.0
|
||||
// protoc v4.24.4
|
||||
// source: woodpecker.proto
|
||||
|
||||
|
@ -36,16 +36,15 @@ const (
|
|||
)
|
||||
|
||||
type StepState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StepUuid string `protobuf:"bytes,1,opt,name=step_uuid,json=stepUuid,proto3" json:"step_uuid,omitempty"`
|
||||
Started int64 `protobuf:"varint,2,opt,name=started,proto3" json:"started,omitempty"`
|
||||
Finished int64 `protobuf:"varint,3,opt,name=finished,proto3" json:"finished,omitempty"`
|
||||
Exited bool `protobuf:"varint,4,opt,name=exited,proto3" json:"exited,omitempty"`
|
||||
ExitCode int32 `protobuf:"varint,5,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"`
|
||||
Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
StepUuid string `protobuf:"bytes,1,opt,name=step_uuid,json=stepUuid,proto3" json:"step_uuid,omitempty"`
|
||||
Started int64 `protobuf:"varint,2,opt,name=started,proto3" json:"started,omitempty"`
|
||||
Finished int64 `protobuf:"varint,3,opt,name=finished,proto3" json:"finished,omitempty"`
|
||||
Exited bool `protobuf:"varint,4,opt,name=exited,proto3" json:"exited,omitempty"`
|
||||
ExitCode int32 `protobuf:"varint,5,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"`
|
||||
Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *StepState) Reset() {
|
||||
|
@ -121,13 +120,12 @@ func (x *StepState) GetError() string {
|
|||
}
|
||||
|
||||
type WorkflowState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Started int64 `protobuf:"varint,4,opt,name=started,proto3" json:"started,omitempty"`
|
||||
Finished int64 `protobuf:"varint,5,opt,name=finished,proto3" json:"finished,omitempty"`
|
||||
Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Started int64 `protobuf:"varint,4,opt,name=started,proto3" json:"started,omitempty"`
|
||||
Finished int64 `protobuf:"varint,5,opt,name=finished,proto3" json:"finished,omitempty"`
|
||||
Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *WorkflowState) Reset() {
|
||||
|
@ -182,15 +180,14 @@ func (x *WorkflowState) GetError() string {
|
|||
}
|
||||
|
||||
type LogEntry struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StepUuid string `protobuf:"bytes,1,opt,name=step_uuid,json=stepUuid,proto3" json:"step_uuid,omitempty"`
|
||||
Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"`
|
||||
Line int32 `protobuf:"varint,3,opt,name=line,proto3" json:"line,omitempty"`
|
||||
Type int32 `protobuf:"varint,4,opt,name=type,proto3" json:"type,omitempty"` // 0 = stdout, 1 = stderr, 2 = exit-code, 3 = metadata, 4 = progress
|
||||
Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
StepUuid string `protobuf:"bytes,1,opt,name=step_uuid,json=stepUuid,proto3" json:"step_uuid,omitempty"`
|
||||
Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"`
|
||||
Line int32 `protobuf:"varint,3,opt,name=line,proto3" json:"line,omitempty"`
|
||||
Type int32 `protobuf:"varint,4,opt,name=type,proto3" json:"type,omitempty"` // 0 = stdout, 1 = stderr, 2 = exit-code, 3 = metadata, 4 = progress
|
||||
Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LogEntry) Reset() {
|
||||
|
@ -259,11 +256,10 @@ func (x *LogEntry) GetData() []byte {
|
|||
}
|
||||
|
||||
type Filter struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Filter) Reset() {
|
||||
|
@ -304,13 +300,12 @@ func (x *Filter) GetLabels() map[string]string {
|
|||
}
|
||||
|
||||
type Workflow struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Timeout int64 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"`
|
||||
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Timeout int64 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"`
|
||||
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Workflow) Reset() {
|
||||
|
@ -365,11 +360,10 @@ func (x *Workflow) GetPayload() []byte {
|
|||
}
|
||||
|
||||
type NextRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Filter *Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Filter *Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NextRequest) Reset() {
|
||||
|
@ -410,12 +404,11 @@ func (x *NextRequest) GetFilter() *Filter {
|
|||
}
|
||||
|
||||
type InitRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *WorkflowState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *WorkflowState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *InitRequest) Reset() {
|
||||
|
@ -463,11 +456,10 @@ func (x *InitRequest) GetState() *WorkflowState {
|
|||
}
|
||||
|
||||
type WaitRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *WaitRequest) Reset() {
|
||||
|
@ -508,12 +500,11 @@ func (x *WaitRequest) GetId() string {
|
|||
}
|
||||
|
||||
type DoneRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *WorkflowState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *WorkflowState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DoneRequest) Reset() {
|
||||
|
@ -561,11 +552,10 @@ func (x *DoneRequest) GetState() *WorkflowState {
|
|||
}
|
||||
|
||||
type ExtendRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ExtendRequest) Reset() {
|
||||
|
@ -606,12 +596,11 @@ func (x *ExtendRequest) GetId() string {
|
|||
}
|
||||
|
||||
type UpdateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *StepState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
State *StepState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UpdateRequest) Reset() {
|
||||
|
@ -659,11 +648,10 @@ func (x *UpdateRequest) GetState() *StepState {
|
|||
}
|
||||
|
||||
type LogRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
LogEntries []*LogEntry `protobuf:"bytes,1,rep,name=logEntries,proto3" json:"logEntries,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
LogEntries []*LogEntry `protobuf:"bytes,1,rep,name=logEntries,proto3" json:"logEntries,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LogRequest) Reset() {
|
||||
|
@ -704,9 +692,9 @@ func (x *LogRequest) GetLogEntries() []*LogEntry {
|
|||
}
|
||||
|
||||
type Empty struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Empty) Reset() {
|
||||
|
@ -740,11 +728,10 @@ func (*Empty) Descriptor() ([]byte, []int) {
|
|||
}
|
||||
|
||||
type ReportHealthRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ReportHealthRequest) Reset() {
|
||||
|
@ -785,15 +772,14 @@ func (x *ReportHealthRequest) GetStatus() string {
|
|||
}
|
||||
|
||||
type AgentInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"`
|
||||
Capacity int32 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"`
|
||||
Backend string `protobuf:"bytes,3,opt,name=backend,proto3" json:"backend,omitempty"`
|
||||
Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
CustomLabels map[string]string `protobuf:"bytes,5,rep,name=customLabels,proto3" json:"customLabels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"`
|
||||
Capacity int32 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"`
|
||||
Backend string `protobuf:"bytes,3,opt,name=backend,proto3" json:"backend,omitempty"`
|
||||
Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
CustomLabels map[string]string `protobuf:"bytes,5,rep,name=customLabels,proto3" json:"customLabels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AgentInfo) Reset() {
|
||||
|
@ -862,11 +848,10 @@ func (x *AgentInfo) GetCustomLabels() map[string]string {
|
|||
}
|
||||
|
||||
type RegisterAgentRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Info *AgentInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Info *AgentInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RegisterAgentRequest) Reset() {
|
||||
|
@ -907,12 +892,11 @@ func (x *RegisterAgentRequest) GetInfo() *AgentInfo {
|
|||
}
|
||||
|
||||
type VersionResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
GrpcVersion int32 `protobuf:"varint,1,opt,name=grpc_version,json=grpcVersion,proto3" json:"grpc_version,omitempty"`
|
||||
ServerVersion string `protobuf:"bytes,2,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
GrpcVersion int32 `protobuf:"varint,1,opt,name=grpc_version,json=grpcVersion,proto3" json:"grpc_version,omitempty"`
|
||||
ServerVersion string `protobuf:"bytes,2,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *VersionResponse) Reset() {
|
||||
|
@ -960,11 +944,10 @@ func (x *VersionResponse) GetServerVersion() string {
|
|||
}
|
||||
|
||||
type NextResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Workflow *Workflow `protobuf:"bytes,1,opt,name=workflow,proto3" json:"workflow,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Workflow *Workflow `protobuf:"bytes,1,opt,name=workflow,proto3" json:"workflow,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NextResponse) Reset() {
|
||||
|
@ -1005,11 +988,10 @@ func (x *NextResponse) GetWorkflow() *Workflow {
|
|||
}
|
||||
|
||||
type RegisterAgentResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AgentId int64 `protobuf:"varint,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AgentId int64 `protobuf:"varint,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RegisterAgentResponse) Reset() {
|
||||
|
@ -1050,12 +1032,11 @@ func (x *RegisterAgentResponse) GetAgentId() int64 {
|
|||
}
|
||||
|
||||
type AuthRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AgentToken string `protobuf:"bytes,1,opt,name=agent_token,json=agentToken,proto3" json:"agent_token,omitempty"`
|
||||
AgentId int64 `protobuf:"varint,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AgentToken string `protobuf:"bytes,1,opt,name=agent_token,json=agentToken,proto3" json:"agent_token,omitempty"`
|
||||
AgentId int64 `protobuf:"varint,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthRequest) Reset() {
|
||||
|
@ -1103,13 +1084,12 @@ func (x *AuthRequest) GetAgentId() int64 {
|
|||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
AgentId int64 `protobuf:"varint,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
AccessToken string `protobuf:"bytes,3,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
AgentId int64 `protobuf:"varint,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
AccessToken string `protobuf:"bytes,3,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthResponse) Reset() {
|
||||
|
|
|
@ -72,7 +72,7 @@ func GetBadge(c *gin.Context) {
|
|||
branch = repo.Branch
|
||||
}
|
||||
|
||||
pipeline, err := _store.GetPipelineLast(repo, branch)
|
||||
pipeline, err := _store.GetPipelineBadge(repo, branch)
|
||||
if err != nil {
|
||||
if !errors.Is(err, types.RecordNotExist) {
|
||||
log.Warn().Err(err).Msg("could not get last pipeline for badge")
|
||||
|
|
|
@ -132,7 +132,7 @@ func GetPipelines(c *gin.Context) {
|
|||
if events := c.Query("event"); events != "" {
|
||||
eventList := strings.Split(events, ",")
|
||||
wel := make(model.WebhookEventList, 0, len(eventList))
|
||||
for _, event := range events {
|
||||
for _, event := range eventList {
|
||||
we := model.WebhookEvent(event)
|
||||
if err := we.Validate(); err != nil {
|
||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||
|
|
|
@ -96,6 +96,24 @@ func TestGetPipelines(t *testing.T) {
|
|||
|
||||
assert.Equal(t, http.StatusOK, c.Writer.Status())
|
||||
})
|
||||
|
||||
t.Run("should filter pipelines by events", func(t *testing.T) {
|
||||
pipelines := []*model.Pipeline{fakePipeline}
|
||||
mockStore := store_mocks.NewStore(t)
|
||||
mockStore.On("GetPipelineList", mock.Anything, mock.Anything, mock.Anything).Return(pipelines, nil)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("store", mockStore)
|
||||
c.Request, _ = http.NewRequest(http.MethodGet, "/?event=push,pull_request", nil)
|
||||
|
||||
GetPipelines(c)
|
||||
|
||||
mockStore.AssertCalled(t, "GetPipelineList", mock.Anything, mock.Anything, &model.PipelineFilter{
|
||||
Events: model.WebhookEventList{model.EventPush, model.EventPull},
|
||||
})
|
||||
assert.Equal(t, http.StatusOK, c.Writer.Status())
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeletePipeline(t *testing.T) {
|
||||
|
|
|
@ -258,12 +258,9 @@ func PatchRepo(c *gin.Context) {
|
|||
c.String(http.StatusBadRequest, "Invalid require-approval setting")
|
||||
return
|
||||
}
|
||||
} else if in.IsGated != nil { // TODO: remove isGated in next major release
|
||||
if *in.IsGated {
|
||||
repo.RequireApproval = model.RequireApprovalAllEvents
|
||||
} else {
|
||||
repo.RequireApproval = model.RequireApprovalForks
|
||||
}
|
||||
} else if in.IsGated != nil {
|
||||
c.String(http.StatusBadRequest, "'gated' option has been removed, use 'require-approval' in >= 3.0")
|
||||
return
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
repo.Timeout = *in.Timeout
|
||||
|
|
|
@ -139,8 +139,8 @@ func (g *RPC) Repo(_ context.Context, u *model.User, remoteID model.ForgeRemoteI
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var resp *modelRepo
|
||||
err = json.Unmarshal(jsonResp, resp)
|
||||
var resp modelRepo
|
||||
err = json.Unmarshal(jsonResp, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ func (s *RPCServer) URL(_ []byte, resp *string) error {
|
|||
}
|
||||
|
||||
func (s *RPCServer) Teams(args []byte, resp *[]byte) error {
|
||||
var a *modelUser
|
||||
err := json.Unmarshal(args, a)
|
||||
var a modelUser
|
||||
err := json.Unmarshal(args, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -82,8 +82,8 @@ func (s *RPCServer) Repo(args []byte, resp *[]byte) error {
|
|||
}
|
||||
|
||||
func (s *RPCServer) Repos(args []byte, resp *[]byte) error {
|
||||
var a *modelUser
|
||||
err := json.Unmarshal(args, a)
|
||||
var a modelUser
|
||||
err := json.Unmarshal(args, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -261,12 +261,12 @@ func (s *RPCServer) Hook(args []byte, resp *[]byte) error {
|
|||
}
|
||||
|
||||
func (s *RPCServer) Login(args []byte, resp *[]byte) error {
|
||||
var a *types.OAuthRequest
|
||||
err := json.Unmarshal(args, a)
|
||||
var a types.OAuthRequest
|
||||
err := json.Unmarshal(args, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user, red, err := s.Impl.Login(mkCtx(), a)
|
||||
user, red, err := s.Impl.Login(mkCtx(), &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -290,11 +290,11 @@ func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model
|
|||
}
|
||||
|
||||
// Status creates a pipeline status for the Bitbucket commit.
|
||||
func (c *config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, _ *model.Workflow) error {
|
||||
func (c *config) Status(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, workflow *model.Workflow) error {
|
||||
status := internal.PipelineStatus{
|
||||
State: convertStatus(pipeline.Status),
|
||||
Desc: common.GetPipelineStatusDescription(pipeline.Status),
|
||||
Key: "Woodpecker",
|
||||
Key: common.GetPipelineStatusContext(repo, pipeline, workflow),
|
||||
URL: common.GetPipelineStatusURL(repo, pipeline, nil),
|
||||
}
|
||||
return c.newClient(ctx, user).CreateStatus(repo.Owner, repo.Name, pipeline.Commit, &status)
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/api/client-go"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
"go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/api/client-go"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/api/client-go"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/xanzy/go-gitlab"
|
||||
"gitlab.com/gitlab-org/api/client-go"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
|
|
@ -282,7 +282,7 @@ func (_m *Forge) Login(ctx context.Context, r *types.OAuthRequest) (*model.User,
|
|||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Name provides a mock function with given fields:
|
||||
// Name provides a mock function with no fields
|
||||
func (_m *Forge) Name() string {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -528,7 +528,7 @@ func (_m *Forge) Teams(ctx context.Context, u *model.User) ([]*model.Team, error
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// URL provides a mock function with given fields:
|
||||
// URL provides a mock function with no fields
|
||||
func (_m *Forge) URL() string {
|
||||
ret := _m.Called()
|
||||
|
||||
|
|
|
@ -31,23 +31,25 @@ func needsApproval(repo *model.Repo, pipeline *model.Pipeline) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
switch repo.RequireApproval {
|
||||
// repository allows all events without approval
|
||||
if repo.RequireApproval == model.RequireApprovalNone {
|
||||
case model.RequireApprovalNone:
|
||||
return false
|
||||
}
|
||||
|
||||
// repository requires approval for pull requests from forks
|
||||
if pipeline.Event == model.EventPull && pipeline.FromFork {
|
||||
return true
|
||||
}
|
||||
case model.RequireApprovalForks:
|
||||
if pipeline.Event == model.EventPull && pipeline.FromFork {
|
||||
return true
|
||||
}
|
||||
|
||||
// repository requires approval for pull requests
|
||||
if pipeline.Event == model.EventPull && repo.RequireApproval == model.RequireApprovalPullRequests {
|
||||
return true
|
||||
}
|
||||
case model.RequireApprovalPullRequests:
|
||||
if pipeline.Event == model.EventPull {
|
||||
return true
|
||||
}
|
||||
|
||||
// repository requires approval for all events
|
||||
if repo.RequireApproval == model.RequireApprovalAllEvents {
|
||||
// repository requires approval for all events
|
||||
case model.RequireApprovalAllEvents:
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -43,20 +43,15 @@ func TestMetadataFromStruct(t *testing.T) {
|
|||
name: "Test with empty info",
|
||||
expectedMetadata: metadata.Metadata{Sys: metadata.System{Name: "woodpecker"}},
|
||||
expectedEnviron: map[string]string{
|
||||
"CI": "woodpecker",
|
||||
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
|
||||
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
|
||||
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_FORGE_TYPE": "", "CI_FORGE_URL": "",
|
||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
|
||||
"CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PIPELINE_FORGE_URL": "",
|
||||
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "", "CI_PREV_COMMIT_SOURCE_BRANCH": "", "CI_PREV_COMMIT_TARGET_BRANCH": "",
|
||||
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
|
||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
|
||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "/repos/0/pipeline/0", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "", "CI_REPO_CLONE_URL": "", "CI_REPO_CLONE_SSH_URL": "", "CI_REPO_DEFAULT_BRANCH": "", "CI_REPO_REMOTE_ID": "",
|
||||
"CI_REPO_NAME": "", "CI_REPO_OWNER": "", "CI_REPO_PRIVATE": "false", "CI_REPO_SCM": "", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false",
|
||||
"CI_REPO_TRUSTED_VOLUMES": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_URL": "",
|
||||
"CI_STEP_NAME": "", "CI_STEP_NUMBER": "0", "CI_STEP_STARTED": "", "CI_STEP_URL": "/repos/0/pipeline/0", "CI_SYSTEM_HOST": "", "CI_SYSTEM_NAME": "woodpecker",
|
||||
"CI_SYSTEM_PLATFORM": "", "CI_SYSTEM_URL": "", "CI_SYSTEM_VERSION": "", "CI_WORKFLOW_NAME": "", "CI_WORKFLOW_NUMBER": "0",
|
||||
"CI": "woodpecker",
|
||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_FILES": "[]", "CI_PIPELINE_NUMBER": "0",
|
||||
"CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "/repos/0/pipeline/0",
|
||||
"CI_PREV_PIPELINE_CREATED": "0",
|
||||
"CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "0", "CI_PREV_PIPELINE_PARENT": "0",
|
||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_URL": "/repos/0/pipeline/0",
|
||||
"CI_REPO_PRIVATE": "false", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_TRUSTED_VOLUMES": "false",
|
||||
"CI_STEP_NUMBER": "0", "CI_STEP_URL": "/repos/0/pipeline/0", "CI_SYSTEM_NAME": "woodpecker",
|
||||
"CI_WORKFLOW_NUMBER": "0",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -79,22 +74,17 @@ func TestMetadataFromStruct(t *testing.T) {
|
|||
Workflow: metadata.Workflow{Name: "hello"},
|
||||
},
|
||||
expectedEnviron: map[string]string{
|
||||
"CI": "woodpecker",
|
||||
"CI_COMMIT_AUTHOR": "", "CI_COMMIT_AUTHOR_AVATAR": "", "CI_COMMIT_AUTHOR_EMAIL": "", "CI_COMMIT_BRANCH": "",
|
||||
"CI_COMMIT_MESSAGE": "", "CI_COMMIT_PULL_REQUEST": "", "CI_COMMIT_PULL_REQUEST_LABELS": "", "CI_COMMIT_REF": "", "CI_COMMIT_REFSPEC": "", "CI_COMMIT_SHA": "", "CI_COMMIT_SOURCE_BRANCH": "",
|
||||
"CI_COMMIT_TAG": "", "CI_COMMIT_TARGET_BRANCH": "", "CI_FORGE_TYPE": "gitea", "CI_FORGE_URL": "https://gitea.com",
|
||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_DEPLOY_TARGET": "", "CI_PIPELINE_DEPLOY_TASK": "", "CI_PIPELINE_EVENT": "", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
|
||||
"CI_PIPELINE_NUMBER": "3", "CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "https://example.com/repos/0/pipeline/3", "CI_PIPELINE_FORGE_URL": "",
|
||||
"CI_PREV_COMMIT_AUTHOR": "", "CI_PREV_COMMIT_AUTHOR_AVATAR": "", "CI_PREV_COMMIT_AUTHOR_EMAIL": "", "CI_PREV_COMMIT_BRANCH": "", "CI_PREV_COMMIT_SOURCE_BRANCH": "", "CI_PREV_COMMIT_TARGET_BRANCH": "",
|
||||
"CI_PREV_COMMIT_MESSAGE": "", "CI_PREV_COMMIT_REF": "", "CI_PREV_COMMIT_REFSPEC": "", "CI_PREV_COMMIT_SHA": "", "CI_PREV_COMMIT_URL": "", "CI_PREV_PIPELINE_CREATED": "0",
|
||||
"CI_PREV_PIPELINE_DEPLOY_TARGET": "", "CI_PREV_PIPELINE_DEPLOY_TASK": "", "CI_PREV_PIPELINE_EVENT": "", "CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
|
||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_STATUS": "", "CI_PREV_PIPELINE_URL": "https://example.com/repos/0/pipeline/2", "CI_PREV_PIPELINE_FORGE_URL": "", "CI_REPO": "testUser/testRepo", "CI_REPO_CLONE_URL": "https://gitea.com/testUser/testRepo.git", "CI_REPO_CLONE_SSH_URL": "git@gitea.com:testUser/testRepo.git",
|
||||
"CI_REPO_DEFAULT_BRANCH": "main", "CI_REPO_NAME": "testRepo", "CI_REPO_OWNER": "testUser", "CI_REPO_PRIVATE": "true", "CI_REPO_REMOTE_ID": "",
|
||||
"CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false",
|
||||
"CI_REPO_TRUSTED_VOLUMES": "false", "CI_REPO_TRUSTED_SECURITY": "false",
|
||||
"CI_REPO_URL": "https://gitea.com/testUser/testRepo",
|
||||
"CI_STEP_NAME": "", "CI_STEP_NUMBER": "0", "CI_STEP_STARTED": "", "CI_STEP_URL": "https://example.com/repos/0/pipeline/3", "CI_SYSTEM_HOST": "example.com",
|
||||
"CI_SYSTEM_NAME": "woodpecker", "CI_SYSTEM_PLATFORM": "", "CI_SYSTEM_URL": "https://example.com", "CI_SYSTEM_VERSION": "", "CI_WORKFLOW_NAME": "hello", "CI_WORKFLOW_NUMBER": "0",
|
||||
"CI": "woodpecker",
|
||||
"CI_FORGE_TYPE": "gitea", "CI_FORGE_URL": "https://gitea.com",
|
||||
"CI_PIPELINE_CREATED": "0", "CI_PIPELINE_FILES": `["test.go","markdown file.md"]`,
|
||||
"CI_PIPELINE_NUMBER": "3", "CI_PIPELINE_PARENT": "0", "CI_PIPELINE_STARTED": "0", "CI_PIPELINE_URL": "https://example.com/repos/0/pipeline/3",
|
||||
"CI_PREV_PIPELINE_CREATED": "0",
|
||||
"CI_PREV_PIPELINE_FINISHED": "0", "CI_PREV_PIPELINE_NUMBER": "2", "CI_PREV_PIPELINE_PARENT": "0",
|
||||
"CI_PREV_PIPELINE_STARTED": "0", "CI_PREV_PIPELINE_URL": "https://example.com/repos/0/pipeline/2", "CI_REPO": "testUser/testRepo", "CI_REPO_CLONE_URL": "https://gitea.com/testUser/testRepo.git", "CI_REPO_CLONE_SSH_URL": "git@gitea.com:testUser/testRepo.git",
|
||||
"CI_REPO_DEFAULT_BRANCH": "main", "CI_REPO_NAME": "testRepo", "CI_REPO_OWNER": "testUser", "CI_REPO_PRIVATE": "true",
|
||||
"CI_REPO_SCM": "git", "CI_REPO_TRUSTED": "false", "CI_REPO_TRUSTED_NETWORK": "false", "CI_REPO_TRUSTED_SECURITY": "false", "CI_REPO_TRUSTED_VOLUMES": "false",
|
||||
"CI_REPO_URL": "https://gitea.com/testUser/testRepo", "CI_STEP_NUMBER": "0", "CI_STEP_URL": "https://example.com/repos/0/pipeline/3", "CI_SYSTEM_HOST": "example.com",
|
||||
"CI_SYSTEM_NAME": "woodpecker", "CI_SYSTEM_URL": "https://example.com", "CI_WORKFLOW_NAME": "hello", "CI_WORKFLOW_NUMBER": "0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ func (_m *Queue) KickAgentWorkers(agentID int64) {
|
|||
_m.Called(agentID)
|
||||
}
|
||||
|
||||
// Pause provides a mock function with given fields:
|
||||
// Pause provides a mock function with no fields
|
||||
func (_m *Queue) Pause() {
|
||||
_m.Called()
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ func (_m *Queue) PushAtOnce(c context.Context, tasks []*model.Task) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// Resume provides a mock function with given fields:
|
||||
// Resume provides a mock function with no fields
|
||||
func (_m *Queue) Resume() {
|
||||
_m.Called()
|
||||
}
|
||||
|
|
|
@ -140,9 +140,9 @@ func (f *forgeFetcherContext) checkPipelineFile(c context.Context, config string
|
|||
func (f *forgeFetcherContext) getFirstAvailableConfig(c context.Context, configs []string) ([]*types.FileMeta, error) {
|
||||
var forgeErr []error
|
||||
for _, fileOrFolder := range configs {
|
||||
log.Trace().Msgf("fetching %s from forge", fileOrFolder)
|
||||
if strings.HasSuffix(fileOrFolder, "/") {
|
||||
// config is a folder
|
||||
log.Trace().Msgf("fetching %s from forge", fileOrFolder)
|
||||
files, err := f.forge.Dir(c, f.user, f.repo, f.pipeline, strings.TrimSuffix(fileOrFolder, "/"))
|
||||
// if folder is not supported we will get a "Not implemented" error and continue
|
||||
if err != nil {
|
||||
|
|
|
@ -48,7 +48,7 @@ func (_m *Manager) ConfigServiceFromRepo(repo *model.Repo) config.Service {
|
|||
return r0
|
||||
}
|
||||
|
||||
// EnvironmentService provides a mock function with given fields:
|
||||
// EnvironmentService provides a mock function with no fields
|
||||
func (_m *Manager) EnvironmentService() environment.Service {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -158,7 +158,7 @@ func (_m *Manager) ForgeFromUser(user *model.User) (forge.Forge, error) {
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// RegistryService provides a mock function with given fields:
|
||||
// RegistryService provides a mock function with no fields
|
||||
func (_m *Manager) RegistryService() registry.Service {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -198,7 +198,7 @@ func (_m *Manager) RegistryServiceFromRepo(repo *model.Repo) registry.Service {
|
|||
return r0
|
||||
}
|
||||
|
||||
// SecretService provides a mock function with given fields:
|
||||
// SecretService provides a mock function with no fields
|
||||
func (_m *Manager) SecretService() secret.Service {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -238,7 +238,7 @@ func (_m *Manager) SecretServiceFromRepo(repo *model.Repo) secret.Service {
|
|||
return r0
|
||||
}
|
||||
|
||||
// SignaturePublicKey provides a mock function with given fields:
|
||||
// SignaturePublicKey provides a mock function with no fields
|
||||
func (_m *Manager) SignaturePublicKey() crypto.PublicKey {
|
||||
ret := _m.Called()
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ package datastore
|
|||
|
||||
import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
@ -46,6 +47,12 @@ func (s storage) LogAppend(_ *model.Step, logEntries []*model.LogEntry) error {
|
|||
}
|
||||
|
||||
func (s storage) LogDelete(step *model.Step) error {
|
||||
_, err := s.engine.Where("step_id = ?", step.ID).Delete(new(model.LogEntry))
|
||||
sess := s.engine.NewSession()
|
||||
defer sess.Close()
|
||||
return logDelete(sess, step.ID)
|
||||
}
|
||||
|
||||
func logDelete(sess *xorm.Session, stepID int64) error {
|
||||
_, err := sess.Where("step_id = ?", stepID).Delete(new(model.LogEntry))
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -26,10 +26,8 @@ var gatedToRequireApproval = xormigrate.Migration{
|
|||
ID: "gated-to-require-approval",
|
||||
MigrateSession: func(sess *xorm.Session) (err error) {
|
||||
const (
|
||||
RequireApprovalNone string = "none"
|
||||
RequireApprovalForks string = "forks"
|
||||
RequireApprovalPullRequests string = "pull_requests"
|
||||
RequireApprovalAllEvents string = "all_events"
|
||||
requireApprovalOldNotGated string = "old_not_gated"
|
||||
requireApprovalAllEvents string = "all_events"
|
||||
)
|
||||
|
||||
type repos struct {
|
||||
|
@ -45,25 +43,17 @@ var gatedToRequireApproval = xormigrate.Migration{
|
|||
|
||||
// migrate gated repos
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalAllEvents}).
|
||||
builder.Update(builder.Eq{"require_approval": requireApprovalAllEvents}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": true})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// migrate public repos to new default require approval
|
||||
// migrate non gated repos to old_not_gated (no approval required)
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalForks}).
|
||||
builder.Update(builder.Eq{"require_approval": requireApprovalOldNotGated}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": false, "visibility": "public"})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// migrate private repos to new default require approval
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalNone}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"gated": false}.And(builder.Neq{"visibility": "public"}))); err != nil {
|
||||
Where(builder.Eq{"gated": false})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// 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 migration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var setNewDefaultsForRequireApproval = xormigrate.Migration{
|
||||
ID: "set-new-defaults-for-require-approval",
|
||||
MigrateSession: func(sess *xorm.Session) (err error) {
|
||||
const (
|
||||
RequireApprovalOldNotGated string = "old_not_gated"
|
||||
RequireApprovalNone string = "none"
|
||||
RequireApprovalForks string = "forks"
|
||||
RequireApprovalAllEvents string = "all_events"
|
||||
)
|
||||
|
||||
type repos struct {
|
||||
RequireApproval string `xorm:"require_approval"`
|
||||
Visibility string `xorm:"varchar(10) 'visibility'"`
|
||||
}
|
||||
|
||||
if err := sess.Sync(new(repos)); err != nil {
|
||||
return fmt.Errorf("sync new models failed: %w", err)
|
||||
}
|
||||
|
||||
// migrate public repos to require approval for forks
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalForks}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"require_approval": RequireApprovalOldNotGated, "visibility": "public"})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// migrate private repos to require no approval
|
||||
if _, err := sess.Exec(
|
||||
builder.Update(builder.Eq{"require_approval": RequireApprovalNone}).
|
||||
From("repos").
|
||||
Where(builder.Eq{"require_approval": RequireApprovalOldNotGated}.And(builder.Neq{"visibility": "public"}))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
|
@ -50,6 +50,7 @@ var migrationTasks = []*xormigrate.Migration{
|
|||
&gatedToRequireApproval,
|
||||
&removeRepoNetrcOnlyTrusted,
|
||||
&renameTokenFields,
|
||||
&setNewDefaultsForRequireApproval,
|
||||
}
|
||||
|
||||
var allBeans = []any{
|
||||
|
|
|
@ -35,6 +35,15 @@ func (s storage) GetPipelineNumber(repo *model.Repo, num int64) (*model.Pipeline
|
|||
).Get(pipeline))
|
||||
}
|
||||
|
||||
func (s storage) GetPipelineBadge(repo *model.Repo, branch string) (*model.Pipeline, error) {
|
||||
pipeline := new(model.Pipeline)
|
||||
return pipeline, wrapGet(s.engine.
|
||||
Desc("number").
|
||||
Where(builder.Eq{"repo_id": repo.ID, "branch": branch, "event": model.EventPush}).
|
||||
Where(builder.Neq{"status": model.StatusBlocked}).
|
||||
Get(pipeline))
|
||||
}
|
||||
|
||||
func (s storage) GetPipelineLast(repo *model.Repo, branch string) (*model.Pipeline, error) {
|
||||
pipeline := new(model.Pipeline)
|
||||
return pipeline, wrapGet(s.engine.
|
||||
|
|
|
@ -84,7 +84,7 @@ func (s storage) StepUpdate(step *model.Step) error {
|
|||
}
|
||||
|
||||
func deleteStep(sess *xorm.Session, stepID int64) error {
|
||||
if _, err := sess.Where("id = ?", stepID).Delete(new(model.LogEntry)); err != nil {
|
||||
if err := logDelete(sess, stepID); err != nil {
|
||||
return err
|
||||
}
|
||||
return wrapDelete(sess.ID(stepID).Delete(new(model.Step)))
|
||||
|
|
|
@ -191,7 +191,7 @@ func (_m *Store) AgentUpdate(_a0 *model.Agent) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
// Close provides a mock function with no fields
|
||||
func (_m *Store) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -748,7 +748,37 @@ func (_m *Store) GetPipeline(_a0 int64) (*model.Pipeline, error) {
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// GetPipelineCount provides a mock function with given fields:
|
||||
// GetPipelineBadge provides a mock function with given fields: _a0, _a1
|
||||
func (_m *Store) GetPipelineBadge(_a0 *model.Repo, _a1 string) (*model.Pipeline, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetPipelineBadge")
|
||||
}
|
||||
|
||||
var r0 *model.Pipeline
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(*model.Repo, string) (*model.Pipeline, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*model.Repo, string) *model.Pipeline); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Pipeline)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(*model.Repo, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetPipelineCount provides a mock function with no fields
|
||||
func (_m *Store) GetPipelineCount() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -896,7 +926,7 @@ func (_m *Store) GetPipelineNumber(_a0 *model.Repo, _a1 int64) (*model.Pipeline,
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// GetPipelineQueue provides a mock function with given fields:
|
||||
// GetPipelineQueue provides a mock function with no fields
|
||||
func (_m *Store) GetPipelineQueue() ([]*model.Feed, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -956,7 +986,7 @@ func (_m *Store) GetRepo(_a0 int64) (*model.Repo, error) {
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// GetRepoCount provides a mock function with given fields:
|
||||
// GetRepoCount provides a mock function with no fields
|
||||
func (_m *Store) GetRepoCount() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1104,7 +1134,7 @@ func (_m *Store) GetUser(_a0 int64) (*model.User, error) {
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUserCount provides a mock function with given fields:
|
||||
// GetUserCount provides a mock function with no fields
|
||||
func (_m *Store) GetUserCount() (int64, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1796,7 +1826,7 @@ func (_m *Store) PermUpsert(perm *model.Perm) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// Ping provides a mock function with given fields:
|
||||
// Ping provides a mock function with no fields
|
||||
func (_m *Store) Ping() error {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1928,7 +1958,7 @@ func (_m *Store) RegistryList(_a0 *model.Repo, _a1 bool, _a2 *model.ListOptions)
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// RegistryListAll provides a mock function with given fields:
|
||||
// RegistryListAll provides a mock function with no fields
|
||||
func (_m *Store) RegistryListAll() ([]*model.Registry, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -2162,7 +2192,7 @@ func (_m *Store) SecretList(_a0 *model.Repo, _a1 bool, _a2 *model.ListOptions) (
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// SecretListAll provides a mock function with given fields:
|
||||
// SecretListAll provides a mock function with no fields
|
||||
func (_m *Store) SecretListAll() ([]*model.Secret, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -2508,7 +2538,7 @@ func (_m *Store) TaskInsert(_a0 *model.Task) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// TaskList provides a mock function with given fields:
|
||||
// TaskList provides a mock function with no fields
|
||||
func (_m *Store) TaskList() ([]*model.Task, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ type Store interface {
|
|||
GetPipeline(int64) (*model.Pipeline, error)
|
||||
// GetPipelineNumber gets a pipeline by number.
|
||||
GetPipelineNumber(*model.Repo, int64) (*model.Pipeline, error)
|
||||
// GetPipelineBadge gets the last relevant pipeline for the badge.
|
||||
GetPipelineBadge(*model.Repo, string) (*model.Pipeline, error)
|
||||
// GetPipelineLast gets the last pipeline for the branch.
|
||||
GetPipelineLast(*model.Repo, string) (*model.Pipeline, error)
|
||||
// GetPipelineLastBefore gets the last pipeline before pipeline number N.
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
"prettier": "^3.3.3",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"typescript": "5.6.3",
|
||||
"vite": "^5.4.1",
|
||||
"vite": "^6.0.0",
|
||||
"vite-plugin-prismjs": "^0.0.11",
|
||||
"vite-plugin-windicss": "^1.9.3",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
|
|
1252
web/pnpm-lock.yaml
1252
web/pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -518,7 +518,8 @@
|
|||
"not_started": "noch nicht gestartet",
|
||||
"sec_short": "sek",
|
||||
"template": "DD.MM.YYYY, HH:mm z",
|
||||
"weeks_short": "w"
|
||||
"weeks_short": "w",
|
||||
"just_now": "gerade eben"
|
||||
},
|
||||
"unknown_error": "Ein unbekannter Fehler ist aufgetreten",
|
||||
"update_woodpecker": "Du solltest deine Woodpecker-Instanz auf {0} aktualisieren",
|
||||
|
@ -576,7 +577,7 @@
|
|||
"cli_and_api": {
|
||||
"desc": "Persönlicher Zugangsschlüssel, CLI- und API-Nutzung",
|
||||
"token": "Persönlicher Zugangsschlüssel",
|
||||
"api_usage": "Beispiel zur Nutzung der API",
|
||||
"api_usage": "Beispiel zur Nutzung des API",
|
||||
"download_cli": "CLI herunterladen",
|
||||
"reset_token": "Schlüssel zurücksetzen",
|
||||
"swagger_ui": "Swagger-UI",
|
||||
|
|
|
@ -193,8 +193,8 @@
|
|||
"add": "Ajouter un dépôt",
|
||||
"branches": "Branches",
|
||||
"deploy_pipeline": {
|
||||
"enter_target": "Environnement de déploiement ciblé",
|
||||
"title": "Déclenchement d'un événement de déploiement pour le pipeline courant #{pipelineId}",
|
||||
"enter_target": "Environnement de 'déploiement' ciblé",
|
||||
"title": "Déclenchement d'un événement de 'déploiement' pour le pipeline courant #{pipelineId}",
|
||||
"trigger": "Déployer",
|
||||
"variables": {
|
||||
"add": "Ajouter une variable",
|
||||
|
@ -365,7 +365,7 @@
|
|||
"general": {
|
||||
"allow_pr": {
|
||||
"allow": "Autoriser les demandes de fusions",
|
||||
"desc": "Les pipelines peuvent se déclencher sur les pull requests."
|
||||
"desc": "Permettre aux pipelines de se déclencher sur les pull requests."
|
||||
},
|
||||
"cancel_prev": {
|
||||
"cancel": "Annuler les pipelines précédents",
|
||||
|
@ -373,8 +373,8 @@
|
|||
},
|
||||
"general": "Général",
|
||||
"netrc_only_trusted": {
|
||||
"desc": "Injecter les identifiants netrc uniquement dans des conteneurs de confiance (recommandé).",
|
||||
"netrc_only_trusted": "Injecter les identifiants netrc uniquement dans des conteneurs de confiance"
|
||||
"desc": "Les plugins listés ici auront accès aux identifiants netrc qui peuvent être utiliser pour cloner des dépôts depuis la forge, ou pour pousser vers celle-ci.",
|
||||
"netrc_only_trusted": "Plugins de clonage personnalisés de confiance"
|
||||
},
|
||||
"pipeline_path": {
|
||||
"default": "Par défaut : .woodpecker/*.{'{yaml,yml}'} -> .woodpecker.yaml -> .woodpecker.yml",
|
||||
|
@ -388,14 +388,23 @@
|
|||
"protected": "Protégé"
|
||||
},
|
||||
"save": "Enregistrer les paramètres",
|
||||
"success": "Paramètres du dépôt mis à jour",
|
||||
"success": "Paramètres du projet mis à jour",
|
||||
"timeout": {
|
||||
"minutes": "minutes",
|
||||
"timeout": "Délai d’inactivité"
|
||||
},
|
||||
"trusted": {
|
||||
"desc": "Les conteneurs du pipeline ont accès à des capacités privilégiées (comme le montage de volumes).",
|
||||
"trusted": "Vérifié"
|
||||
"trusted": "Vérifié",
|
||||
"network": {
|
||||
"network": "Réseau"
|
||||
},
|
||||
"volumes": {
|
||||
"volumes": "Volumes"
|
||||
},
|
||||
"security": {
|
||||
"security": "Sécurité"
|
||||
}
|
||||
},
|
||||
"visibility": {
|
||||
"internal": {
|
||||
|
@ -413,8 +422,8 @@
|
|||
"visibility": "Visibilité du projet"
|
||||
},
|
||||
"allow_deploy": {
|
||||
"allow": "Autoriser les déploiements",
|
||||
"desc": "Autoriser les déploiements depuis les pipelines ayant réussis. À utiliser que si vous avez confiance dans les utilisateurs ayant un accès en écriture."
|
||||
"allow": "Autoriser les événements de 'déploiement'.",
|
||||
"desc": "Permettre les déploiements depuis les pipelines ayant réussis. À utiliser que si vous avez confiance dans les utilisateurs ayant un accès en écriture."
|
||||
}
|
||||
},
|
||||
"not_allowed": "Vous n'êtes pas autorisé à accéder aux paramètres de ce dépôt",
|
||||
|
@ -463,7 +472,22 @@
|
|||
},
|
||||
"settings": "Paramètres"
|
||||
},
|
||||
"user_none": "Cet(te) organisation / utilisateur n'a pas encore de projets."
|
||||
"user_none": "Cet(te) organisation / utilisateur n'a pas encore de projets.",
|
||||
"visibility": {
|
||||
"visibility": "Visibilité du projet",
|
||||
"public": {
|
||||
"public": "Publique",
|
||||
"desc": "Tout le monde peut voir le projet sans être connecté."
|
||||
},
|
||||
"private": {
|
||||
"private": "Privé",
|
||||
"desc": "Seul vous et les propriétaires de ce dépôt peuvent le voir."
|
||||
},
|
||||
"internal": {
|
||||
"internal": "Interne",
|
||||
"desc": "Seuls les comptes identifiés sur cet instance de Woodpecker peuvent voir ce projet."
|
||||
}
|
||||
}
|
||||
},
|
||||
"repos": "Dépôt",
|
||||
"repositories": "Dépôts",
|
||||
|
@ -476,7 +500,8 @@
|
|||
"not_started": "pas encore démarré",
|
||||
"sec_short": "sec",
|
||||
"template": "D MMM, YYYY, HH:mm z",
|
||||
"weeks_short": "s"
|
||||
"weeks_short": "s",
|
||||
"just_now": "il y a peu de temps"
|
||||
},
|
||||
"unknown_error": "Une erreur inconnue est survenue",
|
||||
"update_woodpecker": "Merci de mettre à jour votre instance Woodpecker vers la version {0}",
|
||||
|
|
|
@ -144,8 +144,8 @@
|
|||
"add": "Aggiungi repository",
|
||||
"branches": "Rami",
|
||||
"deploy_pipeline": {
|
||||
"enter_target": "Ambiente di destinazione del deploy",
|
||||
"title": "Avvia evento di deploy per la pipeline corrente #{pipelineId}",
|
||||
"enter_target": "Ambiente di destinazione della 'distribuzione'",
|
||||
"title": "Avvia evento di 'distribuzione' per la pipeline corrente #{pipelineId}",
|
||||
"trigger": "Distribuzione",
|
||||
"variables": {
|
||||
"add": "Aggiungi variabile",
|
||||
|
@ -196,13 +196,13 @@
|
|||
},
|
||||
"no_pipelines": "Non è ancora stata attivata alcuna pipeline.",
|
||||
"pipelines_for": "Pipeline per ramo \"{branch}\"",
|
||||
"files": "File modificati ({files})",
|
||||
"files": "File modificati",
|
||||
"no_pipeline_steps": "Nessuno step disponibile nella pipeline!",
|
||||
"step_not_started": "Questo step non è ancora iniziato.",
|
||||
"config": "Configurazione",
|
||||
"tasks": "Attività",
|
||||
"log_delete_confirm": "Vuoi davvero eliminare i registri attività di questo step?",
|
||||
"errors": "Errori ({count})",
|
||||
"errors": "Errori",
|
||||
"protected": {
|
||||
"awaits": "Questa pipeline è in attesa di approvazione da parte di un manutentore!",
|
||||
"approve": "Approva",
|
||||
|
@ -225,7 +225,7 @@
|
|||
"declined": "rifiutata",
|
||||
"error": "errore"
|
||||
},
|
||||
"warnings": "Avvertenze ({count})",
|
||||
"warnings": "Avvertenze",
|
||||
"show_errors": "Mostra errori",
|
||||
"we_got_some_errors": "Oh no, si sono verificati degli errori!",
|
||||
"event": {
|
||||
|
@ -321,7 +321,7 @@
|
|||
"desc": "Ogni pipeline deve essere approvata prima di essere eseguita."
|
||||
},
|
||||
"save": "Salva impostazioni",
|
||||
"success": "Impostazioni della repository aggiornate",
|
||||
"success": "Impostazioni del progetto aggiornate",
|
||||
"timeout": {
|
||||
"minutes": "minuti",
|
||||
"timeout": "Scadenza"
|
||||
|
@ -342,24 +342,36 @@
|
|||
"visibility": "Visibilità progetto"
|
||||
},
|
||||
"cancel_prev": {
|
||||
"desc": "Consente di annullare le pipeline in sospeso e in esecuzione dello stesso evento e contesto prima di avviare quella appena attivata.",
|
||||
"desc": "I trigger di evento selezionati annulleranno le pipeline in sospeso e in esecuzione dello stesso evento prima di avviare quello più recente.",
|
||||
"cancel": "Annulla pipeline precedenti"
|
||||
},
|
||||
"trusted": {
|
||||
"desc": "I container eseguiti dalle pipeline ottengono accesso a funzionalità avanzate (come il montaggio di volumi).",
|
||||
"trusted": "Attendibile"
|
||||
"trusted": "Attendibile",
|
||||
"network": {
|
||||
"network": "Rete",
|
||||
"desc": "I container di pipeline ottengono l'accesso ai privilegi di rete, come la modifica del DNS."
|
||||
},
|
||||
"volumes": {
|
||||
"volumes": "Volumi",
|
||||
"desc": "I container di pipeline possono montare volumi."
|
||||
},
|
||||
"security": {
|
||||
"security": "Sicurezza",
|
||||
"desc": "I container di pipeline ottengono l'accesso ai privilegi di sicurezza."
|
||||
}
|
||||
},
|
||||
"allow_pr": {
|
||||
"allow": "Consenti Richieste di Modifica",
|
||||
"desc": "Le pipeline possono essere eseguite su richieste di modifica."
|
||||
"desc": "Consenti l'esecuzione di pipeline sulle richieste di modifica."
|
||||
},
|
||||
"allow_deploy": {
|
||||
"allow": "Consenti deployment",
|
||||
"desc": "Consenti deployment da pipeline completate con successo. Utilizza solo se ti fidi di tutti gli utenti con accesso push."
|
||||
"allow": "Consenti eventi di 'distribuzione'.",
|
||||
"desc": "Consenti 'distribuzione' per le pipeline riuscite. Tutti gli utenti con autorizzazioni push possono attivarli, da usare con cautela."
|
||||
},
|
||||
"netrc_only_trusted": {
|
||||
"netrc_only_trusted": "Inietta le credenziali netrc solo nei container attendibili",
|
||||
"desc": "Inietta le credenziali netrc solo nei contenitori attendibili (consigliato)."
|
||||
"netrc_only_trusted": "Estensioni personalizzate affidabili per clone",
|
||||
"desc": "Le estensioni elencate qui avranno accesso alle credenziali netrc che possono essere utilizzate per clonare i repository dal forge o inviarvi il push."
|
||||
}
|
||||
},
|
||||
"not_allowed": "Non ti è consentito accedere alle impostazioni di questa repository",
|
||||
|
@ -395,14 +407,30 @@
|
|||
"branch": "Ramo"
|
||||
}
|
||||
},
|
||||
"user_none": "L'organizzazione / utente non ha ancora alcun progetto."
|
||||
"user_none": "L'organizzazione / utente non ha ancora alcun progetto.",
|
||||
"visibility": {
|
||||
"visibility": "Visibilità progetto",
|
||||
"public": {
|
||||
"public": "Pubblico",
|
||||
"desc": "Ogni utente può vedere il tuo progetto senza aver effettuato l'accesso."
|
||||
},
|
||||
"private": {
|
||||
"private": "Privato",
|
||||
"desc": "Solo tu e gli altri proprietari del repository possono visualizzare questo progetto."
|
||||
},
|
||||
"internal": {
|
||||
"internal": "Interno",
|
||||
"desc": "Solo gli utenti autenticati dell'istanza di Woodpecker possono visualizzare questo progetto."
|
||||
}
|
||||
}
|
||||
},
|
||||
"repos": "Repository",
|
||||
"repositories": "Repository",
|
||||
"search": "Cerca…",
|
||||
"time": {
|
||||
"not_started": "non ancora iniziato",
|
||||
"template": "MMM D, YYYY, HH:mm z"
|
||||
"template": "MMM D, YYYY, HH:mm z",
|
||||
"just_now": "poco fa"
|
||||
},
|
||||
"unknown_error": "Si è verificato un errore sconosciuto",
|
||||
"url": "URL",
|
||||
|
@ -528,5 +556,16 @@
|
|||
"saved": "Credenziali di registro salvate",
|
||||
"deleted": "Credenziali di registro eliminate"
|
||||
},
|
||||
"login_with": "Accedi con {forge}"
|
||||
"login_with": "Accedi con {forge}",
|
||||
"all_repositories": "Tutti i repository",
|
||||
"no_search_results": "Nessun risultato trovato",
|
||||
"require_approval": {
|
||||
"forks": "Richieste di modifica dal repository derivato",
|
||||
"desc": "Impedisci alle pipeline dannose di esporre segreti o eseguire attività dannose approvandole prima dell'esecuzione.",
|
||||
"require_approval_for": "Requisiti di approvazione",
|
||||
"none": "Nessuno",
|
||||
"pull_requests": "Tutte le richieste di modifica",
|
||||
"all_events": "Tutti gli eventi del forge",
|
||||
"none_desc": "Ogni evento attiva le pipeline, incluse le richieste di modifica. Questa impostazione può essere pericolosa ed è consigliata solo per le istanze private."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,7 +194,8 @@
|
|||
"title": "添加流水线变量",
|
||||
"value": "变量值",
|
||||
"delete": "删除变量"
|
||||
}
|
||||
},
|
||||
"enter_task": "部署任务"
|
||||
},
|
||||
"enable": {
|
||||
"disabled": "已禁用",
|
||||
|
@ -215,7 +216,8 @@
|
|||
"title": "添加流水线变量",
|
||||
"value": "变量值",
|
||||
"delete": "删除变量"
|
||||
}
|
||||
},
|
||||
"show_pipelines": "查看流水线"
|
||||
},
|
||||
"not_allowed": "你没有权限访问这个仓库",
|
||||
"open_in_forge": "在版本控制系统中打开",
|
||||
|
@ -436,7 +438,22 @@
|
|||
},
|
||||
"settings": "设置"
|
||||
},
|
||||
"user_none": "此组织/用户还没有任何仓库。"
|
||||
"user_none": "此组织/用户还没有任何仓库。",
|
||||
"visibility": {
|
||||
"visibility": "项目可见性",
|
||||
"public": {
|
||||
"desc": "任何无需登录的用户均可以看到你的项目。",
|
||||
"public": "公共的"
|
||||
},
|
||||
"private": {
|
||||
"private": "私有的",
|
||||
"desc": "只有你和其他仓库拥有者才能看到这个项目。"
|
||||
},
|
||||
"internal": {
|
||||
"internal": "内部的",
|
||||
"desc": "只有Woodpecker的登录用户可以看到这个项目。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repos": "仓库",
|
||||
"repositories": "仓库",
|
||||
|
@ -527,5 +544,6 @@
|
|||
"cli_login_failed": "登录到 CLI 失败",
|
||||
"cli_login_denied": "登录 CLI 被拒绝",
|
||||
"login_to_cli_description": "点击继续以登录到 CLI。",
|
||||
"return_to_cli": "您现在可以关闭此选项卡并返回 CLI。"
|
||||
"return_to_cli": "您现在可以关闭此选项卡并返回 CLI。",
|
||||
"login_with": "使用 {forge} 登录"
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
<template>
|
||||
<span class="text-xs font-medium inline-flex">
|
||||
<span
|
||||
class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full"
|
||||
class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full flex items-center"
|
||||
:class="{
|
||||
'rounded-r-full pr-2': value === undefined,
|
||||
}"
|
||||
>
|
||||
{{ label }}
|
||||
</span>
|
||||
<span v-if="value !== undefined" class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full">
|
||||
<span
|
||||
v-if="value !== undefined"
|
||||
class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full flex items-center"
|
||||
>
|
||||
{{ value }}
|
||||
</span>
|
||||
</span>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<Panel>
|
||||
<div class="flex flex-col border-b mb-4 pb-4 justify-center dark:border-wp-background-100">
|
||||
<h1 class="text-xl text-wp-text-100 flex items-center gap-1">
|
||||
{{ title }}
|
||||
<DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" />
|
||||
</h1>
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-xl text-wp-text-100 flex items-center gap-1">
|
||||
{{ title }}
|
||||
<DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" />
|
||||
</h1>
|
||||
<slot v-if="$slots.titleActions" name="titleActions" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-x-4 gap-y-2 items-center justify-between">
|
||||
<p v-if="description" class="text-sm text-wp-text-alt-100">{{ description }}</p>
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<Scaffold v-if="org" enable-tabs :go-back="goBack">
|
||||
<template #title>
|
||||
<span>
|
||||
<router-link :to="{ name: 'org' }" class="hover:underline">
|
||||
{{ org.name }}
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'org' }" class="hover:underline">{{
|
||||
org.name
|
||||
/* eslint-disable-next-line @intlify/vue-i18n/no-raw-text */
|
||||
}}</router-link>
|
||||
/
|
||||
{{ $t('settings') }}
|
||||
</span>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Settings :title="$t('repo.settings.badge.badge')">
|
||||
<template #headerActions>
|
||||
<template #titleActions>
|
||||
<a v-if="badgeUrl" :href="badgeUrl" target="_blank">
|
||||
<img :src="badgeUrl" />
|
||||
</a>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</InputField>
|
||||
|
||||
<InputField :label="$t('user.settings.cli_and_api.token')">
|
||||
<template #headerActions>
|
||||
<template #titleActions>
|
||||
<Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" />
|
||||
</template>
|
||||
<pre class="code-box">{{ token }}</pre>
|
||||
|
|
|
@ -34,6 +34,15 @@ const (
|
|||
// pathVersion = "%s/version"
|
||||
)
|
||||
|
||||
type ClientError struct {
|
||||
StatusCode int
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ClientError) Error() string {
|
||||
return fmt.Sprintf("client error %d: %s", e.StatusCode, e.Message)
|
||||
}
|
||||
|
||||
type client struct {
|
||||
client *http.Client
|
||||
addr string
|
||||
|
@ -140,7 +149,10 @@ func (c *client) open(rawURL, method string, in any) (io.ReadCloser, error) {
|
|||
if resp.StatusCode > http.StatusPartialContent {
|
||||
defer resp.Body.Close()
|
||||
out, _ := io.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf("client error %d: %s", resp.StatusCode, string(out))
|
||||
return nil, &ClientError{
|
||||
StatusCode: resp.StatusCode,
|
||||
Message: string(out),
|
||||
}
|
||||
}
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ func (_m *Client) AgentDelete(_a0 int64) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// AgentList provides a mock function with given fields:
|
||||
// AgentList provides a mock function with no fields
|
||||
func (_m *Client) AgentList() ([]*woodpecker.Agent, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -629,7 +629,7 @@ func (_m *Client) GlobalSecretUpdate(secret *woodpecker.Secret) (*woodpecker.Sec
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// LogLevel provides a mock function with given fields:
|
||||
// LogLevel provides a mock function with no fields
|
||||
func (_m *Client) LogLevel() (*woodpecker.LogLevel, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ func (_m *Client) PipelineMetadata(repoID int64, pipelineNumber int) ([]byte, er
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// PipelineQueue provides a mock function with given fields:
|
||||
// PipelineQueue provides a mock function with no fields
|
||||
func (_m *Client) PipelineQueue() ([]*woodpecker.Feed, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1319,7 +1319,7 @@ func (_m *Client) PipelineStop(repoID int64, pipeline int64) error {
|
|||
return r0
|
||||
}
|
||||
|
||||
// QueueInfo provides a mock function with given fields:
|
||||
// QueueInfo provides a mock function with no fields
|
||||
func (_m *Client) QueueInfo() (*woodpecker.Info, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
@ -1859,7 +1859,7 @@ func (_m *Client) SecretUpdate(repoID int64, secret *woodpecker.Secret) (*woodpe
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// Self provides a mock function with given fields:
|
||||
// Self provides a mock function with no fields
|
||||
func (_m *Client) Self() (*woodpecker.User, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -31,8 +32,12 @@ const (
|
|||
|
||||
type PipelineListOptions struct {
|
||||
ListOptions
|
||||
Before time.Time
|
||||
After time.Time
|
||||
Before time.Time
|
||||
After time.Time
|
||||
Branch string
|
||||
Events []string
|
||||
RefContains string
|
||||
Status string
|
||||
}
|
||||
|
||||
type CronListOptions struct {
|
||||
|
@ -77,6 +82,18 @@ func (opt *PipelineListOptions) QueryEncode() string {
|
|||
if !opt.After.IsZero() {
|
||||
query.Add("after", opt.After.Format(time.RFC3339))
|
||||
}
|
||||
if opt.Branch != "" {
|
||||
query.Add("branch", opt.Branch)
|
||||
}
|
||||
if len(opt.Events) > 0 {
|
||||
query.Add("event", strings.Join(opt.Events, ","))
|
||||
}
|
||||
if opt.RefContains != "" {
|
||||
query.Add("ref", opt.RefContains)
|
||||
}
|
||||
if opt.Status != "" {
|
||||
query.Add("status", opt.Status)
|
||||
}
|
||||
return query.Encode()
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ type (
|
|||
RepoPatch struct {
|
||||
Config *string `json:"config_file,omitempty"`
|
||||
IsTrusted *bool `json:"trusted,omitempty"`
|
||||
IsGated *bool `json:"gated,omitempty"` // TODO: remove in next major release
|
||||
RequireApproval *ApprovalMode `json:"require_approval,omitempty"`
|
||||
Timeout *int64 `json:"timeout,omitempty"`
|
||||
Visibility *string `json:"visibility"`
|
||||
|
|
Loading…
Reference in a new issue