Repository: ovh/cds
Pull request #6049 (2022-01-03 09:10:45)

refactor(worker): junit parser
1. Description
1. Related issues
1. About tests
1. Mentions

@ovh/cds


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=ovh_cds&pullRequest=6049&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=ovh_cds&pullRequest=6049&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=ovh_cds&pullRequest=6049&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=ovh_cds&pullRequest=6049&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=ovh_cds&pullRequest=6049&metric=coverage&view=list) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=ovh_cds&pullRequest=6049&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/contrib/grpcplugins/action/plugin-archive/go.mod b/contrib/grpcplugins/action/plugin-archive/go.mod
index 6de45ee93..66b881077 100644
--- a/contrib/grpcplugins/action/plugin-archive/go.mod
+++ b/contrib/grpcplugins/action/plugin-archive/go.mod
@@ -26,7 +26,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -37,7 +36,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -53,13 +51,10 @@ require (
 	github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.7 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -72,7 +67,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.10 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -93,6 +87,5 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-archive/go.sum b/contrib/grpcplugins/action/plugin-archive/go.sum
index 725e5bce5..dd9902f7f 100644
--- a/contrib/grpcplugins/action/plugin-archive/go.sum
+++ b/contrib/grpcplugins/action/plugin-archive/go.sum
@@ -133,7 +133,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -415,8 +414,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -453,8 +450,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -532,7 +527,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.mod b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.mod
index 1fb5b8b47..9b3ec60b1 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.mod
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.mod
@@ -33,7 +33,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/fsnotify/fsnotify v1.4.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
@@ -70,12 +69,10 @@ require (
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
 	github.com/mitchellh/mapstructure v1.4.1 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pelletier/go-toml v1.9.3 // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
@@ -88,7 +85,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.6.0 // indirect
 	github.com/spf13/cast v1.4.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.sum b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.sum
index 85dbf6e23..d22e3f2ce 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.sum
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-create/go.sum
@@ -166,7 +166,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -510,8 +509,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
 github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
 github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -548,8 +545,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.mod b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.mod
index cf2f9d013..04da75f5a 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.mod
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.mod
@@ -24,7 +24,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -35,7 +34,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -51,13 +49,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.4.1 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -69,7 +64,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.6.0 // indirect
 	github.com/spf13/viper v1.8.1 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
@@ -91,5 +85,4 @@ require (
 	google.golang.org/grpc v1.38.0 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.sum b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.sum
index 63e5b8959..5714654fa 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.sum
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/go.sum
@@ -157,7 +157,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -465,8 +464,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
 github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
 github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -503,8 +500,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -584,7 +579,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/main.go b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/main.go
index cd3538c23..147573b92 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/main.go
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/main.go
@@ -64,9 +64,6 @@ func (actPlugin *artifactoryReleaseBundleDistributePlugin) Run(ctx context.Conte
 	if err != nil {
 		return actionplugin.Fail("%v", err)
 	}
-	if q.GetOptions()["distribute_only_on_edges"] != "true" {
-		edges = edge.RemoveNonEdge(edges)
-	}
 
 	if len(edges) == 0 {
 		return actionplugin.Fail("No destination available. Please check your credentials", err)
diff --git a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/plugin-artifactory-release-bundle-distribute.yml b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/plugin-artifactory-release-bundle-distribute.yml
index 866bcdf9b..192354503 100644
--- a/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/plugin-artifactory-release-bundle-distribute.yml
+++ b/contrib/grpcplugins/action/plugin-artifactory-release-bundle-distribute/plugin-artifactory-release-bundle-distribute.yml
@@ -19,8 +19,3 @@ parameters:
     type: string
     description: JFrog Distribution token variable name. Leave empty to use integration.
     advanced: true
-  distribute_only_on_edges:
-    type: boolean
-    description: Distribute release bundle only on edges.
-    default: "true"
-    advanced: true
diff --git a/contrib/grpcplugins/action/plugin-download/go.mod b/contrib/grpcplugins/action/plugin-download/go.mod
index 83b5b9207..37c9bae91 100644
--- a/contrib/grpcplugins/action/plugin-download/go.mod
+++ b/contrib/grpcplugins/action/plugin-download/go.mod
@@ -25,7 +25,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -36,7 +35,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -53,13 +51,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -72,7 +67,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -93,6 +87,5 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-download/go.sum b/contrib/grpcplugins/action/plugin-download/go.sum
index 3c8bccbbc..339950179 100644
--- a/contrib/grpcplugins/action/plugin-download/go.sum
+++ b/contrib/grpcplugins/action/plugin-download/go.sum
@@ -132,7 +132,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -414,8 +413,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -452,8 +449,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -530,7 +525,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-group-tmpl/go.mod b/contrib/grpcplugins/action/plugin-group-tmpl/go.mod
index e23151b21..133a83bbb 100644
--- a/contrib/grpcplugins/action/plugin-group-tmpl/go.mod
+++ b/contrib/grpcplugins/action/plugin-group-tmpl/go.mod
@@ -23,7 +23,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -34,7 +33,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -51,13 +49,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -69,7 +64,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -90,5 +84,4 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-group-tmpl/go.sum b/contrib/grpcplugins/action/plugin-group-tmpl/go.sum
index 3c8bccbbc..339950179 100644
--- a/contrib/grpcplugins/action/plugin-group-tmpl/go.sum
+++ b/contrib/grpcplugins/action/plugin-group-tmpl/go.sum
@@ -132,7 +132,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -414,8 +413,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -452,8 +449,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -530,7 +525,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-kafka-publish/go.mod b/contrib/grpcplugins/action/plugin-kafka-publish/go.mod
index 956862603..253c99577 100644
--- a/contrib/grpcplugins/action/plugin-kafka-publish/go.mod
+++ b/contrib/grpcplugins/action/plugin-kafka-publish/go.mod
@@ -51,7 +51,6 @@ require (
 	github.com/gorilla/mux v1.8.0 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/hashicorp/go-uuid v1.0.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -78,8 +77,6 @@ require (
 	github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/olekukonko/tablewriter v0.0.0-20160621093029-daf2955e742c // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
@@ -87,7 +84,6 @@ require (
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
 	github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5 // indirect
 	github.com/ovh/symmecrypt v0.5.1 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4 v2.6.1+incompatible // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
@@ -103,7 +99,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/spf13/cobra v1.1.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
diff --git a/contrib/grpcplugins/action/plugin-kafka-publish/go.sum b/contrib/grpcplugins/action/plugin-kafka-publish/go.sum
index f1c492907..789daf595 100644
--- a/contrib/grpcplugins/action/plugin-kafka-publish/go.sum
+++ b/contrib/grpcplugins/action/plugin-kafka-publish/go.sum
@@ -444,8 +444,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -488,8 +486,6 @@ github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5 h1:E5fS/QLKUEcIn
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1 h1:WjCjCFEHuap5V4sM1AaGm2AzZh0KE/vhx9q9tZn3JVQ=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
@@ -572,7 +568,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-marathon/go.mod b/contrib/grpcplugins/action/plugin-marathon/go.mod
index e0608a813..81319f3f7 100644
--- a/contrib/grpcplugins/action/plugin-marathon/go.mod
+++ b/contrib/grpcplugins/action/plugin-marathon/go.mod
@@ -42,7 +42,6 @@ require (
 	github.com/google/go-querystring v1.0.0 // indirect
 	github.com/gookit/color v1.4.2 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -62,13 +61,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/olekukonko/tablewriter v0.0.0-20160621093029-daf2955e742c // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -81,7 +77,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/spf13/cobra v1.1.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
diff --git a/contrib/grpcplugins/action/plugin-marathon/go.sum b/contrib/grpcplugins/action/plugin-marathon/go.sum
index 721a0a960..b90957374 100644
--- a/contrib/grpcplugins/action/plugin-marathon/go.sum
+++ b/contrib/grpcplugins/action/plugin-marathon/go.sum
@@ -426,8 +426,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -466,8 +464,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20191126072910-b8d81d038865 h1:bK/cGXa
 github.com/ovh/cds/sdk/interpolate v0.0.0-20191126072910-b8d81d038865/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -544,7 +540,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod
index baf8cb67e..21ea17a7e 100644
--- a/contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod
+++ b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod
@@ -23,7 +23,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -34,7 +33,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -51,13 +49,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -69,7 +64,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -90,5 +84,4 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum
index 3c8bccbbc..339950179 100644
--- a/contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum
+++ b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum
@@ -132,7 +132,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -414,8 +413,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -452,8 +449,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -530,7 +525,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-ssh-cmd/go.mod b/contrib/grpcplugins/action/plugin-ssh-cmd/go.mod
index 3529639b8..80a5bd55d 100644
--- a/contrib/grpcplugins/action/plugin-ssh-cmd/go.mod
+++ b/contrib/grpcplugins/action/plugin-ssh-cmd/go.mod
@@ -24,7 +24,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -35,7 +34,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -52,13 +50,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -70,7 +65,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -90,5 +84,4 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-ssh-cmd/go.sum b/contrib/grpcplugins/action/plugin-ssh-cmd/go.sum
index 3c8bccbbc..339950179 100644
--- a/contrib/grpcplugins/action/plugin-ssh-cmd/go.sum
+++ b/contrib/grpcplugins/action/plugin-ssh-cmd/go.sum
@@ -132,7 +132,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -414,8 +413,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -452,8 +449,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -530,7 +525,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-tmpl/go.mod b/contrib/grpcplugins/action/plugin-tmpl/go.mod
index 848b1727c..f2d60040e 100644
--- a/contrib/grpcplugins/action/plugin-tmpl/go.mod
+++ b/contrib/grpcplugins/action/plugin-tmpl/go.mod
@@ -23,7 +23,6 @@ require (
 	github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
 	github.com/eapache/go-resiliency v1.2.0 // indirect
 	github.com/emirpasic/gods v1.12.0 // indirect
-	github.com/fatih/color v1.7.0 // indirect
 	github.com/fsamin/go-dump v1.0.9 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
 	github.com/go-git/go-billy/v5 v5.3.1 // indirect
@@ -34,7 +33,6 @@ require (
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gookit/color v1.4.2 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.2.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -51,13 +49,10 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect
-	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/nwaples/rardecode v1.1.0 // indirect
 	github.com/onsi/ginkgo v1.11.0 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 // indirect
-	github.com/ovh/venom v0.25.0 // indirect
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
 	github.com/pierrec/lz4/v4 v4.1.2 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -69,7 +64,6 @@ require (
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/ulikunitz/xz v0.5.9 // indirect
 	github.com/xanzy/ssh-agent v0.3.0 // indirect
@@ -90,5 +84,4 @@ require (
 	google.golang.org/grpc v1.27.1 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/contrib/grpcplugins/action/plugin-tmpl/go.sum b/contrib/grpcplugins/action/plugin-tmpl/go.sum
index 3c8bccbbc..339950179 100644
--- a/contrib/grpcplugins/action/plugin-tmpl/go.sum
+++ b/contrib/grpcplugins/action/plugin-tmpl/go.sum
@@ -132,7 +132,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -414,8 +413,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -452,8 +449,6 @@ github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25 h1:pV462fy
 github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25/go.mod h1:qrsz1nc0EPZnhuTLZpKK4Y7awUQdeKmkY5M6DbKi6Ws=
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -530,7 +525,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/contrib/grpcplugins/action/plugin-venom/go.sum b/contrib/grpcplugins/action/plugin-venom/go.sum
index 86d6da642..ba43bad19 100644
--- a/contrib/grpcplugins/action/plugin-venom/go.sum
+++ b/contrib/grpcplugins/action/plugin-venom/go.sum
@@ -489,7 +489,6 @@ github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qF
 github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=
 github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/ovh/venom v0.26.0 h1:t+mdbA9Mf0wyRIfBGv9wkYJnsDRbTho5eUpbQ8UChwk=
 github.com/ovh/venom v0.26.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/contrib/integrations/artifactory/plugin-artifactory-release/edge/edge.go b/contrib/integrations/artifactory/plugin-artifactory-release/edge/edge.go
index 0ef30c34a..4fb34a723 100644
--- a/contrib/integrations/artifactory/plugin-artifactory-release/edge/edge.go
+++ b/contrib/integrations/artifactory/plugin-artifactory-release/edge/edge.go
@@ -49,14 +49,3 @@ func ListEdgeNodes(distriClient *distribution.DistributionServicesManager, url,
 	}
 	return edges, nil
 }
-
-func RemoveNonEdge(edges []EdgeNode) []EdgeNode {
-	edgeFiltered := make([]EdgeNode, 0, len(edges))
-	for _, e := range edges {
-		if e.LicenseType != "EDGE" {
-			continue
-		}
-		edgeFiltered = append(edgeFiltered, e)
-	}
-	return edgeFiltered
-}
diff --git a/contrib/integrations/artifactory/plugin-artifactory-release/main.go b/contrib/integrations/artifactory/plugin-artifactory-release/main.go
index 3091fcee3..510dd63b4 100644
--- a/contrib/integrations/artifactory/plugin-artifactory-release/main.go
+++ b/contrib/integrations/artifactory/plugin-artifactory-release/main.go
@@ -154,7 +154,6 @@ func (e *artifactoryReleasePlugin) Run(_ context.Context, opts *integrationplugi
 	if err != nil {
 		return fail("%v", err)
 	}
-	edges = edge.RemoveNonEdge(edges)
 
 	fmt.Printf("Distribute Release %s %s\n", releaseName, releaseVersion)
 	distributionParams := services.NewDistributeReleaseBundleParams(releaseName, releaseVersion)
diff --git a/engine/api/application_variable.go b/engine/api/application_variable.go
index a40249aa5..83344d173 100644
--- a/engine/api/application_variable.go
+++ b/engine/api/application_variable.go
@@ -140,8 +140,11 @@ func (api *API) updateVariableInApplicationHandler() service.Handler {
 		if err := service.UnmarshalBody(r, &newVar); err != nil {
 			return err
 		}
-		if newVar.Type == sdk.KeyVariable {
-			return sdk.WithStack(sdk.ErrWrongRequest)
+		if !sdk.IsInArray(newVar.Type, sdk.AvailableVariableType) {
+			return sdk.NewErrorFrom(sdk.ErrWrongRequest, "invalid given variable type: %q", newVar.Type)
+		}
+		if newVar.Name != varName {
+			return sdk.NewErrorFrom(sdk.ErrWrongRequest, "cannot change variable name")
 		}
 
 		app, err := application.LoadByName(api.mustDB(), key, appName)
diff --git a/engine/api/environment_variable.go b/engine/api/environment_variable.go
index 35f301232..fbef45a66 100644
--- a/engine/api/environment_variable.go
+++ b/engine/api/environment_variable.go
@@ -130,8 +130,11 @@ func (api *API) updateVariableInEnvironmentHandler() service.Handler {
 		if err := service.UnmarshalBody(r, &newVar); err != nil {
 			return sdk.WithStack(sdk.ErrWrongRequest)
 		}
-		if newVar.Name != varName || newVar.Type == sdk.KeyVariable {
-			return sdk.WithStack(sdk.ErrWrongRequest)
+		if !sdk.IsInArray(newVar.Type, sdk.AvailableVariableType) {
+			return sdk.NewErrorFrom(sdk.ErrWrongRequest, "invalid given variable type: %q", newVar.Type)
+		}
+		if newVar.Name != varName {
+			return sdk.NewErrorFrom(sdk.ErrWrongRequest, "cannot change variable name")
 		}
 
 		env, errEnv := environment.LoadEnvironmentByName(api.mustDB(), key, envName)
diff --git a/engine/api/metrics/elasticsearch.go b/engine/api/metrics/elasticsearch.go
index e6c3c4986..29296f970 100644
--- a/engine/api/metrics/elasticsearch.go
+++ b/engine/api/metrics/elasticsearch.go
@@ -6,7 +6,6 @@ import (
 	"time"
 
 	"github.com/go-gorp/gorp"
-	"github.com/ovh/venom"
 	"github.com/rockbears/log"
 	"github.com/sguiheux/go-coverage"
 	"gopkg.in/olivere/elastic.v6"
@@ -89,7 +88,7 @@ func PushVulnerabilities(projKey string, appID int64, workflowID int64, num int6
 }
 
 // PushUnitTests Create metrics from unit tests and send them
-func PushUnitTests(projKey string, appID int64, workflowID int64, num int64, tests venom.Tests) {
+func PushUnitTests(projKey string, appID int64, workflowID int64, num int64, tests sdk.TestsStats) {
 	m := sdk.Metric{
 		Date:          time.Now(),
 		ProjectKey:    projKey,
diff --git a/engine/api/workflow/dao_node_run.go b/engine/api/workflow/dao_node_run.go
index 749673271..3c54e4f3b 100644
--- a/engine/api/workflow/dao_node_run.go
+++ b/engine/api/workflow/dao_node_run.go
@@ -8,7 +8,6 @@ import (
 	"time"
 
 	"github.com/go-gorp/gorp"
-	"github.com/ovh/venom"
 	"github.com/rockbears/log"
 
 	"github.com/ovh/cds/engine/api/database/gorpmapping"
@@ -376,7 +375,7 @@ func fromDBNodeRun(rr NodeRun, opts LoadRunOptions) (*sdk.WorkflowNodeRun, error
 	}
 
 	if rr.Tests.Valid {
-		r.Tests = new(venom.Tests)
+		r.Tests = new(sdk.TestsResults)
 		if err := gorpmapping.JSONNullString(rr.Tests, r.Tests); err != nil {
 			return nil, sdk.WrapError(err, "Error loading node run %d: Tests", r.ID)
 		}
diff --git a/engine/api/workflow_hook.go b/engine/api/workflow_hook.go
index d7a7348d9..2e29c9743 100644
--- a/engine/api/workflow_hook.go
+++ b/engine/api/workflow_hook.go
@@ -3,7 +3,6 @@ package api
 import (
 	"context"
 	"net/http"
-	"strings"
 
 	"github.com/gorilla/mux"
 
@@ -270,6 +269,7 @@ func (api *API) postWorkflowJobHookCallbackHandler() service.Handler {
 			project.LoadOptions.WithIntegrations,
 			project.LoadOptions.WithApplicationVariables,
 			project.LoadOptions.WithApplicationWithDeploymentStrategies,
+			project.LoadOptions.WithGroups,
 		)
 		next()
 		if err != nil {
@@ -288,9 +288,15 @@ func (api *API) postWorkflowJobHookCallbackHandler() service.Handler {
 		}
 
 		// Hide secrets in payload
-		for _, s := range secrets {
-			callback.Log = strings.Replace(callback.Log, string(s.Value), sdk.PasswordPlaceholder, -1)
+		values := make([]string, len(secrets))
+		for i := range secrets {
+			values[i] = string(secrets[i].Value)
 		}
+		b, err := sdk.NewBlur(values)
+		if err != nil {
+			return err
+		}
+		callback.Log = b.String(callback.Log)
 
 		report, err := workflow.UpdateOutgoingHookRunStatus(ctx, tx, api.Cache, *proj, wr, hookRunID, callback)
 		if err != nil {
diff --git a/engine/api/workflow_queue.go b/engine/api/workflow_queue.go
index 357e1b93d..20e663c0d 100644
--- a/engine/api/workflow_queue.go
+++ b/engine/api/workflow_queue.go
@@ -12,7 +12,6 @@ import (
 	"time"
 
 	"github.com/gorilla/mux"
-	"github.com/ovh/venom"
 	"github.com/rockbears/log"
 	"github.com/sguiheux/go-coverage"
 
@@ -464,7 +463,10 @@ func (api *API) postWorkflowJobResultHandler() service.Handler {
 
 		customCtx, cancel := context.WithTimeout(ctx, 180*time.Second)
 		defer cancel()
-		proj, err := project.LoadProjectByNodeJobRunID(ctx, api.mustDBWithCtx(customCtx), api.Cache, id, project.LoadOptions.WithVariables)
+		proj, err := project.LoadProjectByNodeJobRunID(ctx, api.mustDBWithCtx(customCtx), api.Cache, id,
+			project.LoadOptions.WithVariables,
+			project.LoadOptions.WithGroups,
+		)
 		if err != nil {
 			return sdk.WrapError(err, "cannot load project from job %d", id)
 		}
@@ -1017,10 +1019,11 @@ func (api *API) postWorkflowJobTestsResultsHandler() service.Handler {
 		}
 
 		// Unmarshal into results
-		var new venom.Tests
+		var new sdk.JUnitTestsSuites
 		if err := service.UnmarshalBody(r, &new); err != nil {
 			return err
 		}
+		new = new.EnsureData()
 
 		// Load and lock Existing workflow Run Job
 		id, err := requestVarInt(r, "permJobID")
@@ -1045,7 +1048,7 @@ func (api *API) postWorkflowJobTestsResultsHandler() service.Handler {
 		}
 
 		if nr.Tests == nil {
-			nr.Tests = &venom.Tests{}
+			nr.Tests = &sdk.TestsResults{}
 		}
 
 		for k := range new.TestSuites {
@@ -1060,17 +1063,8 @@ func (api *API) postWorkflowJobTestsResultsHandler() service.Handler {
 			nr.Tests.TestSuites = append(nr.Tests.TestSuites, new.TestSuites[k])
 		}
 
-		// update total values
-		nr.Tests.Total = 0
-		nr.Tests.TotalOK = 0
-		nr.Tests.TotalKO = 0
-		nr.Tests.TotalSkipped = 0
-		for _, ts := range nr.Tests.TestSuites {
-			nr.Tests.Total += ts.Total
-			nr.Tests.TotalKO += ts.Failures + ts.Errors
-			nr.Tests.TotalOK += ts.Total - ts.Skipped - ts.Failures - ts.Errors
-			nr.Tests.TotalSkipped += ts.Skipped
-		}
+		nr.Tests.JUnitTestsSuites = nr.Tests.JUnitTestsSuites.EnsureData()
+		nr.Tests.TestsStats = nr.Tests.JUnitTestsSuites.ComputeStats()
 
 		if err := workflow.UpdateNodeRun(tx, nr); err != nil {
 			return sdk.WrapError(err, "cannot update node run")
@@ -1103,7 +1097,7 @@ func (api *API) postWorkflowJobTestsResultsHandler() service.Handler {
 
 			if defaultBranch.DisplayID == nr.VCSBranch {
 				// Push metrics
-				metrics.PushUnitTests(p.Key, nr.ApplicationID, nr.WorkflowID, nr.Number, *nr.Tests)
+				metrics.PushUnitTests(p.Key, nr.ApplicationID, nr.WorkflowID, nr.Number, nr.Tests.TestsStats)
 			}
 		}
 
diff --git a/engine/api/workflow_run.go b/engine/api/workflow_run.go
index 3b6b8ea7a..aab982530 100644
--- a/engine/api/workflow_run.go
+++ b/engine/api/workflow_run.go
@@ -521,6 +521,7 @@ func (api *API) updateParentWorkflowRun(ctx context.Context, run *sdk.WorkflowRu
 		project.LoadOptions.WithIntegrations,
 		project.LoadOptions.WithApplicationVariables,
 		project.LoadOptions.WithApplicationWithDeploymentStrategies,
+		project.LoadOptions.WithGroups,
 	)
 	if err != nil {
 		return sdk.WrapError(err, "cannot load project")
diff --git a/engine/worker/cmd_junit_parser.go b/engine/worker/cmd_junit_parser.go
index a662e7be0..3fd548db0 100644
--- a/engine/worker/cmd_junit_parser.go
+++ b/engine/worker/cmd_junit_parser.go
@@ -6,7 +6,6 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/ovh/venom"
 	"github.com/spf13/cobra"
 
 	"github.com/ovh/cds/engine/worker/internal/action"
@@ -18,12 +17,12 @@ func cmdJunitParser() *cobra.Command {
 		Use:   "junit-parser",
 		Short: "worker junit-parser",
 		Long: `
-worker junit-parser command helps you to parse junit files and print a summary. 
+worker junit-parser command helps you to parse junit files and print a summary.
 
 It displays the number of tests, the number of passed tests, the number of failed tests and the number of skipped tests.
 
 Examples:
-	$ ls 
+	$ ls
 	result1.xml		result2.xml
 	$ worker junit-parser result1.xml
 	10 10 0 0
@@ -46,29 +45,26 @@ func junitParserCmd() func(cmd *cobra.Command, args []string) error {
 			filepaths = append(filepaths, matches...)
 		}
 
-		var tests venom.Tests
+		var tests sdk.JUnitTestsSuites
 		for _, f := range filepaths {
-			var ftests venom.Tests
 			data, err := os.ReadFile(f)
 			if err != nil {
 				return fmt.Errorf("junit parser: cannot read file %s (%s)", f, err)
 			}
-			var vf venom.Tests
-			if err := xml.Unmarshal(data, &vf); err != nil {
+			var ftests sdk.JUnitTestsSuites
+			if err := xml.Unmarshal(data, &ftests); err != nil {
 				// Check if file contains testsuite only (and no testsuites)
 				if s, ok := action.ParseTestsuiteAlone(data); ok {
 					ftests.TestSuites = append(ftests.TestSuites, s)
 				}
-				tests.TestSuites = append(tests.TestSuites, ftests.TestSuites...)
-			} else {
-				tests.TestSuites = append(tests.TestSuites, vf.TestSuites...)
 			}
+			tests.TestSuites = append(tests.TestSuites, ftests.TestSuites...)
 		}
 
-		var res sdk.Result
-		_ = action.ComputeStats(&res, &tests)
+		tests = tests.EnsureData()
+		stats := tests.ComputeStats()
 
-		fmt.Println(tests.Total, tests.TotalOK, tests.TotalKO, tests.TotalSkipped)
+		fmt.Println(stats.Total, stats.TotalOK, stats.TotalKO, stats.TotalSkipped)
 
 		return nil
 	}
diff --git a/engine/worker/internal/action/builtin_junit.go b/engine/worker/internal/action/builtin_junit.go
index aa8683a74..69e5eaf9d 100644
--- a/engine/worker/internal/action/builtin_junit.go
+++ b/engine/worker/internal/action/builtin_junit.go
@@ -12,7 +12,6 @@ import (
 
 	"github.com/ovh/cds/engine/worker/pkg/workerruntime"
 	"github.com/ovh/cds/sdk"
-	"github.com/ovh/venom"
 )
 
 func RunParseJunitTestResultAction(ctx context.Context, wk workerruntime.Runtime, a sdk.Action, secrets []sdk.Variable) (sdk.Result, error) {
@@ -57,44 +56,37 @@ func RunParseJunitTestResultAction(ctx context.Context, wk workerruntime.Runtime
 		return res, errors.New("UnitTest parser: Cannot find requested files, invalid pattern")
 	}
 
-	var tests venom.Tests
+	var tests sdk.JUnitTestsSuites
 	wk.SendLog(ctx, workerruntime.LevelInfo, fmt.Sprintf("%d", len(files))+" file(s) to analyze")
 
 	for _, f := range files {
-		var ftests venom.Tests
-
 		data, errRead := afero.ReadFile(afero.NewOsFs(), f)
 		if errRead != nil {
 			return res, fmt.Errorf("UnitTest parser: cannot read file %s (%s)", f, errRead)
 		}
 
-		var vf venom.Tests
-		if err := xml.Unmarshal(data, &vf); err != nil {
+		var ftests sdk.JUnitTestsSuites
+		if err := xml.Unmarshal(data, &ftests); err != nil {
 			// Check if file contains testsuite only (and no testsuites)
 			if s, ok := ParseTestsuiteAlone(data); ok {
 				ftests.TestSuites = append(ftests.TestSuites, s)
 			}
-			tests.TestSuites = append(tests.TestSuites, ftests.TestSuites...)
-			if len(ftests.TestSuites) == 0 {
-				log.Error(ctx, "unable to find testsuites in %q", f)
-				wk.SendLog(ctx, workerruntime.LevelInfo, fmt.Sprintf("WARNING: unable to parse %q as valid xUnit report file", filepath.Base(f)))
-				continue
-			}
-			log.Info(ctx, "found %d testsuites in %q", len(ftests.TestSuites), f)
-		} else {
-			tests.TestSuites = append(tests.TestSuites, vf.TestSuites...)
-
-			if len(ftests.TestSuites) == 0 {
-				log.Error(ctx, "unable to find testsuites in %q", f)
-				wk.SendLog(ctx, workerruntime.LevelInfo, fmt.Sprintf("WARNING: unable to parse %q as valid xUnit report file", filepath.Base(f)))
-				continue
-			}
-			log.Info(ctx, "found %d testsuites in %q", len(vf.TestSuites), f)
 		}
+
+		log.Debug(ctx, "found %d testsuites in %q", len(ftests.TestSuites), f)
+
+		if len(ftests.TestSuites) == 0 {
+			wk.SendLog(ctx, workerruntime.LevelInfo, fmt.Sprintf("WARNING: No JUnit testsuites found in file %q", filepath.Base(f)))
+			continue
+		}
+
+		tests.TestSuites = append(tests.TestSuites, ftests.TestSuites...)
 	}
 
+	tests = tests.EnsureData()
+
 	wk.SendLog(ctx, workerruntime.LevelInfo, fmt.Sprintf("%d", len(tests.TestSuites))+" Total Testsuite(s)")
-	reasons := ComputeStats(&res, &tests)
+	reasons := ComputeTestsReasons(tests)
 	for _, r := range reasons {
 		wk.SendLog(ctx, workerruntime.LevelInfo, r)
 	}
@@ -103,6 +95,11 @@ func RunParseJunitTestResultAction(ctx context.Context, wk workerruntime.Runtime
 		return res, err
 	}
 
+	stats := tests.ComputeStats()
+	if stats.TotalKO == 0 {
+		res.Status = sdk.StatusSuccess
+	}
+
 	if err := wk.Client().QueueSendUnitTests(ctx, jobID, tests); err != nil {
 		return res, fmt.Errorf("JUnit parse: failed to send tests details: %s", err)
 	}
@@ -110,115 +107,47 @@ func RunParseJunitTestResultAction(ctx context.Context, wk workerruntime.Runtime
 	return res, nil
 }
 
-// ComputeStats computes failures / errors on testSuites,
-// set result.Status and return a list of log to send to API
-func ComputeStats(res *sdk.Result, v *venom.Tests) []string {
-	// update global stats
-	for _, ts := range v.TestSuites {
-		nSkipped := 0
-		for _, tc := range ts.TestCases {
-			nSkipped += len(tc.Skipped)
-		}
-		if ts.Skipped < nSkipped {
-			ts.Skipped = nSkipped
-		}
-		if ts.Total < len(ts.TestCases)-nSkipped {
-			ts.Total = len(ts.TestCases) - nSkipped
-		}
-		v.Total += ts.Total
-		v.TotalOK += ts.Total - ts.Failures - ts.Errors
-		v.TotalKO += ts.Failures + ts.Errors
-		v.TotalSkipped += ts.Skipped
+func ParseTestsuiteAlone(data []byte) (sdk.JUnitTestSuite, bool) {
+	var s sdk.JUnitTestSuite
+	err := xml.Unmarshal([]byte(data), &s)
+	if err != nil {
+		return s, false
 	}
 
-	var nbOK, nbKO, nbSkipped int
+	if s.Name == "" {
+		return s, false
+	}
 
-	reasons := []string{}
-	reasons = append(reasons, fmt.Sprintf("JUnit parser: %d testsuite(s)", len(v.TestSuites)))
+	return s, true
+}
 
-	for i, ts := range v.TestSuites {
-		var nbKOTC, nbFailures, nbErrors, nbSkippedTC int
-		if ts.Name == "" {
-			ts.Name = fmt.Sprintf("TestSuite.%d", i)
-		}
+func ComputeTestsReasons(s sdk.JUnitTestsSuites) []string {
+	reasons := []string{fmt.Sprintf("JUnit parser: %d testsuite(s)", len(s.TestSuites))}
+	for _, ts := range s.TestSuites {
 		reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d testcase(s)", ts.Name, len(ts.TestCases)))
-		for k, tc := range ts.TestCases {
-			if tc.Name == "" {
-				tc.Name = fmt.Sprintf("TestCase.%d", k)
-			}
+		for _, tc := range ts.TestCases {
 			if len(tc.Failures) > 0 {
 				reasons = append(reasons, fmt.Sprintf("JUnit parser: testcase %s has %d failure(s)", tc.Name, len(tc.Failures)))
-				nbFailures += len(tc.Failures)
 			}
 			if len(tc.Errors) > 0 {
 				reasons = append(reasons, fmt.Sprintf("JUnit parser: testcase %s has %d error(s)", tc.Name, len(tc.Errors)))
-				nbErrors += len(tc.Errors)
 			}
-			if len(tc.Failures) > 0 || len(tc.Errors) > 0 {
-				nbKOTC++
-			} else if len(tc.Skipped) > 0 {
-				nbSkippedTC += len(tc.Skipped)
+			if len(tc.Skipped) > 0 {
+				reasons = append(reasons, fmt.Sprintf("JUnit parser: testcase %s has %d test(s) skipped", tc.Name, len(tc.Skipped)))
 			}
-			v.TestSuites[i].TestCases[k] = tc
 		}
-		nbOK += len(ts.TestCases) - nbKOTC
-		nbKO += nbKOTC
-		nbSkipped += nbSkippedTC
-		if ts.Failures > nbFailures {
-			nbFailures = ts.Failures
+		if ts.Failures > 0 {
+			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d failure(s)", ts.Name, ts.Failures))
 		}
-		if ts.Errors > nbErrors {
-			nbErrors = ts.Errors
+		if ts.Errors > 0 {
+			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d error(s)", ts.Name, ts.Errors))
 		}
-
-		if nbFailures > 0 {
-			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d failure(s)", ts.Name, nbFailures))
+		if ts.Failures+ts.Errors > 0 {
+			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d test(s) failed", ts.Name, ts.Failures+ts.Errors))
 		}
-		if nbErrors > 0 {
-			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d error(s)", ts.Name, nbErrors))
+		if ts.Skipped > 0 {
+			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d test(s) skipped", ts.Name, ts.Skipped))
 		}
-		if nbKOTC > 0 {
-			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d test(s) failed", ts.Name, nbKOTC))
-		}
-		if nbSkippedTC > 0 {
-			reasons = append(reasons, fmt.Sprintf("JUnit parser: testsuite %s has %d test(s) skipped", ts.Name, nbSkippedTC))
-		}
-		v.TestSuites[i] = ts
-	}
-
-	if nbKO > v.TotalKO {
-		v.TotalKO = nbKO
-	}
-
-	if nbOK != v.TotalOK {
-		v.TotalOK = nbOK
-	}
-
-	if nbSkipped != v.TotalSkipped {
-		v.TotalSkipped = nbSkipped
-	}
-
-	if v.TotalKO+v.TotalOK != v.Total {
-		v.Total = v.TotalKO + v.TotalOK + v.TotalSkipped
-	}
-
-	res.Status = sdk.StatusFail
-	if v.TotalKO == 0 {
-		res.Status = sdk.StatusSuccess
 	}
 	return reasons
 }
-
-func ParseTestsuiteAlone(data []byte) (venom.TestSuite, bool) {
-	var s venom.TestSuite
-	err := xml.Unmarshal([]byte(data), &s)
-	if err != nil {
-		return s, false
-	}
-
-	if s.Name == "" {
-		return s, false
-	}
-
-	return s, true
-}
diff --git a/engine/worker/internal/handler_check_secret.go b/engine/worker/internal/handler_check_secret.go
index ee488e733..b5a473450 100644
--- a/engine/worker/internal/handler_check_secret.go
+++ b/engine/worker/internal/handler_check_secret.go
@@ -39,7 +39,8 @@ func checkSecretHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc
 
 		var varFound string
 		for _, p := range wk.currentJob.params {
-			if (p.Type == sdk.SecretVariable || p.Type == sdk.KeyVariable) && len(p.Value) >= sdk.SecretMinLength && strings.Contains(sbtes, p.Value) {
+			isSecret := p.Type == sdk.SecretVariable || p.Type == sdk.KeyVariable || p.Type == sdk.SSHKeyVariable || p.Type == sdk.PGPKeyVariable
+			if isSecret && len(p.Value) >= sdk.SecretMinLength && strings.Contains(sbtes, p.Value) {
 				varFound = p.Name
 				break
 			}
diff --git a/engine/worker/internal/take.go b/engine/worker/internal/take.go
index bc4b1b5f0..1832bdab8 100644
--- a/engine/worker/internal/take.go
+++ b/engine/worker/internal/take.go
@@ -32,7 +32,9 @@ func (w *CurrentWorker) Take(ctx context.Context, job sdk.WorkflowNodeJobRun) er
 
 	// Set build variables
 	w.currentJob.wJob = &info.NodeJobRun
-	w.currentJob.secrets = info.Secrets
+	if err := w.SetSecrets(info.Secrets); err != nil {
+		return err
+	}
 	w.currentJob.projectKey = info.ProjectKey
 	w.currentJob.workflowName = info.WorkflowName
 	w.currentJob.workflowID = info.WorkflowID
diff --git a/engine/worker/internal/types.go b/engine/worker/internal/types.go
index 62cd619f1..60e8e0bed 100644
--- a/engine/worker/internal/types.go
+++ b/engine/worker/internal/types.go
@@ -3,7 +3,6 @@ package internal
 import (
 	"context"
 	"crypto/md5"
-	"encoding/json"
 	"fmt"
 	"os"
 	"strings"
@@ -69,6 +68,7 @@ type CurrentWorker struct {
 		Status string `json:"status"`
 	}
 	client cdsclient.WorkerInterface
+	blur   *sdk.Blur
 }
 
 // BuiltInAction defines builtin action signature
@@ -195,11 +195,12 @@ func (wk *CurrentWorker) prepareLog(ctx context.Context, level workerruntime.Lev
 	var res cdslog.Message
 
 	if wk.currentJob.wJob == nil {
-		return res, "", sdk.WithStack(fmt.Errorf("job is nill"))
+		return res, "", sdk.WithStack(fmt.Errorf("job is nil"))
 	}
-	if err := wk.Blur(&s); err != nil {
-		return res, "", sdk.WrapError(err, "unable to blur log")
+	if wk.blur == nil {
+		return res, "", sdk.WithStack(fmt.Errorf("blur is nil"))
 	}
+	s = wk.blur.String(s)
 
 	switch level {
 	case workerruntime.LevelDebug:
@@ -330,25 +331,31 @@ func (wk *CurrentWorker) Environ() []string {
 }
 
 func (w *CurrentWorker) Blur(i interface{}) error {
-	data, err := json.Marshal(i)
-	if err != nil {
-		return err
+	if w.blur == nil {
+		return fmt.Errorf("blur is not define for current worker")
 	}
 
-	dataS := string(data)
-	for i := range w.currentJob.secrets {
-		if len(w.currentJob.secrets[i].Value) >= sdk.SecretMinLength {
-			dataS = strings.Replace(dataS, w.currentJob.secrets[i].Value, sdk.PasswordPlaceholder, -1)
-		}
+	return w.blur.Interface(i)
+}
+
+func (w *CurrentWorker) HTTPPort() int32 {
+	return w.httpPort
+}
+
+func (wk *CurrentWorker) SetSecrets(secrets []sdk.Variable) error {
+	wk.currentJob.secrets = secrets
+
+	values := make([]string, len(wk.currentJob.secrets))
+	for i := range wk.currentJob.secrets {
+		values[i] = wk.currentJob.secrets[i].Value
 	}
 
-	if err := sdk.JSONUnmarshal([]byte(dataS), i); err != nil {
+	b, err := sdk.NewBlur(values)
+	if err != nil {
 		return err
 	}
 
-	return nil
-}
+	wk.blur = b
 
-func (w *CurrentWorker) HTTPPort() int32 {
-	return w.httpPort
+	return nil
 }
diff --git a/go.mod b/go.mod
index fdf145539..bba10f23f 100644
--- a/go.mod
+++ b/go.mod
@@ -60,7 +60,6 @@ require (
 	github.com/ovh/cds/sdk/interpolate v0.0.0-20190319104452-71125b036b25
 	github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5
 	github.com/ovh/symmecrypt v0.5.1
-	github.com/ovh/venom v0.25.0
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c
 	github.com/pelletier/go-toml v1.8.0
@@ -207,7 +206,6 @@ require (
 	github.com/mholt/archiver/v3 v3.5.1-0.20210618180617-81fac4ba96e4 // indirect
 	github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
-	github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.1 // indirect
 	github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317 // indirect
@@ -228,7 +226,6 @@ require (
 	github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
 	github.com/ryanuber/go-glob v1.0.0 // indirect
 	github.com/sergi/go-diff v1.1.0 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/subosito/gotenv v1.2.0 // indirect
diff --git a/go.sum b/go.sum
index b2885f047..7b6d96725 100644
--- a/go.sum
+++ b/go.sum
@@ -526,8 +526,6 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b h1:/1WAr2jAZnfxlWW3M3VJ4P3VRi57AjbrUv9U1kCRHyk=
-github.com/mndrix/tap-go v0.0.0-20170113192335-56cca451570b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -575,8 +573,6 @@ github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5 h1:E5fS/QLKUEcIn
 github.com/ovh/configstore v0.3.3-0.20200701085609-a539fcf61db5/go.mod h1:IXY5qFC5mqMIFPXZjeZiAz/qIt+mO6F6SmsOCf/yits=
 github.com/ovh/symmecrypt v0.5.1 h1:WjCjCFEHuap5V4sM1AaGm2AzZh0KE/vhx9q9tZn3JVQ=
 github.com/ovh/symmecrypt v0.5.1/go.mod h1:566sFU1+ZRapOXcGeM4H8o+5/2l2zZcTN7bG1FvNWkE=
-github.com/ovh/venom v0.25.0 h1:q0NC8KHuG1UoWNYXqhZUM/VbOnS8ciQJr6Afn230OIw=
-github.com/ovh/venom v0.25.0/go.mod h1:vf+2wztk/hOPS9AU32/B9XhwVPxKZ97wBJLu+AGXhYQ=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/sdk/blur.go b/sdk/blur.go
new file mode 100644
index 000000000..9d376dea7
--- /dev/null
+++ b/sdk/blur.go
@@ -0,0 +1,89 @@
+package sdk
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+func NewBlur(secrets []string) (*Blur, error) {
+	alternativeFuncs := func(v string) ([]string, error) {
+		jsonAlternative, err := json.Marshal(v)
+		if err != nil {
+			return nil, WithStack(err)
+		}
+		return []string{
+			v,
+			strings.Replace(v, "'", `'"'"'`, -1), // Useful to match secrets from 'env' in script steps
+			strings.Trim(string(jsonAlternative), "\""),
+			url.QueryEscape(v),
+			base64.StdEncoding.EncodeToString([]byte(v)),
+		}, nil
+	}
+
+	var alternatives []string
+	for i := range secrets {
+		as, err := alternativeFuncs(secrets[i])
+		if err != nil {
+			return nil, err
+		}
+		alternatives = append(alternatives, as...)
+	}
+	sort.Slice(alternatives, func(i, j int) bool { return len(alternatives[i]) > len(alternatives[j]) })
+
+	oldNew := make([]string, 0, 2*len(alternatives))
+	for i := range alternatives {
+		if len(alternatives[i]) >= SecretMinLength {
+			oldNew = append(oldNew, alternatives[i], PasswordPlaceholder)
+		}
+	}
+
+	return &Blur{
+		replacer: strings.NewReplacer(oldNew...),
+	}, nil
+}
+
+type Blur struct {
+	replacer *strings.Replacer
+}
+
+func (b *Blur) String(s string) string {
+	return b.replacer.Replace(s)
+}
+
+func (b *Blur) Interface(i interface{}) error {
+	v := reflect.ValueOf(i)
+	e := v.Elem()
+
+	switch e.Kind() {
+	case reflect.Slice:
+		for i := 0; i < e.Len(); i++ {
+			if err := b.Interface(e.Index(i).Addr().Interface()); err != nil {
+				return err
+			}
+		}
+	case reflect.String:
+		data := e.Interface().(string)
+		e.SetString(b.String(data))
+	case reflect.Struct:
+		for i := 0; i < e.NumField(); i++ {
+			if err := b.Interface(e.Field(i).Addr().Interface()); err != nil {
+				return err
+			}
+		}
+	case reflect.Int:
+		data := e.Interface().(int)
+		if b.String(strconv.Itoa(data)) == PasswordPlaceholder {
+			e.SetInt(0)
+		}
+	default:
+		return fmt.Errorf("cannot blur given value of type %q", v.Type())
+	}
+
+	return nil
+}
diff --git a/sdk/cdsclient/client_queue.go b/sdk/cdsclient/client_queue.go
index 8d28f151c..eac21c596 100644
--- a/sdk/cdsclient/client_queue.go
+++ b/sdk/cdsclient/client_queue.go
@@ -17,7 +17,6 @@ import (
 	"time"
 
 	"github.com/ovh/cds/sdk"
-	"github.com/ovh/venom"
 	"github.com/sguiheux/go-coverage"
 )
 
@@ -246,7 +245,7 @@ func (c *client) QueueSendCoverage(ctx context.Context, id int64, report coverag
 	return err
 }
 
-func (c *client) QueueSendUnitTests(ctx context.Context, id int64, report venom.Tests) error {
+func (c *client) QueueSendUnitTests(ctx context.Context, id int64, report sdk.JUnitTestsSuites) error {
 	path := fmt.Sprintf("/queue/workflows/%d/test", id)
 	_, err := c.PostJSON(ctx, path, report, nil)
 	return err
diff --git a/sdk/cdsclient/interface.go b/sdk/cdsclient/interface.go
index 0bf6ee340..da7464334 100644
--- a/sdk/cdsclient/interface.go
+++ b/sdk/cdsclient/interface.go
@@ -16,7 +16,6 @@ import (
 	"github.com/sguiheux/go-coverage"
 
 	"github.com/ovh/cds/sdk"
-	"github.com/ovh/venom"
 )
 
 type Filter struct {
@@ -263,7 +262,7 @@ type QueueClient interface {
 	QueueJobInfo(ctx context.Context, id int64) (*sdk.WorkflowNodeJobRun, error)
 	QueueJobSendSpawnInfo(ctx context.Context, id int64, in []sdk.SpawnInfo) error
 	QueueSendCoverage(ctx context.Context, id int64, report coverage.Report) error
-	QueueSendUnitTests(ctx context.Context, id int64, report venom.Tests) error
+	QueueSendUnitTests(ctx context.Context, id int64, report sdk.JUnitTestsSuites) error
 	QueueSendVulnerability(ctx context.Context, id int64, report sdk.VulnerabilityWorkerReport) error
 	QueueSendStepResult(ctx context.Context, id int64, res sdk.StepStatus) error
 	QueueSendResult(ctx context.Context, id int64, res sdk.Result) error
diff --git a/sdk/cdsclient/mock_cdsclient/interface_mock.go b/sdk/cdsclient/mock_cdsclient/interface_mock.go
index 3c5eae36e..1974fc0d6 100644
--- a/sdk/cdsclient/mock_cdsclient/interface_mock.go
+++ b/sdk/cdsclient/mock_cdsclient/interface_mock.go
@@ -17,7 +17,6 @@ import (
 	websocket "github.com/gorilla/websocket"
 	sdk "github.com/ovh/cds/sdk"
 	cdsclient "github.com/ovh/cds/sdk/cdsclient"
-	venom "github.com/ovh/venom"
 	coverage "github.com/sguiheux/go-coverage"
 	afero "github.com/spf13/afero"
 )
@@ -3271,7 +3270,7 @@ func (mr *MockQueueClientMockRecorder) QueueSendStepResult(ctx, id, res interfac
 }
 
 // QueueSendUnitTests mocks base method.
-func (m *MockQueueClient) QueueSendUnitTests(ctx context.Context, id int64, report venom.Tests) error {
+func (m *MockQueueClient) QueueSendUnitTests(ctx context.Context, id int64, report sdk.JUnitTestsSuites) error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "QueueSendUnitTests", ctx, id, report)
 	ret0, _ := ret[0].(error)
@@ -7301,7 +7300,7 @@ func (mr *MockInterfaceMockRecorder) QueueSendStepResult(ctx, id, res interface{
 }
 
 // QueueSendUnitTests mocks base method.
-func (m *MockInterface) QueueSendUnitTests(ctx context.Context, id int64, report venom.Tests) error {
+func (m *MockInterface) QueueSendUnitTests(ctx context.Context, id int64, report sdk.JUnitTestsSuites) error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "QueueSendUnitTests", ctx, id, report)
 	ret0, _ := ret[0].(error)
@@ -9401,7 +9400,7 @@ func (mr *MockWorkerInterfaceMockRecorder) QueueSendStepResult(ctx, id, res inte
 }
 
 // QueueSendUnitTests mocks base method.
-func (m *MockWorkerInterface) QueueSendUnitTests(ctx context.Context, id int64, report venom.Tests) error {
+func (m *MockWorkerInterface) QueueSendUnitTests(ctx context.Context, id int64, report sdk.JUnitTestsSuites) error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "QueueSendUnitTests", ctx, id, report)
 	ret0, _ := ret[0].(error)
diff --git a/sdk/notif.go b/sdk/notif.go
index 6d466a04e..026cb87e5 100644
--- a/sdk/notif.go
+++ b/sdk/notif.go
@@ -8,8 +8,6 @@ import (
 	"text/template"
 	"time"
 
-	"github.com/ovh/venom"
-
 	"github.com/ovh/cds/sdk/interpolate"
 )
 
@@ -157,7 +155,7 @@ func (nr WorkflowNodeRun) Report() (string, error) {
 		Stages           []Stage
 		Start            time.Time
 		Done             time.Time
-		Tests            *venom.Tests
+		Tests            *TestsResults
 	}{
 		WorkflowNodeName: nr.WorkflowNodeName,
 		Status:           nr.Status,
diff --git a/sdk/variable.go b/sdk/variable.go
index bfbd7e617..ea0f205d1 100644
--- a/sdk/variable.go
+++ b/sdk/variable.go
@@ -131,6 +131,8 @@ const (
 	BooleanVariable    = "boolean"
 	NumberVariable     = "number"
 	RepositoryVariable = "repository"
+	SSHKeyVariable     = "ssh"
+	PGPKeyVariable     = "pgp"
 )
 
 var (
@@ -181,7 +183,7 @@ var (
 // NeedPlaceholder returns true if variable type is either secret or key
 func NeedPlaceholder(t string) bool {
 	switch t {
-	case SecretVariable, KeyVariable:
+	case SecretVariable, KeyVariable, SSHKeyVariable, PGPKeyVariable:
 		return true
 	default:
 		return false
diff --git a/sdk/workflow_run.go b/sdk/workflow_run.go
index 4f8e75dc1..242bb4731 100644
--- a/sdk/workflow_run.go
+++ b/sdk/workflow_run.go
@@ -10,7 +10,6 @@ import (
 	"time"
 
 	"github.com/blang/semver"
-	"github.com/ovh/venom"
 	"github.com/sguiheux/go-coverage"
 )
 
@@ -364,7 +363,7 @@ type WorkflowNodeRun struct {
 	StaticFiles            []StaticFiles                        `json:"static_files,omitempty"`
 	Coverage               WorkflowNodeRunCoverage              `json:"coverage,omitempty"`
 	VulnerabilitiesReport  WorkflowNodeRunVulnerabilityReport   `json:"vulnerabilities_report,omitempty"`
-	Tests                  *venom.Tests                         `json:"tests,omitempty"`
+	Tests                  *TestsResults                        `json:"tests,omitempty"`
 	Commits                []VCSCommit                          `json:"commits,omitempty"`
 	TriggersRun            map[int64]WorkflowNodeTriggerRun     `json:"triggers_run,omitempty"`
 	VCSRepository          string                               `json:"vcs_repository"`
diff --git a/ui/src/app/model/pipeline.model.ts b/ui/src/app/model/pipeline.model.ts
index 5782a8a55..dbb6ebb14 100644
--- a/ui/src/app/model/pipeline.model.ts
+++ b/ui/src/app/model/pipeline.model.ts
@@ -275,10 +275,10 @@ export class TestCase {
     skipped: Array<Skipped>;
     systemout: InnerResult;
     systemerr: InnerResult;
-    errorsAndFailures: string;
 
     // UI param
     displayed: boolean;
+    messages: string;
 }
 
 // Failure contains data related to a failed test.
@@ -291,6 +291,7 @@ export class Failure {
 // Skipped contains data related to a skipped test.
 export class Skipped {
     value: string;
+    message: string;
 }
 
 // InnerResult is used by TestCase
diff --git a/ui/src/app/shared/table/data-table.component.ts b/ui/src/app/shared/table/data-table.component.ts
index be5f810c9..29c683f8e 100644
--- a/ui/src/app/shared/table/data-table.component.ts
+++ b/ui/src/app/shared/table/data-table.component.ts
@@ -105,6 +105,7 @@ export class DataTableComponent<T extends WithKey> extends Table<T> implements O
     @Input() columns: Array<Column<T>>;
     @Output() sortChange = new EventEmitter<string>();
     @Output() dataChange = new EventEmitter<number>();
+    @Output() filterChange = new EventEmitter<string>();
     @Input() loading: boolean;
     @Input() withLineClick: boolean;
     @Output() clickLine = new EventEmitter<T>();
@@ -224,8 +225,9 @@ export class DataTableComponent<T extends WithKey> extends Table<T> implements O
         return data;
     }
 
-    filterChange() {
+    filterKeyUp() {
         this.getDataForCurrentPage();
+        this.filterChange.emit(this.filter);
     }
 
     pageChange(n: number) {
diff --git a/ui/src/app/shared/table/data-table.html b/ui/src/app/shared/table/data-table.html
index 1fce84e2d..e737020a4 100644
--- a/ui/src/app/shared/table/data-table.html
+++ b/ui/src/app/shared/table/data-table.html
@@ -3,7 +3,7 @@
         <div class="ui wide column">
             <div class="ui fluid input">
                 <input type="text" placeholder="{{ 'filter' | translate }}" [(ngModel)]="filter"
-                    (keyup)="filterChange()">
+                    (keyup)="filterKeyUp()">
             </div>
         </div>
     </div>


Test patch:
diff --git a/engine/api/workflow_queue_test.go b/engine/api/workflow_queue_test.go
index 2a6e828ff..db7cf39da 100644
--- a/engine/api/workflow_queue_test.go
+++ b/engine/api/workflow_queue_test.go
@@ -21,8 +21,6 @@ import (
 	"github.com/ovh/cds/engine/featureflipping"
 	"github.com/ovh/cds/sdk/cdsclient"
 
-	"github.com/ovh/venom"
-
 	"github.com/rockbears/log"
 	"github.com/sguiheux/go-coverage"
 	"github.com/stretchr/testify/assert"
@@ -844,16 +842,11 @@ func Test_postWorkflowJobTestsResultsHandler(t *testing.T) {
 	require.Equal(t, 200, rec.Code)
 
 	//Send test
-	tests := venom.Tests{
-		Total:        2,
-		TotalKO:      1,
-		TotalOK:      1,
-		TotalSkipped: 0,
-		TestSuites: []venom.TestSuite{
+	tests := sdk.JUnitTestsSuites{
+		TestSuites: []sdk.JUnitTestSuite{
 			{
-				Total: 1,
-				Name:  "TestSuite1",
-				TestCases: []venom.TestCase{
+				Name: "TestSuite1",
+				TestCases: []sdk.JUnitTestCase{
 					{
 						Name:   "TestCase1",
 						Status: "OK",
@@ -861,13 +854,12 @@ func Test_postWorkflowJobTestsResultsHandler(t *testing.T) {
 				},
 			},
 			{
-				Total: 1,
-				Name:  "TestSuite2",
-				TestCases: []venom.TestCase{
+				Name: "TestSuite2",
+				TestCases: []sdk.JUnitTestCase{
 					{
 						Name:   "TestCase1",
 						Status: "KO",
-						Failures: []venom.Failure{
+						Failures: []sdk.JUnitTestFailure{
 							{
 								Value:   "Fail",
 								Type:    "Assertion error",
@@ -909,8 +901,10 @@ func Test_postWorkflowJobTestsResultsHandler(t *testing.T) {
 	nodeRun, errN := workflow.LoadNodeRunByID(context.Background(), api.mustDB(), wNodeJobRun.WorkflowNodeRunID, workflow.LoadRunOptions{WithArtifacts: true, WithTests: true})
 	require.NoError(t, errN)
 
-	assert.NotNil(t, nodeRun.Tests)
+	require.NotNil(t, nodeRun.Tests)
 	require.Equal(t, 2, nodeRun.Tests.Total)
+	require.Equal(t, 1, nodeRun.Tests.TotalKO)
+	require.Equal(t, 1, nodeRun.Tests.TotalOK)
 }
 
 func Test_postWorkflowJobArtifactHandler(t *testing.T) {
diff --git a/engine/worker/internal/action/builtin_junit_test.go b/engine/worker/internal/action/builtin_junit_test.go
index b46e8a48e..5c60ab420 100644
--- a/engine/worker/internal/action/builtin_junit_test.go
+++ b/engine/worker/internal/action/builtin_junit_test.go
@@ -10,7 +10,6 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/ovh/venom"
 	"github.com/spf13/afero"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -62,12 +61,13 @@ func TestRunParseJunitTestResultAction_Absolute(t *testing.T) {
 			t.Logf("%s %s - Body: %s", mock.Request().Method, mock.Request().URLStruct.String(), string(bodyContent))
 			switch mock.Request().URLStruct.String() {
 			case "http://lolcat.host/queue/workflows/666/test":
-				var report venom.Tests
-				err := json.Unmarshal(bodyContent, &report)
-				assert.NoError(t, err)
-				assert.Equal(t, 3, report.Total)
-				assert.Equal(t, 1, report.TotalKO)
-				assert.Equal(t, 1, report.TotalSkipped)
+				var report sdk.JUnitTestsSuites
+				require.NoError(t, json.Unmarshal(bodyContent, &report))
+				report = report.EnsureData()
+				stats := report.ComputeStats()
+				assert.Equal(t, 3, stats.Total)
+				assert.Equal(t, 1, stats.TotalKO)
+				assert.Equal(t, 1, stats.TotalSkipped)
 			}
 		}
 	}
@@ -87,7 +87,6 @@ func TestRunParseJunitTestResultAction_Absolute(t *testing.T) {
 		}, nil)
 	assert.NoError(t, err)
 	assert.Equal(t, sdk.StatusFail, res.Status)
-
 }
 
 func TestRunParseJunitTestResultAction_Relative(t *testing.T) {
@@ -127,12 +126,13 @@ func TestRunParseJunitTestResultAction_Relative(t *testing.T) {
 			t.Logf("%s %s - Body: %s", mock.Request().Method, mock.Request().URLStruct.String(), string(bodyContent))
 			switch mock.Request().URLStruct.String() {
 			case "http://lolcat.host/queue/workflows/666/test":
-				var report venom.Tests
-				err := json.Unmarshal(bodyContent, &report)
-				assert.NoError(t, err)
-				assert.Equal(t, 3, report.Total)
-				assert.Equal(t, 1, report.TotalKO)
-				assert.Equal(t, 1, report.TotalSkipped)
+				var report sdk.JUnitTestsSuites
+				require.NoError(t, json.Unmarshal(bodyContent, &report))
+				report = report.EnsureData()
+				stats := report.ComputeStats()
+				assert.Equal(t, 3, stats.Total)
+				assert.Equal(t, 1, stats.TotalKO)
+				assert.Equal(t, 1, stats.TotalSkipped)
 			}
 		}
 	}
@@ -152,17 +152,12 @@ func TestRunParseJunitTestResultAction_Relative(t *testing.T) {
 		}, nil)
 	assert.NoError(t, err)
 	assert.Equal(t, sdk.StatusFail, res.Status)
-
 }
 
-func Test_ComputeStats(t *testing.T) {
-	type args struct {
-		res *sdk.Result
-		v   *venom.Tests
-	}
+func Test_EnsureAndComputeStats(t *testing.T) {
 	tests := []struct {
 		name                    string
-		args                    args
+		args                    sdk.JUnitTestsSuites
 		want                    []string
 		status                  string
 		totalOK, totalKO, total int
@@ -177,18 +172,15 @@ func Test_ComputeStats(t *testing.T) {
 				"JUnit parser: 1 testsuite(s)",
 				"JUnit parser: testsuite myTestSuite has 1 testcase(s)",
 			},
-			args: args{
-				res: &sdk.Result{},
-				v: &venom.Tests{
-					TestSuites: []venom.TestSuite{
-						{
-							Name:     "myTestSuite",
-							Errors:   0,
-							Failures: 0,
-							TestCases: []venom.TestCase{
-								{
-									Name: "myTestCase",
-								},
+			args: sdk.JUnitTestsSuites{
+				TestSuites: []sdk.JUnitTestSuite{
+					{
+						Name:     "myTestSuite",
+						Errors:   0,
+						Failures: 0,
+						TestCases: []sdk.JUnitTestCase{
+							{
+								Name: "myTestCase",
 							},
 						},
 					},
@@ -208,19 +200,16 @@ func Test_ComputeStats(t *testing.T) {
 				"JUnit parser: testsuite myTestSuite has 1 failure(s)",
 				"JUnit parser: testsuite myTestSuite has 1 test(s) failed",
 			},
-			args: args{
-				res: &sdk.Result{},
-				v: &venom.Tests{
-					TestSuites: []venom.TestSuite{
-						{
-							Name:     "myTestSuite",
-							Errors:   0,
-							Failures: 1,
-							TestCases: []venom.TestCase{
-								{
-									Name:     "myTestCase",
-									Failures: []venom.Failure{{Value: "Foo"}},
-								},
+			args: sdk.JUnitTestsSuites{
+				TestSuites: []sdk.JUnitTestSuite{
+					{
+						Name:     "myTestSuite",
+						Errors:   0,
+						Failures: 1,
+						TestCases: []sdk.JUnitTestCase{
+							{
+								Name:     "myTestCase",
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}},
 							},
 						},
 					},
@@ -241,20 +230,17 @@ func Test_ComputeStats(t *testing.T) {
 				"JUnit parser: testsuite TestSuite.0 has 2 failure(s)",
 				"JUnit parser: testsuite TestSuite.0 has 2 test(s) failed",
 			},
-			args: args{
-				res: &sdk.Result{},
-				v: &venom.Tests{
-					TestSuites: []venom.TestSuite{
-						{
-							Errors:   0,
-							Failures: 1,
-							TestCases: []venom.TestCase{
-								{
-									Failures: []venom.Failure{{Value: "Foo"}},
-								},
-								{
-									Failures: []venom.Failure{{Value: "Foo"}},
-								},
+			args: sdk.JUnitTestsSuites{
+				TestSuites: []sdk.JUnitTestSuite{
+					{
+						Errors:   0,
+						Failures: 1,
+						TestCases: []sdk.JUnitTestCase{
+							{
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}},
+							},
+							{
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}},
 							},
 						},
 					},
@@ -265,31 +251,27 @@ func Test_ComputeStats(t *testing.T) {
 			name:    "malformed",
 			status:  sdk.StatusFail,
 			totalOK: 0,
-			totalKO: 2, // sum of failure + errors on testsuite attribute. So 1+1
-			total:   2,
+			totalKO: 1,
+			total:   1,
 			want: []string{
 				"JUnit parser: 1 testsuite(s)",
 				"JUnit parser: testsuite myTestSuite has 1 testcase(s)",
 				"JUnit parser: testcase myTestCase has 3 failure(s)",
 				"JUnit parser: testcase myTestCase has 2 error(s)",
-				"JUnit parser: testsuite myTestSuite has 3 failure(s)",
-				"JUnit parser: testsuite myTestSuite has 2 error(s)",
+				"JUnit parser: testsuite myTestSuite has 1 error(s)",
 				"JUnit parser: testsuite myTestSuite has 1 test(s) failed",
 			},
-			args: args{
-				res: &sdk.Result{},
-				v: &venom.Tests{
-					TestSuites: []venom.TestSuite{
-						{
-							Name:     "myTestSuite",
-							Errors:   1,
-							Failures: 1,
-							TestCases: []venom.TestCase{
-								{
-									Name:     "myTestCase",
-									Errors:   []venom.Failure{{Value: "Foo"}, {Value: "Foo"}},
-									Failures: []venom.Failure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
-								},
+			args: sdk.JUnitTestsSuites{
+				TestSuites: []sdk.JUnitTestSuite{
+					{
+						Name:     "myTestSuite",
+						Errors:   1,
+						Failures: 1,
+						TestCases: []sdk.JUnitTestCase{
+							{
+								Name:     "myTestCase",
+								Errors:   []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}},
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
 							},
 						},
 					},
@@ -309,29 +291,25 @@ func Test_ComputeStats(t *testing.T) {
 				"JUnit parser: testcase myTestCase 1 has 2 error(s)",
 				"JUnit parser: testcase myTestCase 2 has 3 failure(s)",
 				"JUnit parser: testcase myTestCase 2 has 2 error(s)",
-				"JUnit parser: testsuite myTestSuite has 6 failure(s)",
-				"JUnit parser: testsuite myTestSuite has 4 error(s)",
+				"JUnit parser: testsuite myTestSuite has 2 error(s)",
 				"JUnit parser: testsuite myTestSuite has 2 test(s) failed",
 			},
-			args: args{
-				res: &sdk.Result{},
-				v: &venom.Tests{
-					TestSuites: []venom.TestSuite{
-						{
-							Name:     "myTestSuite",
-							Errors:   1,
-							Failures: 1,
-							TestCases: []venom.TestCase{
-								{
-									Name:     "myTestCase 1",
-									Errors:   []venom.Failure{{Value: "Foo"}, {Value: "Foo"}},
-									Failures: []venom.Failure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
-								},
-								{
-									Name:     "myTestCase 2",
-									Errors:   []venom.Failure{{Value: "Foo"}, {Value: "Foo"}},
-									Failures: []venom.Failure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
-								},
+			args: sdk.JUnitTestsSuites{
+				TestSuites: []sdk.JUnitTestSuite{
+					{
+						Name:     "myTestSuite",
+						Errors:   1,
+						Failures: 1,
+						TestCases: []sdk.JUnitTestCase{
+							{
+								Name:     "myTestCase 1",
+								Errors:   []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}},
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
+							},
+							{
+								Name:     "myTestCase 2",
+								Errors:   []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}},
+								Failures: []sdk.JUnitTestFailure{{Value: "Foo"}, {Value: "Foo"}, {Value: "Foo"}},
 							},
 						},
 					},
@@ -341,23 +319,15 @@ func Test_ComputeStats(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := ComputeStats(tt.args.res, tt.args.v); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ComputeStats() = %v, want %v", got, tt.want)
-			}
-			if tt.args.res.Status != tt.status {
-				t.Errorf("status = %v, want %v", tt.args.res.Status, tt.status)
-			}
-
-			if tt.args.v.TotalOK != tt.totalOK {
-				t.Errorf("totalOK = %v, want %v", tt.args.v.TotalOK, tt.totalOK)
-			}
-
-			if tt.args.v.TotalKO != tt.totalKO {
-				t.Errorf("totalKO = %v, want %v", tt.args.v.TotalKO, tt.totalKO)
-			}
-			if tt.args.v.Total != tt.total {
-				t.Errorf("total = %v, want %v", tt.args.v.Total, tt.total)
+			tests := tt.args.EnsureData()
+			stats := tests.ComputeStats()
+			reasons := ComputeTestsReasons(tests)
+			if !reflect.DeepEqual(reasons, tt.want) {
+				t.Fatalf("ComputeStats() = %v, want %v", reasons, tt.want)
 			}
+			require.Equal(t, tt.totalOK, stats.TotalOK)
+			require.Equal(t, tt.totalKO, stats.TotalKO)
+			require.Equal(t, tt.total, stats.Total)
 		})
 	}
 }
diff --git a/sdk/blur_test.go b/sdk/blur_test.go
new file mode 100644
index 000000000..e7734a884
--- /dev/null
+++ b/sdk/blur_test.go
@@ -0,0 +1,77 @@
+package sdk_test
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"net/url"
+	"testing"
+
+	"github.com/ovh/cds/sdk"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestBlur(t *testing.T) {
+	b, err := sdk.NewBlur([]string{
+		"1234567890",
+		"1234567890abcdef",
+		"&é'(§è!çà",
+		`"1234567890`,
+		"12345",
+		"123456",
+	})
+	require.NoError(t, err)
+
+	require.Equal(t, "12345", b.String("12345"), "Secret size < secret min length")
+	require.Equal(t, sdk.PasswordPlaceholder, b.String("1234567890abcdef"))
+	require.Equal(t, sdk.PasswordPlaceholder, b.String("&é'(§è!çà"))
+	require.Equal(t, sdk.PasswordPlaceholder, b.String(`&é'"'"'(§è!çà`))
+	require.Equal(t, sdk.PasswordPlaceholder, b.String(url.QueryEscape("&é'(§è!çà")))
+	require.Equal(t, sdk.PasswordPlaceholder, b.String(base64.StdEncoding.EncodeToString([]byte("&é'(§è!çà"))))
+
+	buf, err := json.Marshal(`"1234567890`)
+	require.NoError(t, err)
+	require.Equal(t, "\""+sdk.PasswordPlaceholder+"\"", b.String(string(buf)))
+
+	type report struct {
+		String      string   `json:"string,omitempty"`
+		StringSlice []string `json:"string_slice,omitempty"`
+		Number      int      `json:"number,omitempty"`
+	}
+	r := report{
+		String:      "&é'(§è!çà",
+		StringSlice: []string{"1234567890", "&é'(§è!çà"},
+	}
+	require.NoError(t, b.Interface(&r))
+	require.Equal(t, sdk.PasswordPlaceholder, r.String)
+	require.Equal(t, sdk.PasswordPlaceholder, r.StringSlice[0])
+	require.Equal(t, sdk.PasswordPlaceholder, r.StringSlice[1])
+
+	expected, err := json.Marshal(report{
+		String:      sdk.PasswordPlaceholder,
+		StringSlice: []string{sdk.PasswordPlaceholder, sdk.PasswordPlaceholder},
+	})
+	require.NoError(t, err)
+	source, err := json.Marshal(report{
+		String:      "&é'(§è!çà",
+		StringSlice: []string{`"1234567890`, "&é'(§è!çà"},
+	})
+	require.NoError(t, err)
+	require.Equal(t, string(expected), b.String(string(source)))
+
+	tests := sdk.JUnitTestsSuites{
+		TestSuites: []sdk.JUnitTestSuite{{
+			Total:   123456,
+			Skipped: 5,
+			TestCases: []sdk.JUnitTestCase{{
+				Systemout: sdk.JUnitInnerResult{
+					Value: "1234567890abcdef",
+				},
+			}},
+		}},
+	}
+	require.NoError(t, b.Interface(&tests))
+	require.Equal(t, sdk.PasswordPlaceholder, tests.TestSuites[0].TestCases[0].Systemout.Value)
+	require.Equal(t, 0, tests.TestSuites[0].Total)
+	require.Equal(t, 5, tests.TestSuites[0].Skipped)
+}
diff --git a/sdk/tests.go b/sdk/tests.go
new file mode 100644
index 000000000..10b9bde4e
--- /dev/null
+++ b/sdk/tests.go
@@ -0,0 +1,116 @@
+package sdk
+
+import (
+	"encoding/xml"
+	"fmt"
+)
+
+type TestsResults struct {
+	JUnitTestsSuites
+	TestsStats
+}
+
+type TestsStats struct {
+	Total        int `json:"total,omitempty"`
+	TotalOK      int `json:"ok,omitempty"`
+	TotalKO      int `json:"ko,omitempty"`
+	TotalSkipped int `json:"skipped,omitempty"`
+}
+
+type JUnitTestsSuites struct {
+	XMLName    xml.Name         `xml:"testsuites" json:"-"`
+	TestSuites []JUnitTestSuite `xml:"testsuite" json:"test_suites"`
+}
+
+// EnsureData add missing names on test cases and suites also compute
+// test suites total values from test cases data.
+func (s JUnitTestsSuites) EnsureData() JUnitTestsSuites {
+	cleaned := s
+
+	// Add names if missing
+	for i := range cleaned.TestSuites {
+		if cleaned.TestSuites[i].Name == "" {
+			cleaned.TestSuites[i].Name = fmt.Sprintf("TestSuite.%d", i)
+		}
+		for j := range cleaned.TestSuites[i].TestCases {
+			if cleaned.TestSuites[i].TestCases[j].Name == "" {
+				cleaned.TestSuites[i].TestCases[j].Name = fmt.Sprintf("TestCase.%d", j)
+			}
+		}
+	}
+
+	// Validate total values for test suites
+	for i, ts := range cleaned.TestSuites {
+		var nSkipped, nFailures, nErrors int
+		for _, tc := range cleaned.TestSuites[i].TestCases {
+			// For a test case we should only increment one counter
+			if len(tc.Errors) > 0 {
+				nErrors++
+			} else if len(tc.Failures) > 0 {
+				nFailures++
+			} else if len(tc.Skipped) > 0 {
+				nSkipped++
+			}
+		}
+		cleaned.TestSuites[i].Skipped = nSkipped
+		cleaned.TestSuites[i].Failures = nFailures
+		cleaned.TestSuites[i].Errors = nErrors
+		cleaned.TestSuites[i].Total = len(ts.TestCases)
+	}
+
+	return cleaned
+}
+
+func (s JUnitTestsSuites) ComputeStats() TestsStats {
+	var stats TestsStats
+	for _, ts := range s.TestSuites {
+		stats.Total += ts.Total
+		stats.TotalKO += ts.Failures + ts.Errors
+		stats.TotalSkipped += ts.Skipped
+		stats.TotalOK += ts.Total - (ts.Failures + ts.Errors + ts.Skipped)
+	}
+	return stats
+}
+
+type JUnitTestSuite struct {
+	XMLName   xml.Name        `xml:"testsuite" json:"-"`
+	Disabled  int             `xml:"disabled,attr,omitempty" json:"disabled,omitempty"`
+	Errors    int             `xml:"errors,attr,omitempty" json:"errors,omitempty"`
+	Failures  int             `xml:"failures,attr,omitempty" json:"failures,omitempty"`
+	ID        string          `xml:"id,attr" json:"id,omitempty"`
+	Name      string          `xml:"name,attr" json:"name,omitempty"`
+	Package   string          `xml:"package,attr,omitempty" json:"package,omitempty"`
+	Skipped   int             `xml:"skipped,attr,omitempty" json:"skipped,omitempty"`
+	TestCases []JUnitTestCase `xml:"testcase" json:"tests,omitempty"`
+	Time      string          `xml:"time,attr,omitempty" json:"time,omitempty"`
+	Timestamp string          `xml:"timestamp,attr,omitempty" json:"timestamp,omitempty"`
+	Total     int             `xml:"tests,attr" json:"total,omitempty"`
+}
+
+type JUnitTestCase struct {
+	XMLName   xml.Name           `xml:"testcase" json:"-"`
+	Classname string             `xml:"classname,attr,omitempty" json:"classname,omitempty"`
+	Errors    []JUnitTestFailure `xml:"error,omitempty" json:"errors,omitempty"`
+	Failures  []JUnitTestFailure `xml:"failure,omitempty" json:"failures,omitempty"`
+	Name      string             `xml:"name,attr" json:"name,omitempty"`
+	Skipped   []JUnitTestSkipped `xml:"skipped,omitempty" json:"skipped,omitempty"`
+	Status    string             `xml:"status,attr,omitempty" json:"status,omitempty"`
+	Systemerr JUnitInnerResult   `xml:"system-err,omitempty" json:"systemerr,omitempty"`
+	Systemout JUnitInnerResult   `xml:"system-out,omitempty" json:"systemout,omitempty"`
+	Time      string             `xml:"time,attr,omitempty" json:"time,omitempty"`
+}
+
+type JUnitTestSkipped struct {
+	Message string `xml:"message,attr,omitempty" json:"message,omitempty"`
+	Value   string `xml:",cdata" json:"value,omitempty"`
+}
+
+type JUnitTestFailure struct {
+	Message string `xml:"message,attr,omitempty" json:"message,omitempty"`
+	Type    string `xml:"type,attr,omitempty" json:"type,omitempty"`
+	Value   string `xml:",cdata" json:"value,omitempty"`
+}
+
+type JUnitInnerResult struct {
+	Value string `xml:",cdata" json:"value,omitempty"`
+}
diff --git a/sdk/workflow_run_test.go b/sdk/workflow_run_test.go
index 1407d3239..9d9a412cc 100644
--- a/sdk/workflow_run_test.go
+++ b/sdk/workflow_run_test.go
@@ -4,7 +4,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/ovh/venom"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -48,31 +47,35 @@ func TestWorkflowRunReport(t *testing.T) {
 				},
 			},
 		},
-		Tests: &venom.Tests{
-			TotalKO: 1,
-			TestSuites: []venom.TestSuite{
-				{
-					Name: "Test suite1",
-					TestCases: []venom.TestCase{
-						{
-							Name: "test case 1",
-							Errors: []venom.Failure{
-								{},
+		Tests: &TestsResults{
+			TestsStats: TestsStats{
+				TotalKO: 1,
+			},
+			JUnitTestsSuites: JUnitTestsSuites{
+				TestSuites: []JUnitTestSuite{
+					{
+						Name: "Test suite1",
+						TestCases: []JUnitTestCase{
+							{
+								Name: "test case 1",
+								Errors: []JUnitTestFailure{
+									{},
+								},
+								Failures: []JUnitTestFailure{
+									{},
+								},
 							},
-							Failures: []venom.Failure{
-								{},
+							{
+								Name: "test case 2",
 							},
 						},
-						{
-							Name: "test case 2",
-						},
 					},
 				},
 			},
 		},
 	}
 	s, err := wfr.Report()
-	assert.NoError(t, err)
+	require.NoError(t, err)
 	t.Log(s)
 
 	wfr = WorkflowNodeRun{
diff --git a/ui/src/app/views/workflow/run/node/test/table/test.table.component.ts b/ui/src/app/views/workflow/run/node/test/table/test.table.component.ts
index 6949358d1..75ed5ac35 100644
--- a/ui/src/app/views/workflow/run/node/test/table/test.table.component.ts
+++ b/ui/src/app/views/workflow/run/node/test/table/test.table.component.ts
@@ -1,5 +1,5 @@
 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewChild } from '@angular/core';
-import { Failure, TestCase, Tests } from 'app/model/pipeline.model';
+import { Failure, Skipped, TestCase, Tests } from 'app/model/pipeline.model';
 import { ThemeStore } from 'app/service/services.module';
 import { Column, ColumnType, Filter } from 'app/shared/table/data-table.component';
 import { cloneDeep } from 'lodash-es';
@@ -24,8 +24,6 @@ export class WorkflowRunTestTableComponent implements OnInit {
 
     beforeClickFilter: string;
     filterInput: string;
-    filterIndex: number;
-    countFilteredElement: number;
 
     testCaseSelected: TestCase;
     themeSubscription: Subscription;
@@ -58,6 +56,9 @@ export class WorkflowRunTestTableComponent implements OnInit {
                 if (lowerFilter.indexOf('status:') === 0) {
                     return lowerFilter.indexOf(d.status) >= 7;
                 }
+                if (lowerFilter.indexOf('fullname:') === 0) {
+                    return d.fullname.toLowerCase() === lowerFilter.substring(9);
+                }
                 return d.fullname.toLowerCase().indexOf(lowerFilter) !== -1;
             };
         };
@@ -85,23 +86,26 @@ export class WorkflowRunTestTableComponent implements OnInit {
                 type: ColumnType.BUTTON,
                 name: '',
                 class: 'two right aligned',
-                selector: (tc: TestCase, index?: number) => ({
+                selector: (tc: TestCase) => ({
                     icon: 'eye',
                     class: 'icon small',
-                    click: () => this.clickTestCase(tc, index)
+                    click: () => this.clickTestCase(tc)
                 })
             },
         ];
     }
 
-    resetFilter(count: number): void {
-        if (this.countFilteredElement !== count) {
-            this.countFilteredElement = count;
+    dataChanged(count: number): void {
+        if (count !== 1) {
             delete this.testCaseSelected;
-            delete this.beforeClickFilter;
+            this._cd.markForCheck();
         }
     }
 
+    filterChanged(value: string): void {
+        this.filterInput = value;
+    }
+
     ngOnInit(): void {
         this.themeSubscription = this._theme.get()
             .pipe(finalize(() => this._cd.markForCheck()))
@@ -144,9 +148,9 @@ export class WorkflowRunTestTableComponent implements OnInit {
             if (ts.tests) {
                 let testCase = ts.tests.map(tc => {
                     tc.fullname = ts.name + ' / ' + tc.name;
-                    if (!tc.errors && !tc.failures) {
+                    if (!tc.errors && !tc.failures && !tc.skipped) {
                         tc.status = 'success';
-                    } else if ((tc.errors && tc.errors.length > 0) || (tc.failures && tc.failures.length > 0)) {
+                    } else if (tc.errors?.length > 0 || tc.failures?.length > 0) {
                         tc.status = 'failed';
                     } else {
                         tc.status = 'skipped';
@@ -160,37 +164,37 @@ export class WorkflowRunTestTableComponent implements OnInit {
         this._cd.detectChanges();
     }
 
-    clickTestCase(tc: TestCase, index: number): void {
-        if (this.testCaseSelected && this.testCaseSelected.fullname === tc.fullname && this.filterIndex === index) {
-            this.testCaseSelected = undefined;
+    clickTestCase(tc: TestCase): void {
+        if (this.testCaseSelected && this.testCaseSelected.fullname === tc.fullname) {
             this.filterInput = this.beforeClickFilter;
             delete this.beforeClickFilter;
+            delete this.testCaseSelected;
+            this._cd.markForCheck();
             return;
         }
-        this.filterIndex = index;
         this.beforeClickFilter = this.filterInput;
-        this.filterInput = tc.fullname;
-        tc.errorsAndFailures = this.getFailureString(tc.errors);
-        tc.errorsAndFailures += this.getFailureString(tc.failures);
+        this.filterInput = 'fullname:' + tc.fullname;
+        tc.messages = this.getFailureString(tc.errors);
+        tc.messages += this.getFailureString(tc.failures);
+        tc.messages += this.getFailureString(tc.skipped);
         this.testCaseSelected = tc;
         this._cd.markForCheck();
     }
 
-    getFailureString(fs: Array<Failure>): string {
+    getFailureString(fs: Array<Failure | Skipped>): string {
         if (!fs) {
             return '';
         }
-        let r = '';
-        for (const f of fs) {
+        return fs.map(f => {
+            let r = '';
             if (f.message) {
-                r += f.message + '<hr>';
+                r += f.message;
             }
             if (f.value) {
                 r += f.value;
             }
-            r += '\n';
-        }
-        return r;
+            return r;
+        }).filter(r => !!r).join('\n');
     }
 
 }
diff --git a/ui/src/app/views/workflow/run/node/test/table/test.table.html b/ui/src/app/views/workflow/run/node/test/table/test.table.html
index 556ed68c6..090423e7e 100644
--- a/ui/src/app/views/workflow/run/node/test/table/test.table.html
+++ b/ui/src/app/views/workflow/run/node/test/table/test.table.html
@@ -26,45 +26,40 @@
             </div>
         </div>
     </div>
-    
+
     <div class="ui grid">
         <div class="sixteen wide column">
-            <app-data-table [withPagination]="20" [filter]="filterInput" [withFilter]="filter"
-                [columns]="columns" [data]="testcases" (dataChange)="resetFilter($event)">
+            <app-data-table [withPagination]="20" [filter]="filterInput" [withFilter]="filter" [columns]="columns"
+                [data]="testcases" (dataChange)="dataChanged($event)" (filterChange)="filterChanged($event)">
             </app-data-table>
         </div>
         <div class="sixteen wide column" *ngIf="testCaseSelected">
             <div>
-                <h4>Errors / Failures</h4>
-                <codemirror
-                    *ngIf="testCaseSelected.errorsAndFailures && testCaseSelected.errorsAndFailures !== ''"
-                    [ngModel]="testCaseSelected.errorsAndFailures"
-                    [config]="codeMirrorConfig"
-                    #codemirror1>
+                <h4>Errors / Failures / Skipped</h4>
+                <codemirror *ngIf="testCaseSelected.messages && testCaseSelected.messages !== ''"
+                    [ngModel]="testCaseSelected.messages" [config]="codeMirrorConfig" #codemirror1>
                 </codemirror>
-                <div class="ui info message" *ngIf="!testCaseSelected.errorsAndFailures || testCaseSelected.errorsAndFailures === ''">
+                <div class="ui info message" *ngIf="!testCaseSelected.messages || testCaseSelected.messages === ''">
                     {{ 'common_no_data' | translate }}
                 </div>
 
                 <h4>Systemout</h4>
                 <codemirror
-                    *ngIf="testCaseSelected.systemout && testCaseSelected.systemout.value !== ''"
-                    [ngModel]="testCaseSelected.systemout.value"
-                    [config]="codeMirrorConfig"
-                    #codemirror2>
+                    *ngIf="testCaseSelected.systemout && testCaseSelected.systemout.value && testCaseSelected.systemout.value !== ''"
+                    [ngModel]="testCaseSelected.systemout.value" [config]="codeMirrorConfig" #codemirror2>
                 </codemirror>
-                <div class="ui info message" *ngIf="!testCaseSelected.systemout || testCaseSelected.systemout.value === ''">
+                <div class="ui info message"
+                    *ngIf="!testCaseSelected.systemout || !testCaseSelected.systemout.value || testCaseSelected.systemout.value === ''">
                     {{ 'common_no_data' | translate }}
                 </div>
 
                 <h4>Systemerr</h4>
                 <codemirror
-                    *ngIf="testCaseSelected.systemerr && testCaseSelected.systemerr.value !== ''"
-                    [ngModel]="testCaseSelected.systemerr.value"
-                    [config]="codeMirrorConfig"
-                    #codemirror3>
+                    *ngIf="testCaseSelected.systemerr && testCaseSelected.systemerr.value && testCaseSelected.systemerr.value !== ''"
+                    [ngModel]="testCaseSelected.systemerr.value" [config]="codeMirrorConfig" #codemirror3>
                 </codemirror>
-                <div class="ui info message" *ngIf="!testCaseSelected.systemerr || testCaseSelected.systemerr.value === ''">
+                <div class="ui info message"
+                    *ngIf="!testCaseSelected.systemerr || !testCaseSelected.systemerr.value || testCaseSelected.systemerr.value === ''">
                     {{ 'common_no_data' | translate }}
                 </div>
             </div>