diff --git a/.golangci.yml b/.golangci.yml index 65be680b72..7c3bc4bb2d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,30 +1,31 @@ run: - deadline: 5m + timeout: 15m skip-files: - ^.*\.(pb|y)\.go$ skip-dirs: - "vendor$" + - "pkg/app/piped/executor/analysis/mannwhitney" linters: disable-all: true enable: - - prealloc + - depguard + - exportloopref + - gocritic + - goimports + - gosimple - ineffassign - - goerr113 - misspell - - errcheck - - gosimple + - prealloc - staticcheck - - gosec - - gocritic - - unparam - - deadcode - - unconvert - - typecheck - stylecheck - - exportloopref - - depguard - - goimports + - typecheck + - unconvert + - unparam + # TODO: Enable these linters + # - errcheck + # - goerr113 + # - gosec issues: exclude-rules: @@ -37,10 +38,15 @@ output: linters-settings: depguard: - list-type: blacklist - include-go-root: true - packages-with-error-message: - - sync/atomic: "Use go.uber.org/atomic instead of sync/atomic" - - io/ioutil: "Use corresponding 'os' or 'io' functions instead." + rules: + main: + deny: + - pkg: "sync/atomic" + desc: "Use go.uber.org/atomic instead of sync/atomic." + - pkg: "io/ioutil" + desc: "Use corresponding 'os' or 'io' functions instead." + gocritic: + disabled-checks: + - appendAssign goimports: local-prefixes: github.com/pipe-cd/pipecd diff --git a/Makefile b/Makefile index b027b328df..ac8ac831a8 100644 --- a/Makefile +++ b/Makefile @@ -149,13 +149,13 @@ run/site: .PHONY: lint/go lint/go: FIX ?= false -lint/go: VERSION ?= sha256:78d1bbd01a9886a395dc8374218a6c0b7b67694e725dd76f0c8ac1de411b85e8 #v1.46.2 -lint/go: FLAGS ?= --rm --platform linux/amd64 -e GOLANGCI_LINT_CACHE=/repo/.cache/golangci-lint -v ${PWD}:/repo -w /repo -it +lint/go: VERSION ?= sha256:fb70c9b2e6d0763141f057abcafde7f88d5e4bb3b5882d6b14bc79382f04481c #v1.55.2 +lint/go: FLAGS ?= --rm --platform linux/amd64 -e GOCACHE=/repo/.cache/go-build -e GOLANGCI_LINT_CACHE=/repo/.cache/golangci-lint -v ${PWD}:/repo -w /repo -it lint/go: ifeq ($(FIX),true) - docker run ${FLAGS} golangci/golangci-lint@${VERSION} golangci-lint run --fix + docker run ${FLAGS} golangci/golangci-lint@${VERSION} golangci-lint run -v --fix else - docker run ${FLAGS} golangci/golangci-lint@${VERSION} golangci-lint run + docker run ${FLAGS} golangci/golangci-lint@${VERSION} golangci-lint run -v endif .PHONY: lint/web diff --git a/docs/content/en/docs-dev/user-guide/configuration-reference.md b/docs/content/en/docs-dev/user-guide/configuration-reference.md index 68b0bcdaae..cc29dafc6d 100644 --- a/docs/content/en/docs-dev/user-guide/configuration-reference.md +++ b/docs/content/en/docs-dev/user-guide/configuration-reference.md @@ -445,6 +445,7 @@ One of `yamlField` or `regex` is required. | serviceDefinitionFile | string | The path ECS Service configuration file. Allow file in both `yaml` and `json` format. The default value is `service.json`. See [here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html) for parameters.| No | | taskDefinitionFile | string | The path to ECS TaskDefinition configuration file. Allow file in both `yaml` and `json` format. The default value is `taskdef.json`. See [here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html) for parameters. | No | | targetGroups | [ECSTargetGroupInput](#ecstargetgroupinput) | The target groups configuration, will be used to routing traffic to created task sets. | Yes (if you want to perform progressive delivery) | +| runStandaloneTask | bool | Run standalone tasks during deployments. About standalone task, see [here](https://docs.aws.amazon.com/AmazonECS/latest/userguide/ecs_run_task-v2.html). The default value is `true`. | ### ECSTargetGroupInput diff --git a/docs/content/en/docs-v0.45.x/user-guide/configuration-reference.md b/docs/content/en/docs-v0.45.x/user-guide/configuration-reference.md index 68b0bcdaae..cc29dafc6d 100644 --- a/docs/content/en/docs-v0.45.x/user-guide/configuration-reference.md +++ b/docs/content/en/docs-v0.45.x/user-guide/configuration-reference.md @@ -445,6 +445,7 @@ One of `yamlField` or `regex` is required. | serviceDefinitionFile | string | The path ECS Service configuration file. Allow file in both `yaml` and `json` format. The default value is `service.json`. See [here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html) for parameters.| No | | taskDefinitionFile | string | The path to ECS TaskDefinition configuration file. Allow file in both `yaml` and `json` format. The default value is `taskdef.json`. See [here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html) for parameters. | No | | targetGroups | [ECSTargetGroupInput](#ecstargetgroupinput) | The target groups configuration, will be used to routing traffic to created task sets. | Yes (if you want to perform progressive delivery) | +| runStandaloneTask | bool | Run standalone tasks during deployments. About standalone task, see [here](https://docs.aws.amazon.com/AmazonECS/latest/userguide/ecs_run_task-v2.html). The default value is `true`. | ### ECSTargetGroupInput diff --git a/docs/main.go b/docs/main.go index e3e30de0e2..08097cbc82 100644 --- a/docs/main.go +++ b/docs/main.go @@ -45,7 +45,7 @@ func main() { // Redirect /docs/ to /docs-{latest-version}/ mux.HandleFunc("/docs/", func(w http.ResponseWriter, r *http.Request) { latestPattern := strings.Replace(r.URL.Path, "/docs/", latestPath, 1) - http.Redirect(w, r, latestPattern, 307) + http.Redirect(w, r, latestPattern, http.StatusTemporaryRedirect) }) defer func() { diff --git a/go.mod b/go.mod index 9cf6204cd2..3ca616ec68 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/lambda v1.30.2 github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0 github.com/creasty/defaults v1.6.0 - github.com/envoyproxy/protoc-gen-validate v0.9.1 + github.com/envoyproxy/protoc-gen-validate v0.10.1 github.com/fsouza/fake-gcs-server v1.21.0 github.com/go-sql-driver/mysql v1.6.0 github.com/goccy/go-yaml v1.9.8 @@ -44,13 +44,13 @@ require ( github.com/stretchr/testify v1.8.1 go.uber.org/atomic v1.7.0 go.uber.org/zap v1.10.1-0.20190709142728-9a9fa7d4b5f0 - golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b - golang.org/x/net v0.8.0 - golang.org/x/oauth2 v0.6.0 + golang.org/x/crypto v0.14.0 + golang.org/x/net v0.17.0 + golang.org/x/oauth2 v0.7.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.116.0 - google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633 - google.golang.org/grpc v1.54.0 + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 + google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.30.0 istio.io/api v0.0.0-20200710191538-00b73d23c685 k8s.io/api v0.24.3 @@ -61,7 +61,7 @@ require ( require ( cloud.google.com/go v0.110.0 // indirect - cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/longrunning v0.4.1 // indirect @@ -101,7 +101,7 @@ require ( github.com/containerd/continuity v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/cli v20.10.14+incompatible // indirect - github.com/docker/docker v20.10.24+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/emicklei/go-restful v2.16.0+incompatible // indirect @@ -166,9 +166,9 @@ require ( github.com/zclconf/go-cty v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.2.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.1.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 276ef3a30b..177423350d 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -211,8 +211,8 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v20.10.14+incompatible h1:dSBKJOVesDgHo7rbxlYjYsXe7gPzrTT+/cKQgpDAazg= github.com/docker/cli v20.10.14+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= -github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -230,8 +230,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -721,8 +721,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -805,8 +805,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -819,8 +819,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -906,12 +906,12 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -922,8 +922,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/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.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1071,8 +1071,8 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633 h1:0BOZf6qNozI3pkN3fJLwNubheHJYHhMh91GRFOWWK08= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1093,8 +1093,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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= diff --git a/pkg/app/ops/deploymentchaincontroller/controller.go b/pkg/app/ops/deploymentchaincontroller/controller.go index 93e2ba9d42..d40f65cf4f 100644 --- a/pkg/app/ops/deploymentchaincontroller/controller.go +++ b/pkg/app/ops/deploymentchaincontroller/controller.go @@ -88,9 +88,7 @@ func (d *DeploymentChainController) Run(ctx context.Context) error { d.logger.Error("failed while sync controller updaters", zap.Error(err)) } case <-syncDeploymentChainsTicker.C: - if err := d.syncDeploymentChains(ctx); err != nil { - d.logger.Error("failed while sync deployment chains", zap.Error(err)) - } + d.syncDeploymentChains(ctx) } } } @@ -130,7 +128,7 @@ func (d *DeploymentChainController) syncUpdaters(ctx context.Context) error { return nil } -func (d *DeploymentChainController) syncDeploymentChains(ctx context.Context) error { +func (d *DeploymentChainController) syncDeploymentChains(ctx context.Context) { var ( updatersNum = len(d.updaters) updaterCh = make(chan *updater, updatersNum) @@ -162,8 +160,6 @@ func (d *DeploymentChainController) syncDeploymentChains(ctx context.Context) er d.logger.Info("waiting for all updaters to finish") wg.Wait() - - return nil } func listNotCompletedDeploymentChain(ctx context.Context, dcs deploymentChainStore) ([]*model.DeploymentChain, error) { diff --git a/pkg/app/ops/handler/handler.go b/pkg/app/ops/handler/handler.go index 714c389e1c..757b643636 100644 --- a/pkg/app/ops/handler/handler.go +++ b/pkg/app/ops/handler/handler.go @@ -238,7 +238,7 @@ func groupApplicationCounts(counts []model.InsightApplicationCount) (total int, for _, c := range counts { total += int(c.Count) kind := c.Labels[model.InsightApplicationCountLabelKey_KIND.String()] - groups[kind] = groups[kind] + int(c.Count) + groups[kind] += int(c.Count) } return } diff --git a/pkg/app/ops/planpreviewoutputcleaner/cleaner.go b/pkg/app/ops/planpreviewoutputcleaner/cleaner.go index 96ca56acc0..b490a9bc3c 100644 --- a/pkg/app/ops/planpreviewoutputcleaner/cleaner.go +++ b/pkg/app/ops/planpreviewoutputcleaner/cleaner.go @@ -28,7 +28,6 @@ import ( const ( outputTTL = 48 * time.Hour cronSchedule = "0 9 * * *" // Run at 09:00 every day. - interval = 24 * time.Hour prefix = "command-output/" ) diff --git a/pkg/app/pipectl/client/deployment.go b/pkg/app/pipectl/client/deployment.go index ff4e8ec6c0..bd36170ab9 100644 --- a/pkg/app/pipectl/client/deployment.go +++ b/pkg/app/pipectl/client/deployment.go @@ -89,7 +89,7 @@ func WaitDeploymentStatuses( func makeDeploymentStatusesMap(statuses []model.DeploymentStatus) map[model.DeploymentStatus]struct{} { out := make(map[model.DeploymentStatus]struct{}, len(statuses)) for _, s := range statuses { - out[model.DeploymentStatus(s)] = struct{}{} + out[(s)] = struct{}{} } return out } diff --git a/pkg/app/piped/apistore/applicationstore/store.go b/pkg/app/piped/apistore/applicationstore/store.go index 145c7c5a93..962124a7cd 100644 --- a/pkg/app/piped/apistore/applicationstore/store.go +++ b/pkg/app/piped/apistore/applicationstore/store.go @@ -16,9 +16,9 @@ package applicationstore import ( "context" - "sync/atomic" "time" + "go.uber.org/atomic" "go.uber.org/zap" "google.golang.org/grpc" diff --git a/pkg/app/piped/apistore/deploymentstore/store.go b/pkg/app/piped/apistore/deploymentstore/store.go index 875a99f4b5..cc98ec31af 100644 --- a/pkg/app/piped/apistore/deploymentstore/store.go +++ b/pkg/app/piped/apistore/deploymentstore/store.go @@ -16,9 +16,9 @@ package deploymentstore import ( "context" - "sync/atomic" "time" + "go.uber.org/atomic" "go.uber.org/zap" "google.golang.org/grpc" diff --git a/pkg/app/piped/apistore/eventstore/store.go b/pkg/app/piped/apistore/eventstore/store.go index 29055a30b6..b812b72162 100644 --- a/pkg/app/piped/apistore/eventstore/store.go +++ b/pkg/app/piped/apistore/eventstore/store.go @@ -17,9 +17,9 @@ package eventstore import ( "context" "fmt" - "sync/atomic" "time" + "go.uber.org/atomic" "go.uber.org/zap" "google.golang.org/grpc" diff --git a/pkg/app/piped/appconfigreporter/appconfigreporter.go b/pkg/app/piped/appconfigreporter/appconfigreporter.go index e256e1b10c..d18ec3c9cc 100644 --- a/pkg/app/piped/appconfigreporter/appconfigreporter.go +++ b/pkg/app/piped/appconfigreporter/appconfigreporter.go @@ -167,10 +167,7 @@ func (r *Reporter) updateRegisteredApps(ctx context.Context, headCommits map[str outOfSyncRegisteredApps := make([]*model.ApplicationInfo, 0) for repoID, repo := range r.gitRepos { headCommit := headCommits[repoID] - rs, err := r.findOutOfSyncRegisteredApps(repo.GetPath(), repoID, headCommit) - if err != nil { - return err - } + rs := r.findOutOfSyncRegisteredApps(repo.GetPath(), repoID, headCommit) r.logger.Info(fmt.Sprintf("found out %d valid registered applications that config has been changed in repository %q", len(rs), repoID)) outOfSyncRegisteredApps = append(outOfSyncRegisteredApps, rs...) } @@ -233,7 +230,7 @@ func (r *Reporter) updateUnregisteredApps(ctx context.Context) error { } // findOutOfSyncRegisteredApps finds out registered application info that should be updated in the given git repository. -func (r *Reporter) findOutOfSyncRegisteredApps(repoPath, repoID, headCommit string) ([]*model.ApplicationInfo, error) { +func (r *Reporter) findOutOfSyncRegisteredApps(repoPath, repoID, headCommit string) []*model.ApplicationInfo { // Compare the apps registered on Control-plane with the latest config file // and return only the ones that have been changed. apps := make([]*model.ApplicationInfo, 0) @@ -275,7 +272,7 @@ func (r *Reporter) findOutOfSyncRegisteredApps(repoPath, repoID, headCommit stri appCfg.Id = app.Id apps = append(apps, appCfg) } - return apps, nil + return apps } func (r *Reporter) isSynced(appInfo *model.ApplicationInfo, app *model.Application) bool { diff --git a/pkg/app/piped/appconfigreporter/appconfigreporter_test.go b/pkg/app/piped/appconfigreporter/appconfigreporter_test.go index e523ea1408..91a3255193 100644 --- a/pkg/app/piped/appconfigreporter/appconfigreporter_test.go +++ b/pkg/app/piped/appconfigreporter/appconfigreporter_test.go @@ -157,8 +157,7 @@ spec: } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - got, err := tc.reporter.findOutOfSyncRegisteredApps(tc.args.repoPath, tc.args.repoID, "not-existed-head-commit") - assert.Equal(t, tc.wantErr, err != nil) + got := tc.reporter.findOutOfSyncRegisteredApps(tc.args.repoPath, tc.args.repoID, "not-existed-head-commit") assert.Equal(t, tc.want, got) }) } diff --git a/pkg/app/piped/cmd/piped/piped.go b/pkg/app/piped/cmd/piped/piped.go index ec342e3342..1a9507e6f7 100644 --- a/pkg/app/piped/cmd/piped/piped.go +++ b/pkg/app/piped/cmd/piped/piped.go @@ -696,17 +696,14 @@ func (p *piped) sendPipedMeta(ctx context.Context, client pipedservice.Client, c } // Configure secret management. - if sm := cfg.SecretManagement; sm != nil { - switch sm.Type { - case model.SecretManagementTypeKeyPair: - publicKey, err := sm.KeyPair.LoadPublicKey() - if err != nil { - return fmt.Errorf("failed to read public key for secret management (%w)", err) - } - req.SecretEncryption = &model.Piped_SecretEncryption{ - Type: sm.Type.String(), - PublicKey: string(publicKey), - } + if sm := cfg.SecretManagement; sm != nil && sm.Type == model.SecretManagementTypeKeyPair { + publicKey, err := sm.KeyPair.LoadPublicKey() + if err != nil { + return fmt.Errorf("failed to read public key for secret management (%w)", err) + } + req.SecretEncryption = &model.Piped_SecretEncryption{ + Type: sm.Type.String(), + PublicKey: string(publicKey), } } if req.SecretEncryption == nil { diff --git a/pkg/app/piped/controller/controller.go b/pkg/app/piped/controller/controller.go index 76e057de3c..65f1923520 100644 --- a/pkg/app/piped/controller/controller.go +++ b/pkg/app/piped/controller/controller.go @@ -288,7 +288,7 @@ func (c *controller) checkCommands() { } // syncPlanners adds new planner for newly PENDING deployments. -func (c *controller) syncPlanners(ctx context.Context) error { +func (c *controller) syncPlanners(ctx context.Context) { // Remove stale planners from the recently completed list. for id, t := range c.donePlanners { if time.Since(t) >= plannerStaleDuration { @@ -324,7 +324,7 @@ func (c *controller) syncPlanners(ctx context.Context) error { // Add missing planners. pendings := c.deploymentLister.ListPendings() if len(pendings) == 0 { - return nil + return } c.logger.Info(fmt.Sprintf("there are %d pending deployments for planning", len(pendings)), @@ -426,8 +426,6 @@ func (c *controller) syncPlanners(ctx context.Context) error { ) } } - - return nil } func (c *controller) startNewPlanner(ctx context.Context, d *model.Deployment) (*planner, error) { @@ -506,7 +504,7 @@ func (c *controller) startNewPlanner(ctx context.Context, d *model.Deployment) ( // syncSchedulers adds new scheduler for newly PLANNED/RUNNING deployments // as well as removes the schedulers for the completed deployments. -func (c *controller) syncSchedulers(ctx context.Context) error { +func (c *controller) syncSchedulers(ctx context.Context) { // Update the most recent successful commit hashes. for id, s := range c.schedulers { if !s.IsDone() { @@ -556,7 +554,7 @@ func (c *controller) syncSchedulers(ctx context.Context) error { targets := append(runnings, planneds...) if len(targets) == 0 { - return nil + return } c.logger.Info(fmt.Sprintf("there are %d planned/running deployments for scheduling", len(targets)), @@ -589,8 +587,6 @@ func (c *controller) syncSchedulers(ctx context.Context) error { zap.Int("count", len(c.schedulers)), ) } - - return nil } // startNewScheduler creates and starts running a new scheduler diff --git a/pkg/app/piped/controller/controllermetrics/metrics.go b/pkg/app/piped/controller/controllermetrics/metrics.go index d2f8c0e001..d42cb7feac 100644 --- a/pkg/app/piped/controller/controllermetrics/metrics.go +++ b/pkg/app/piped/controller/controllermetrics/metrics.go @@ -15,8 +15,9 @@ package controllermetrics import ( - "github.com/pipe-cd/pipecd/pkg/model" "github.com/prometheus/client_golang/prometheus" + + "github.com/pipe-cd/pipecd/pkg/model" ) const ( diff --git a/pkg/app/piped/driftdetector/cloudrun/detector.go b/pkg/app/piped/driftdetector/cloudrun/detector.go index a3fb460a3e..914b51ccdb 100644 --- a/pkg/app/piped/driftdetector/cloudrun/detector.go +++ b/pkg/app/piped/driftdetector/cloudrun/detector.go @@ -122,7 +122,7 @@ func (d *detector) ProviderName() string { return d.provider.Name } -func (d *detector) check(ctx context.Context) error { +func (d *detector) check(ctx context.Context) { appsByRepo := d.listGroupedApplication() for repoID, apps := range appsByRepo { @@ -168,7 +168,6 @@ func (d *detector) check(ctx context.Context) error { } } } - return nil } func (d *detector) cloneGitRepository(ctx context.Context, repoID string) (git.Repo, error) { @@ -315,7 +314,7 @@ func makeSyncState(r *provider.DiffResult, commit string) model.ApplicationSyncS } } - shortReason := fmt.Sprintf("The service manifest doesn't be synced") + shortReason := "The service manifest doesn't be synced" if len(commit) >= 7 { commit = commit[:7] } diff --git a/pkg/app/piped/driftdetector/kubernetes/detector.go b/pkg/app/piped/driftdetector/kubernetes/detector.go index 6eb37b67da..1f951e7fd2 100644 --- a/pkg/app/piped/driftdetector/kubernetes/detector.go +++ b/pkg/app/piped/driftdetector/kubernetes/detector.go @@ -120,7 +120,7 @@ func (d *detector) Run(ctx context.Context) error { } } -func (d *detector) check(ctx context.Context) error { +func (d *detector) check(ctx context.Context) { appsByRepo := d.listGroupedApplication() for repoID, apps := range appsByRepo { @@ -171,8 +171,6 @@ func (d *detector) check(ctx context.Context) error { } } } - - return nil } func (d *detector) checkApplication(ctx context.Context, app *model.Application, repo git.Repo, headCommit git.Commit) error { diff --git a/pkg/app/piped/driftdetector/terraform/detector.go b/pkg/app/piped/driftdetector/terraform/detector.go index 7edd099c86..005e095735 100644 --- a/pkg/app/piped/driftdetector/terraform/detector.go +++ b/pkg/app/piped/driftdetector/terraform/detector.go @@ -121,7 +121,7 @@ func (d *detector) Run(ctx context.Context) error { } } -func (d *detector) check(ctx context.Context) error { +func (d *detector) check(ctx context.Context) { appsByRepo := d.listGroupedApplication() for repoID, apps := range appsByRepo { @@ -167,8 +167,6 @@ func (d *detector) check(ctx context.Context) error { } } } - - return nil } func (d *detector) checkApplication(ctx context.Context, app *model.Application, repo git.Repo, headCommit git.Commit) error { diff --git a/pkg/app/piped/executor/analysis/analysis.go b/pkg/app/piped/executor/analysis/analysis.go index ec1669a22d..12ad436481 100644 --- a/pkg/app/piped/executor/analysis/analysis.go +++ b/pkg/app/piped/executor/analysis/analysis.go @@ -116,7 +116,7 @@ func (e *Executor) Execute(sig executor.StopSignal) model.StageStatus { continue } status = model.StageStatus_STAGE_SKIPPED - // Stop the context to cancel all running analysises. + // Stop the context to cancel all running analyses. cancel() return case <-doneCh: @@ -160,8 +160,8 @@ func (e *Executor) Execute(sig executor.StopSignal) model.StageStatus { }) } // Run analyses with http providers. - for i := range options.Https { - analyzer, err := e.newAnalyzerForHTTP(i, &options.Https[i], templateCfg) + for i := range options.HTTPS { + analyzer, err := e.newAnalyzerForHTTP(i, &options.HTTPS[i], templateCfg) if err != nil { e.LogPersister.Errorf("Failed to spawn analyzer for HTTP: %v", err) return model.StageStatus_STAGE_FAILURE @@ -312,7 +312,7 @@ func (e *Executor) getHTTPConfig(templatableCfg *config.TemplatableAnalysisHTTP, return &templatableCfg.AnalysisHTTP, nil } - cfg, ok := templateCfg.HTTPs[name] + cfg, ok := templateCfg.HTTPS[name] if !ok { return nil, fmt.Errorf("analysis template %s not found despite template specified", name) } diff --git a/pkg/app/piped/executor/ecs/ecs.go b/pkg/app/piped/executor/ecs/ecs.go index 1c6ec70007..ee025b5b21 100644 --- a/pkg/app/piped/executor/ecs/ecs.go +++ b/pkg/app/piped/executor/ecs/ecs.go @@ -199,6 +199,11 @@ func runStandaloneTask( return false } + if !*ecsInput.RunStandaloneTask { + in.LogPersister.Infof("Skipped running task") + return true + } + err = client.RunTask( ctx, *td, diff --git a/pkg/app/piped/executor/kubernetes/kubernetes.go b/pkg/app/piped/executor/kubernetes/kubernetes.go index a655f7a29e..8983557920 100644 --- a/pkg/app/piped/executor/kubernetes/kubernetes.go +++ b/pkg/app/piped/executor/kubernetes/kubernetes.go @@ -308,7 +308,7 @@ func deleteResources(ctx context.Context, ag applierGetter, resources []provider } func findManifests(kind, name string, manifests []provider.Manifest) []provider.Manifest { - var out []provider.Manifest + out := make([]provider.Manifest, 0, len(manifests)) for _, m := range manifests { if m.Key.Kind != kind { continue @@ -322,7 +322,7 @@ func findManifests(kind, name string, manifests []provider.Manifest) []provider. } func findConfigMapManifests(manifests []provider.Manifest) []provider.Manifest { - var out []provider.Manifest + out := make([]provider.Manifest, 0, len(manifests)) for _, m := range manifests { if !m.Key.IsConfigMap() { continue @@ -333,7 +333,7 @@ func findConfigMapManifests(manifests []provider.Manifest) []provider.Manifest { } func findSecretManifests(manifests []provider.Manifest) []provider.Manifest { - var out []provider.Manifest + out := make([]provider.Manifest, 0, len(manifests)) for _, m := range manifests { if !m.Key.IsSecret() { continue diff --git a/pkg/app/piped/executor/kubernetes/kubernetes_test.go b/pkg/app/piped/executor/kubernetes/kubernetes_test.go index fbe77d0d1a..c2bc871a8a 100644 --- a/pkg/app/piped/executor/kubernetes/kubernetes_test.go +++ b/pkg/app/piped/executor/kubernetes/kubernetes_test.go @@ -1018,7 +1018,7 @@ func TestPatchManifests(t *testing.T) { patcher := func(m provider.Manifest, cfg config.K8sResourcePatch) (*provider.Manifest, error) { out := m - out.Key.Namespace = out.Key.Namespace + "+" + out.Key.Namespace = fmt.Sprintf("%s+", out.Key.Namespace) return &out, nil } diff --git a/pkg/app/piped/executor/kubernetes/traffic.go b/pkg/app/piped/executor/kubernetes/traffic.go index fbec34e37c..92e4779899 100644 --- a/pkg/app/piped/executor/kubernetes/traffic.go +++ b/pkg/app/piped/executor/kubernetes/traffic.go @@ -226,7 +226,7 @@ func findIstioVirtualServiceManifests(manifests []provider.Manifest, ref config. return nil, fmt.Errorf("support only %q kind for VirtualService reference", istioVirtualServiceKind) } - var out []provider.Manifest + out := make([]provider.Manifest, 0, len(manifests)) for _, m := range manifests { if !strings.HasPrefix(m.Key.APIVersion, istioNetworkingAPIVersionPrefix) { continue diff --git a/pkg/app/piped/livestatereporter/cloudrun/report.go b/pkg/app/piped/livestatereporter/cloudrun/report.go index 0c6f1a8808..3c48f172fb 100644 --- a/pkg/app/piped/livestatereporter/cloudrun/report.go +++ b/pkg/app/piped/livestatereporter/cloudrun/report.go @@ -96,7 +96,7 @@ func (r *reporter) ProviderName() string { return r.provider.Name } -func (r *reporter) flushSnapshots(ctx context.Context) error { +func (r *reporter) flushSnapshots(ctx context.Context) { apps := r.appLister.ListByPlatformProvider(r.provider.Name) for _, app := range apps { state, ok := r.stateGetter.GetState(app.Id) @@ -130,5 +130,4 @@ func (r *reporter) flushSnapshots(ctx context.Context) error { r.snapshotVersions[app.Id] = state.Version r.logger.Info(fmt.Sprintf("successfully reported application live state for application: %s", app.Id)) } - return nil } diff --git a/pkg/app/piped/livestatereporter/kubernetes/reporter.go b/pkg/app/piped/livestatereporter/kubernetes/reporter.go index 91b92ecc2c..84c86de5bd 100644 --- a/pkg/app/piped/livestatereporter/kubernetes/reporter.go +++ b/pkg/app/piped/livestatereporter/kubernetes/reporter.go @@ -109,7 +109,7 @@ func (r *reporter) Run(ctx context.Context) error { } } -func (r *reporter) flushSnapshots(ctx context.Context) error { +func (r *reporter) flushSnapshots(ctx context.Context) { // TODO: In the future, maybe we should apply worker model for this or // send multiple application states in one request. apps := r.appLister.ListByPlatformProvider(r.provider.Name) @@ -145,7 +145,6 @@ func (r *reporter) flushSnapshots(ctx context.Context) error { r.snapshotVersions[app.Id] = state.Version r.logger.Info(fmt.Sprintf("successfully reported application live state for application: %s", app.Id)) } - return nil } func (r *reporter) flushEvents(ctx context.Context) error { diff --git a/pkg/app/piped/livestatestore/cloudrun/store.go b/pkg/app/piped/livestatestore/cloudrun/store.go index 07ce50dfaa..f445f1406d 100644 --- a/pkg/app/piped/livestatestore/cloudrun/store.go +++ b/pkg/app/piped/livestatestore/cloudrun/store.go @@ -17,9 +17,9 @@ package cloudrun import ( "context" "fmt" - "sync/atomic" "time" + "go.uber.org/atomic" "go.uber.org/zap" provider "github.com/pipe-cd/pipecd/pkg/app/piped/platformprovider/cloudrun" diff --git a/pkg/app/piped/livestatestore/kubernetes/appnodes.go b/pkg/app/piped/livestatestore/kubernetes/appnodes.go index ca2fd37738..b633991d9a 100644 --- a/pkg/app/piped/livestatestore/kubernetes/appnodes.go +++ b/pkg/app/piped/livestatestore/kubernetes/appnodes.go @@ -84,7 +84,7 @@ func (a *appNodes) addManagingResource(uid string, key provider.ResourceKey, obj }, true } -func (a *appNodes) deleteManagingResource(uid string, key provider.ResourceKey, now time.Time) (model.KubernetesResourceStateEvent, bool) { +func (a *appNodes) deleteManagingResource(uid string, _ provider.ResourceKey, now time.Time) (model.KubernetesResourceStateEvent, bool) { a.mu.Lock() n, ok := a.managingNodes[uid] if !ok { @@ -138,7 +138,7 @@ func (a *appNodes) addDependedResource(uid string, key provider.ResourceKey, obj }, true } -func (a *appNodes) deleteDependedResource(uid string, key provider.ResourceKey, now time.Time) (model.KubernetesResourceStateEvent, bool) { +func (a *appNodes) deleteDependedResource(uid string, _ provider.ResourceKey, now time.Time) (model.KubernetesResourceStateEvent, bool) { a.mu.Lock() n, ok := a.dependedNodes[uid] if !ok { diff --git a/pkg/app/piped/livestatestore/kubernetes/reflector.go b/pkg/app/piped/livestatestore/kubernetes/reflector.go index 4ef37375f9..d4ae050c6e 100644 --- a/pkg/app/piped/livestatestore/kubernetes/reflector.go +++ b/pkg/app/piped/livestatestore/kubernetes/reflector.go @@ -150,7 +150,7 @@ type reflector struct { logger *zap.Logger } -func (r *reflector) start(ctx context.Context) error { +func (r *reflector) start(_ context.Context) error { matcher := newResourceMatcher(r.config.AppStateInformer) // Use discovery to discover APIs supported by the Kubernetes API server. diff --git a/pkg/app/piped/notifier/slack.go b/pkg/app/piped/notifier/slack.go index fadd1222f1..80e9548a4f 100644 --- a/pkg/app/piped/notifier/slack.go +++ b/pkg/app/piped/notifier/slack.go @@ -350,6 +350,7 @@ func makeSlackDate(unix int64) string { return fmt.Sprintf("", unix) } +// nolint:unparam func truncateText(text string, max int) string { if len(text) <= max { return text diff --git a/pkg/app/piped/planner/cloudrun/pipeline.go b/pkg/app/piped/planner/cloudrun/pipeline.go index b6d10dc513..a4afd0974f 100644 --- a/pkg/app/piped/planner/cloudrun/pipeline.go +++ b/pkg/app/piped/planner/cloudrun/pipeline.go @@ -32,7 +32,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS ) for i, s := range stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -58,7 +58,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -79,7 +79,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, ) for i, s := range pp.Stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -105,7 +105,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, diff --git a/pkg/app/piped/planner/ecs/pipeline.go b/pkg/app/piped/planner/ecs/pipeline.go index b900f6ffee..df38990a3b 100644 --- a/pkg/app/piped/planner/ecs/pipeline.go +++ b/pkg/app/piped/planner/ecs/pipeline.go @@ -32,7 +32,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS ) for i, s := range stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -58,7 +58,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -79,7 +79,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, ) for i, s := range pp.Stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -105,7 +105,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, diff --git a/pkg/app/piped/planner/kubernetes/kubernetes.go b/pkg/app/piped/planner/kubernetes/kubernetes.go index 3e42732c6e..f209c54bed 100644 --- a/pkg/app/piped/planner/kubernetes/kubernetes.go +++ b/pkg/app/piped/planner/kubernetes/kubernetes.go @@ -341,7 +341,7 @@ func findWorkloadManifests(manifests []provider.Manifest, refs []config.K8sResou } func findManifests(kind, name string, manifests []provider.Manifest) []provider.Manifest { - var out []provider.Manifest + out := make([]provider.Manifest, 0, len(manifests)) for _, m := range manifests { if m.Key.Kind != kind { continue diff --git a/pkg/app/piped/planner/kubernetes/pipeline.go b/pkg/app/piped/planner/kubernetes/pipeline.go index d27c1d75b3..e53db56b9e 100644 --- a/pkg/app/piped/planner/kubernetes/pipeline.go +++ b/pkg/app/piped/planner/kubernetes/pipeline.go @@ -32,7 +32,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS ) for i, s := range stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -58,7 +58,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -79,7 +79,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, ) for i, s := range pp.Stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -105,7 +105,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, diff --git a/pkg/app/piped/planner/lambda/pipeline.go b/pkg/app/piped/planner/lambda/pipeline.go index 3618b5e456..d43ab8840f 100644 --- a/pkg/app/piped/planner/lambda/pipeline.go +++ b/pkg/app/piped/planner/lambda/pipeline.go @@ -32,7 +32,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS ) for i, s := range stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -58,7 +58,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -80,7 +80,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, shouldRollbackCustomSync := false for i, s := range pp.Stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -110,7 +110,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, if shouldRollbackCustomSync { s, _ := planner.GetPredefinedStage(planner.PredefinedStageCustomSyncRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -122,7 +122,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, } else { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, diff --git a/pkg/app/piped/planner/predefined_stages.go b/pkg/app/piped/planner/predefined_stages.go index 5a25a5aeb7..7fe9ead7d4 100644 --- a/pkg/app/piped/planner/predefined_stages.go +++ b/pkg/app/piped/planner/predefined_stages.go @@ -31,37 +31,37 @@ const ( var predefinedStages = map[string]config.PipelineStage{ PredefinedStageK8sSync: { - Id: PredefinedStageK8sSync, + ID: PredefinedStageK8sSync, Name: model.StageK8sSync, Desc: "Sync by applying all manifests", }, PredefinedStageTerraformSync: { - Id: PredefinedStageTerraformSync, + ID: PredefinedStageTerraformSync, Name: model.StageTerraformSync, Desc: "Sync by automatically applying any detected changes", }, PredefinedStageCloudRunSync: { - Id: PredefinedStageCloudRunSync, + ID: PredefinedStageCloudRunSync, Name: model.StageCloudRunSync, Desc: "Deploy the new version and configure all traffic to it", }, PredefinedStageLambdaSync: { - Id: PredefinedStageLambdaSync, + ID: PredefinedStageLambdaSync, Name: model.StageLambdaSync, Desc: "Deploy the new version and configure all traffic to it", }, PredefinedStageECSSync: { - Id: PredefinedStageECSSync, + ID: PredefinedStageECSSync, Name: model.StageECSSync, Desc: "Deploy the new version and configure all traffic to it", }, PredefinedStageRollback: { - Id: PredefinedStageRollback, + ID: PredefinedStageRollback, Name: model.StageRollback, Desc: "Rollback the deployment", }, PredefinedStageCustomSyncRollback: { - Id: PredefinedStageCustomSyncRollback, + ID: PredefinedStageCustomSyncRollback, Name: model.StageCustomSyncRollback, Desc: "Rollback the custom stages", }, diff --git a/pkg/app/piped/planner/terraform/pipeline.go b/pkg/app/piped/planner/terraform/pipeline.go index faf7704445..81638ba432 100644 --- a/pkg/app/piped/planner/terraform/pipeline.go +++ b/pkg/app/piped/planner/terraform/pipeline.go @@ -30,7 +30,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS ) // Append SYNC stage. - id := s.Id + id := s.ID if id == "" { id = "stage-0" } @@ -52,7 +52,7 @@ func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineS if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, @@ -73,7 +73,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, ) for i, s := range pp.Stages { - id := s.Id + id := s.ID if id == "" { id = fmt.Sprintf("stage-%d", i) } @@ -99,7 +99,7 @@ func buildProgressivePipeline(pp *config.DeploymentPipeline, autoRollback bool, if autoRollback { s, _ := planner.GetPredefinedStage(planner.PredefinedStageRollback) out = append(out, &model.PipelineStage{ - Id: s.Id, + Id: s.ID, Name: s.Name.String(), Desc: s.Desc, Predefined: true, diff --git a/pkg/app/piped/planpreview/builder.go b/pkg/app/piped/planpreview/builder.go index af6bd36711..1a307ea259 100644 --- a/pkg/app/piped/planpreview/builder.go +++ b/pkg/app/piped/planpreview/builder.go @@ -151,10 +151,7 @@ func (b *builder) build(ctx context.Context, id string, cmd model.Command_BuildP } // Find all applications that should be triggered. - triggerApps, failedResults, err := b.findTriggerApps(ctx, repo, apps, mergedCommit.Hash) - if err != nil { - return nil, err - } + triggerApps, failedResults := b.findTriggerApps(ctx, repo, apps, mergedCommit.Hash) results := failedResults if len(triggerApps) == 0 { @@ -301,7 +298,7 @@ func (b *builder) cloneHeadCommit(ctx context.Context, headBranch, headCommit st return repo, nil } -func (b *builder) findTriggerApps(ctx context.Context, repo git.Repo, apps []*model.Application, headCommit string) (triggerApps []*model.Application, failedResults []*model.ApplicationPlanPreviewResult, err error) { +func (b *builder) findTriggerApps(ctx context.Context, repo git.Repo, apps []*model.Application, headCommit string) (triggerApps []*model.Application, failedResults []*model.ApplicationPlanPreviewResult) { d := trigger.NewOnCommitDeterminer(repo, headCommit, b.commitGetter, b.logger) determine := func(app *model.Application) (bool, error) { appCfg, err := config.LoadApplication(repo.GetPath(), app.GitPath.GetApplicationConfigFilePath(), app.Kind) diff --git a/pkg/app/piped/platformprovider/kubernetes/hasher.go b/pkg/app/piped/platformprovider/kubernetes/hasher.go index 3e19a587ac..edce6c319b 100644 --- a/pkg/app/piped/platformprovider/kubernetes/hasher.go +++ b/pkg/app/piped/platformprovider/kubernetes/hasher.go @@ -47,19 +47,20 @@ func HashManifests(manifests []Manifest) (string, error) { var encoded string var err error - if m.Key.IsConfigMap() { + switch { + case m.Key.IsConfigMap(): obj := &v1.ConfigMap{} if err := m.ConvertToStructuredObject(obj); err != nil { return "", err } encoded, err = encodeConfigMap(obj) - } else if m.Key.IsSecret() { + case m.Key.IsSecret(): obj := &v1.Secret{} if err := m.ConvertToStructuredObject(obj); err != nil { return "", err } encoded, err = encodeSecret(obj) - } else { + default: var encodedBytes []byte encodedBytes, err = m.MarshalJSON() encoded = string(encodedBytes) diff --git a/pkg/app/piped/platformprovider/kubernetes/resourcekey.go b/pkg/app/piped/platformprovider/kubernetes/resourcekey.go index 2d61ed3fb2..d3e83aac24 100644 --- a/pkg/app/piped/platformprovider/kubernetes/resourcekey.go +++ b/pkg/app/piped/platformprovider/kubernetes/resourcekey.go @@ -21,7 +21,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -var builtInApiVersions = map[string]struct{}{ +var builtInAPIVersions = map[string]struct{}{ "admissionregistration.k8s.io/v1": {}, "admissionregistration.k8s.io/v1beta1": {}, "apiextensions.k8s.io/v1": {}, @@ -273,7 +273,7 @@ func DecodeResourceKey(key string) (ResourceKey, error) { } func IsKubernetesBuiltInResource(apiVersion string) bool { - _, ok := builtInApiVersions[apiVersion] + _, ok := builtInAPIVersions[apiVersion] // TODO: Change the way to detect whether an APIVersion is built-in or not // rather than depending on this fixed list. return ok diff --git a/pkg/app/piped/platformprovider/kubernetes/state.go b/pkg/app/piped/platformprovider/kubernetes/state.go index 10f8e063c8..913d794d0d 100644 --- a/pkg/app/piped/platformprovider/kubernetes/state.go +++ b/pkg/app/piped/platformprovider/kubernetes/state.go @@ -424,7 +424,6 @@ func determineIngressHealth(obj *unstructured.Unstructured) (status model.Kubern return } status = model.KubernetesResourceState_HEALTHY - return } v1Ingress := &networkingv1.Ingress{} diff --git a/pkg/app/piped/platformprovider/terraform/module.go b/pkg/app/piped/platformprovider/terraform/module.go index d18e42f0e9..1bb9876a9a 100644 --- a/pkg/app/piped/platformprovider/terraform/module.go +++ b/pkg/app/piped/platformprovider/terraform/module.go @@ -16,7 +16,7 @@ package terraform import ( "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/hashicorp/hcl/v2" @@ -56,7 +56,7 @@ const tfFileExtension = ".tf" // LoadTerraformFiles loads terraform files from a given dir. func LoadTerraformFiles(dir string) ([]File, error) { - fileInfos, err := ioutil.ReadDir(dir) + fileInfos, err := os.ReadDir(dir) if err != nil { return nil, err } diff --git a/pkg/app/piped/platformprovider/terraform/terraform.go b/pkg/app/piped/platformprovider/terraform/terraform.go index 2b9679f38f..8a497d916b 100644 --- a/pkg/app/piped/platformprovider/terraform/terraform.go +++ b/pkg/app/piped/platformprovider/terraform/terraform.go @@ -120,9 +120,7 @@ func (t *Terraform) Init(ctx context.Context, w io.Writer) error { "init", } args = append(args, t.makeCommonCommandArgs()...) - for _, f := range t.options.initFlags { - args = append(args, f) - } + args = append(args, t.options.initFlags...) cmd := exec.CommandContext(ctx, t.execPath, args...) cmd.Dir = t.dir @@ -278,9 +276,7 @@ func (t *Terraform) Plan(ctx context.Context, w io.Writer) (PlanResult, error) { "-detailed-exitcode", } args = append(args, t.makeCommonCommandArgs()...) - for _, f := range t.options.planFlags { - args = append(args, f) - } + args = append(args, t.options.planFlags...) var buf bytes.Buffer stdout := io.MultiWriter(w, &buf) @@ -316,9 +312,7 @@ func (t *Terraform) makeCommonCommandArgs() (args []string) { for _, f := range t.options.varFiles { args = append(args, fmt.Sprintf("-var-file=%s", f)) } - for _, f := range t.options.sharedFlags { - args = append(args, f) - } + args = append(args, t.options.sharedFlags...) return } @@ -398,9 +392,7 @@ func (t *Terraform) Apply(ctx context.Context, w io.Writer) error { "-input=false", } args = append(args, t.makeCommonCommandArgs()...) - for _, f := range t.options.applyFlags { - args = append(args, f) - } + args = append(args, t.options.applyFlags...) cmd := exec.CommandContext(ctx, t.execPath, args...) cmd.Dir = t.dir diff --git a/pkg/app/piped/platformprovider/terraform/terraform_test.go b/pkg/app/piped/platformprovider/terraform/terraform_test.go index c09e7e6e7e..873dbb02bc 100644 --- a/pkg/app/piped/platformprovider/terraform/terraform_test.go +++ b/pkg/app/piped/platformprovider/terraform/terraform_test.go @@ -97,3 +97,57 @@ func TestParsePlanResult(t *testing.T) { }) } } + +func TestRender(t *testing.T) { + t.Parallel() + + testcases := []struct { + name string + expected string + planResult *PlanResult + expectedErr bool + }{ + { + name: "success", + planResult: &PlanResult{ + Imports: 1, + Adds: 2, + Changes: 3, + Destroys: 4, + PlanOutput: ` +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + resource "test-add" "test" { + + id = (known after apply) + } + - resource "test-del" "test" { + + id = "foo" + } + +Plan: 1 to import, 2 to add, 3 to change, 4 to destroy. +`, + }, + expected: ` resource "test-add" "test" { ++ id = (known after apply) + } + resource "test-del" "test" { ++ id = "foo" + } +Plan: 1 to import, 2 to add, 3 to change, 4 to destroy. +`, + expectedErr: false, + }, + } + + for _, tc := range testcases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + actual, err := tc.planResult.Render() + assert.Equal(t, tc.expected, actual) + assert.Equal(t, tc.expectedErr, err != nil) + }) + } +} diff --git a/pkg/app/piped/trigger/trigger.go b/pkg/app/piped/trigger/trigger.go index 35b807d57e..e73b1f15bb 100644 --- a/pkg/app/piped/trigger/trigger.go +++ b/pkg/app/piped/trigger/trigger.go @@ -177,12 +177,12 @@ func (t *Trigger) checkCandidates(ctx context.Context, cs []candidate) (err erro // Group candidates by repository to reduce the number of Git operations on each repo. csm := make(map[string][]candidate) for _, c := range cs { - repoId := c.application.GitPath.Repo.Id - if _, ok := csm[repoId]; !ok { - csm[repoId] = []candidate{c} + repoID := c.application.GitPath.Repo.Id + if _, ok := csm[repoID]; !ok { + csm[repoID] = []candidate{c} continue } - csm[repoId] = append(csm[repoId], c) + csm[repoID] = append(csm[repoID], c) } // Iterate each repository and check its candidates. @@ -474,7 +474,7 @@ func (t *Trigger) GetLastTriggeredCommitGetter() LastTriggeredCommitGetter { return t.commitStore } -func (t *Trigger) notifyDeploymentTriggered(ctx context.Context, appCfg *config.GenericApplicationSpec, d *model.Deployment) { +func (t *Trigger) notifyDeploymentTriggered(_ context.Context, appCfg *config.GenericApplicationSpec, d *model.Deployment) { var mentions []string if n := appCfg.DeploymentNotification; n != nil { mentions = n.FindSlackAccounts(model.NotificationEventType_EVENT_DEPLOYMENT_TRIGGERED) diff --git a/pkg/app/server/apikeyverifier/verifier.go b/pkg/app/server/apikeyverifier/verifier.go index b16e67f6a2..d3145b90ff 100644 --- a/pkg/app/server/apikeyverifier/verifier.go +++ b/pkg/app/server/apikeyverifier/verifier.go @@ -86,7 +86,7 @@ func (v *Verifier) Verify(ctx context.Context, key string) (*model.APIKey, error return apiKey, nil } -func (v *Verifier) checkAPIKey(ctx context.Context, apiKey *model.APIKey, id, key string) error { +func (v *Verifier) checkAPIKey(_ context.Context, apiKey *model.APIKey, id, key string) error { if apiKey.Disabled { return fmt.Errorf("the api key %s was already disabled", id) } diff --git a/pkg/app/server/grpcapi/grpcapi.go b/pkg/app/server/grpcapi/grpcapi.go index 420c6887b6..1e1acfae97 100644 --- a/pkg/app/server/grpcapi/grpcapi.go +++ b/pkg/app/server/grpcapi/grpcapi.go @@ -184,10 +184,6 @@ func gRPCStoreError(err error, msg string) error { return status.Error(codes.Internal, fmt.Sprintf("Failed to %s", msg)) } -func makeUnregisteredAppsCacheKey(projectID string) string { - return fmt.Sprintf("HASHKEY:UNREGISTERED_APPS:%s", projectID) -} - func getPipedStatus(cs cache.Cache, id string) (model.Piped_ConnectionStatus, error) { pipedStatus, err := cs.Get(id) if errors.Is(err, cache.ErrNotFound) { diff --git a/pkg/app/server/grpcapi/grpcapi_test.go b/pkg/app/server/grpcapi/grpcapi_test.go index 58def4f62b..19159b3617 100644 --- a/pkg/app/server/grpcapi/grpcapi_test.go +++ b/pkg/app/server/grpcapi/grpcapi_test.go @@ -19,11 +19,12 @@ import ( "fmt" "testing" - "github.com/pipe-cd/pipecd/pkg/datastore" - "github.com/pipe-cd/pipecd/pkg/filestore" "github.com/stretchr/testify/assert" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + "github.com/pipe-cd/pipecd/pkg/datastore" + "github.com/pipe-cd/pipecd/pkg/filestore" ) func TestGRPCStoreError(t *testing.T) { diff --git a/pkg/app/server/grpcapi/piped_api.go b/pkg/app/server/grpcapi/piped_api.go index 7f00561921..ac95b08a2f 100644 --- a/pkg/app/server/grpcapi/piped_api.go +++ b/pkg/app/server/grpcapi/piped_api.go @@ -42,7 +42,7 @@ import ( "github.com/pipe-cd/pipecd/pkg/rpc/rpcauth" ) -type pipedApiApplicationStore interface { +type pipedAPIApplicationStore interface { Get(ctx context.Context, id string) (*model.Application, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.Application, string, error) UpdateSyncState(ctx context.Context, id string, state *model.ApplicationSyncState) error @@ -51,7 +51,7 @@ type pipedApiApplicationStore interface { UpdateMostRecentDeployment(ctx context.Context, id string, status model.DeploymentStatus, d *model.ApplicationDeploymentReference) error } -type pipedApiDeploymentStore interface { +type pipedAPIDeploymentStore interface { Add(ctx context.Context, app *model.Deployment) error Get(ctx context.Context, id string) (*model.Deployment, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.Deployment, string, error) @@ -63,17 +63,17 @@ type pipedApiDeploymentStore interface { UpdateStageMetadata(ctx context.Context, deploymentID, stageID string, metadata map[string]string) error } -type pipedApiDeploymentChainStore interface { +type pipedAPIDeploymentChainStore interface { Add(ctx context.Context, d *model.DeploymentChain) error Get(ctx context.Context, id string) (*model.DeploymentChain, error) } -type pipedApiPipedStore interface { +type pipedAPIPipedStore interface { Get(ctx context.Context, id string) (*model.Piped, error) UpdateMetadata(ctx context.Context, id, version, config string, pps []*model.Piped_PlatformProvider, repos []*model.ApplicationGitRepository, se *model.Piped_SecretEncryption, startedAt int64) error } -type pipedApiEventStore interface { +type pipedAPIEventStore interface { List(ctx context.Context, opts datastore.ListOptions) ([]*model.Event, string, error) UpdateStatus(ctx context.Context, eventID string, status model.EventStatus, statusDescription string) error } @@ -86,11 +86,11 @@ type commandOutputPutter interface { type PipedAPI struct { pipedservice.UnimplementedPipedServiceServer - applicationStore pipedApiApplicationStore - deploymentStore pipedApiDeploymentStore - deploymentChainStore pipedApiDeploymentChainStore - pipedStore pipedApiPipedStore - eventStore pipedApiEventStore + applicationStore pipedAPIApplicationStore + deploymentStore pipedAPIDeploymentStore + deploymentChainStore pipedAPIDeploymentChainStore + pipedStore pipedAPIPipedStore + eventStore pipedAPIEventStore stageLogStore stagelogstore.Store applicationLiveStateStore applicationlivestatestore.Store analysisResultStore analysisresultstore.Store diff --git a/pkg/app/server/grpcapi/web_api.go b/pkg/app/server/grpcapi/web_api.go index 7e3eac6fab..02734d21d6 100644 --- a/pkg/app/server/grpcapi/web_api.go +++ b/pkg/app/server/grpcapi/web_api.go @@ -48,7 +48,7 @@ type encrypter interface { Encrypt(text string) (string, error) } -type webApiApplicationStore interface { +type webAPIApplicationStore interface { Add(ctx context.Context, app *model.Application) error Get(ctx context.Context, id string) (*model.Application, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.Application, string, error) @@ -58,17 +58,17 @@ type webApiApplicationStore interface { Disable(ctx context.Context, id string) error } -type webApiDeploymentChainStore interface { +type webAPIDeploymentChainStore interface { Get(ctx context.Context, id string) (*model.DeploymentChain, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.DeploymentChain, string, error) } -type webApiDeploymentStore interface { +type webAPIDeploymentStore interface { Get(ctx context.Context, id string) (*model.Deployment, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.Deployment, string, error) } -type webApiPipedStore interface { +type webAPIPipedStore interface { Add(ctx context.Context, piped *model.Piped) error Get(ctx context.Context, id string) (*model.Piped, error) List(ctx context.Context, opts datastore.ListOptions) ([]*model.Piped, error) @@ -80,7 +80,7 @@ type webApiPipedStore interface { UpdateDesiredVersion(ctx context.Context, id, version string) error } -type webApiProjectStore interface { +type webAPIProjectStore interface { Get(ctx context.Context, id string) (*model.Project, error) UpdateProjectStaticAdmin(ctx context.Context, id, username, password string) error EnableStaticAdmin(ctx context.Context, id string) error @@ -94,18 +94,17 @@ type webApiProjectStore interface { DeleteProjectUserGroup(ctx context.Context, id, sso string) error } -type webApiEventStore interface { +type webAPIEventStore interface { List(ctx context.Context, opts datastore.ListOptions) ([]*model.Event, string, error) } -type webApiAPIKeyStore interface { +type webAPIAPIKeyStore interface { Add(ctx context.Context, k *model.APIKey) error List(ctx context.Context, opts datastore.ListOptions) ([]*model.APIKey, error) Disable(ctx context.Context, id, projectID string) error } -// TODO: all structs webApi should be webAPI -type webApiAPIKeyLastUsedStore interface { //nolint:stylecheck +type webAPIAPIKeyLastUsedStore interface { Get(k string) (interface{}, error) } @@ -113,14 +112,14 @@ type webApiAPIKeyLastUsedStore interface { //nolint:stylecheck type WebAPI struct { webservice.UnimplementedWebServiceServer - applicationStore webApiApplicationStore - deploymentChainStore webApiDeploymentChainStore - deploymentStore webApiDeploymentStore - pipedStore webApiPipedStore - projectStore webApiProjectStore - apiKeyStore webApiAPIKeyStore - apiKeyLastUsedStore webApiAPIKeyLastUsedStore - eventStore webApiEventStore + applicationStore webAPIApplicationStore + deploymentChainStore webAPIDeploymentChainStore + deploymentStore webAPIDeploymentStore + pipedStore webAPIPipedStore + projectStore webAPIProjectStore + apiKeyStore webAPIAPIKeyStore + apiKeyLastUsedStore webAPIAPIKeyLastUsedStore + eventStore webAPIEventStore stageLogStore stagelogstore.Store applicationLiveStateStore applicationlivestatestore.Store commandStore commandstore.Store @@ -832,6 +831,8 @@ func (a *WebAPI) ListDeployments(ctx context.Context, req *webservice.ListDeploy Value: req.PageMinUpdatedAt, }, } + + var labels map[string]string if o := req.Options; o != nil { // Allowing multiple so that it can do In Query later. // Currently only the first value is used. @@ -863,6 +864,9 @@ func (a *WebAPI) ListDeployments(ctx context.Context, req *webservice.ListDeploy Value: o.ApplicationName, }) } + if o.Labels != nil { + labels = o.Labels + } } pageSize := int(req.PageSize) @@ -877,7 +881,6 @@ func (a *WebAPI) ListDeployments(ctx context.Context, req *webservice.ListDeploy a.logger.Error("failed to get deployments", zap.Error(err)) return nil, gRPCStoreError(err, "get deployments") } - labels := req.Options.Labels if len(labels) == 0 || len(deployments) == 0 { return &webservice.ListDeploymentsResponse{ Deployments: deployments, @@ -1210,7 +1213,7 @@ func (a *WebAPI) GetProject(ctx context.Context, req *webservice.GetProjectReque func (a *WebAPI) getProject(ctx context.Context, projectID string) (*model.Project, error) { if p, ok := a.projectsInConfig[projectID]; ok { p := &model.Project{ - Id: p.Id, + Id: p.ID, Desc: p.Desc, StaticAdmin: &model.ProjectStaticUser{ Username: p.StaticAdmin.Username, diff --git a/pkg/app/server/httpapi/httpapimetrics/delegator.go b/pkg/app/server/httpapi/httpapimetrics/delegator.go index 9caee5eec5..ac976ef5e6 100644 --- a/pkg/app/server/httpapi/httpapimetrics/delegator.go +++ b/pkg/app/server/httpapi/httpapimetrics/delegator.go @@ -100,7 +100,7 @@ type pusherDelegator struct{ *responseWriterDelegator } func (d closeNotifierDelegator) CloseNotify() <-chan bool { //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + // remove support from client_golang yet. return d.ResponseWriter.(http.CloseNotifier).CloseNotify() } func (d flusherDelegator) Flush() { @@ -278,7 +278,7 @@ func init() { http.Flusher }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } - pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23 + pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23 return struct { *responseWriterDelegator http.Pusher @@ -365,7 +365,7 @@ func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) deleg id := 0 //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + // remove support from client_golang yet. if _, ok := w.(http.CloseNotifier); ok { id += closeNotifier } diff --git a/pkg/app/server/pipedverifier/verifier_test.go b/pkg/app/server/pipedverifier/verifier_test.go index bc299113f2..bccea150a7 100644 --- a/pkg/app/server/pipedverifier/verifier_test.go +++ b/pkg/app/server/pipedverifier/verifier_test.go @@ -121,7 +121,7 @@ func TestVerify(t *testing.T) { &config.ControlPlaneSpec{ Projects: []config.ControlPlaneProject{ { - Id: "project-0", + ID: "project-0", }, }, }, diff --git a/pkg/cli/app.go b/pkg/cli/app.go index 8d578d4a30..c060c04a32 100644 --- a/pkg/cli/app.go +++ b/pkg/cli/app.go @@ -30,7 +30,7 @@ type App struct { telemetryFlags TelemetryFlags } -var FlagParseErr = errors.New("FlagParseErr") +var ErrFlagParse = errors.New("FlagParseErr") func NewApp(name, desc string) *App { a := &App{ @@ -45,7 +45,7 @@ func NewApp(name, desc string) *App { a.rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error { cmd.Println(err) cmd.Println(cmd.UsageString()) - return FlagParseErr + return ErrFlagParse }) versionCmd := &cobra.Command{ Use: "version", diff --git a/pkg/cli/cmd.go b/pkg/cli/cmd.go index 5c9741c707..49c7360ba0 100644 --- a/pkg/cli/cmd.go +++ b/pkg/cli/cmd.go @@ -192,5 +192,5 @@ func (t Input) CustomMetricsHandlerFor(reg prometheus.Gatherer, mb MetricsBuilde } func extractServiceName(cmd *cobra.Command) string { - return strings.Replace(cmd.CommandPath(), " ", ".", -1) + return strings.ReplaceAll(cmd.CommandPath(), " ", ".") } diff --git a/pkg/config/analysis_template.go b/pkg/config/analysis_template.go index fb16e98775..086bb38749 100644 --- a/pkg/config/analysis_template.go +++ b/pkg/config/analysis_template.go @@ -23,7 +23,7 @@ import ( type AnalysisTemplateSpec struct { Metrics map[string]AnalysisMetrics `json:"metrics"` Logs map[string]AnalysisLog `json:"logs"` - HTTPs map[string]AnalysisHTTP `json:"https"` + HTTPS map[string]AnalysisHTTP `json:"https"` } // LoadAnalysisTemplate finds the config file for the analysis template in the .pipe diff --git a/pkg/config/application.go b/pkg/config/application.go index 08220283e1..bc277b0fea 100644 --- a/pkg/config/application.go +++ b/pkg/config/application.go @@ -216,7 +216,7 @@ type DeploymentPipeline struct { // PipelineStage represents a single stage of a pipeline. // This is used as a generic struct for all stage type. type PipelineStage struct { - Id string + ID string Name model.Stage Desc string Timeout Duration @@ -252,7 +252,7 @@ type PipelineStage struct { } type genericPipelineStage struct { - Id string `json:"id"` + ID string `json:"id"` Name model.Stage `json:"name"` Desc string `json:"desc,omitempty"` Timeout Duration `json:"timeout"` @@ -265,7 +265,7 @@ func (s *PipelineStage) UnmarshalJSON(data []byte) error { if err = json.Unmarshal(data, &gs); err != nil { return err } - s.Id = gs.Id + s.ID = gs.ID s.Name = gs.Name s.Desc = gs.Desc s.Timeout = gs.Timeout @@ -440,7 +440,7 @@ type AnalysisStageOptions struct { RestartThreshold int `json:"restartThreshold"` Metrics []TemplatableAnalysisMetrics `json:"metrics"` Logs []TemplatableAnalysisLog `json:"logs"` - Https []TemplatableAnalysisHTTP `json:"https"` + HTTPS []TemplatableAnalysisHTTP `json:"https"` } func (a *AnalysisStageOptions) Validate() error { @@ -471,7 +471,7 @@ func (a *AnalysisStageOptions) Validate() error { return fmt.Errorf("one of log configurations of ANALYSIS stage is invalid: %w", err) } } - for _, h := range a.Https { + for _, h := range a.HTTPS { if h.Template.Name != "" { if err := h.Template.Validate(); err != nil { return fmt.Errorf("one of http configurations of ANALYSIS stage is invalid: %w", err) diff --git a/pkg/config/application_ecs.go b/pkg/config/application_ecs.go index 9ef8cb8c9c..fb0e5e72d3 100644 --- a/pkg/config/application_ecs.go +++ b/pkg/config/application_ecs.go @@ -54,6 +54,9 @@ type ECSDeploymentInput struct { // Automatically reverts all changes from all stages when one of them failed. // Default is true. AutoRollback *bool `json:"autoRollback,omitempty" default:"true"` + // Run standalone task during deployment. + // Default is true. + RunStandaloneTask *bool `json:"runStandaloneTask" default:"true"` } func (in *ECSDeploymentInput) IsStandaloneTask() bool { diff --git a/pkg/config/application_ecs_test.go b/pkg/config/application_ecs_test.go index a44c4288f1..2b63f733e1 100644 --- a/pkg/config/application_ecs_test.go +++ b/pkg/config/application_ecs_test.go @@ -61,8 +61,9 @@ func TestECSApplicationConfig(t *testing.T) { TargetGroups: ECSTargetGroups{ Primary: json.RawMessage(`{"containerName":"web","containerPort":80,"targetGroupArn":"arn:aws:elasticloadbalancing:xyz"}`), }, - LaunchType: "FARGATE", - AutoRollback: newBoolPointer(true), + LaunchType: "FARGATE", + AutoRollback: newBoolPointer(true), + RunStandaloneTask: newBoolPointer(true), }, }, expectedError: nil, diff --git a/pkg/config/application_test.go b/pkg/config/application_test.go index 7658989a85..f92d4d03a3 100644 --- a/pkg/config/application_test.go +++ b/pkg/config/application_test.go @@ -596,7 +596,7 @@ func TestGenericAnalysisConfiguration(t *testing.T) { Name: model.StageAnalysis, AnalysisStageOptions: &AnalysisStageOptions{ Duration: Duration(10 * time.Minute), - Https: []TemplatableAnalysisHTTP{ + HTTPS: []TemplatableAnalysisHTTP{ { AnalysisHTTP: AnalysisHTTP{ URL: "https://canary-endpoint.dev", diff --git a/pkg/config/control_plane.go b/pkg/config/control_plane.go index 8f8e424e88..b4bcdab52a 100644 --- a/pkg/config/control_plane.go +++ b/pkg/config/control_plane.go @@ -52,7 +52,7 @@ func (s *ControlPlaneSpec) Validate() error { type ControlPlaneProject struct { // The unique identifier of the project. - Id string `json:"id"` + ID string `json:"id"` // The description about the project. Desc string `json:"desc"` // Static admin account of the project. @@ -108,7 +108,7 @@ func (s *SharedSSOConfig) UnmarshalJSON(data []byte) error { // FindProject finds and returns a specific project in the configured list. func (s *ControlPlaneSpec) FindProject(id string) (ControlPlaneProject, bool) { for i := range s.Projects { - if s.Projects[i].Id != id { + if s.Projects[i].ID != id { continue } return s.Projects[i], true @@ -119,7 +119,7 @@ func (s *ControlPlaneSpec) FindProject(id string) (ControlPlaneProject, bool) { func (s *ControlPlaneSpec) ProjectMap() map[string]ControlPlaneProject { m := make(map[string]ControlPlaneProject, len(s.Projects)) for i := range s.Projects { - m[s.Projects[i].Id] = s.Projects[i] + m[s.Projects[i].ID] = s.Projects[i] } return m } @@ -281,7 +281,7 @@ func (f *ControlPlaneFileStore) UnmarshalJSON(data []byte) error { } default: // Left comment out for mock response. - //err = fmt.Errorf("unsupported filestore type: %s", f.Type) + // err = fmt.Errorf("unsupported filestore type: %s", f.Type) err = nil } return err diff --git a/pkg/config/control_plane_test.go b/pkg/config/control_plane_test.go index 6e9041114f..0329920554 100644 --- a/pkg/config/control_plane_test.go +++ b/pkg/config/control_plane_test.go @@ -40,7 +40,7 @@ func TestControlPlaneConfig(t *testing.T) { expectedSpec: &ControlPlaneSpec{ Projects: []ControlPlaneProject{ { - Id: "abc", + ID: "abc", StaticAdmin: ProjectStaticUser{ Username: "test-user", PasswordHash: "test-password", diff --git a/pkg/config/piped.go b/pkg/config/piped.go index b1b6cabab2..911dad6971 100644 --- a/pkg/config/piped.go +++ b/pkg/config/piped.go @@ -643,7 +643,7 @@ type PlatformProviderTerraformConfig struct { // 'image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}' Vars []string `json:"vars,omitempty"` // Enable drift detection. - // TODO: This is a temporary option because Terraform drift detection is buggy and has performace issues. This will be possibly removed in the future release. + // TODO: This is a temporary option because Terraform drift detection is buggy and has performance issues. This will be possibly removed in the future release. DriftDetectionEnabled *bool `json:"driftDetectionEnabled" default:"true"` } diff --git a/pkg/crypto/hybrid.go b/pkg/crypto/hybrid.go index c041703ebe..884d7d81b2 100644 --- a/pkg/crypto/hybrid.go +++ b/pkg/crypto/hybrid.go @@ -45,7 +45,8 @@ func NewHybridEncrypter(key []byte) (*HybridEncrypter, error) { // Encrypt performs a regular AES-GCM + RSA-OAEP encryption. // The output string is: -// RSA ciphertext length || RSA ciphertext || AES ciphertext +// +// RSA ciphertext length || RSA ciphertext || AES ciphertext // // The implementation of this function was brought from well known Bitnami's SealedSecret library. // https://github.com/bitnami-labs/sealed-secrets/blob/master/pkg/crypto/crypto.go#L35 diff --git a/pkg/datastore/deploymentstore_test.go b/pkg/datastore/deploymentstore_test.go index fb76163261..6dda1b9e83 100644 --- a/pkg/datastore/deploymentstore_test.go +++ b/pkg/datastore/deploymentstore_test.go @@ -484,7 +484,7 @@ func TestMergeMetadata(t *testing.T) { expected: map[string]string{}, }, { - name: "ori map is emtpy", + name: "ori map is empty", new: map[string]string{ "key-1": "value-1", }, @@ -493,7 +493,7 @@ func TestMergeMetadata(t *testing.T) { }, }, { - name: "new map is emtpy", + name: "new map is empty", ori: map[string]string{ "key-1": "value-1", }, diff --git a/pkg/datastore/filedb/filter.go b/pkg/datastore/filedb/filter.go index 5a68eaf62c..760803a7d7 100644 --- a/pkg/datastore/filedb/filter.go +++ b/pkg/datastore/filedb/filter.go @@ -70,7 +70,7 @@ func filter(col datastore.Collection, e interface{}, filters []datastore.ListFil } val, ok := omap[field] - // If the object does not contain given field name in filter, return false immidiately. + // If the object does not contain given field name in filter, return false immediately. if !ok { return false, nil } diff --git a/pkg/datastore/mysql/query.go b/pkg/datastore/mysql/query.go index da414225e0..ce82db0565 100644 --- a/pkg/datastore/mysql/query.go +++ b/pkg/datastore/mysql/query.go @@ -92,7 +92,7 @@ func buildWhereClause(filters []datastore.ListFilter) (string, error) { conds[i] = fmt.Sprintf("%s %s ?", filter.Field, op) } } - return fmt.Sprintf("WHERE %s", strings.Join(conds[:], " AND ")), nil + return fmt.Sprintf("WHERE %s", strings.Join(conds, " AND ")), nil } func buildPaginationCondition(opts datastore.ListOptions) string { @@ -165,7 +165,7 @@ func buildOrderByClause(orders []datastore.Order) (string, error) { return "", fmt.Errorf("id field is required as ordering field") } - return fmt.Sprintf("ORDER BY %s", strings.Join(conds[:], ", ")), nil + return fmt.Sprintf("ORDER BY %s", strings.Join(conds, ", ")), nil } func buildLimitClause(limit int) string { diff --git a/pkg/diff/renderer_test.go b/pkg/diff/renderer_test.go index 0ae9e31f9f..3353e0cf9c 100644 --- a/pkg/diff/renderer_test.go +++ b/pkg/diff/renderer_test.go @@ -66,7 +66,7 @@ func TestRenderNodeValue(t *testing.T) { expected: "hello", }, { - name: "slice of primative elements", + name: "slice of primitive elements", value: func() reflect.Value { v := []int{1, 2, 3} return reflect.ValueOf(v) @@ -110,7 +110,7 @@ two: two-value`, v := map[string]interface{}{ "1-number": 1, "2-string": "hello", - "3-map-of-primative": mapOfPrimative, + "3-map-of-primitive": mapOfPrimative, "4-map-of-map": mapOfMap, "5-map-of-slice": mapOfSlice, "6-slice": []string{"a", "b"}, @@ -120,7 +120,7 @@ two: two-value`, }(), expected: `1-number: 1 2-string: hello -3-map-of-primative: +3-map-of-primitive: one: 1 two: 2 4-map-of-map: diff --git a/pkg/filematcher/filematcher.go b/pkg/filematcher/filematcher.go index 6a7caf5edf..f0cd1a1b6c 100644 --- a/pkg/filematcher/filematcher.go +++ b/pkg/filematcher/filematcher.go @@ -184,7 +184,8 @@ func (p *Pattern) regexpString() string { for scan.Peek() != scanner.EOF { ch := scan.Next() - if ch == '*' { + switch ch { + case '*': if scan.Peek() == '*' { // Is some flavor of "**". scan.Next() @@ -207,14 +208,14 @@ func (p *Pattern) regexpString() string { // Is "*" so map it to anything but "/". regStr += "[^" + escSL + "]*" } - } else if ch == '?' { + case '?': // "?" is any char except "/". regStr += "[^" + escSL + "]" - } else if ch == '.' || ch == '$' { + case '.', '$': // Escape some regexp special chars that have no meaning // in golang's filepath.Match. regStr += `\` + string(ch) - } else if ch == '\\' { + case '\\': // Escape next char. Note that a trailing \ in the pattern // will be left alone (but need to escape it). if sl == `\` { @@ -229,7 +230,7 @@ func (p *Pattern) regexpString() string { } else { regStr += `\` } - } else { + default: regStr += string(ch) } } diff --git a/pkg/git/client.go b/pkg/git/client.go index 980f0f5038..ea56e74072 100644 --- a/pkg/git/client.go +++ b/pkg/git/client.go @@ -268,6 +268,8 @@ func runGitCommand(ctx context.Context, execPath, dir string, envs []string, arg } // retryCommand retries a command a few times with a constant backoff. +// +//nolint:unparam func retryCommand(retries int, interval time.Duration, logger *zap.Logger, commander func() ([]byte, error)) (out []byte, err error) { for i := 0; i < retries; i++ { out, err = commander() diff --git a/pkg/git/client_test.go b/pkg/git/client_test.go index 340c2a1550..3c6caa3781 100644 --- a/pkg/git/client_test.go +++ b/pkg/git/client_test.go @@ -116,6 +116,7 @@ func (f *faker) clean() { os.RemoveAll(f.dir) } +//nolint:unparam func (f *faker) repoDir(org, repo string) string { return filepath.Join(f.dir, org, repo) } diff --git a/pkg/insight/application.go b/pkg/insight/application.go index ade280ab0b..facd806ce7 100644 --- a/pkg/insight/application.go +++ b/pkg/insight/application.go @@ -19,7 +19,7 @@ import ( ) type ApplicationData struct { - Id string `json:"id"` + ID string `json:"id"` Labels map[string]string `json:"labels"` Kind string `json:"kind"` Status string `json:"status"` @@ -34,7 +34,7 @@ func BuildApplicationData(a *model.Application) ApplicationData { status := determineApplicationStatus(a) return ApplicationData{ - Id: a.Id, + ID: a.Id, Labels: a.Labels, Kind: a.Kind.String(), Status: status.String(), diff --git a/pkg/insight/deployment.go b/pkg/insight/deployment.go index df8222415a..7aafc4901e 100644 --- a/pkg/insight/deployment.go +++ b/pkg/insight/deployment.go @@ -19,7 +19,7 @@ import ( ) type DeploymentData struct { - Id string `json:"id"` + ID string `json:"id"` AppID string `json:"app_id"` Labels map[string]string `json:"labels"` StartedAt int64 `json:"started_at"` @@ -35,7 +35,7 @@ func BuildDeploymentData(d *model.Deployment) DeploymentData { } return DeploymentData{ - Id: d.Id, + ID: d.Id, AppID: d.ApplicationId, Labels: d.Labels, StartedAt: d.CreatedAt, diff --git a/pkg/insight/insightmetrics/metrics.go b/pkg/insight/insightmetrics/metrics.go index 34ce460c75..e46d498c30 100644 --- a/pkg/insight/insightmetrics/metrics.go +++ b/pkg/insight/insightmetrics/metrics.go @@ -100,7 +100,7 @@ func groupApplicationCounts(counts []model.InsightApplicationCount) map[string]i groups := make(map[string]int, len(counts)) for _, c := range counts { kind := c.Labels[model.InsightApplicationCountLabelKey_KIND.String()] - groups[kind] = groups[kind] + int(c.Count) + groups[kind] += int(c.Count) } return groups } diff --git a/pkg/insight/insightstore/deployment_store.go b/pkg/insight/insightstore/deployment_store.go index 4d0eaf1366..29622fa622 100644 --- a/pkg/insight/insightstore/deployment_store.go +++ b/pkg/insight/insightstore/deployment_store.go @@ -272,11 +272,11 @@ func (s *store) putCompletedDeploymentsToChunk(ctx context.Context, projectID, b duplicates = 0 ) for _, d := range chunk.Deployments { - dsMap[d.Id] = struct{}{} + dsMap[d.ID] = struct{}{} mergedList = append(mergedList, d) } for _, d := range ds { - if _, ok := dsMap[d.Id]; ok { + if _, ok := dsMap[d.ID]; ok { duplicates++ continue } diff --git a/pkg/insight/insightstore/deployment_store_test.go b/pkg/insight/insightstore/deployment_store_test.go index 74909ee0d9..75ebf0a6b1 100644 --- a/pkg/insight/insightstore/deployment_store_test.go +++ b/pkg/insight/insightstore/deployment_store_test.go @@ -97,10 +97,10 @@ func TestChunkStoring(t *testing.T) { ChunkID: chunkID, Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", }, }, } @@ -137,10 +137,10 @@ func TestPutCompletedDeploymentsToChunk(t *testing.T) { ds := []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", }, } err = s.putCompletedDeploymentsToChunk(ctx, projectID, blockID, chunkID, ds) @@ -150,10 +150,10 @@ func TestPutCompletedDeploymentsToChunk(t *testing.T) { ChunkID: chunkID, Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", }, }, } @@ -164,13 +164,13 @@ func TestPutCompletedDeploymentsToChunk(t *testing.T) { // Add to an existing chunk. ds = []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", }, &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", }, &insight.DeploymentData{ - Id: "deployment-5", + ID: "deployment-5", }, } err = s.putCompletedDeploymentsToChunk(ctx, projectID, blockID, chunkID, ds) @@ -180,16 +180,16 @@ func TestPutCompletedDeploymentsToChunk(t *testing.T) { ChunkID: chunkID, Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", }, &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", }, &insight.DeploymentData{ - Id: "deployment-5", + ID: "deployment-5", }, }, } @@ -217,7 +217,7 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ds := []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: 100, }, } @@ -245,7 +245,7 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ChunkID: "chunk_0", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: 100, }, }, @@ -260,15 +260,15 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { // Add to require a new chunk because of size limit. ds = []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: 200, }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: 300, }, &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", CompletedAt: 400, }, } @@ -305,15 +305,15 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ChunkID: "chunk_0", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: 100, }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: 200, }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: 300, }, }, @@ -322,7 +322,7 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ChunkID: "chunk_1", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", CompletedAt: 400, }, }, @@ -337,11 +337,11 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { // Add to the limit of chunk to test the edge case. ds = []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-5", + ID: "deployment-5", CompletedAt: 500, }, &insight.DeploymentData{ - Id: "deployment-6", + ID: "deployment-6", CompletedAt: 600, }, } @@ -378,15 +378,15 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ChunkID: "chunk_0", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: 100, }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: 200, }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: 300, }, }, @@ -395,15 +395,15 @@ func TestPutCompletedDeploymentsBlock(t *testing.T) { ChunkID: "chunk_1", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", CompletedAt: 400, }, &insight.DeploymentData{ - Id: "deployment-5", + ID: "deployment-5", CompletedAt: 500, }, &insight.DeploymentData{ - Id: "deployment-6", + ID: "deployment-6", CompletedAt: 600, }, }, @@ -439,15 +439,15 @@ func TestGroupCompletedDeploymentsByBlock(t *testing.T) { name: "one block", ds: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: date2022.Unix(), }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: date2022.Unix() + 200, }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: date2022.Unix() + 100, }, }, @@ -456,15 +456,15 @@ func TestGroupCompletedDeploymentsByBlock(t *testing.T) { BlockID: "block_2022", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: date2022.Unix(), }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: date2022.Unix() + 100, }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: date2022.Unix() + 200, }, }, @@ -475,19 +475,19 @@ func TestGroupCompletedDeploymentsByBlock(t *testing.T) { name: "multiple blocks", ds: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: date2022.Unix(), }, &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", CompletedAt: date2023.Unix(), }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: date2022.Unix() + 200, }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: date2022.Unix() + 100, }, }, @@ -496,15 +496,15 @@ func TestGroupCompletedDeploymentsByBlock(t *testing.T) { BlockID: "block_2022", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-1", + ID: "deployment-1", CompletedAt: date2022.Unix(), }, &insight.DeploymentData{ - Id: "deployment-2", + ID: "deployment-2", CompletedAt: date2022.Unix() + 100, }, &insight.DeploymentData{ - Id: "deployment-3", + ID: "deployment-3", CompletedAt: date2022.Unix() + 200, }, }, @@ -513,7 +513,7 @@ func TestGroupCompletedDeploymentsByBlock(t *testing.T) { BlockID: "block_2023", Deployments: []*insight.DeploymentData{ &insight.DeploymentData{ - Id: "deployment-4", + ID: "deployment-4", CompletedAt: date2023.Unix(), }, }, diff --git a/pkg/model/apikey_test.go b/pkg/model/apikey_test.go index f85a4e4d0d..e480b07530 100644 --- a/pkg/model/apikey_test.go +++ b/pkg/model/apikey_test.go @@ -15,10 +15,13 @@ package model import ( + "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/crypto/bcrypt" ) func TestGenerateAPIKey(t *testing.T) { @@ -49,3 +52,93 @@ func TestAPIKeyRedactSensitiveData(t *testing.T) { apiKey.RedactSensitiveData() assert.Equal(t, apiKey.KeyHash, "redacted") } + +func TestExtractAPIKeyID(t *testing.T) { + tests := []struct { + name string + input string + expected string + expectedErr error + }{ + { + name: "Valid API Key", + input: "abc.def", + expected: "abc", + expectedErr: nil, + }, + { + name: "Empty Key", + input: "", + expected: "", + expectedErr: errors.New("malformed api key"), + }, + { + name: "Only one part", + input: "abc", + expected: "", + expectedErr: errors.New("malformed api key"), + }, + { + name: "Multiple periods", + input: "abc.def.ghi", + expected: "", + expectedErr: errors.New("malformed api key"), + }, + { + name: "Empty first part", + input: ".def", + expected: "", + expectedErr: errors.New("malformed api key"), + }, + { + name: "Empty second part", + input: "abc.", + expected: "", + expectedErr: errors.New("malformed api key"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual, err := ExtractAPIKeyID(tt.input) + assert.Equal(t, tt.expected, actual) + assert.Equal(t, tt.expectedErr, err) + }) + } +} + +func TestCompareKey(t *testing.T) { + password := "my-secret-key" + hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + hashedStr := string(hashedPassword) + apiKey := &APIKey{KeyHash: hashedStr} + + tests := []struct { + name string + input string + expectedError error + }{ + { + name: "Valid Key", + input: password, + expectedError: nil, + }, + { + name: "Invalid Key", + input: "wrong-key", + expectedError: fmt.Errorf("wrong api key wrong-key: %w", bcrypt.ErrMismatchedHashAndPassword), + }, + { + name: "Empty Key", + input: "", + expectedError: errors.New("key was empty"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := apiKey.CompareKey(tt.input) + assert.Equal(t, tt.expectedError, err) + }) + } +} diff --git a/pkg/model/application.go b/pkg/model/application.go index a912629ff3..96e5d4c912 100644 --- a/pkg/model/application.go +++ b/pkg/model/application.go @@ -89,8 +89,8 @@ func (a *Application) SetUpdatedAt(t int64) { a.UpdatedAt = t } -func (k *ApplicationKind) CompatiblePlatformProviderType() PlatformProviderType { - switch *k { +func (ak ApplicationKind) CompatiblePlatformProviderType() PlatformProviderType { + switch ak { case ApplicationKind_KUBERNETES: return PlatformProviderKubernetes case ApplicationKind_TERRAFORM: diff --git a/pkg/model/application_live_state.go b/pkg/model/application_live_state.go index 933797b2d1..077bbea2d3 100644 --- a/pkg/model/application_live_state.go +++ b/pkg/model/application_live_state.go @@ -68,7 +68,6 @@ func (s *ApplicationLiveStateSnapshot) DetermineAppHealthStatus() { case ApplicationKind_CLOUDRUN: s.determineCloudRunAppHealthStatus() } - return } func (s *ApplicationLiveStateSnapshot) determineKubernetesAppHealthStatus() { diff --git a/pkg/model/application_test.go b/pkg/model/application_test.go index fe122920b6..87cd108925 100644 --- a/pkg/model/application_test.go +++ b/pkg/model/application_test.go @@ -97,3 +97,147 @@ func TestApplication_ContainLabels(t *testing.T) { }) } } + +func TestCompatiblePlatformProviderType(t *testing.T) { + tests := []struct { + name string + kind ApplicationKind + expected PlatformProviderType + }{ + { + name: "Kubernetes Application", + kind: ApplicationKind_KUBERNETES, + expected: PlatformProviderKubernetes, + }, + { + name: "Terraform Application", + kind: ApplicationKind_TERRAFORM, + expected: PlatformProviderTerraform, + }, + { + name: "Lambda Application", + kind: ApplicationKind_LAMBDA, + expected: PlatformProviderLambda, + }, + { + name: "CloudRun Application", + kind: ApplicationKind_CLOUDRUN, + expected: PlatformProviderCloudRun, + }, + { + name: "ECS Application", + kind: ApplicationKind_ECS, + expected: PlatformProviderECS, + }, + { + name: "Default Case (assumed non-defined ApplicationKind)", + kind: ApplicationKind(9999), // assuming this isn't a defined kind + expected: PlatformProviderKubernetes, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := tt.kind.CompatiblePlatformProviderType() + assert.Equal(t, tt.expected, actual) + }) + } +} + +func TestIsOutOfSync(t *testing.T) { + tests := []struct { + name string + app *Application + expected bool + }{ + { + name: "Nil SyncState", + app: &Application{}, + expected: false, + }, + { + name: "SyncState IN_SYNC", + app: &Application{SyncState: &ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED}}, + expected: false, + }, + { + name: "SyncState OUT_OF_SYNC", + app: &Application{SyncState: &ApplicationSyncState{Status: ApplicationSyncStatus_OUT_OF_SYNC}}, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := tt.app.IsOutOfSync() + assert.Equal(t, tt.expected, actual) + }) + } +} + +func TestHasChanged(t *testing.T) { + tests := []struct { + name string + current ApplicationSyncState + next ApplicationSyncState + expected bool + }{ + { + name: "No Change", + current: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "C"}, + next: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "C"}, + expected: false, + }, + { + name: "Status Changed", + current: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "C"}, + next: ApplicationSyncState{Status: ApplicationSyncStatus_DEPLOYING, ShortReason: "B", Reason: "C"}, + expected: true, + }, + { + name: "ShortReason Changed", + current: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "C"}, + next: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "Y", Reason: "C"}, + expected: true, + }, + { + name: "Reason Changed", + current: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "C"}, + next: ApplicationSyncState{Status: ApplicationSyncStatus_SYNCED, ShortReason: "B", Reason: "Z"}, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := tt.current.HasChanged(tt.next) + assert.Equal(t, tt.expected, actual) + }) + } +} + +func TestGetApplicationConfigFilename(t *testing.T) { + tests := []struct { + name string + gitPath ApplicationGitPath + expectedName string + }{ + { + name: "Default Filename", + gitPath: ApplicationGitPath{ConfigFilename: ""}, + expectedName: oldDefaultApplicationConfigFilename, + }, + { + name: "Custom Filename", + gitPath: ApplicationGitPath{ConfigFilename: "customConfig.yaml"}, + expectedName: "customConfig.yaml", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualName := tt.gitPath.GetApplicationConfigFilename() + assert.Equal(t, tt.expectedName, actualName) + }) + } +} diff --git a/pkg/model/common.go b/pkg/model/common.go index f82bbcbbbd..093e9ad1a7 100644 --- a/pkg/model/common.go +++ b/pkg/model/common.go @@ -23,8 +23,8 @@ func ApplicationKindStrings() []string { return out } -func (x ApplicationKind) ToRollbackKind() RollbackKind { - switch x { +func (ak ApplicationKind) ToRollbackKind() RollbackKind { + switch ak { case ApplicationKind_KUBERNETES: return RollbackKind_Rollback_KUBERNETES case ApplicationKind_TERRAFORM: diff --git a/pkg/model/deployment_chain_test.go b/pkg/model/deployment_chain_test.go index 80ed67a23a..150ded5c28 100644 --- a/pkg/model/deployment_chain_test.go +++ b/pkg/model/deployment_chain_test.go @@ -21,6 +21,7 @@ import ( ) func TestDeploymentChainDesireStatus(t *testing.T) { + t.Parallel() testcases := []struct { name string deploymentChain DeploymentChain @@ -104,9 +105,258 @@ func TestDeploymentChainDesireStatus(t *testing.T) { } for _, tc := range testcases { + tc := tc t.Run(tc.name, func(t *testing.T) { + t.Parallel() desireStatus := tc.deploymentChain.DesiredStatus() assert.Equal(t, tc.expectedDesireStatus, desireStatus) }) } } +func TestListAllInChainApplicationDeploymentsMap(t *testing.T) { + t.Parallel() + dc := &DeploymentChain{ + Blocks: []*ChainBlock{ + { + Nodes: []*ChainNode{ + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app1"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep1"}, + }, + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app2"}, + DeploymentRef: nil, + }, + }, + }, + { + Nodes: []*ChainNode{ + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app2"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep2"}, + }, + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app3"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep3"}, + }, + }, + }, + }, + } + + want := map[string]*ChainDeploymentRef{ + "app1": {DeploymentId: "dep1"}, + "app2": {DeploymentId: "dep2"}, + "app3": {DeploymentId: "dep3"}, + } + + got := dc.ListAllInChainApplicationDeploymentsMap() + + assert.Equal(t, want, got) +} +func TestListAllInChainApplications(t *testing.T) { + t.Parallel() + dc := &DeploymentChain{ + Blocks: []*ChainBlock{ + { + Nodes: []*ChainNode{ + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app1"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep1"}, + }, + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app2"}, + DeploymentRef: nil, + }, + }, + }, + { + Nodes: []*ChainNode{ + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app2"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep2"}, + }, + { + ApplicationRef: &ChainApplicationRef{ApplicationId: "app3"}, + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep3"}, + }, + }, + }, + }, + } + + want := []*ChainApplicationRef{ + {ApplicationId: "app1"}, + {ApplicationId: "app2"}, + {ApplicationId: "app2"}, + {ApplicationId: "app3"}, + } + + got := dc.ListAllInChainApplications() + + assert.Equal(t, want, got) +} + +func TestIsCompleted(t *testing.T) { + t.Parallel() + tests := []struct { + name string + status ChainBlockStatus + want bool + }{ + { + name: "returns true for DEPLOYMENT_BLOCK_SUCCESS", + status: ChainBlockStatus_DEPLOYMENT_BLOCK_SUCCESS, + want: true, + }, + { + name: "returns true for DEPLOYMENT_BLOCK_FAILURE", + status: ChainBlockStatus_DEPLOYMENT_BLOCK_FAILURE, + want: true, + }, + { + name: "returns true for DEPLOYMENT_BLOCK_CANCELLED", + status: ChainBlockStatus_DEPLOYMENT_BLOCK_CANCELLED, + want: true, + }, + { + name: "returns false for DEPLOYMENT_BLOCK_PENDING", + status: ChainBlockStatus_DEPLOYMENT_BLOCK_PENDING, + want: false, + }, + { + name: "returns false for DEPLOYMENT_BLOCK_RUNNING", + status: ChainBlockStatus_DEPLOYMENT_BLOCK_RUNNING, + want: false, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + b := &ChainBlock{Status: tt.status} + got := b.IsCompleted() + assert.Equal(t, tt.want, got) + }) + } +} +func TestDesiredStatus(t *testing.T) { + t.Parallel() + tests := []struct { + name string + block *ChainBlock + wantDesired ChainBlockStatus + wantIsComplete bool + }{ + { + name: "returns DEPLOYMENT_BLOCK_SUCCESS for all successful deployments", + block: &ChainBlock{ + Nodes: []*ChainNode{ + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_SUCCESS}}, + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_SUCCESS}}, + }, + }, + wantDesired: ChainBlockStatus_DEPLOYMENT_BLOCK_SUCCESS, + }, + { + name: "returns DEPLOYMENT_BLOCK_FAILURE for at least one failed deployment", + block: &ChainBlock{ + Nodes: []*ChainNode{ + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_SUCCESS}}, + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_FAILURE}}, + }, + }, + wantDesired: ChainBlockStatus_DEPLOYMENT_BLOCK_FAILURE, + }, + { + name: "returns DEPLOYMENT_BLOCK_CANCELLED for at least one cancelled deployment", + block: &ChainBlock{ + Nodes: []*ChainNode{ + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_SUCCESS}}, + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_CANCELLED}}, + }, + }, + wantDesired: ChainBlockStatus_DEPLOYMENT_BLOCK_CANCELLED, + }, + { + name: "returns DEPLOYMENT_BLOCK_RUNNING for at least one running deployment", + block: &ChainBlock{ + Nodes: []*ChainNode{ + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_SUCCESS}}, + {DeploymentRef: &ChainDeploymentRef{Status: DeploymentStatus_DEPLOYMENT_RUNNING}}, + }, + }, + wantDesired: ChainBlockStatus_DEPLOYMENT_BLOCK_RUNNING, + }, + { + name: "returns original status if no deployments", + block: &ChainBlock{ + Status: ChainBlockStatus_DEPLOYMENT_BLOCK_PENDING, + }, + wantDesired: ChainBlockStatus_DEPLOYMENT_BLOCK_SUCCESS, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + gotDesired := tt.block.DesiredStatus() + assert.Equal(t, tt.wantDesired, gotDesired) + }) + } +} + +func TestGetNodeByDeploymentID(t *testing.T) { + t.Parallel() + block := &ChainBlock{ + Nodes: []*ChainNode{ + { + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep1"}, + }, + { + DeploymentRef: &ChainDeploymentRef{DeploymentId: "dep2"}, + }, + { + DeploymentRef: nil, + }, + }, + } + + tests := []struct { + name string + deploymentID string + wantNode *ChainNode + wantErr bool + }{ + { + name: "returns node with matching deployment ID", + deploymentID: "dep1", + wantNode: block.Nodes[0], + wantErr: false, + }, + { + name: "returns error for non-existent deployment ID", + deploymentID: "dep3", + wantNode: nil, + wantErr: true, + }, + { + name: "returns error for nil deployment ref", + deploymentID: "", + wantNode: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + gotNode, err := block.GetNodeByDeploymentID(tt.deploymentID) + assert.Equal(t, tt.wantErr, err != nil) + assert.Equal(t, tt.wantNode, gotNode) + }) + } +} diff --git a/pkg/model/deployment_test.go b/pkg/model/deployment_test.go index 4e69ca28bd..f118877ed2 100644 --- a/pkg/model/deployment_test.go +++ b/pkg/model/deployment_test.go @@ -16,6 +16,7 @@ package model import ( "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -249,3 +250,350 @@ func TestDeployment_Stage(t *testing.T) { }) } } + +func TestCanUpdateDeploymentStatus(t *testing.T) { + tests := []struct { + name string + cur DeploymentStatus + next DeploymentStatus + want bool + }{ + { + name: "can update from PENDING to PLANNED", + cur: DeploymentStatus_DEPLOYMENT_PENDING, + next: DeploymentStatus_DEPLOYMENT_PLANNED, + want: true, + }, + { + name: "cannot update from PLANNED to PENDING", + cur: DeploymentStatus_DEPLOYMENT_PLANNED, + next: DeploymentStatus_DEPLOYMENT_PENDING, + want: false, + }, + { + name: "can update from RUNNING to ROLLING_BACK", + cur: DeploymentStatus_DEPLOYMENT_RUNNING, + next: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + want: true, + }, + { + name: "cannot update from ROLLING_BACK to RUNNING", + cur: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + next: DeploymentStatus_DEPLOYMENT_RUNNING, + want: false, + }, + { + name: "can update from ROLLING_BACK to SUCCESS", + cur: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + next: DeploymentStatus_DEPLOYMENT_SUCCESS, + want: true, + }, + { + name: "cannot update from SUCCESS to ROLLING_BACK", + cur: DeploymentStatus_DEPLOYMENT_SUCCESS, + next: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + want: false, + }, + { + name: "can update from ROLLING_BACK to FAILURE", + cur: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + next: DeploymentStatus_DEPLOYMENT_FAILURE, + want: true, + }, + { + name: "cannot update from FAILURE to ROLLING_BACK", + cur: DeploymentStatus_DEPLOYMENT_FAILURE, + next: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + want: false, + }, + { + name: "can update from ROLLING_BACK to CANCELLED", + cur: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + next: DeploymentStatus_DEPLOYMENT_CANCELLED, + want: true, + }, + { + name: "cannot update from CANCELLED to ROLLING_BACK", + cur: DeploymentStatus_DEPLOYMENT_CANCELLED, + next: DeploymentStatus_DEPLOYMENT_ROLLING_BACK, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := CanUpdateDeploymentStatus(tt.cur, tt.next) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestCanUpdateStageStatus(t *testing.T) { + tests := []struct { + name string + cur StageStatus + next StageStatus + want bool + }{ + { + name: "can update from NOT_STARTED_YET to RUNNING", + cur: StageStatus_STAGE_NOT_STARTED_YET, + next: StageStatus_STAGE_RUNNING, + want: true, + }, + { + name: "can update from RUNNING to SUCCESS", + cur: StageStatus_STAGE_RUNNING, + next: StageStatus_STAGE_SUCCESS, + want: true, + }, + { + name: "can update from RUNNING to FAILURE", + cur: StageStatus_STAGE_RUNNING, + next: StageStatus_STAGE_FAILURE, + want: true, + }, + { + name: "can update from RUNNING to CANCELLED", + cur: StageStatus_STAGE_RUNNING, + next: StageStatus_STAGE_CANCELLED, + want: true, + }, + { + name: "cannot update from SUCCESS to RUNNING", + cur: StageStatus_STAGE_SUCCESS, + next: StageStatus_STAGE_RUNNING, + want: false, + }, + { + name: "cannot update from FAILURE to RUNNING", + cur: StageStatus_STAGE_FAILURE, + next: StageStatus_STAGE_RUNNING, + want: false, + }, + { + name: "cannot update from CANCELLED to RUNNING", + cur: StageStatus_STAGE_CANCELLED, + next: StageStatus_STAGE_RUNNING, + want: false, + }, + { + name: "cannot update from SUCCESS to FAILURE", + cur: StageStatus_STAGE_SUCCESS, + next: StageStatus_STAGE_FAILURE, + want: false, + }, + { + name: "cannot update from SUCCESS to CANCELLED", + cur: StageStatus_STAGE_SUCCESS, + next: StageStatus_STAGE_CANCELLED, + want: false, + }, + { + name: "cannot update from FAILURE to SUCCESS", + cur: StageStatus_STAGE_FAILURE, + next: StageStatus_STAGE_SUCCESS, + want: false, + }, + { + name: "cannot update from FAILURE to CANCELLED", + cur: StageStatus_STAGE_FAILURE, + next: StageStatus_STAGE_CANCELLED, + want: false, + }, + { + name: "cannot update from CANCELLED to SUCCESS", + cur: StageStatus_STAGE_CANCELLED, + next: StageStatus_STAGE_SUCCESS, + want: false, + }, + { + name: "cannot update from CANCELLED to FAILURE", + cur: StageStatus_STAGE_CANCELLED, + next: StageStatus_STAGE_FAILURE, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := CanUpdateStageStatus(tt.cur, tt.next) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestTriggeredBy(t *testing.T) { + tests := []struct { + name string + trigger DeploymentTrigger + want string + }{ + { + name: "returns commander name if set", + trigger: DeploymentTrigger{ + Commander: "Alice", + Commit: &Commit{ + Author: "Bob", + }, + }, + want: "Alice", + }, + { + name: "returns commit author name if commander not set", + trigger: DeploymentTrigger{ + Commander: "", + Commit: &Commit{ + Author: "Bob", + }, + }, + want: "Bob", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := &Deployment{ + Trigger: &tt.trigger, + } + got := d.TriggeredBy() + assert.Equal(t, tt.want, got) + }) + } +} + +func TestTriggerBefore(t *testing.T) { + now := time.Now() + tests := []struct { + name string + d Deployment + other Deployment + want bool + }{ + { + name: "returns true if d trigger is before other trigger", + d: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Add(-time.Hour).Unix(), + }, + Timestamp: now.Add(-time.Minute).Unix(), + }, + }, + other: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Unix(), + }, + }, + want: true, + }, + { + name: "returns false if d trigger is after other trigger", + d: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Unix(), + }, + }, + other: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Add(-time.Hour).Unix(), + }, + Timestamp: now.Add(-time.Minute).Unix(), + }, + }, + want: false, + }, + { + name: "returns true if d trigger is same as other trigger", + d: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Unix(), + }, + }, + other: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Unix(), + }, + }, + want: true, + }, + { + name: "returns false if d trigger is same as other trigger", + d: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Add(time.Minute).Unix(), + }, + }, + other: Deployment{ + Trigger: &DeploymentTrigger{ + Commit: &Commit{ + CreatedAt: now.Unix(), + }, + Timestamp: now.Unix(), + }, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.d.TriggerBefore(&tt.other) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestFindRollbackStage(t *testing.T) { + tests := []struct { + name string + stages []*PipelineStage + wantStage *PipelineStage + wantStageFound bool + }{ + { + name: "found", + stages: []*PipelineStage{ + {Name: StageK8sSync.String()}, + {Name: StageRollback.String()}, + }, + wantStage: &PipelineStage{Name: StageRollback.String()}, + wantStageFound: true, + }, + { + name: "not found", + stages: []*PipelineStage{ + {Name: StageK8sSync.String()}, + }, + wantStage: nil, + wantStageFound: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := &Deployment{ + Stages: tt.stages, + } + stage, found := d.FindRollbackStage() + assert.Equal(t, tt.wantStage, stage) + assert.Equal(t, tt.wantStageFound, found) + }) + } +} diff --git a/pkg/model/notificationevent_test.go b/pkg/model/notificationevent_test.go new file mode 100644 index 0000000000..53e5c43770 --- /dev/null +++ b/pkg/model/notificationevent_test.go @@ -0,0 +1,66 @@ +// Copyright 2023 The PipeCD 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 model + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGroup(t *testing.T) { + t.Parallel() + tests := []struct { + name string + typ NotificationEventType + want NotificationEventGroup + }{ + { + name: "returns EVENT_DEPLOYMENT for type < 100", + typ: 99, + want: NotificationEventGroup_EVENT_DEPLOYMENT, + }, + { + name: "returns EVENT_APPLICATION_SYNC for type < 200", + typ: 199, + want: NotificationEventGroup_EVENT_APPLICATION_SYNC, + }, + { + name: "returns EVENT_APPLICATION_HEALTH for type < 300", + typ: 299, + want: NotificationEventGroup_EVENT_APPLICATION_HEALTH, + }, + { + name: "returns EVENT_PIPED for type < 400", + typ: 399, + want: NotificationEventGroup_EVENT_PIPED, + }, + { + name: "returns EVENT_NONE for type >= 400", + typ: 400, + want: NotificationEventGroup_EVENT_NONE, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + e := NotificationEvent{Type: tt.typ} + got := e.Group() + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/model/project.go b/pkg/model/project.go index f21bc48827..d7752bbb3d 100644 --- a/pkg/model/project.go +++ b/pkg/model/project.go @@ -209,51 +209,39 @@ func (p *ProjectStaticUser) Auth(username, password string) error { // RedactSensitiveData redacts sensitive data. func (p *ProjectSSOConfig) RedactSensitiveData() { - if p.Github != nil { - p.Github.RedactSensitiveData() - } - if p.Google != nil { + if p.Github == nil { + return } + p.Github.RedactSensitiveData() } // Update updates ProjectSSOConfig with given data. func (p *ProjectSSOConfig) Update(sso *ProjectSSOConfig) error { p.Provider = sso.Provider - if sso.Github != nil { - if p.Github == nil { - p.Github = &ProjectSSOConfig_GitHub{} - } - if err := p.Github.Update(sso.Github); err != nil { - return err - } + if sso.Github == nil { + return nil } - if sso.Google != nil { + + if p.Github == nil { + p.Github = &ProjectSSOConfig_GitHub{} } - return nil + return p.Github.Update(sso.Github) } // Encrypt encrypts sensitive data in ProjectSSOConfig. func (p *ProjectSSOConfig) Encrypt(encrypter encrypter) error { - if p.Github != nil { - if err := p.Github.Encrypt(encrypter); err != nil { - return err - } - } - if p.Google != nil { + if p.Github == nil { + return nil } - return nil + return p.Github.Encrypt(encrypter) } // Decrypt decrypts encrypted data in ProjectSSOConfig. func (p *ProjectSSOConfig) Decrypt(decrypter decrypter) error { - if p.Github != nil { - if err := p.Github.Decrypt(decrypter); err != nil { - return err - } - } - if p.Google != nil { + if p.Github == nil { + return nil } - return nil + return p.Github.Decrypt(decrypter) } // GenerateAuthCodeURL generates an auth URL for the specified configuration. diff --git a/pkg/rpc/grpc_test.go b/pkg/rpc/grpc_test.go index 5a657e737f..105876c6df 100644 --- a/pkg/rpc/grpc_test.go +++ b/pkg/rpc/grpc_test.go @@ -22,5 +22,5 @@ import ( ) func TestVersion(t *testing.T) { - require.Equal(t, "1.54.0", grpc.Version) + require.Equal(t, "1.56.3", grpc.Version) } diff --git a/tool/actions-gh-release/go.mod b/tool/actions-gh-release/go.mod index 987c66554f..89dce2114f 100644 --- a/tool/actions-gh-release/go.mod +++ b/tool/actions-gh-release/go.mod @@ -15,8 +15,8 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/tool/actions-gh-release/go.sum b/tool/actions-gh-release/go.sum index d0ab75e4f9..877a1ef1fa 100644 --- a/tool/actions-gh-release/go.sum +++ b/tool/actions-gh-release/go.sum @@ -23,12 +23,12 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= diff --git a/tool/actions-plan-preview/go.mod b/tool/actions-plan-preview/go.mod index 71649357b5..b97ddc8d31 100644 --- a/tool/actions-plan-preview/go.mod +++ b/tool/actions-plan-preview/go.mod @@ -15,8 +15,8 @@ require ( github.com/google/go-querystring v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect diff --git a/tool/actions-plan-preview/go.sum b/tool/actions-plan-preview/go.sum index 8b9cb50b94..4ec54ececd 100644 --- a/tool/actions-plan-preview/go.sum +++ b/tool/actions-plan-preview/go.sum @@ -22,12 +22,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= diff --git a/tool/actions-plan-preview/main.go b/tool/actions-plan-preview/main.go index 9194030543..34f321eff6 100644 --- a/tool/actions-plan-preview/main.go +++ b/tool/actions-plan-preview/main.go @@ -36,11 +36,12 @@ const ( commentEventName = "issue_comment" pushEventName = "push" - argAddress = "address" - argAPIKey = "api-key" - argToken = "token" - argTimeout = "timeout" - argPRNum = "pull-request-number" + argAddress = "address" + argAPIKey = "api-key" + argToken = "token" + argTimeout = "timeout" + argPipedHandleTimeout = "piped-handle-timeout" + argPRNum = "pull-request-number" ) func main() { @@ -101,14 +102,14 @@ func main() { } if event.PRClosed { - doComment(failureBadgeURL + "Unable to run plan-preview for a closed pull request.") + doComment(failureBadgeURL + "\nUnable to run plan-preview for a closed pull request.") return } // TODO: When PR opened, `Mergeable` is nil for calculation. // Here it is not considered for now, but needs to be handled. if event.PRMergeable != nil && *event.PRMergeable == false { - doComment(failureBadgeURL + "Unable to run plan-preview for an un-mergeable pull request. Please resolve the conficts and try again.") + doComment(failureBadgeURL + "\nUnable to run plan-preview for an un-mergeable pull request. Please resolve the conficts and try again.") return } @@ -121,8 +122,10 @@ func main() { args.Address, args.APIKey, args.Timeout, + args.PipedHandleTimeout, ) if err != nil { + doComment(failureBadgeURL + "\nUnable to run plan-preview. \ncause: " + err.Error()) log.Fatal(err) } log.Println("Successfully retrieved plan-preview result") @@ -131,12 +134,17 @@ func main() { if result.HasError() { pr, err := getPullRequest(ctx, ghClient.PullRequests, event.Owner, event.Repo, event.PRNumber) if err != nil { + doComment(failureBadgeURL + "\nUnable to run plan-preview. \ncause: " + err.Error()) log.Fatal(err) } if !pr.GetClosedAt().IsZero() { - doComment(failureBadgeURL + "Unable to run plan-preview for a closed pull request.") + doComment(failureBadgeURL + "\nUnable to run plan-preview for a closed pull request.") return } + body := makeCommentBody(event, result) + doComment(failureBadgeURL + "\n" + body) + log.Println("plan-preview result has error") + os.Exit(1) } // Find comments we sent before @@ -166,11 +174,12 @@ func main() { } type arguments struct { - Address string - APIKey string - Token string - Timeout time.Duration - PRNum int + Address string + APIKey string + Token string + Timeout time.Duration + PipedHandleTimeout time.Duration + PRNum int } func parseArgs(args []string) (arguments, error) { @@ -194,6 +203,12 @@ func parseArgs(args []string) (arguments, error) { return arguments{}, err } out.Timeout = d + case argPipedHandleTimeout: + d, err := time.ParseDuration(ps[1]) + if err != nil { + return arguments{}, err + } + out.PipedHandleTimeout = d case argPRNum: if ps[1] == "" { continue @@ -221,6 +236,9 @@ func parseArgs(args []string) (arguments, error) { if out.Timeout == 0 { out.Timeout = defaultTimeout } + if out.PipedHandleTimeout == 0 { + out.PipedHandleTimeout = defaultTimeout + } return out, nil } diff --git a/tool/actions-plan-preview/main_test.go b/tool/actions-plan-preview/main_test.go index b098fed85d..14d96dc068 100644 --- a/tool/actions-plan-preview/main_test.go +++ b/tool/actions-plan-preview/main_test.go @@ -16,8 +16,11 @@ package main import ( "embed" + "fmt" "testing" + "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -33,3 +36,134 @@ func readTestdataFile(t *testing.T, name string) []byte { func boolPointer(b bool) *bool { return &b } + +func Test_parseArgs(t *testing.T) { + type args struct { + args []string + } + tests := []struct { + name string + args args + want arguments + wantErr assert.ErrorAssertionFunc + }{ + { + name: "minimum required args with no error", + args: args{ + args: []string{ + "address=localhost:8080", + "api-key=xxxxxxxxxxxxxx", + "token=xxxxxxxxxxxxxxxx", + }, + }, + want: arguments{ + Address: "localhost:8080", + APIKey: "xxxxxxxxxxxxxx", + Token: "xxxxxxxxxxxxxxxx", + Timeout: defaultTimeout, + PipedHandleTimeout: defaultTimeout, + }, + wantErr: assert.NoError, + }, + { + name: "minimum required args and specified timeout arg with no error", + args: args{ + args: []string{ + "address=localhost:8080", + "api-key=xxxxxxxxxxxxxx", + "token=xxxxxxxxxxxxxxxx", + "timeout=10m", + }, + }, + want: arguments{ + Address: "localhost:8080", + APIKey: "xxxxxxxxxxxxxx", + Token: "xxxxxxxxxxxxxxxx", + Timeout: 10 * time.Minute, + PipedHandleTimeout: defaultTimeout, + }, + wantErr: assert.NoError, + }, + { + name: "minimum required args and specified piped-handle-timeout arg with no error", + args: args{ + args: []string{ + "address=localhost:8080", + "api-key=xxxxxxxxxxxxxx", + "token=xxxxxxxxxxxxxxxx", + "piped-handle-timeout=10m", + }, + }, + want: arguments{ + Address: "localhost:8080", + APIKey: "xxxxxxxxxxxxxx", + Token: "xxxxxxxxxxxxxxxx", + Timeout: defaultTimeout, + PipedHandleTimeout: 10 * time.Minute, + }, + wantErr: assert.NoError, + }, + { + name: "minimum required args and specified timeout and piped-handle-timeout arg with no error", + args: args{ + args: []string{ + "address=localhost:8080", + "api-key=xxxxxxxxxxxxxx", + "token=xxxxxxxxxxxxxxxx", + "timeout=12m", + "piped-handle-timeout=15m", + }, + }, + want: arguments{ + Address: "localhost:8080", + APIKey: "xxxxxxxxxxxxxx", + Token: "xxxxxxxxxxxxxxxx", + Timeout: 12 * time.Minute, + PipedHandleTimeout: 15 * time.Minute, + }, + wantErr: assert.NoError, + }, + { + name: "missing required args (address) returns error", + args: args{ + args: []string{ + "api-key=xxxxxxxxxxxxxx", + "token=xxxxxxxxxxxxxxxx", + }, + }, + want: arguments{}, + wantErr: assert.Error, + }, + { + name: "missing required args (api-key) returns error", + args: args{ + args: []string{ + "address=localhost:8080", + "token=xxxxxxxxxxxxxxxx", + }, + }, + want: arguments{}, + wantErr: assert.Error, + }, + { + name: "missing required args (token) returns error", + args: args{ + args: []string{ + "address=localhost:8080", + "api-key=xxxxxxxxxxxxxx", + }, + }, + want: arguments{}, + wantErr: assert.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseArgs(tt.args.args) + if tt.wantErr(t, err, fmt.Sprintf("parseArgs(%v)", tt.args.args)) { + return + } + assert.Equalf(t, tt.want, got, "parseArgs(%v)", tt.args.args) + }) + } +} diff --git a/tool/actions-plan-preview/planpreview.go b/tool/actions-plan-preview/planpreview.go index c30dbff490..48a7d2f3e3 100644 --- a/tool/actions-plan-preview/planpreview.go +++ b/tool/actions-plan-preview/planpreview.go @@ -84,6 +84,7 @@ func retrievePlanPreview( address, apiKey string, timeout time.Duration, + pipedHandleTimeout time.Duration, ) (*PlanPreviewResult, error) { dir, err := os.MkdirTemp("", "") @@ -101,6 +102,7 @@ func retrievePlanPreview( "--address", address, "--api-key", apiKey, "--timeout", timeout.String(), + "--piped-handle-timeout", pipedHandleTimeout.String(), "--out", outPath, } cmd := exec.CommandContext(ctx, "pipectl", args...) diff --git a/tool/actions-plan-preview/testdata/comment-has-failed-app.txt b/tool/actions-plan-preview/testdata/comment-has-failed-app.txt index 451a394c9d..34734d3a00 100644 --- a/tool/actions-plan-preview/testdata/comment-has-failed-app.txt +++ b/tool/actions-plan-preview/testdata/comment-has-failed-app.txt @@ -3,7 +3,9 @@ Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. -## app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 +## Plans + +### app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 Sync strategy: PIPELINE Summary: plan-summary-1 @@ -17,12 +19,11 @@ plan-details-1

---- ## NOTE **An error occurred while building plan-preview for the following applications** -## app: [app-name-2](app-url-2), env: env-2, kind: app-kind-2 +### app: [app-name-2](app-url-2), env: env-2, kind: app-kind-2 Reason: reason-2 diff --git a/tool/actions-plan-preview/testdata/comment-has-failed-piped.txt b/tool/actions-plan-preview/testdata/comment-has-failed-piped.txt index 633ccca518..5075144422 100644 --- a/tool/actions-plan-preview/testdata/comment-has-failed-piped.txt +++ b/tool/actions-plan-preview/testdata/comment-has-failed-piped.txt @@ -3,7 +3,9 @@ Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. -## app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 +## Plans + +### app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 Sync strategy: PIPELINE Summary: plan-summary-1 @@ -17,12 +19,11 @@ plan-details-1

---- ## NOTE **An error occurred while building plan-preview for applications of the following Pipeds** -## piped: [piped-id-1](piped-url-1) +### piped: [piped-id-1](piped-url-1) Reason: piped-reason-1 diff --git a/tool/actions-plan-preview/testdata/comment-has-no-diff-apps.txt b/tool/actions-plan-preview/testdata/comment-has-no-diff-apps.txt index 9b9f548857..bdb55d2781 100644 --- a/tool/actions-plan-preview/testdata/comment-has-no-diff-apps.txt +++ b/tool/actions-plan-preview/testdata/comment-has-no-diff-apps.txt @@ -3,7 +3,9 @@ Ran plan-preview against head commit abc of this pull request. PipeCD detected `3` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. -## app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 +## Plans + +### app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 Sync strategy: PIPELINE Summary: plan-summary-1 @@ -17,7 +19,7 @@ plan-details-1

-## No resource changes were detected but the following apps will also be triggered +### No resource changes were detected but the following apps will also be triggered ###### `PIPELINE` diff --git a/tool/actions-plan-preview/testdata/comment-no-env.txt b/tool/actions-plan-preview/testdata/comment-no-env.txt index 3a413ea0f9..7afcbf2d63 100644 --- a/tool/actions-plan-preview/testdata/comment-no-env.txt +++ b/tool/actions-plan-preview/testdata/comment-no-env.txt @@ -3,7 +3,9 @@ Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. -## app: [app-name-1](app-url-1), kind: app-kind-1 +## Plans + +### app: [app-name-1](app-url-1), kind: app-kind-1 Sync strategy: PIPELINE Summary: plan-summary-1 @@ -16,3 +18,4 @@ plan-details-1 ```

+ diff --git a/tool/actions-plan-preview/testdata/comment-only-changed-app.txt b/tool/actions-plan-preview/testdata/comment-only-changed-app.txt index 7424801491..da1f4a5dc0 100644 --- a/tool/actions-plan-preview/testdata/comment-only-changed-app.txt +++ b/tool/actions-plan-preview/testdata/comment-only-changed-app.txt @@ -3,7 +3,9 @@ Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. -## app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 +## Plans + +### app: [app-name-1](app-url-1), env: env-1, kind: app-kind-1 Sync strategy: PIPELINE Summary: plan-summary-1 @@ -16,3 +18,4 @@ plan-details-1 ```

+ diff --git a/web/yarn.lock b/web/yarn.lock index 3bc789ffab..df3371eaef 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -31,13 +31,6 @@ dependencies: "@babel/highlight" "^7.12.13" -"@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -45,6 +38,14 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + "@babel/code-frame@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" @@ -104,15 +105,6 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.14.5", "@babel/generator@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" - integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== - dependencies: - "@babel/types" "^7.14.5" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" @@ -132,6 +124,25 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + dependencies: + "@babel/types" "^7.23.0" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/generator@^7.7.2": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" + integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== + dependencies: + "@babel/types" "^7.14.5" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" @@ -160,64 +171,23 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-environment-visitor@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== -"@babel/helper-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" - integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== - dependencies: - "@babel/helper-get-function-arity" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" - integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== - dependencies: - "@babel/helper-get-function-arity" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" - integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== dependencies: - "@babel/template" "^7.22.5" - "@babel/types" "^7.22.5" - -"@babel/helper-get-function-arity@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" - integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-get-function-arity@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" - integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-hoist-variables@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" - integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" @@ -302,13 +272,6 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" - integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== - dependencies: - "@babel/types" "^7.14.5" - "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -323,6 +286,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" @@ -353,6 +323,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" @@ -413,15 +388,6 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - "@babel/highlight@^7.16.7": version "7.16.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" @@ -431,6 +397,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + "@babel/highlight@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" @@ -445,7 +420,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.1.tgz#2e142c27ca58aa2c7b119d09269b702c8bbad28c" integrity sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg== -"@babel/parser@^7.14.5", "@babel/parser@^7.14.7": +"@babel/parser@^7.14.7": version "7.14.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== @@ -455,6 +430,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.10.tgz#aba1b1cb9696a24a19f59c41af9cf17d1c716a88" integrity sha512-Sm/S9Or6nN8uiFsQU1yodyDW3MWXQhFeqzMPM+t8MJjM+pLsnFVxFZzkpXKvUXh+Gz9cbMoYYs484+Jw/NTEFQ== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + "@babel/parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" @@ -616,15 +596,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" - "@babel/template@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -634,6 +605,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + "@babel/template@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" @@ -652,50 +632,19 @@ "@babel/parser" "^7.10.1" "@babel/types" "^7.10.1" -"@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" - integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== +"@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7", "@babel/traverse@^7.22.5", "@babel/traverse@^7.7.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.10" - "@babel/types" "^7.16.8" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" - integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== - dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.7.2": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" - integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.7" - "@babel/types" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" @@ -724,6 +673,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@babel/types@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" @@ -2477,7 +2435,7 @@ caniuse-lite@^1.0.30001503: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz#4461bbc895c692a96da399639cc1e146e7302a33" integrity sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw== -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==