mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-06-02 13:39:55 +00:00
Merge branch 'main' into auth-id-token
This commit is contained in:
commit
25e34a30d0
213
.cspell.json
213
.cspell.json
|
@ -2,118 +2,139 @@
|
|||
"version": "0.2",
|
||||
"language": "en",
|
||||
"words": [
|
||||
"ciphertext",
|
||||
"evenodd",
|
||||
"gitea",
|
||||
"gonic",
|
||||
"BUILDPLATFORM",
|
||||
"Codeberg",
|
||||
"Curr",
|
||||
"DATASOURCE",
|
||||
"Debugf",
|
||||
"Fediverse",
|
||||
"Fogas",
|
||||
"GOARCH",
|
||||
"GOBIN",
|
||||
"GODEBUG",
|
||||
"GOPATH",
|
||||
"Georgiana",
|
||||
"HEALTHCHECK",
|
||||
"HTTPFS",
|
||||
"Hetzner",
|
||||
"Infof",
|
||||
"Ionescu",
|
||||
"Kaniko",
|
||||
"Keyfunc",
|
||||
"Laszlo",
|
||||
"Msgf",
|
||||
"Netrc",
|
||||
"prismjs",
|
||||
"rawurl",
|
||||
"PROTOC",
|
||||
"Pinia",
|
||||
"Println",
|
||||
"Refspec",
|
||||
"Reviewdog",
|
||||
"Rydzewski",
|
||||
"TARGETARCH",
|
||||
"TARGETOS",
|
||||
"Upsert",
|
||||
"WORKDIR",
|
||||
"Warnf",
|
||||
"Weblate",
|
||||
"Wrapf",
|
||||
"anbraten",
|
||||
"autoincr",
|
||||
"autoscaler",
|
||||
"binutils",
|
||||
"bitbucketdatacenter",
|
||||
"bradrydzewski",
|
||||
"brightbox",
|
||||
"buildx",
|
||||
"ccmenu",
|
||||
"charmbracelet",
|
||||
"ciphertext",
|
||||
"compatiblelicenses",
|
||||
"corepack",
|
||||
"creativecommons",
|
||||
"datacenter",
|
||||
"desaturate",
|
||||
"devx",
|
||||
"doublestar",
|
||||
"envsubst",
|
||||
"estree",
|
||||
"evenodd",
|
||||
"excalidraw",
|
||||
"favicons",
|
||||
"fsnotify",
|
||||
"gitea",
|
||||
"golangci",
|
||||
"gomod",
|
||||
"gonic",
|
||||
"httpsig",
|
||||
"httputil",
|
||||
"iconify",
|
||||
"intlify",
|
||||
"kyvg",
|
||||
"laszlocph",
|
||||
"logfile",
|
||||
"loglevel",
|
||||
"markdownlint",
|
||||
"multiarch",
|
||||
"multierr",
|
||||
"netdns",
|
||||
"nfpm",
|
||||
"nixos",
|
||||
"nocolor",
|
||||
"nolint",
|
||||
"octocat",
|
||||
"posix",
|
||||
"ppid",
|
||||
"prismjs",
|
||||
"proto",
|
||||
"protoc",
|
||||
"rawurl",
|
||||
"repology",
|
||||
"securecookie",
|
||||
"sess",
|
||||
"stepbuilder",
|
||||
"stretchr",
|
||||
"sublicensable",
|
||||
"techknowlogick",
|
||||
"testdata",
|
||||
"tink",
|
||||
"tinycolor",
|
||||
"typecheck",
|
||||
"unplugin",
|
||||
"urfave",
|
||||
"varchar",
|
||||
"vite",
|
||||
"vitejs",
|
||||
"vueuse",
|
||||
"waivable",
|
||||
"windi",
|
||||
"windicss",
|
||||
"woodpeckerci",
|
||||
"xlog",
|
||||
"xorm",
|
||||
"xormigrate",
|
||||
"zerolog",
|
||||
"Msgf",
|
||||
"varchar",
|
||||
"autoincr",
|
||||
"stretchr",
|
||||
"bradrydzewski",
|
||||
"octocat",
|
||||
"brightbox",
|
||||
"anbraten",
|
||||
"Codeberg",
|
||||
"Fediverse",
|
||||
"Weblate",
|
||||
"Hetzner",
|
||||
"windi",
|
||||
"intlify",
|
||||
"unplugin",
|
||||
"Pinia",
|
||||
"woodpeckerci",
|
||||
"tinycolor",
|
||||
"favicons",
|
||||
"Laszlo",
|
||||
"Fogas",
|
||||
"Georgiana",
|
||||
"Ionescu",
|
||||
"typecheck",
|
||||
"HTTPFS",
|
||||
"Println",
|
||||
"ppid",
|
||||
"xlog",
|
||||
"Debugf",
|
||||
"Warnf",
|
||||
"Infof",
|
||||
"Wrapf",
|
||||
"urfave",
|
||||
"creativecommons",
|
||||
"compatiblelicenses",
|
||||
"sublicensable",
|
||||
"waivable",
|
||||
"kyvg",
|
||||
"iconify",
|
||||
"Upsert",
|
||||
"Rydzewski",
|
||||
"fsnotify",
|
||||
"tink",
|
||||
"desaturate",
|
||||
"golangci",
|
||||
"Kaniko",
|
||||
"Reviewdog",
|
||||
"DATASOURCE",
|
||||
"httpsig",
|
||||
"envsubst",
|
||||
"TARGETOS",
|
||||
"TARGETARCH",
|
||||
"GOARCH",
|
||||
"Curr",
|
||||
"doublestar",
|
||||
"multierr",
|
||||
"markdownlint",
|
||||
"buildx",
|
||||
"HEALTHCHECK",
|
||||
"devx",
|
||||
"gomod",
|
||||
"laszlocph",
|
||||
"charmbracelet",
|
||||
"GODEBUG",
|
||||
"netdns",
|
||||
"BUILDPLATFORM",
|
||||
"repology",
|
||||
"WORKDIR",
|
||||
"corepack",
|
||||
"binutils",
|
||||
"nocolor",
|
||||
"logfile",
|
||||
"Keyfunc",
|
||||
"protoc",
|
||||
"PROTOC",
|
||||
"GOBIN",
|
||||
"GOPATH"
|
||||
"zerologger"
|
||||
],
|
||||
"ignorePaths": [
|
||||
"**/node_modules/**/*",
|
||||
"pnpm-lock.yaml",
|
||||
".gitignore",
|
||||
".git/**/*",
|
||||
".cspell.json",
|
||||
".golangci.yaml",
|
||||
".vscode/extensions.json",
|
||||
"web/src/assets/locales/**/*",
|
||||
"web/components.d.ts",
|
||||
"server/store/datastore/migration/**/*",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
"*.excalidraw",
|
||||
"*.svg",
|
||||
"Makefile",
|
||||
// TODO: remove the following
|
||||
".cspell.json",
|
||||
".git/**/*",
|
||||
".gitignore",
|
||||
".golangci.yaml",
|
||||
".vscode/extensions.json",
|
||||
"CHANGELOG.md",
|
||||
"Makefile",
|
||||
"flake.lock",
|
||||
"flake.nix",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
"pnpm-lock.yaml",
|
||||
"server/store/datastore/migration/**/*",
|
||||
"web/components.d.ts",
|
||||
"web/src/assets/locales/**/*",
|
||||
// TODO: remove the following
|
||||
".woodpecker/",
|
||||
"agent/",
|
||||
"cli/",
|
||||
|
|
|
@ -9,7 +9,7 @@ tasks:
|
|||
WOODPECKER_DEV_WWW_PROXY: http://localhost:8010
|
||||
WOODPECKER_BACKEND_DOCKER_NETWORK: ci_default
|
||||
init: |
|
||||
GO_VERSION=1.21.5
|
||||
GO_VERSION=1.22
|
||||
rm -rf ~/go
|
||||
curl -fsSL https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz | tar xzs -C ~/
|
||||
go mod tidy
|
||||
|
|
|
@ -108,7 +108,7 @@ linters-settings:
|
|||
- standard
|
||||
- default
|
||||
- prefix(go.woodpecker-ci.org/woodpecker)
|
||||
gomnd:
|
||||
mnd:
|
||||
ignored-numbers:
|
||||
- '0o600'
|
||||
- '0o660'
|
||||
|
@ -121,6 +121,13 @@ linters-settings:
|
|||
- strings.Split
|
||||
- callerName
|
||||
- securecookie.GenerateRandomKey
|
||||
godot:
|
||||
scope: toplevel
|
||||
period: true
|
||||
capital: true
|
||||
exclude:
|
||||
- '^\s*cSpell:'
|
||||
- '^\s*TODO:'
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
|
@ -166,13 +173,14 @@ linters:
|
|||
- contextcheck
|
||||
- forcetypeassert
|
||||
- gci
|
||||
- gomnd
|
||||
- mnd
|
||||
- godot
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: 'fixtures|cmd/agent/flags.go|cmd/server/flags.go|pipeline/backend/kubernetes/flags.go|_test.go'
|
||||
linters:
|
||||
- gomnd
|
||||
- mnd
|
||||
|
||||
run:
|
||||
timeout: 15m
|
||||
|
|
|
@ -10,7 +10,7 @@ repos:
|
|||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.57.2
|
||||
rev: v1.58.1
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
|
@ -55,5 +55,5 @@ ci:
|
|||
autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
|
||||
autoupdate_schedule: quarterly
|
||||
# NB: hadolint not included in pre-commit.ci
|
||||
skip: [check-hooks-apply, check-useless-excludes, hadolint, prettier]
|
||||
skip: [check-hooks-apply, check-useless-excludes, hadolint, prettier, golangci-lint]
|
||||
submodules: false
|
||||
|
|
|
@ -2,10 +2,9 @@ when:
|
|||
event: tag
|
||||
|
||||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22.2'
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:22-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.2'
|
||||
- &xgo_version 'go-1.21.2'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.x'
|
||||
|
||||
steps:
|
||||
build-web:
|
||||
|
@ -34,7 +33,6 @@ steps:
|
|||
environment:
|
||||
PLATFORMS: linux|arm64/v8;linux|amd64;windows|amd64
|
||||
TAGS: bindata sqlite sqlite_unlock_notify netgo
|
||||
XGO_VERSION: *xgo_version
|
||||
TARGZ: '1'
|
||||
|
||||
build-tarball:
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.22.2'
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:22-alpine'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.2'
|
||||
- &xgo_version 'go-1.21.2'
|
||||
- &xgo_image 'docker.io/techknowlogick/xgo:go-1.22.x'
|
||||
- &buildx_plugin 'docker.io/woodpeckerci/plugin-docker-buildx:3.2.1'
|
||||
- &platforms_release 'linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/386,linux/amd64,linux/ppc64le,linux/riscv64,linux/s390x,freebsd/arm64,freebsd/amd64,openbsd/arm64,openbsd/amd64'
|
||||
- &platforms_server 'linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le,linux/riscv64'
|
||||
|
@ -98,7 +97,6 @@ steps:
|
|||
environment:
|
||||
PLATFORMS: linux|amd64
|
||||
TAGS: bindata sqlite sqlite_unlock_notify netgo
|
||||
XGO_VERSION: *xgo_version
|
||||
when:
|
||||
- event: pull_request
|
||||
evaluate: 'CI_COMMIT_PULL_REQUEST_LABELS contains "build_pr_images"'
|
||||
|
@ -121,7 +119,6 @@ steps:
|
|||
environment:
|
||||
PLATFORMS: linux|arm/v7;linux|arm64/v8;linux|amd64;linux|ppc64le;linux|riscv64
|
||||
TAGS: bindata sqlite sqlite_unlock_notify netgo
|
||||
XGO_VERSION: *xgo_version
|
||||
when:
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.21.5'
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &node_image 'docker.io/node:21-alpine'
|
||||
- &alpine_image 'docker.io/alpine:3.19'
|
||||
- path: &when_path
|
||||
|
|
|
@ -18,6 +18,8 @@ steps:
|
|||
commands:
|
||||
- corepack enable
|
||||
- pnpx cspell lint --no-progress --gitignore '{**,.*}/{*,.*}'
|
||||
- apk add --no-cache -U tree # busybox tree dont understand "-I"
|
||||
- tree --gitignore -I 012_columns_rename_procs_to_steps.go -I versioned_docs -I '*opensource.svg'| pnpx cspell lint --no-progress stdin
|
||||
|
||||
- name: prettier
|
||||
image: docker.io/woodpeckerci/plugin-prettier:0.1.0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
variables:
|
||||
- &golang_image 'docker.io/golang:1.21.5'
|
||||
- &golang_image 'docker.io/golang:1.22'
|
||||
- &when
|
||||
- path: &when_path # related config files
|
||||
- '.woodpecker/test.yaml'
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
- Remove contributing/security to use globally defined [[#3192](https://github.com/woodpecker-ci/woodpecker/pull/3192)]
|
||||
- Add "Kaniko" Plugin [[#3183](https://github.com/woodpecker-ci/woodpecker/pull/3183)]
|
||||
- Document core development ideas [[#3184](https://github.com/woodpecker-ci/woodpecker/pull/3184)]
|
||||
- Add continous deployment cookbook [[#3098](https://github.com/woodpecker-ci/woodpecker/pull/3098)]
|
||||
- Add continuous deployment cookbook [[#3098](https://github.com/woodpecker-ci/woodpecker/pull/3098)]
|
||||
- Make k8s backend configuration docs in the same format as others [[#3081](https://github.com/woodpecker-ci/woodpecker/pull/3081)]
|
||||
- Hide backend config options from TOC [[#3126](https://github.com/woodpecker-ci/woodpecker/pull/3126)]
|
||||
- Add X/Twitter account [[#3127](https://github.com/woodpecker-ci/woodpecker/pull/3127)]
|
||||
|
@ -637,7 +637,7 @@
|
|||
- Fix active tab not updating on prop change [[#2712](https://github.com/woodpecker-ci/woodpecker/pull/2712)]
|
||||
- Unique status for matrix [[#2695](https://github.com/woodpecker-ci/woodpecker/pull/2695)]
|
||||
- Fix secret image filter regex [[#2674](https://github.com/woodpecker-ci/woodpecker/pull/2674)]
|
||||
- local backend ignore errors in commands inbetween [[#2636](https://github.com/woodpecker-ci/woodpecker/pull/2636)]
|
||||
- local backend ignore errors in commands in between [[#2636](https://github.com/woodpecker-ci/woodpecker/pull/2636)]
|
||||
- Do not print log level on CLI [[#2638](https://github.com/woodpecker-ci/woodpecker/pull/2638)]
|
||||
- Fix error when closing logs [[#2637](https://github.com/woodpecker-ci/woodpecker/pull/2637)]
|
||||
- Fix `CI_WORKSPACE` in local backend [[#2627](https://github.com/woodpecker-ci/woodpecker/pull/2627)]
|
||||
|
|
4
Makefile
4
Makefile
|
@ -309,6 +309,10 @@ bundle: bundle-agent bundle-server bundle-cli ## Create all bundles
|
|||
.PHONY: spellcheck
|
||||
spellcheck:
|
||||
pnpx cspell lint --no-progress --gitignore '{**,.*}/{*,.*}'
|
||||
tree --gitignore \
|
||||
-I 012_columns_rename_procs_to_steps.go \
|
||||
-I versioned_docs -I '*opensource.svg' | \
|
||||
pnpx cspell lint --no-progress stdin
|
||||
|
||||
##@ Docs
|
||||
.PHONY: docs
|
||||
|
|
|
@ -40,7 +40,7 @@ func NewAuthGrpcClient(conn *grpc.ClientConn, agentToken string, agentID int64)
|
|||
}
|
||||
|
||||
func (c *AuthClient) Auth() (string, int64, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) //nolint: gomnd
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) //nolint:mnd
|
||||
defer cancel()
|
||||
|
||||
req := &proto.AuthRequest{
|
||||
|
|
|
@ -23,13 +23,13 @@ import (
|
|||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
// AuthInterceptor is a client interceptor for authentication
|
||||
// AuthInterceptor is a client interceptor for authentication.
|
||||
type AuthInterceptor struct {
|
||||
authClient *AuthClient
|
||||
accessToken string
|
||||
}
|
||||
|
||||
// NewAuthInterceptor returns a new auth interceptor
|
||||
// NewAuthInterceptor returns a new auth interceptor.
|
||||
func NewAuthInterceptor(
|
||||
authClient *AuthClient,
|
||||
refreshDuration time.Duration,
|
||||
|
@ -46,7 +46,7 @@ func NewAuthInterceptor(
|
|||
return interceptor, nil
|
||||
}
|
||||
|
||||
// Unary returns a client interceptor to authenticate unary RPC
|
||||
// Unary returns a client interceptor to authenticate unary RPC.
|
||||
func (interceptor *AuthInterceptor) Unary() grpc.UnaryClientInterceptor {
|
||||
return func(
|
||||
ctx context.Context,
|
||||
|
@ -60,7 +60,7 @@ func (interceptor *AuthInterceptor) Unary() grpc.UnaryClientInterceptor {
|
|||
}
|
||||
}
|
||||
|
||||
// Stream returns a client interceptor to authenticate stream RPC
|
||||
// Stream returns a client interceptor to authenticate stream RPC.
|
||||
func (interceptor *AuthInterceptor) Stream() grpc.StreamClientInterceptor {
|
||||
return func(
|
||||
ctx context.Context,
|
||||
|
|
|
@ -31,7 +31,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/rpc/proto"
|
||||
)
|
||||
|
||||
// set grpc version on compile time to compare against server version response
|
||||
// Set grpc version on compile time to compare against server version response.
|
||||
const ClientGrpcVersion int32 = proto.Version
|
||||
|
||||
type client struct {
|
||||
|
@ -54,12 +54,12 @@ func (c *client) Close() error {
|
|||
func (c *client) newBackOff() backoff.BackOff {
|
||||
b := backoff.NewExponentialBackOff()
|
||||
b.MaxElapsedTime = 0
|
||||
b.MaxInterval = 10 * time.Second //nolint: gomnd
|
||||
b.InitialInterval = 10 * time.Millisecond //nolint: gomnd
|
||||
b.MaxInterval = 10 * time.Second //nolint:mnd
|
||||
b.InitialInterval = 10 * time.Millisecond //nolint:mnd
|
||||
return b
|
||||
}
|
||||
|
||||
// Version returns the server- & grpc-version
|
||||
// Version returns the server- & grpc-version.
|
||||
func (c *client) Version(ctx context.Context) (*rpc.Version, error) {
|
||||
res, err := c.client.Version(ctx, &proto.Empty{})
|
||||
if err != nil {
|
||||
|
@ -242,7 +242,7 @@ func (c *client) Done(ctx context.Context, id string, state rpc.State) (err erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// Extend extends the workflow deadline
|
||||
// Extend extends the workflow deadline.
|
||||
func (c *client) Extend(ctx context.Context, id string) (err error) {
|
||||
retry := c.newBackOff()
|
||||
req := new(proto.ExtendRequest)
|
||||
|
|
|
@ -198,12 +198,10 @@ func (r *Runner) Run(runnerCtx context.Context) error { //nolint:contextcheck
|
|||
return nil
|
||||
}
|
||||
|
||||
// extract repository name from the configuration
|
||||
func extractRepositoryName(config *backend.Config) string {
|
||||
return config.Stages[0].Steps[0].Environment["CI_REPO"]
|
||||
}
|
||||
|
||||
// extract pipeline number from the configuration
|
||||
func extractPipelineNumber(config *backend.Config) string {
|
||||
return config.Stages[0].Steps[0].Environment["CI_PIPELINE_NUMBER"]
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func (r *Runner) createTracer(ctxmeta context.Context, logger zerolog.Logger, wo
|
|||
StepUUID: state.Pipeline.Step.UUID,
|
||||
Exited: state.Process.Exited,
|
||||
ExitCode: state.Process.ExitCode,
|
||||
Started: time.Now().Unix(), // TODO do not do this
|
||||
Started: time.Now().Unix(), // TODO: do not do this
|
||||
Finished: time.Now().Unix(),
|
||||
}
|
||||
if state.Process.Error != nil {
|
||||
|
|
|
@ -65,7 +65,7 @@ var GlobalFlags = append([]cli.Flag{
|
|||
}, logger.GlobalLoggerFlags...)
|
||||
|
||||
// FormatFlag return format flag with value set based on template
|
||||
// if hidden value is set, flag will be hidden
|
||||
// if hidden value is set, flag will be hidden.
|
||||
func FormatFlag(tmpl string, hidden ...bool) *cli.StringFlag {
|
||||
return &cli.StringFlag{
|
||||
Name: "format",
|
||||
|
|
|
@ -67,7 +67,7 @@ func cronList(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for pipeline list information
|
||||
// tTemplate for pipeline list information.
|
||||
var tmplCronList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
ID: {{ .ID }}
|
||||
Branch: {{ .Branch }}
|
||||
|
|
|
@ -126,7 +126,7 @@ func deploy(c *cli.Context) error {
|
|||
return tmpl.Execute(os.Stdout, deploy)
|
||||
}
|
||||
|
||||
// template for deployment information
|
||||
// Template for deployment information.
|
||||
var tmplDeployInfo = `Number: {{ .Number }}
|
||||
Status: {{ .Status }}
|
||||
Commit: {{ .Commit }}
|
||||
|
|
|
@ -263,7 +263,7 @@ func convertPathForWindows(path string) string {
|
|||
base := filepath.VolumeName(path)
|
||||
|
||||
// Check if path is volume name like C:
|
||||
//nolint: gomnd
|
||||
//nolint:mnd
|
||||
if len(base) == 2 {
|
||||
path = strings.TrimPrefix(path, base)
|
||||
base = strings.ToLower(strings.TrimSuffix(base, ":"))
|
||||
|
|
|
@ -52,6 +52,6 @@ func info(c *cli.Context) error {
|
|||
return tmpl.Execute(os.Stdout, user)
|
||||
}
|
||||
|
||||
// template for user information
|
||||
// Template for user information.
|
||||
var tmplInfo = `User: {{ .Login }}
|
||||
Email: {{ .Email }}`
|
||||
|
|
|
@ -45,7 +45,7 @@ func logPurge(c *cli.Context) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
stepArg := c.Args().Get(2) //nolint: gomnd
|
||||
stepArg := c.Args().Get(2) //nolint:mnd
|
||||
// TODO: Add lookup by name: stepID, err := internal.ParseStep(client, repoID, stepIDOrName)
|
||||
var stepID int64
|
||||
if len(stepArg) != 0 {
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
|
||||
)
|
||||
|
||||
//nolint:gomnd
|
||||
//nolint:mnd
|
||||
var pipelineListCmd = &cli.Command{
|
||||
Name: "ls",
|
||||
Usage: "show pipeline history",
|
||||
|
|
|
@ -83,7 +83,7 @@ func pipelinePs(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for pipeline ps information
|
||||
// Template for pipeline ps information.
|
||||
var tmplPipelinePs = "\x1b[33mStep #{{ .PID }} \x1b[0m" + `
|
||||
Step: {{ .Name }}
|
||||
State: {{ .State }}
|
||||
|
|
|
@ -62,7 +62,7 @@ func pipelineQueue(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for pipeline list information
|
||||
// Template for pipeline list information.
|
||||
var tmplPipelineQueue = "\x1b[33m{{ .FullName }} #{{ .Number }} \x1b[0m" + `
|
||||
Status: {{ .Status }}
|
||||
Event: {{ .Event }}
|
||||
|
|
|
@ -67,7 +67,7 @@ func registryList(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for registry list information
|
||||
// Template for registry list information.
|
||||
var tmplRegistryList = "\x1b[33m{{ .Address }} \x1b[0m" + `
|
||||
Username: {{ .Username }}
|
||||
Email: {{ .Email }}
|
||||
|
|
|
@ -55,7 +55,7 @@ func repoInfo(c *cli.Context) error {
|
|||
return tmpl.Execute(os.Stdout, repo)
|
||||
}
|
||||
|
||||
// template for repo information
|
||||
// tTemplate for repo information.
|
||||
var tmplRepoInfo = `Owner: {{ .Owner }}
|
||||
Repo: {{ .Name }}
|
||||
URL: {{ .ForgeURL }}
|
||||
|
|
|
@ -66,5 +66,5 @@ func repoList(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for repository list items
|
||||
// Template for repository list items.
|
||||
var tmplRepoList = "\x1b[33m{{ .FullName }}\x1b[0m (id: {{ .ID }}, forgeRemoteID: {{ .ForgeRemoteID }})"
|
||||
|
|
|
@ -86,7 +86,7 @@ func secretList(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for secret list items
|
||||
// Template for secret list items.
|
||||
var tmplSecretList = "\x1b[33m{{ .Name }} \x1b[0m" + `
|
||||
Events: {{ list .Events }}
|
||||
{{- if .Images }}
|
||||
|
|
|
@ -56,6 +56,6 @@ func userInfo(c *cli.Context) error {
|
|||
return tmpl.Execute(os.Stdout, user)
|
||||
}
|
||||
|
||||
// template for user information
|
||||
// Template for user information.
|
||||
var tmplUserInfo = `User: {{ .Login }}
|
||||
Email: {{ .Email }}`
|
||||
|
|
|
@ -55,5 +55,5 @@ func userList(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// template for user list items
|
||||
// Template for user list items.
|
||||
var tmplUserList = `{{ .Login }}`
|
||||
|
|
|
@ -89,7 +89,7 @@ func run(c *cli.Context, backends []types.Backend) error {
|
|||
|
||||
agentToken := c.String("grpc-token")
|
||||
authClient := agentRpc.NewAuthGrpcClient(authConn, agentToken, agentConfig.AgentID)
|
||||
authInterceptor, err := agentRpc.NewAuthInterceptor(authClient, 30*time.Minute) //nolint: gomnd
|
||||
authInterceptor, err := agentRpc.NewAuthInterceptor(authClient, 30*time.Minute) //nolint:mnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
//nolint:gomnd
|
||||
//nolint:mnd
|
||||
var flags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
EnvVars: []string{"WOODPECKER_SERVER"},
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/version"
|
||||
)
|
||||
|
||||
// the file implements some basic healthcheck logic based on the
|
||||
// The file implements some basic healthcheck logic based on the
|
||||
// following specification:
|
||||
// https://github.com/mozilla-services/Dockerflow
|
||||
|
||||
|
@ -74,7 +74,7 @@ type versionResp struct {
|
|||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
// default statistics counter
|
||||
// Default statistics counter.
|
||||
var counter = &agent.State{
|
||||
Metadata: map[string]agent.Info{},
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package core
|
|||
import (
|
||||
"os"
|
||||
|
||||
// Load config from .env
|
||||
// Load config from .env file.
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
|
|
@ -273,6 +273,12 @@ var flags = append([]cli.Flag{
|
|||
Usage: "how many seconds before timeout when fetching the Woodpecker configuration from a Forge",
|
||||
Value: time.Second * 3,
|
||||
},
|
||||
&cli.UintFlag{
|
||||
EnvVars: []string{"WOODPECKER_FORGE_RETRY"},
|
||||
Name: "forge-retry",
|
||||
Usage: "How many retries of fetching the Woodpecker configuration from a forge are done before we fail",
|
||||
Value: 3,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
EnvVars: []string{"WOODPECKER_LIMIT_MEM_SWAP"},
|
||||
Name: "limit-mem-swap",
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/version"
|
||||
)
|
||||
|
||||
// generate docs/swagger.json via:
|
||||
// Generate docs/swagger.json via:
|
||||
//go:generate go run woodpecker_docs_gen.go swagger.go
|
||||
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@latest validate ../../docs/swagger.json
|
||||
|
||||
|
|
|
@ -525,6 +525,12 @@ Specify a configuration service endpoint, see [Configuration Extension](./100-ex
|
|||
|
||||
Specify timeout when fetching the Woodpecker configuration from forge. See <https://pkg.go.dev/time#ParseDuration> for syntax reference.
|
||||
|
||||
### `WOODPECKER_FORGE_RETRY`
|
||||
|
||||
> Default: 3
|
||||
|
||||
Specify how many retries of fetching the Woodpecker configuration from a forge are done before we fail.
|
||||
|
||||
### `WOODPECKER_ENABLE_SWAGGER`
|
||||
|
||||
> Default: true
|
||||
|
|
|
@ -4,19 +4,19 @@ toc_max_heading_level: 2
|
|||
|
||||
# Kubernetes backend
|
||||
|
||||
The kubernetes backend executes steps inside standalone pods. A temporary PVC is created for the lifetime of the pipeline to transfer files between steps.
|
||||
The Kubernetes backend executes steps inside standalone Pods. A temporary PVC is created for the lifetime of the pipeline to transfer files between steps.
|
||||
|
||||
## Images from private registries
|
||||
|
||||
In order to pull private container images defined in your pipeline YAML you must provide [registry credentials in Kubernetes secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).
|
||||
As the secret is Agent-wide, it has to be placed in namespace defined by `WOODPECKER_BACKEND_K8S_NAMESPACE`.
|
||||
Besides, you need to provide the secret name to Agent via `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES`.
|
||||
In order to pull private container images defined in your pipeline YAML you must provide [registry credentials in Kubernetes Secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).
|
||||
As the Secret is Agent-wide, it has to be placed in namespace defined by `WOODPECKER_BACKEND_K8S_NAMESPACE`.
|
||||
Besides, you need to provide the Secret name to Agent via `WOODPECKER_BACKEND_K8S_PULL_SECRET_NAMES`.
|
||||
|
||||
## Job specific configuration
|
||||
|
||||
### Resources
|
||||
|
||||
The kubernetes backend also allows for specifying requests and limits on a per-step basic, most commonly for CPU and memory.
|
||||
The Kubernetes backend also allows for specifying requests and limits on a per-step basic, most commonly for CPU and memory.
|
||||
We recommend to add a `resources` definition to all steps to ensure efficient scheduling.
|
||||
|
||||
Here is an example definition with an arbitrary `resources` definition below the `backend_options` section:
|
||||
|
@ -42,13 +42,13 @@ You can use [Limit Ranges](https://kubernetes.io/docs/concepts/policy/limit-rang
|
|||
|
||||
### Runtime class
|
||||
|
||||
`runtimeClassName` specifies the name of the RuntimeClass which will be used to run this pod. If no `runtimeClassName` is specified, the default RuntimeHandler will be used.
|
||||
See the [kubernetes documentation](https://kubernetes.io/docs/concepts/containers/runtime-class/) for more information on specifying runtime classes.
|
||||
`runtimeClassName` specifies the name of the RuntimeClass which will be used to run this Pod. If no `runtimeClassName` is specified, the default RuntimeHandler will be used.
|
||||
See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/runtime-class/) for more information on specifying runtime classes.
|
||||
|
||||
### Service account
|
||||
|
||||
`serviceAccountName` specifies the name of the ServiceAccount which the pod will mount. This service account must be created externally.
|
||||
See the [kubernetes documentation](https://kubernetes.io/docs/concepts/security/service-accounts/) for more information on using service accounts.
|
||||
`serviceAccountName` specifies the name of the ServiceAccount which the Pod will mount. This service account must be created externally.
|
||||
See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/security/service-accounts/) for more information on using service accounts.
|
||||
|
||||
### Node selector
|
||||
|
||||
|
@ -83,8 +83,8 @@ You can use [PodNodeSelector](https://kubernetes.io/docs/reference/access-authn-
|
|||
|
||||
### Tolerations
|
||||
|
||||
When you use `nodeSelector` and the node pool is configured with Taints, you need to specify the Tolerations. Tolerations allow the scheduler to schedule pods with matching taints.
|
||||
See the [kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for more information on using tolerations.
|
||||
When you use `nodeSelector` and the node pool is configured with Taints, you need to specify the Tolerations. Tolerations allow the scheduler to schedule Pods with matching taints.
|
||||
See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for more information on using tolerations.
|
||||
|
||||
Example pipeline configuration:
|
||||
|
||||
|
@ -117,7 +117,7 @@ steps:
|
|||
|
||||
### Volumes
|
||||
|
||||
To mount volumes a persistent volume (PV) and persistent volume claim (PVC) are needed on the cluster which can be referenced in steps via the `volumes` option.
|
||||
To mount volumes a PersistentVolume (PV) and PersistentVolumeClaim (PVC) are needed on the cluster which can be referenced in steps via the `volumes` option.
|
||||
Assuming a PVC named `woodpecker-cache` exists, it can be referenced as follows in a step:
|
||||
|
||||
```yaml
|
||||
|
@ -134,7 +134,7 @@ steps:
|
|||
|
||||
### Security context
|
||||
|
||||
Use the following configuration to set the [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for the pod/container running a given pipeline step:
|
||||
Use the following configuration to set the [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for the Pod/container running a given pipeline step:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
|
@ -151,9 +151,9 @@ steps:
|
|||
[...]
|
||||
```
|
||||
|
||||
Note that the `backend_options.kubernetes.securityContext` object allows you to set both pod and container level security context options in one object.
|
||||
By default, the properties will be set at the pod level. Properties that are only supported on the container level will be set there instead. So, the
|
||||
configuration shown above will result in something like the following pod spec:
|
||||
Note that the `backend_options.kubernetes.securityContext` object allows you to set both Pod and container level security context options in one object.
|
||||
By default, the properties will be set at the Pod level. Properties that are only supported on the container level will be set there instead. So, the
|
||||
configuration shown above will result in something like the following Pod spec:
|
||||
|
||||
```yaml
|
||||
kind: Pod
|
||||
|
@ -195,6 +195,24 @@ backend_options:
|
|||
AppArmor syntax follows [KEP-24](https://github.com/kubernetes/enhancements/blob/fddcbb9cbf3df39ded03bad71228265ac6e5215f/keps/sig-node/24-apparmor/README.md).
|
||||
:::
|
||||
|
||||
### Annotations and labels
|
||||
|
||||
You can specify arbitrary [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) and [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) to be set on the Pod definition for a given workflow step using the following configuration:
|
||||
|
||||
```yaml
|
||||
backend_options:
|
||||
kubernetes:
|
||||
annotations:
|
||||
workflow-group: alpha
|
||||
io.kubernetes.cri-o.Devices: /dev/fuse
|
||||
labels:
|
||||
environment: ci
|
||||
app.kubernetes.io/name: builder
|
||||
```
|
||||
|
||||
In order to enable this configuration you need to set the appropriate environment variables to `true` on the woodpecker agent:
|
||||
[WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS_ALLOW_FROM_STEP](#woodpecker_backend_k8s_pod_annotations_allow_from_step) and/or [WOODPECKER_BACKEND_K8S_POD_LABELS_ALLOW_FROM_STEP](#woodpecker_backend_k8s_pod_labels_allow_from_step).
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
### CRI-O
|
||||
|
@ -217,7 +235,7 @@ These env vars can be set in the `env:` sections of the agent.
|
|||
|
||||
> Default: `woodpecker`
|
||||
|
||||
The namespace to create worker pods in.
|
||||
The namespace to create worker Pods in.
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_VOLUME_SIZE`
|
||||
|
||||
|
@ -241,13 +259,25 @@ Determines if `RWX` should be used for the pipeline volume's [access mode](https
|
|||
|
||||
> Default: empty
|
||||
|
||||
Additional labels to apply to worker pods. Must be a YAML object, e.g. `{"example.com/test-label":"test-value"}`.
|
||||
Additional labels to apply to worker Pods. Must be a YAML object, e.g. `{"example.com/test-label":"test-value"}`.
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_POD_LABELS_ALLOW_FROM_STEP`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Determines if additional Pod labels can be defined from a step's backend options.
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS`
|
||||
|
||||
> Default: empty
|
||||
|
||||
Additional annotations to apply to worker pods. Must be a YAML object, e.g. `{"example.com/test-annotation":"test-value"}`.
|
||||
Additional annotations to apply to worker Pods. Must be a YAML object, e.g. `{"example.com/test-annotation":"test-value"}`.
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_POD_ANNOTATIONS_ALLOW_FROM_STEP`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Determines if Pod annotations can be defined from a step's backend options.
|
||||
|
||||
### `WOODPECKER_BACKEND_K8S_SECCTX_NONROOT`
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ If you have some missing resources, please feel free to [open a pull-request](ht
|
|||
|
||||
- [Setup Gitea with Woodpecker CI](https://containers.fan/posts/setup-gitea-with-woodpecker-ci/)
|
||||
- [Step-by-step guide to modern, secure and Open-source CI setup](https://devforth.io/blog/step-by-step-guide-to-modern-secure-ci-setup/)
|
||||
- [Using Woodpecker CI for my static sites](https://jan.wildeboer.net/2022/07/Woodpecker-CI-Jekyll/)
|
||||
- [Using Woodpecker CI for my static sites](https://web.archive.org/web/20240212182516/https://jan.wildeboer.net/2022/07/Woodpecker-CI-Jekyll/)
|
||||
- [Woodpecker CI @ Codeberg](https://www.sarkasti.eu/articles/post/woodpecker/)
|
||||
- [Deploy Docker/Compose using Woodpecker CI](https://hinty.io/vverenko/deploy-docker-compose-using-woodpecker-ci/)
|
||||
- [Installing Woodpecker CI in your personal homelab](https://pwa.io/articles/installing-woodpecker-in-your-homelab/)
|
||||
|
|
|
@ -209,6 +209,11 @@
|
|||
"name": "Twine",
|
||||
"docs": "https://gitea.elara.ws/music-kraken/plugin-twine/raw/branch/master/docs.md",
|
||||
"verified": false
|
||||
},
|
||||
{
|
||||
"name": "Gitea Package",
|
||||
"docs": "https://gitea.ocram85.com/plugins/gitea-package/raw/branch/main/docs.md",
|
||||
"verified": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
61
flake.lock
Normal file
61
flake.lock
Normal file
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1715614915,
|
||||
"narHash": "sha256-O6sqpppOtlfgx6PK5bnkAvBudK1rpjP7ig0dj7HvIl0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d2ed14aa4f912254c578fc19b842f2910c9146be",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "master",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
38
flake.nix
Normal file
38
flake.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
# Override nixpkgs to use the latest set of node packages
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/master";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
# generic
|
||||
gnumake
|
||||
gnutar
|
||||
|
||||
# frontend
|
||||
nodejs
|
||||
nodePackages.pnpm
|
||||
nodePackages.typescript
|
||||
nodePackages.typescript-language-server
|
||||
|
||||
# backend
|
||||
go
|
||||
gofumpt
|
||||
golangci-lint
|
||||
go-mockery
|
||||
protobuf
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
|
@ -22,7 +22,7 @@ import (
|
|||
)
|
||||
|
||||
// generateScriptPosix is a helper function that generates a step script
|
||||
// for a linux container using the given
|
||||
// for a linux container using the given.
|
||||
func generateScriptPosix(commands []string) string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
backend "go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
)
|
||||
|
||||
// BackendOptions defines all the advanced options for the kubernetes backend
|
||||
// BackendOptions defines all the advanced options for the kubernetes backend.
|
||||
type BackendOptions struct {
|
||||
Resources Resources `mapstructure:"resources"`
|
||||
RuntimeClassName *string `mapstructure:"runtimeClassName"`
|
||||
|
@ -18,13 +18,13 @@ type BackendOptions struct {
|
|||
SecurityContext *SecurityContext `mapstructure:"securityContext"`
|
||||
}
|
||||
|
||||
// Resources defines two maps for kubernetes resource definitions
|
||||
// Resources defines two maps for kubernetes resource definitions.
|
||||
type Resources struct {
|
||||
Requests map[string]string `mapstructure:"requests"`
|
||||
Limits map[string]string `mapstructure:"limits"`
|
||||
}
|
||||
|
||||
// Toleration defines Kubernetes toleration
|
||||
// Toleration defines Kubernetes toleration.
|
||||
type Toleration struct {
|
||||
Key string `mapstructure:"key"`
|
||||
Operator TolerationOperator `mapstructure:"operator"`
|
||||
|
|
|
@ -32,8 +32,7 @@ import (
|
|||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
// To authenticate to GCP K8s clusters
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" // To authenticate to GCP K8s clusters
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
|
@ -42,7 +41,7 @@ import (
|
|||
|
||||
const (
|
||||
EngineName = "kubernetes"
|
||||
// TODO 5 seconds is against best practice, k3s didn't work otherwise
|
||||
// TODO: 5 seconds is against best practice, k3s didn't work otherwise
|
||||
defaultResyncDuration = 5 * time.Second
|
||||
)
|
||||
|
||||
|
@ -268,7 +267,7 @@ func (e *kube) WaitStep(ctx context.Context, step *types.Step, taskUUID string)
|
|||
si.Start(stop)
|
||||
defer close(stop)
|
||||
|
||||
// TODO Cancel on ctx.Done
|
||||
// TODO: Cancel on ctx.Done
|
||||
<-finished
|
||||
|
||||
pod, err := e.client.CoreV1().Pods(e.config.Namespace).Get(ctx, podName, metav1.GetOptions{})
|
||||
|
|
|
@ -268,7 +268,7 @@ func containerPort(port types.Port) v1.ContainerPort {
|
|||
}
|
||||
}
|
||||
|
||||
// Here is the service IPs (placed in /etc/hosts in the Pod)
|
||||
// Here is the service IPs (placed in /etc/hosts in the Pod).
|
||||
func hostAliases(extraHosts []types.HostAlias) []v1.HostAlias {
|
||||
var hostAliases []v1.HostAlias
|
||||
for _, extraHost := range extraHosts {
|
||||
|
|
|
@ -65,7 +65,7 @@ func isImagePullBackOffState(pod *v1.Pod) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// getClientOutOfCluster returns a k8s clientset to the request from outside of cluster
|
||||
// getClientOutOfCluster returns a k8s clientset to the request from outside of cluster.
|
||||
func getClientOutOfCluster() (kubernetes.Interface, error) {
|
||||
kubeConfigPath := os.Getenv("KUBECONFIG")
|
||||
if kubeConfigPath == "" {
|
||||
|
@ -81,7 +81,7 @@ func getClientOutOfCluster() (kubernetes.Interface, error) {
|
|||
return kubernetes.NewForConfig(config)
|
||||
}
|
||||
|
||||
// getClient returns a k8s clientset to the request from inside of cluster
|
||||
// getClient returns a k8s clientset to the request from inside of cluster.
|
||||
func getClientInsideOfCluster() (kubernetes.Interface, error) {
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
|
|
|
@ -30,13 +30,13 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/pipeline/backend/types"
|
||||
)
|
||||
|
||||
// checkGitCloneCap check if we have the git binary on hand
|
||||
// checkGitCloneCap check if we have the git binary on hand.
|
||||
func checkGitCloneCap() error {
|
||||
_, err := exec.LookPath("git")
|
||||
return err
|
||||
}
|
||||
|
||||
// loadClone on backend start determine if there is a global plugin-git binary
|
||||
// loadClone on backend start determine if there is a global plugin-git binary.
|
||||
func (e *local) loadClone() {
|
||||
binary, err := exec.LookPath("plugin-git")
|
||||
if err != nil || binary == "" {
|
||||
|
@ -46,7 +46,7 @@ func (e *local) loadClone() {
|
|||
e.pluginGitBinary = binary
|
||||
}
|
||||
|
||||
// setupClone prepare the clone environment before exec
|
||||
// setupClone prepare the clone environment before exec.
|
||||
func (e *local) setupClone(state *workflowState) error {
|
||||
if e.pluginGitBinary != "" {
|
||||
state.pluginGitBinary = e.pluginGitBinary
|
||||
|
@ -61,7 +61,7 @@ func (e *local) setupClone(state *workflowState) error {
|
|||
return e.downloadLatestGitPluginBinary(state.pluginGitBinary)
|
||||
}
|
||||
|
||||
// execClone executes a clone-step locally
|
||||
// execClone executes a clone-step locally.
|
||||
func (e *local) execClone(ctx context.Context, step *types.Step, state *workflowState, env []string) error {
|
||||
if scm := step.Environment["CI_REPO_SCM"]; scm != "git" {
|
||||
return fmt.Errorf("local backend can only clone from git repos, but this repo use '%s'", scm)
|
||||
|
@ -113,7 +113,7 @@ func (e *local) execClone(ctx context.Context, step *types.Step, state *workflow
|
|||
return cmd.Start()
|
||||
}
|
||||
|
||||
// writeNetRC write a netrc file into the home dir of a given workflow state
|
||||
// writeNetRC write a netrc file into the home dir of a given workflow state.
|
||||
func (e *local) writeNetRC(step *types.Step, state *workflowState) (string, error) {
|
||||
if step.Environment["CI_NETRC_MACHINE"] == "" {
|
||||
log.Trace().Msg("no netrc to write")
|
||||
|
@ -132,7 +132,7 @@ func (e *local) writeNetRC(step *types.Step, state *workflowState) (string, erro
|
|||
}
|
||||
|
||||
// downloadLatestGitPluginBinary download the latest plugin-git binary based on runtime OS and Arch
|
||||
// and saves it to dest
|
||||
// and saves it to dest.
|
||||
func (e *local) downloadLatestGitPluginBinary(dest string) error {
|
||||
type asset struct {
|
||||
Name string
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// notAllowedEnvVarOverwrites are all env vars that cannot be overwritten by step config
|
||||
// notAllowedEnvVarOverwrites are all env vars that cannot be overwritten by step config.
|
||||
var notAllowedEnvVarOverwrites = []string{
|
||||
"CI_NETRC_MACHINE",
|
||||
"CI_NETRC_USERNAME",
|
||||
|
|
|
@ -147,10 +147,10 @@ func (e *local) StartStep(ctx context.Context, step *types.Step, taskUUID string
|
|||
}
|
||||
}
|
||||
|
||||
// execCommands use step.Image as shell and run the commands in it
|
||||
// execCommands use step.Image as shell and run the commands in it.
|
||||
func (e *local) execCommands(ctx context.Context, step *types.Step, state *workflowState, env []string) error {
|
||||
// Prepare commands
|
||||
// TODO support `entrypoint` from pipeline config
|
||||
// TODO: support `entrypoint` from pipeline config
|
||||
args, err := e.genCmdByShell(step.Image, step.Commands)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not convert commands into args: %w", err)
|
||||
|
@ -176,7 +176,7 @@ func (e *local) execCommands(ctx context.Context, step *types.Step, state *workf
|
|||
return cmd.Start()
|
||||
}
|
||||
|
||||
// execPlugin use step.Image as exec binary
|
||||
// execPlugin use step.Image as exec binary.
|
||||
func (e *local) execPlugin(ctx context.Context, step *types.Step, state *workflowState, env []string) error {
|
||||
binary, err := exec.LookPath(step.Image)
|
||||
if err != nil {
|
||||
|
|
|
@ -56,7 +56,7 @@ type Backend interface {
|
|||
DestroyWorkflow(ctx context.Context, conf *Config, taskUUID string) error
|
||||
}
|
||||
|
||||
// BackendInfo represents the reported information of a loaded backend
|
||||
// BackendInfo represents the reported information of a loaded backend.
|
||||
type BackendInfo struct {
|
||||
Platform string
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ type Config struct {
|
|||
Secrets []*Secret `json:"secrets"` // secret definitions
|
||||
}
|
||||
|
||||
// CliContext is the context key to pass cli context to backends if needed
|
||||
// CliContext is the context key to pass cli context to backends if needed.
|
||||
var CliContext ContextKey
|
||||
|
||||
// ContextKey is just an empty struct. It exists so CliContext can be
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
package types
|
||||
|
||||
// Secret defines a runtime secret
|
||||
// Secret defines a runtime secret.
|
||||
type Secret struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
|
|
|
@ -49,7 +49,7 @@ type Step struct {
|
|||
BackendOptions map[string]any `json:"backend_options,omitempty"`
|
||||
}
|
||||
|
||||
// StepType identifies the type of step
|
||||
// StepType identifies the type of step.
|
||||
type StepType string
|
||||
|
||||
const (
|
||||
|
|
|
@ -26,9 +26,11 @@ const (
|
|||
EventManual = "manual"
|
||||
)
|
||||
|
||||
// Different ways to handle failure states
|
||||
// Different ways to handle failure states.
|
||||
const (
|
||||
FailureIgnore = "ignore"
|
||||
FailureFail = "fail"
|
||||
// FailureCancel = "cancel" // Not implemented yet
|
||||
//nolint:godot
|
||||
// TODO: Not implemented yet.
|
||||
// FailureCancel = "cancel"
|
||||
)
|
||||
|
|
|
@ -38,7 +38,7 @@ func (m *Metadata) Environ() map[string]string {
|
|||
)
|
||||
|
||||
branchParts := strings.Split(m.Curr.Commit.Refspec, ":")
|
||||
if len(branchParts) == 2 { //nolint: gomnd
|
||||
if len(branchParts) == 2 { //nolint:mnd
|
||||
sourceBranch = branchParts[0]
|
||||
targetBranch = branchParts[1]
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func (m *Metadata) Environ() map[string]string {
|
|||
"CI_FORGE_TYPE": m.Forge.Type,
|
||||
"CI_FORGE_URL": m.Forge.URL,
|
||||
|
||||
// TODO Deprecated, remove in 3.x
|
||||
// TODO: Deprecated, remove in 3.x
|
||||
"CI_COMMIT_URL": m.Curr.ForgeURL,
|
||||
}
|
||||
if m.Curr.Event == EventTag || m.Curr.Event == EventRelease || strings.HasPrefix(m.Curr.Commit.Ref, "refs/tags/") {
|
||||
|
|
|
@ -93,7 +93,7 @@ type (
|
|||
Number int `json:"number,omitempty"`
|
||||
}
|
||||
|
||||
// Secret defines a runtime secret
|
||||
// Secret defines a runtime secret.
|
||||
Secret struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
|
@ -110,13 +110,13 @@ type (
|
|||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// Forge defines runtime metadata about the forge that host the repo
|
||||
// Forge defines runtime metadata about the forge that host the repo.
|
||||
Forge struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// ServerForge represent the needed func of a server forge to get its metadata
|
||||
// ServerForge represent the needed func of a server forge to get its metadata.
|
||||
ServerForge interface {
|
||||
// Name returns the string name of this driver
|
||||
Name() string
|
||||
|
|
|
@ -28,7 +28,7 @@ const (
|
|||
defaultCloneName = "clone"
|
||||
)
|
||||
|
||||
// Registry represents registry credentials
|
||||
// Registry represents registry credentials.
|
||||
type Registry struct {
|
||||
Hostname string
|
||||
Username string
|
||||
|
@ -89,7 +89,7 @@ type ResourceLimit struct {
|
|||
CPUSet string
|
||||
}
|
||||
|
||||
// Compiler compiles the yaml
|
||||
// Compiler compiles the yaml.
|
||||
type Compiler struct {
|
||||
local bool
|
||||
escalated []string
|
||||
|
|
|
@ -122,7 +122,7 @@ func (c *Compiler) createProcess(container *yaml_types.Container, stepType backe
|
|||
}
|
||||
|
||||
environment[requested.Target] = secretValue
|
||||
// TODO deprecated, remove in 3.x
|
||||
// TODO: deprecated, remove in 3.x
|
||||
environment[strings.ToUpper(requested.Target)] = secretValue
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ func WithEnviron(env map[string]string) Option {
|
|||
}
|
||||
|
||||
// WithNetworks configures the compiler with additional networks
|
||||
// to be connected to pipeline containers
|
||||
// to be connected to pipeline containers.
|
||||
func WithNetworks(networks ...string) Option {
|
||||
return func(compiler *Compiler) {
|
||||
compiler.networks = networks
|
||||
|
@ -178,14 +178,14 @@ func WithDefaultCloneImage(cloneImage string) Option {
|
|||
}
|
||||
}
|
||||
|
||||
// WithTrusted configures the compiler with the trusted repo option
|
||||
// WithTrusted configures the compiler with the trusted repo option.
|
||||
func WithTrusted(trusted bool) Option {
|
||||
return func(compiler *Compiler) {
|
||||
compiler.trustedPipeline = trusted
|
||||
}
|
||||
}
|
||||
|
||||
// WithNetrcOnlyTrusted configures the compiler with the netrcOnlyTrusted repo option
|
||||
// WithNetrcOnlyTrusted configures the compiler with the netrcOnlyTrusted repo option.
|
||||
func WithNetrcOnlyTrusted(only bool) Option {
|
||||
return func(compiler *Compiler) {
|
||||
compiler.netrcOnlyTrusted = only
|
||||
|
|
|
@ -42,7 +42,7 @@ func ParamsToEnv(from map[string]any, to map[string]string, prefix string, upper
|
|||
return nil
|
||||
}
|
||||
|
||||
// format the environment variable key
|
||||
// sanitizeParamKey formats the environment variable key.
|
||||
func sanitizeParamKey(prefix string, upper bool, k string) string {
|
||||
r := strings.ReplaceAll(strings.ReplaceAll(k, ".", "_"), "-", "_")
|
||||
if upper {
|
||||
|
@ -51,7 +51,7 @@ func sanitizeParamKey(prefix string, upper bool, k string) string {
|
|||
return prefix + r
|
||||
}
|
||||
|
||||
// indicate if a data type can be turned into string without encoding as json
|
||||
// isComplex indicate if a data type can be turned into string without encoding as json.
|
||||
func isComplex(t reflect.Kind) bool {
|
||||
switch t {
|
||||
case reflect.Bool,
|
||||
|
@ -64,7 +64,7 @@ func isComplex(t reflect.Kind) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// sanitizeParamValue returns the value of a setting as string prepared to be injected as environment variable
|
||||
// sanitizeParamValue returns the value of a setting as string prepared to be injected as environment variable.
|
||||
func sanitizeParamValue(v any, getSecretValue func(name string) (string, error)) (string, error) {
|
||||
t := reflect.TypeOf(v)
|
||||
vv := reflect.ValueOf(v)
|
||||
|
@ -141,7 +141,7 @@ func sanitizeParamValue(v any, getSecretValue func(name string) (string, error))
|
|||
return handleComplex(vv.Interface(), getSecretValue)
|
||||
}
|
||||
|
||||
// handleComplex uses yaml2json to get json strings as values for environment variables
|
||||
// handleComplex uses yaml2json to get json strings as values for environment variables.
|
||||
func handleComplex(v any, getSecretValue func(name string) (string, error)) (string, error) {
|
||||
v, err := injectSecretRecursive(v, getSecretValue)
|
||||
if err != nil {
|
||||
|
@ -161,7 +161,7 @@ func handleComplex(v any, getSecretValue func(name string) (string, error)) (str
|
|||
|
||||
// injectSecret probes if a map is a from_secret request.
|
||||
// If it's a from_secret request it either returns the secret value or an error if the secret was not found
|
||||
// else it just indicates to progress normally using the provided map as is
|
||||
// else it just indicates to progress normally using the provided map as is.
|
||||
func injectSecret(v map[string]any, getSecretValue func(name string) (string, error)) (string, bool, error) {
|
||||
if secretNameI, ok := v["from_secret"]; ok {
|
||||
if secretName, ok := secretNameI.(string); ok {
|
||||
|
@ -178,7 +178,7 @@ func injectSecret(v map[string]any, getSecretValue func(name string) (string, er
|
|||
}
|
||||
|
||||
// injectSecretRecursive iterates over all types and if they contain elements
|
||||
// it iterates recursively over them too, using injectSecret internally
|
||||
// it iterates recursively over them too, using injectSecret internally.
|
||||
func injectSecretRecursive(v any, getSecretValue func(name string) (string, error)) (any, error) {
|
||||
t := reflect.TypeOf(v)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ type (
|
|||
Local yamlBaseTypes.BoolTrue
|
||||
Path Path
|
||||
Evaluate string `yaml:"evaluate,omitempty"`
|
||||
// TODO change to StringOrSlice in 3.x
|
||||
// TODO: change to StringOrSlice in 3.x
|
||||
Event List
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ func (when *When) IncludesStatusSuccess() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// False if (any) non local
|
||||
// False if (any) non local.
|
||||
func (when *When) IsLocal() bool {
|
||||
for _, c := range when.Constraints {
|
||||
if !c.Local.Bool() {
|
||||
|
@ -206,7 +206,7 @@ func (c *Constraint) Match(m metadata.Metadata, global bool, env map[string]stri
|
|||
return match, nil
|
||||
}
|
||||
|
||||
// IsEmpty return true if a constraint has no conditions
|
||||
// IsEmpty return true if a constraint has no conditions.
|
||||
func (c List) IsEmpty() bool {
|
||||
return len(c.Include) == 0 && len(c.Exclude) == 0
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import (
|
|||
//go:embed schema.json
|
||||
var schemaDefinition []byte
|
||||
|
||||
// Lint lints an io.Reader against the Woodpecker schema.json
|
||||
// Lint lints an io.Reader against the Woodpecker `schema.json`.
|
||||
func Lint(r io.Reader) ([]gojsonschema.ResultError, error) {
|
||||
schemaLoader := gojsonschema.NewBytesLoader(schemaDefinition)
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ func (s *StringOrInt) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
}
|
||||
|
||||
// MemStringOrInt represents a string or an integer
|
||||
// the String supports notations like 10m for then Megabyte of memory
|
||||
// the String supports notations like 10m for then Megabyte of memory.
|
||||
type MemStringOrInt int64
|
||||
|
||||
// UnmarshalYAML implements the Unmarshaler interface.
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// SliceOrMap represents a map of strings, string slice are converted into a map
|
||||
// SliceOrMap represents a map of strings, string slice are converted into a map.
|
||||
type SliceOrMap map[string]any
|
||||
|
||||
// UnmarshalYAML implements the Unmarshaler interface.
|
||||
|
|
|
@ -49,9 +49,9 @@ type (
|
|||
Ports []string `yaml:"ports,omitempty"`
|
||||
DependsOn base.StringOrSlice `yaml:"depends_on,omitempty"`
|
||||
|
||||
// TODO make []string in 3.x
|
||||
// TODO: make []string in 3.x
|
||||
Secrets Secrets `yaml:"secrets,omitempty"`
|
||||
// TODO make map[string]any in 3.x
|
||||
// TODO: make map[string]any in 3.x
|
||||
Environment base.SliceOrMap `yaml:"environment,omitempty"`
|
||||
|
||||
// Docker and Kubernetes Specific
|
||||
|
|
|
@ -26,7 +26,7 @@ type Volumes struct {
|
|||
Volumes []*Volume
|
||||
}
|
||||
|
||||
// Volume represent a service volume
|
||||
// Volume represent a service volume.
|
||||
type Volume struct {
|
||||
Source string `yaml:"-"`
|
||||
Destination string `yaml:"-"`
|
||||
|
@ -68,7 +68,7 @@ func (v *Volumes) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
}
|
||||
elts := strings.SplitN(name, ":", 3)
|
||||
var vol *Volume
|
||||
//nolint: gomnd
|
||||
//nolint:mnd
|
||||
switch {
|
||||
case len(elts) == 1:
|
||||
vol = &Volume{
|
||||
|
|
|
@ -88,7 +88,7 @@ func (r *Runtime) MakeLogger() zerolog.Logger {
|
|||
return logCtx.Logger()
|
||||
}
|
||||
|
||||
// Run starts the execution of a workflow and waits for it to complete
|
||||
// Run starts the execution of a workflow and waits for it to complete.
|
||||
func (r *Runtime) Run(runnerCtx context.Context) error {
|
||||
logger := r.MakeLogger()
|
||||
logger.Debug().Msgf("executing %d stages, in order of:", len(r.spec.Stages))
|
||||
|
@ -129,7 +129,7 @@ func (r *Runtime) Run(runnerCtx context.Context) error {
|
|||
return r.err
|
||||
}
|
||||
|
||||
// Updates the current status of a step
|
||||
// Updates the current status of a step.
|
||||
func (r *Runtime) traceStep(processState *backend.State, err error, step *backend.Step) error {
|
||||
if r.tracer == nil {
|
||||
// no tracer nothing to trace :)
|
||||
|
@ -158,7 +158,7 @@ func (r *Runtime) traceStep(processState *backend.State, err error, step *backen
|
|||
return err
|
||||
}
|
||||
|
||||
// Executes a set of parallel steps
|
||||
// Executes a set of parallel steps.
|
||||
func (r *Runtime) execAll(steps []*backend.Step) <-chan error {
|
||||
var g errgroup.Group
|
||||
done := make(chan error)
|
||||
|
|
|
@ -97,12 +97,12 @@ func (w *LineWriter) Write(p []byte) (n int, err error) {
|
|||
return len(p), nil
|
||||
}
|
||||
|
||||
// Lines returns the line history
|
||||
// Lines returns the line history.
|
||||
func (w *LineWriter) Lines() []*LogEntry {
|
||||
return w.lines
|
||||
}
|
||||
|
||||
// Clear clears the line history
|
||||
// Clear clears the line history.
|
||||
func (w *LineWriter) Clear() {
|
||||
w.lines = w.lines[:0]
|
||||
}
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
package proto
|
||||
|
||||
// Version is the version of the woodpecker.proto file,
|
||||
// !IMPORTANT! increased by 1 each time it get changed !IMPORTANT!
|
||||
// IMPORTANT: increased by 1 each time it get changed.
|
||||
const Version int32 = 7
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package api
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package api
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
// errInvalidToken is returned when the api request token is invalid.
|
||||
var errInvalidToken = errors.New("invalid or missing token")
|
||||
|
||||
// PromHandler will pass the call from /api/metrics/prometheus to prometheus
|
||||
// PromHandler will pass the call from /api/metrics/prometheus to prometheus.
|
||||
func PromHandler() gin.HandlerFunc {
|
||||
handler := promhttp.Handler()
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package api
|
||||
|
||||
|
@ -551,7 +549,7 @@ func PostPipeline(c *gin.Context) {
|
|||
pl.DeployTask = c.DefaultQuery("deploy_task", pl.DeployTask)
|
||||
|
||||
// make Event overridable to deploy
|
||||
// TODO refactor to use own proper API for deploy
|
||||
// TODO: refactor to use own proper API for deploy
|
||||
if event, ok := c.GetQuery("event"); ok {
|
||||
pl.Event = model.WebhookEvent(event)
|
||||
if pl.Event != model.EventDeploy {
|
||||
|
|
|
@ -24,7 +24,7 @@ var (
|
|||
badgeNone = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20" role="img" aria-label="pipeline: none"><title>pipeline: none</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="90" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="53" height="20" fill="#555"/><rect x="53" width="37" height="20" fill="#9f9f9f"/><rect width="90" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="275" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">pipeline</text><text x="275" y="140" transform="scale(.1)" fill="#fff" textLength="430">pipeline</text><text aria-hidden="true" x="705" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">none</text><text x="705" y="140" transform="scale(.1)" fill="#fff" textLength="270">none</text></g></svg>`
|
||||
)
|
||||
|
||||
// Generate an SVG badge based on a pipeline
|
||||
// Generate an SVG badge based on a pipeline.
|
||||
func Generate(pipeline *model.Pipeline) string {
|
||||
if pipeline == nil {
|
||||
return badgeNone
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
||||
// Generate an SVG badge based on a pipeline
|
||||
// Generate an SVG badge based on a pipeline.
|
||||
func TestGenerate(t *testing.T) {
|
||||
assert.Equal(t, badgeNone, Generate(nil))
|
||||
assert.Equal(t, badgeSuccess, Generate(&model.Pipeline{Status: model.StatusSuccess}))
|
||||
|
|
2
server/cache/membership.go
vendored
2
server/cache/membership.go
vendored
|
@ -41,7 +41,7 @@ type membershipCache struct {
|
|||
// NewMembershipService creates a new membership service.
|
||||
func NewMembershipService(_store store.Store) MembershipService {
|
||||
return &membershipCache{
|
||||
ttl: 10 * time.Minute, //nolint: gomnd
|
||||
ttl: 10 * time.Minute, //nolint:mnd
|
||||
store: _store,
|
||||
cache: ttlcache.New(ttlcache.WithDisableTouchOnHit[string, *model.OrgPerm]()),
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package server
|
||||
|
||||
|
|
|
@ -30,14 +30,14 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// checkTime specifies the interval woodpecker checks for new crons to exec
|
||||
// Specifies the interval woodpecker checks for new crons to exec.
|
||||
checkTime = 10 * time.Second
|
||||
|
||||
// checkItems specifies the batch size of crons to retrieve per check from database
|
||||
// Specifies the batch size of crons to retrieve per check from database.
|
||||
checkItems = 10
|
||||
)
|
||||
|
||||
// Start starts the cron scheduler loop
|
||||
// Start starts the cron scheduler loop.
|
||||
func Start(ctx context.Context, store store.Store) error {
|
||||
for {
|
||||
select {
|
||||
|
@ -64,7 +64,7 @@ func Start(ctx context.Context, store store.Store) error {
|
|||
}
|
||||
}
|
||||
|
||||
// CalcNewNext parses a cron string and calculates the next exec time based on it
|
||||
// CalcNewNext parses a cron string and calculates the next exec time based on it.
|
||||
func CalcNewNext(schedule string, now time.Time) (time.Time, error) {
|
||||
// remove local timezone
|
||||
now = now.UTC()
|
||||
|
|
|
@ -90,7 +90,7 @@ type httpRequest struct {
|
|||
Body []byte `json:"body"`
|
||||
}
|
||||
|
||||
// modelUser is an extension of model.User to marshal all fields to JSON
|
||||
// modelUser is an extension of model.User to marshal all fields to JSON.
|
||||
type modelUser struct {
|
||||
User *model.User `json:"user"`
|
||||
|
||||
|
@ -129,7 +129,7 @@ func modelUserFromModel(u *model.User) *modelUser {
|
|||
}
|
||||
}
|
||||
|
||||
// modelRepo is an extension of model.Repo to marshal all fields to JSON
|
||||
// modelRepo is an extension of model.Repo to marshal all fields to JSON.
|
||||
type modelRepo struct {
|
||||
Repo *model.Repo `json:"repo"`
|
||||
UserID int64 `json:"user_id"`
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
||||
// make sure RPC implements forge.Forge
|
||||
// make sure RPC implements forge.Forge.
|
||||
var _ forge.Forge = new(RPC)
|
||||
|
||||
func Load(file string) (forge.Forge, error) {
|
||||
|
@ -44,7 +44,7 @@ func Load(file string) (forge.Forge, error) {
|
|||
logger: log.With().Str("addon", file).Logger(),
|
||||
},
|
||||
})
|
||||
// TODO defer client.Kill()
|
||||
// TODO: defer client.Kill()
|
||||
|
||||
rpcClient, err := client.Client()
|
||||
if err != nil {
|
||||
|
|
|
@ -42,7 +42,7 @@ const (
|
|||
pageSize = 100
|
||||
)
|
||||
|
||||
// Opts are forge options for bitbucket
|
||||
// Opts are forge options for bitbucket.
|
||||
type Opts struct {
|
||||
Client string
|
||||
Secret string
|
||||
|
@ -67,12 +67,12 @@ func New(opts *Opts) (forge.Forge, error) {
|
|||
// TODO: add checks
|
||||
}
|
||||
|
||||
// Name returns the string name of this driver
|
||||
// Name returns the string name of this driver.
|
||||
func (c *config) Name() string {
|
||||
return "bitbucket"
|
||||
}
|
||||
|
||||
// URL returns the root url of a configured forge
|
||||
// URL returns the root url of a configured forge.
|
||||
func (c *config) URL() string {
|
||||
return c.url
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ func (c *config) File(ctx context.Context, u *model.User, r *model.Repo, p *mode
|
|||
return []byte(*config), nil
|
||||
}
|
||||
|
||||
// Dir fetches a folder from the bitbucket repository
|
||||
// Dir fetches a folder from the bitbucket repository.
|
||||
func (c *config) Dir(ctx context.Context, u *model.User, r *model.Repo, p *model.Pipeline, f string) ([]*forge_types.FileMeta, error) {
|
||||
var page *string
|
||||
repoPathFiles := []*forge_types.FileMeta{}
|
||||
|
@ -375,7 +375,7 @@ func (c *config) Branches(ctx context.Context, u *model.User, r *model.Repo, p *
|
|||
return branches, nil
|
||||
}
|
||||
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch.
|
||||
func (c *config) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (*model.Commit, error) {
|
||||
commit, err := c.newClient(ctx, u).GetBranchHead(r.Owner, r.Name, branch)
|
||||
if err != nil {
|
||||
|
@ -432,7 +432,7 @@ func (c *config) Org(ctx context.Context, u *model.User, owner string) (*model.O
|
|||
}, nil
|
||||
}
|
||||
|
||||
// helper function to return the bitbucket oauth2 client
|
||||
// helper function to return the bitbucket oauth2 client.
|
||||
func (c *config) newClient(ctx context.Context, u *model.User) *internal.Client {
|
||||
if u == nil {
|
||||
return c.newClientToken(ctx, "", "")
|
||||
|
@ -440,7 +440,7 @@ func (c *config) newClient(ctx context.Context, u *model.User) *internal.Client
|
|||
return c.newClientToken(ctx, u.Token, u.Secret)
|
||||
}
|
||||
|
||||
// helper function to return the bitbucket oauth2 client
|
||||
// helper function to return the bitbucket oauth2 client.
|
||||
func (c *config) newClientToken(ctx context.Context, token, secret string) *internal.Client {
|
||||
return internal.NewClientToken(
|
||||
ctx,
|
||||
|
@ -454,7 +454,7 @@ func (c *config) newClientToken(ctx context.Context, token, secret string) *inte
|
|||
)
|
||||
}
|
||||
|
||||
// helper function to return the bitbucket oauth2 config
|
||||
// helper function to return the bitbucket oauth2 config.
|
||||
func (c *config) newOAuth2Config() *oauth2.Config {
|
||||
return &oauth2.Config{
|
||||
ClientID: c.Client,
|
||||
|
|
|
@ -213,10 +213,10 @@ func convertPushHook(hook *internal.PushHook, change *internal.Change) *model.Pi
|
|||
return pipeline
|
||||
}
|
||||
|
||||
// regex for git author fields ("name <name@mail.tld>")
|
||||
// regex for git author fields (r.g. "name <name@mail.tld>").
|
||||
var reGitMail = regexp.MustCompile("<(.*)>")
|
||||
|
||||
// extracts the email from a git commit author string
|
||||
// extracts the email from a git commit author string.
|
||||
func extractEmail(gitauthor string) (author string) {
|
||||
matches := reGitMail.FindAllStringSubmatch(gitauthor, -1)
|
||||
if len(matches) == 1 {
|
||||
|
|
|
@ -80,12 +80,12 @@ func New(opts Opts) (forge.Forge, error) {
|
|||
return config, nil
|
||||
}
|
||||
|
||||
// Name returns the string name of this driver
|
||||
// Name returns the string name of this driver.
|
||||
func (c *client) Name() string {
|
||||
return "bitbucket_dc"
|
||||
}
|
||||
|
||||
// URL returns the root url of a configured forge
|
||||
// URL returns the root url of a configured forge.
|
||||
func (c *client) URL() string {
|
||||
return c.url
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func NewClientWithToken(ctx context.Context, ts oauth2.TokenSource, url string)
|
|||
}
|
||||
}
|
||||
|
||||
// FindCurrentUser is returning the current user id - however it is not really part of the API so it is not part of the Bitbucket go client
|
||||
// FindCurrentUser is returning the current user id - however it is not really part of the API so it is not part of the Bitbucket go client.
|
||||
func (c *Client) FindCurrentUser(ctx context.Context) (string, error) {
|
||||
url := fmt.Sprintf(currentUserID, c.base)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
package fixtures
|
||||
|
||||
// HookPush is a sample Gitea push hook
|
||||
// HookPush is a sample Gitea push hook.
|
||||
const HookPush = `
|
||||
{
|
||||
"ref": "refs/heads/main",
|
||||
|
@ -75,7 +75,7 @@ const HookPush = `
|
|||
}
|
||||
`
|
||||
|
||||
// HookPushMulti push multible commits to a branch
|
||||
// HookPushMulti push multible commits to a branch.
|
||||
const HookPushMulti = `
|
||||
{
|
||||
"ref": "refs/heads/main",
|
||||
|
@ -272,7 +272,7 @@ const HookPushMulti = `
|
|||
}
|
||||
`
|
||||
|
||||
// HookPushBranch is a sample Gitea push hook where a new branch was created from an existing commit
|
||||
// HookPushBranch is a sample Gitea push hook where a new branch was created from an existing commit.
|
||||
const HookPushBranch = `
|
||||
{
|
||||
"ref": "refs/heads/fdsafdsa",
|
||||
|
@ -425,7 +425,7 @@ const HookPushBranch = `
|
|||
}
|
||||
}`
|
||||
|
||||
// HookTag is a sample Gitea tag hook
|
||||
// HookTag is a sample Gitea tag hook.
|
||||
const HookTag = `{
|
||||
"sha": "ef98532add3b2feb7a137426bba1248724367df5",
|
||||
"secret": "l26Un7G7HXogLAvsyf2hOA4EMARSTsR3",
|
||||
|
@ -468,7 +468,7 @@ const HookTag = `{
|
|||
}
|
||||
}`
|
||||
|
||||
// HookPullRequest is a sample pull_request webhook payload
|
||||
// HookPullRequest is a sample pull_request webhook payload.
|
||||
const HookPullRequest = `{
|
||||
"action": "opened",
|
||||
"number": 1,
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package gitea
|
||||
|
||||
|
@ -84,12 +82,12 @@ func New(opts Opts) (forge.Forge, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Name returns the string name of this driver
|
||||
// Name returns the string name of this driver.
|
||||
func (c *Gitea) Name() string {
|
||||
return "gitea"
|
||||
}
|
||||
|
||||
// URL returns the root url of a configured forge
|
||||
// URL returns the root url of a configured forge.
|
||||
func (c *Gitea) URL() string {
|
||||
return c.url
|
||||
}
|
||||
|
@ -458,7 +456,7 @@ func (c *Gitea) Branches(ctx context.Context, u *model.User, r *model.Repo, p *m
|
|||
return result, err
|
||||
}
|
||||
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch.
|
||||
func (c *Gitea) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (*model.Commit, error) {
|
||||
token := common.UserToken(ctx, r, u)
|
||||
client, err := c.newClientToken(ctx, token)
|
||||
|
@ -585,7 +583,7 @@ func (c *Gitea) Org(ctx context.Context, u *model.User, owner string) (*model.Or
|
|||
}, nil
|
||||
}
|
||||
|
||||
// helper function to return the Gitea client with Token
|
||||
// newClientToken returns the Gitea client with Token.
|
||||
func (c *Gitea) newClientToken(ctx context.Context, token string) (*gitea.Client, error) {
|
||||
httpClient := &http.Client{}
|
||||
if c.SkipVerify {
|
||||
|
|
|
@ -29,7 +29,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/shared/utils"
|
||||
)
|
||||
|
||||
// helper function that converts a Gitea repository to a Woodpecker repository.
|
||||
// toRepo converts a Gitea repository to a Woodpecker repository.
|
||||
func toRepo(from *gitea.Repository) *model.Repo {
|
||||
name := strings.Split(from.FullName, "/")[1]
|
||||
avatar := expandAvatar(
|
||||
|
@ -53,7 +53,7 @@ func toRepo(from *gitea.Repository) *model.Repo {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function that converts a Gitea permission to a Woodpecker permission.
|
||||
// toPerm converts a Gitea permission to a Woodpecker permission.
|
||||
func toPerm(from *gitea.Permission) *model.Perm {
|
||||
return &model.Perm{
|
||||
Pull: from.Pull,
|
||||
|
@ -62,7 +62,7 @@ func toPerm(from *gitea.Permission) *model.Perm {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function that converts a Gitea team to a Woodpecker team.
|
||||
// toTeam converts a Gitea team to a Woodpecker team.
|
||||
func toTeam(from *gitea.Organization, link string) *model.Team {
|
||||
return &model.Team{
|
||||
Login: from.UserName,
|
||||
|
@ -70,7 +70,7 @@ func toTeam(from *gitea.Organization, link string) *model.Team {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function that extracts the Pipeline data from a Gitea push hook
|
||||
// pipelineFromPush extracts the Pipeline data from a Gitea push hook.
|
||||
func pipelineFromPush(hook *pushHook) *model.Pipeline {
|
||||
avatar := expandAvatar(
|
||||
hook.Repo.HTMLURL,
|
||||
|
@ -121,7 +121,7 @@ func getChangedFilesFromPushHook(hook *pushHook) []string {
|
|||
return utils.DeduplicateStrings(files)
|
||||
}
|
||||
|
||||
// helper function that extracts the Pipeline data from a Gitea tag hook
|
||||
// pipelineFromTag extracts the Pipeline data from a Gitea tag hook.
|
||||
func pipelineFromTag(hook *pushHook) *model.Pipeline {
|
||||
avatar := expandAvatar(
|
||||
hook.Repo.HTMLURL,
|
||||
|
@ -143,7 +143,7 @@ func pipelineFromTag(hook *pushHook) *model.Pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function that extracts the Pipeline data from a Gitea pull_request hook
|
||||
// pipelineFromPullRequest extracts the Pipeline data from a Gitea pull_request hook.
|
||||
func pipelineFromPullRequest(hook *pullRequestHook) *model.Pipeline {
|
||||
avatar := expandAvatar(
|
||||
hook.Repo.HTMLURL,
|
||||
|
@ -197,7 +197,7 @@ func pipelineFromRelease(hook *releaseHook) *model.Pipeline {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function that parses a push hook from a read closer.
|
||||
// parsePush parses a push hook from a read closer.
|
||||
func parsePush(r io.Reader) (*pushHook, error) {
|
||||
push := new(pushHook)
|
||||
err := json.NewDecoder(r).Decode(push)
|
||||
|
@ -216,8 +216,7 @@ func parseRelease(r io.Reader) (*releaseHook, error) {
|
|||
return pr, err
|
||||
}
|
||||
|
||||
// fixMalformedAvatar is a helper function that fixes an avatar url if malformed
|
||||
// (currently a known bug with gitea)
|
||||
// fixMalformedAvatar fixes an avatar url if malformed (currently a known bug with gitea).
|
||||
func fixMalformedAvatar(url string) string {
|
||||
index := strings.Index(url, "///")
|
||||
if index != -1 {
|
||||
|
@ -230,8 +229,7 @@ func fixMalformedAvatar(url string) string {
|
|||
return url
|
||||
}
|
||||
|
||||
// expandAvatar is a helper function that converts a relative avatar URL to the
|
||||
// absolute url.
|
||||
// expandAvatar converts a relative avatar URL to the absolute url.
|
||||
func expandAvatar(repo, rawurl string) string {
|
||||
aurl, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
|
@ -252,7 +250,7 @@ func expandAvatar(repo, rawurl string) string {
|
|||
return aurl.String()
|
||||
}
|
||||
|
||||
// helper function to return matching hooks.
|
||||
// matchingHooks return matching hooks.
|
||||
func matchingHooks(hooks []*gitea.Hook, rawurl string) *gitea.Hook {
|
||||
link, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
|
|
|
@ -72,7 +72,7 @@ func parsePushHook(payload io.Reader) (repo *model.Repo, pipeline *model.Pipelin
|
|||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// TODO is this even needed?
|
||||
// TODO: is this even needed?
|
||||
if push.RefType == refBranch {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
|
|
@ -84,12 +84,12 @@ type client struct {
|
|||
OnlyPublic bool
|
||||
}
|
||||
|
||||
// Name returns the string name of this driver
|
||||
// Name returns the string name of this driver.
|
||||
func (c *client) Name() string {
|
||||
return "github"
|
||||
}
|
||||
|
||||
// URL returns the root url of a configured forge
|
||||
// URL returns the root url of a configured forge.
|
||||
func (c *client) URL() string {
|
||||
return c.url
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ func (c *client) Org(ctx context.Context, u *model.User, owner string) (*model.O
|
|||
}, nil
|
||||
}
|
||||
|
||||
// helper function to return the GitHub oauth2 context using an HTTPClient that
|
||||
// newContext returns the GitHub oauth2 context using an HTTPClient that
|
||||
// disables TLS verification if disabled in the forge settings.
|
||||
func (c *client) newContext(ctx context.Context) context.Context {
|
||||
if !c.SkipVerify {
|
||||
|
@ -406,7 +406,7 @@ func (c *client) newContext(ctx context.Context) context.Context {
|
|||
})
|
||||
}
|
||||
|
||||
// helper function to return the GitHub oauth2 config
|
||||
// newConfig returns the GitHub oauth2 config.
|
||||
func (c *client) newConfig() *oauth2.Config {
|
||||
scopes := []string{"user:email", "read:org"}
|
||||
if c.OnlyPublic {
|
||||
|
@ -427,7 +427,7 @@ func (c *client) newConfig() *oauth2.Config {
|
|||
}
|
||||
}
|
||||
|
||||
// helper function to return the GitHub oauth2 client
|
||||
// newClientToken returns the GitHub oauth2 client.
|
||||
func (c *client) newClientToken(ctx context.Context, token string) *github.Client {
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: token},
|
||||
|
@ -447,7 +447,7 @@ func (c *client) newClientToken(ctx context.Context, token string) *github.Clien
|
|||
return client
|
||||
}
|
||||
|
||||
// helper function to return matching user email.
|
||||
// matchingEmail returns matching user email.
|
||||
func matchingEmail(emails []*github.UserEmail, rawURL string) *github.UserEmail {
|
||||
for _, email := range emails {
|
||||
if email.Email == nil || email.Primary == nil || email.Verified == nil {
|
||||
|
@ -465,7 +465,7 @@ func matchingEmail(emails []*github.UserEmail, rawURL string) *github.UserEmail
|
|||
return nil
|
||||
}
|
||||
|
||||
// helper function to return matching hook.
|
||||
// matchingHooks returns matching hook.
|
||||
func matchingHooks(hooks []*github.Hook, rawurl string) *github.Hook {
|
||||
link, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
|
@ -493,7 +493,7 @@ func (c *client) Status(ctx context.Context, user *model.User, repo *model.Repo,
|
|||
if pipeline.Event == model.EventDeploy {
|
||||
// Get id from url. If not found, skip.
|
||||
matches := reDeploy.FindStringSubmatch(pipeline.ForgeURL)
|
||||
//nolint:gomnd
|
||||
//nolint:mnd
|
||||
if len(matches) != 2 {
|
||||
return nil
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ func (c *client) Branches(ctx context.Context, u *model.User, r *model.Repo, p *
|
|||
return branches, nil
|
||||
}
|
||||
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch.
|
||||
func (c *client) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (*model.Commit, error) {
|
||||
token := common.UserToken(ctx, r, u)
|
||||
b, _, err := c.newClientToken(ctx, token).Repositories.GetBranch(ctx, r.Owner, r.Name, branch, 1)
|
||||
|
|
|
@ -53,7 +53,7 @@ type Opts struct {
|
|||
SkipVerify bool // Skip ssl verification.
|
||||
}
|
||||
|
||||
// Gitlab implements "Forge" interface
|
||||
// Gitlab implements "Forge" interface.
|
||||
type GitLab struct {
|
||||
url string
|
||||
ClientID string
|
||||
|
@ -75,12 +75,12 @@ func New(opts Opts) (forge.Forge, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Name returns the string name of this driver
|
||||
// Name returns the string name of this driver.
|
||||
func (g *GitLab) Name() string {
|
||||
return "gitlab"
|
||||
}
|
||||
|
||||
// URL returns the root url of a configured forge
|
||||
// URL returns the root url of a configured forge.
|
||||
func (g *GitLab) URL() string {
|
||||
return g.url
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func (g *GitLab) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// Auth authenticates the session and returns the forge user login for the given token
|
||||
// Auth authenticates the session and returns the forge user login for the given token.
|
||||
func (g *GitLab) Auth(ctx context.Context, token, _ string) (string, error) {
|
||||
client, err := newClient(g.url, token, g.SkipVerify)
|
||||
if err != nil {
|
||||
|
@ -381,7 +381,7 @@ func (g *GitLab) File(ctx context.Context, user *model.User, repo *model.Repo, p
|
|||
return file, err
|
||||
}
|
||||
|
||||
// Dir fetches a folder from the forge repository
|
||||
// Dir fetches a folder from the forge repository.
|
||||
func (g *GitLab) Dir(ctx context.Context, user *model.User, repo *model.Repo, pipeline *model.Pipeline, path string) ([]*forge_types.FileMeta, error) {
|
||||
client, err := newClient(g.url, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
|
@ -605,7 +605,7 @@ func (g *GitLab) Branches(ctx context.Context, user *model.User, repo *model.Rep
|
|||
return branches, nil
|
||||
}
|
||||
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch
|
||||
// BranchHead returns the sha of the head (latest commit) of the specified branch.
|
||||
func (g *GitLab) BranchHead(ctx context.Context, u *model.User, r *model.Repo, branch string) (*model.Commit, error) {
|
||||
token := common.UserToken(ctx, r, u)
|
||||
client, err := newClient(g.url, token, g.SkipVerify)
|
||||
|
|
|
@ -40,7 +40,7 @@ func (ae *AuthError) Error() string {
|
|||
return err
|
||||
}
|
||||
|
||||
// check interface
|
||||
// Check interface implementation at compile time.
|
||||
var _ error = new(AuthError)
|
||||
|
||||
var ErrNotImplemented = errors.New("not implemented")
|
||||
|
|
|
@ -16,7 +16,7 @@ package types
|
|||
|
||||
import "sort"
|
||||
|
||||
// FileMeta represents a file in version control
|
||||
// FileMeta represents a file in version control.
|
||||
type FileMeta struct {
|
||||
Name string
|
||||
Data []byte
|
||||
|
|
|
@ -22,13 +22,13 @@ import (
|
|||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// JWTManager is a JSON web token manager
|
||||
// JWTManager is a JSON web token manager.
|
||||
type JWTManager struct {
|
||||
secretKey string
|
||||
tokenDuration time.Duration
|
||||
}
|
||||
|
||||
// UserClaims is a custom JWT claims that contains some user's information
|
||||
// UserClaims is a custom JWT claims that contains some user's information.
|
||||
type AgentTokenClaims struct {
|
||||
jwt.RegisteredClaims
|
||||
AgentID int64 `json:"agent_id"`
|
||||
|
@ -36,12 +36,12 @@ type AgentTokenClaims struct {
|
|||
|
||||
const jwtTokenDuration = 1 * time.Hour
|
||||
|
||||
// NewJWTManager returns a new JWT manager
|
||||
// NewJWTManager returns a new JWT manager.
|
||||
func NewJWTManager(secretKey string) *JWTManager {
|
||||
return &JWTManager{secretKey, jwtTokenDuration}
|
||||
}
|
||||
|
||||
// Generate generates and signs a new token for a user
|
||||
// Generate generates and signs a new token for a user.
|
||||
func (manager *JWTManager) Generate(agentID int64) (string, error) {
|
||||
claims := AgentTokenClaims{
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
|
@ -60,7 +60,7 @@ func (manager *JWTManager) Generate(agentID int64) (string, error) {
|
|||
return token.SignedString([]byte(manager.secretKey))
|
||||
}
|
||||
|
||||
// Verify verifies the access token string and return a user claim if the token is valid
|
||||
// Verify verifies the access token string and return a user claim if the token is valid.
|
||||
func (manager *JWTManager) Verify(accessToken string) (*AgentTokenClaims, error) {
|
||||
token, err := jwt.ParseWithClaims(
|
||||
accessToken,
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
// 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.
|
||||
//
|
||||
// This file has been modified by Informatyka Boguslawski sp. z o.o. sp.k.
|
||||
|
||||
package grpc
|
||||
|
||||
|
@ -50,7 +48,7 @@ type RPC struct {
|
|||
pipelineCount *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// Next implements the rpc.Next function
|
||||
// Next implements the rpc.Next function.
|
||||
func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Workflow, error) {
|
||||
if hostname, err := s.getHostnameFromContext(c); err == nil {
|
||||
log.Debug().Msgf("agent connected: %s: polling", hostname)
|
||||
|
@ -88,17 +86,17 @@ func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Workflow, er
|
|||
}
|
||||
}
|
||||
|
||||
// Wait implements the rpc.Wait function
|
||||
// Wait implements the rpc.Wait function.
|
||||
func (s *RPC) Wait(c context.Context, id string) error {
|
||||
return s.queue.Wait(c, id)
|
||||
}
|
||||
|
||||
// Extend implements the rpc.Extend function
|
||||
// Extend implements the rpc.Extend function.
|
||||
func (s *RPC) Extend(c context.Context, id string) error {
|
||||
return s.queue.Extend(c, id)
|
||||
}
|
||||
|
||||
// Update implements the rpc.Update function
|
||||
// Update implements the rpc.Update function.
|
||||
func (s *RPC) Update(_ context.Context, id string, state rpc.State) error {
|
||||
workflowID, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -164,7 +162,7 @@ func (s *RPC) Update(_ context.Context, id string, state rpc.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Init implements the rpc.Init function
|
||||
// Init implements the rpc.Init function.
|
||||
func (s *RPC) Init(c context.Context, id string, state rpc.State) error {
|
||||
stepID, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -230,7 +228,7 @@ func (s *RPC) Init(c context.Context, id string, state rpc.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Done implements the rpc.Done function
|
||||
// Done implements the rpc.Done function.
|
||||
func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||
workflowID, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -319,7 +317,7 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Log implements the rpc.Log function
|
||||
// Log implements the rpc.Log function.
|
||||
func (s *RPC) Log(c context.Context, _logEntry *rpc.LogEntry) error {
|
||||
// convert rpc log_entry to model.log_entry
|
||||
step, err := s.store.StepByUUID(_logEntry.StepUUID)
|
||||
|
|
|
@ -21,15 +21,17 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/v2/server/model"
|
||||
)
|
||||
|
||||
// TODO (bradrydzewski) writing to subscribers is currently a blocking
|
||||
// TODO: (bradrydzewski) writing to subscribers is currently a blocking
|
||||
// operation and does not protect against slow clients from locking
|
||||
// the stream. This should be resolved.
|
||||
|
||||
// TODO (bradrydzewski) implement a mux.Info to fetch information and
|
||||
//nolint:godot
|
||||
// TODO: (bradrydzewski) implement a mux.Info to fetch information and
|
||||
// statistics for the multiplexer. Streams, subscribers, etc
|
||||
// mux.Info()
|
||||
|
||||
// TODO (bradrydzewski) refactor code to place publisher and subscriber
|
||||
//nolint:godot
|
||||
// TODO: (bradrydzewski) refactor code to place publisher and subscriber
|
||||
// operations in separate files with more encapsulated logic.
|
||||
// sub.push()
|
||||
// sub.join()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue