diff --git a/.build/core.mk b/.build/core.mk
new file mode 100644
index 0000000000..4f935e131a
--- /dev/null
+++ b/.build/core.mk
@@ -0,0 +1,16 @@
+CI		 			:= $(if ${CI},${CI},0)
+VERSION 			:= $(if ${CDS_SEMVER},${CDS_SEMVER},snapshot)
+CDS_VERSION 		:= $(if ${CDS_VERSION},${CDS_VERSION},snapshot)
+GITHASH 			:= $(if ${GIT_HASH},${GIT_HASH},`git log -1 --format="%H"`)
+BUILDTIME 			:= `date "+%m/%d/%y-%H:%M:%S"`
+UNAME 				:= $(shell uname)
+UNAME_LOWERCASE     := $(shell uname -s| tr A-Z a-z)
+
+.PHONY: help
+help:
+	@grep -hE '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
+		awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-17s\033[0m %s\n", $$1, $$2}'
+
+install-venom: ## install venom, usage: make venom-install venom_version=v0.27.0 venom_path=/usr/bin/ 
+	@curl https://github.com/ovh/venom/releases/download/$(venom_version)/venom.$(UNAME_LOWERCASE)-amd64 -L -o $(venom_path)/venom && \
+	chmod +x $(venom_path)/venom
diff --git a/.build/go.mk b/.build/go.mk
new file mode 100644
index 0000000000..994499af30
--- /dev/null
+++ b/.build/go.mk
@@ -0,0 +1,198 @@
+GO_BUILD 			= GOPRIVATE="${GO_PRIVATE}" CGO_ENABLED=0 go build -a -installsuffix cgo
+GO_LIST 			= env GO111MODULE=on GOPRIVATE="${GO_PRIVATE}" go list
+TEST_CMD 			= go test -v -timeout 600s -coverprofile=profile.coverprofile
+TEST_C_CMD 			= go test -c -coverprofile=profile.coverprofile
+TEST_RUN_ARGS 		= -test.v -test.timeout 600s -test.coverprofile=profile.coverprofile
+LDFLAGS		 		= -ldflags "-X github.com/ovh/cds/sdk.VERSION=$(VERSION) -X github.com/ovh/cds/sdk.GOOS=$$GOOS -X github.com/ovh/cds/sdk.GOARCH=$$GOARCH -X github.com/ovh/cds/sdk.GITHASH=$(GITHASH) -X github.com/ovh/cds/sdk.BUILDTIME=$(BUILDTIME) -X github.com/ovh/cds/sdk.BINARY=$(TARGET_ENGINE) -X github.com/ovh/cds/sdk.DBMIGRATE=$(DBMIGRATE)"
+CURRENT_PACKAGE 	= $(shell $(GO_LIST))
+TARGET_DIST 		:= ./dist
+TARGET_RESULTS 		:= ./results
+ENABLE_CROSS_COMPILATION := true
+
+
+##### =====> Clean <===== #####
+
+mk_go_clean: # clean target directory
+	@rm -rf $(TARGET_DIST)
+	@rm -rf $(TARGET_RESULTS)
+	@for testfile in `find ./ -name "bin.test"`; do \
+		rm $$testfile; \
+	done;
+	@for TST in `find ./ -name "tests.log"`; do \
+		rm $$TST; \
+	done;
+	@for profile in `find ./ -name "*.coverprofile"`; do \
+		rm $$profile; \
+	done;
+
+##### =====> Compile <===== #####
+
+IS_TEST 							:= 	$(filter test,$(MAKECMDGOALS))
+TARGET_OS 							:= 	$(if ${ENABLE_CROSS_COMPILATION},$(if ${OS},${OS}, $(if $(IS_TEST), $(shell go env GOOS), darwin linux freebsd)),$(shell go env GOOS))
+TARGET_ARCH 						:= 	$(if ${ARCH},${ARCH}, $(if $(IS_TEST), $(shell go env GOARCH),amd64))
+BINARIES 							=	$(addprefix $(TARGET_DIST)/, $(addsuffix -$(OS)-$(ARCH)$(if $(IS_WINDOWS),.exe), $(notdir $(TARGET_NAME))))
+CROSS_COMPILED_BINARIES 			= 	$(foreach OS, $(TARGET_OS), $(foreach ARCH, $(TARGET_ARCH), $(BINARIES)))
+GOFILES 							= $(call get_recursive_files, '.')
+
+mk_go_build:
+	$(info *** mk_go_build)
+
+$(CROSS_COMPILED_BINARIES): $(GOFILES) $(TARGET_DIST)
+	$(info *** compiling $@)
+	@GOOS=$(call get_os_from_binary_file,$@) \
+	GOARCH=$(call get_arch_from_binary_file,$@) \
+	$(GO_BUILD) $(LDFLAGS) -o $@;
+
+##### =====> Compile Tests <===== #####
+
+PKGS     = $(or $(PKG),$(shell $(GO_LIST) ./...))
+TESTPKGS = $(shell $(GO_LIST) -f \
+			'{{ if or .TestGoFiles .XTestGoFiles }}{{ .ImportPath }}{{ end }}' \
+			$(PKGS))
+
+TESTPKGS_C_FILE = $(addsuffix /bin.test, $(subst $(CURRENT_PACKAGE),.,$(PKG)))
+TESTPKGS_C = $(foreach PKG, $(TESTPKGS), $(TESTPKGS_C_FILE))
+
+$(TESTPKGS_C): #main_test.go
+	$(info *** compiling test $@)
+	@cd $(dir $@) && $(TEST_C_CMD) -o bin.test .
+
+##### =====> Running Tests <===== #####
+
+TESTPKGS_RESULTS_LOG_FILE = $(addsuffix /tests.log, $(subst $(CURRENT_PACKAGE),.,$(PKG)))
+TESTPKGS_RESULTS = $(foreach PKG, $(TESTPKGS), $(TESTPKGS_RESULTS_LOG_FILE))
+
+$(HOME)/.richstyle.yml:
+	echo "leaveTestPrefix: true" > $(HOME)/.richstyle.yml
+
+GO_RICHGO = ${GOPATH}/bin/richgo
+$(GO_RICHGO): $(HOME)/.richstyle.yml
+	go get -u github.com/kyoh86/richgo
+
+EXIT_TESTS := 0
+$(TESTPKGS_RESULTS): $(GOFILES) $(TESTPKGS_C) $(GO_RICHGO)
+	$(info *** executing tests in $(dir $@))
+	@-cd $(dir $@) && ./bin.test $(TEST_RUN_ARGS) | tee tests.log | richgo testfilter ;
+
+GO_COV_MERGE = ${GOPATH}/bin/gocovmerge
+$(GO_COV_MERGE):
+	go get -u github.com/wadey/gocovmerge
+
+GO_GOJUNIT = ${GOPATH}/bin/go-junit-report
+$(GO_GOJUNIT):
+	go get -u github.com/jstemmer/go-junit-report
+
+GO_COBERTURA = ${GOPATH}/bin/gocover-cobertura
+$(GO_COBERTURA):
+	go get -u github.com/t-yuki/gocover-cobertura
+
+mk_go_test: $(GO_COV_MERGE) $(GO_COBERTURA) $(GOFILES) $(TARGET_RESULTS) $(TESTPKGS_RESULTS)# Run tests
+	@echo "Generating unit tests coverage..."
+	@$(GO_COV_MERGE) `find ./ -name "*.coverprofile"` > $(TARGET_RESULTS)/cover.out
+	@$(GO_COBERTURA) < $(TARGET_RESULTS)/cover.out > $(TARGET_RESULTS)/coverage.xml
+	@go tool cover -html=$(TARGET_RESULTS)/cover.out -o=$(TARGET_RESULTS)/cover.html
+	@NB=$$(grep -c "^FAIL" `find . -type f -name "tests.log"`|grep -v ':0'|wc -l); echo "tests failed $$NB" && exit $$NB
+
+mk_go_test-xunit: $(GO_GOJUNIT) $(TARGET_RESULTS) # Generate test with xunit report
+	@echo "Generating xUnit Report..."
+	@for TST in `find . -name "tests.log"`; do \
+		if [ -s $$TST ]; then \
+			FAILED=`grep -E '(FAIL)+\s([a-z\.\/]*)\s\[build failed\]' $$TST | wc -l`; \
+			if [ $$FAILED -gt 0 ]; then \
+				echo "Build Failed \t\t\t($$TST)"; \
+				echo "Build Failed \t\t\t($$TST)" >>  $(TARGET_RESULTS)/fail; \
+			else \
+				NO_TESTS=`grep -E '\?+\s+([a-z\.\/]*)\s\[no test files\]' $$TST | wc -l`; \
+				if [ $$NO_TESTS -gt 0 ]; then \
+					echo "No tests found \t\t\t($$TST)"; \
+				else \
+					if [ ! -z "${CDS_VERSION}" ]; then \
+						echo "Sending $$TST to CDS"; \
+						worker upload --tag `echo $$TST | sed 's|./||' | sed 's|./||' | sed 's|/|_|g') | sed 's|_tests.log||'` $(abspath $$TST); \
+					fi; \
+					echo "Generating xUnit report \t$$TST.tests-results.xml"; \
+					cat $$TST | $(GO_GOJUNIT) > $$TST.tests-results.xml; \
+				fi; \
+			fi; \
+		else \
+			echo "Ignoring empty file \t\t$$TST"; \
+		fi; \
+	done; \
+	for XML in `find . -name "tests.log.tests-results.xml"`; do \
+		if [ "$$XML" =  "./tests.log.tests-results.xml" ]; then \
+      		PWD=`pwd`; \
+		 	mv $$XML $(TARGET_RESULTS)/`basename $(PWD)`.tests-results.xml; \
+		else \
+			mv $$XML $(TARGET_RESULTS)/`echo $$XML | sed 's|./||' | sed 's|/|_|g' | sed 's|_tests.log||'`; \
+		fi; \
+	done; \
+	rm -f $(TARGET_RESULTS)/report; \
+	for XML in `find . -name "*.tests-results.xml"`; do \
+		if [ -s $$XML ]; then \
+			if grep -q 'testsuite' $$XML; then \
+				echo "Generating report: " $$XML; \
+				echo "`xmllint --xpath "//testsuite/@name" $$XML | sed 's/name=//' | sed 's/"//g'`" \
+				"`xmllint --xpath "//testsuite/@tests" $$XML | sed 's/tests=//' | sed 's/"//g'` Tests :" \
+				"`xmllint --xpath "//testsuite/@errors" $$XML 2>/dev/null | sed 's/errors=//' | sed 's/"//g'` Errors ;"\
+				"`xmllint --xpath "//testsuite/@failures" $$XML 2>/dev/null | sed 's/failures=//' | sed 's/"//g'` Failures;" \
+				"`xmllint --xpath "//testsuite/@skip" $$XML 2>/dev/null | sed 's/skip=//' | sed 's/"//g'` Skipped;" \
+				>> $(TARGET_RESULTS)/report; \
+			fi; \
+		fi; \
+	done; \
+	if [ -e $(TARGET_RESULTS)/report ]; then \
+		cat $(TARGET_RESULTS)/report; \
+	fi; \
+	echo "#########################"; \
+	for XML in `find . -name "*.tests-results.xml"`; do \
+		if [ -s $$XML ]; then \
+			if grep -q 'errors' $$XML && grep -q 'testsuite' $$XML; then \
+				if [ "`xmllint --xpath "//testsuite/@errors" $$XML | sed 's/errors=//' | sed 's/"//g'`" -gt "0" ]; then  \
+					echo "	$$XML : Tests failed";  \
+				fi; \
+			fi; \
+			if grep -q 'failures' $$XML && grep -q 'testsuite' $$XML $$XML; then \
+				if [ "`xmllint --xpath "//testsuite/@failures" $$XML | sed 's/failures=//' | sed 's/"//g'`" -gt "0" ]; then  \
+					echo "	$$XML : Tests failed";  \
+				fi; \
+			fi; \
+		fi; \
+	done; \
+	if [ -e $(TARGET_RESULTS)/fail ]; then \
+		echo "#########################"; \
+		echo "ERROR: Test compilation failure"; \
+		cat $(TARGET_RESULTS)/fail; \
+		exit 1; \
+	fi;
+
+##### =====> lint <===== #####
+
+GOLANG_CI_LINT 		:= ${GOPATH}/bin/golangci-lint
+$(GOLANG_CI_LINT):
+	curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.27.0
+
+mk_go_lint: $(GOLANG_CI_LINT) # run golangci lint
+	$(info *** running lint)
+	$(GOLANG_CI_LINT) run
+
+##### =====> Internals <===== #####
+
+$(TARGET_RESULTS):
+	$(info create $(TARGET_RESULTS) directory)
+	@mkdir -p $(TARGET_RESULTS)
+
+$(TARGET_DIST):
+	$(info create $(TARGET_DIST) directory)
+	@mkdir -p $(TARGET_DIST)
+
+define get_os_from_binary_file
+$(strip $(shell echo $(1) | cut -d'_' -f 2))
+endef
+
+define get_arch_from_binary_file
+$(strip $(patsubst %.exe, %,$(shell echo $(1) | cut -d'_' -f 3)))
+endef
+
+define get_recursive_files
+$(subst ./,,$(shell find $(1) -type f -name "*.go" -print))
+endef
diff --git a/.build/plugin.mk b/.build/plugin.mk
new file mode 100644
index 0000000000..13f22b5874
--- /dev/null
+++ b/.build/plugin.mk
@@ -0,0 +1,57 @@
+
+BINARIES_CONF 					=	$(addprefix $(TARGET_DIST)/, $(addsuffix -$(OS)-$(ARCH).yml, $(notdir $(TARGET_NAME))))
+PLUGIN_CONF 					=	$(addprefix $(TARGET_DIST)/, $(addsuffix .yml, $(notdir $(TARGET_NAME))))
+CROSS_COMPILED_CONF 			= 	$(foreach OS, $(TARGET_OS), $(foreach ARCH, $(TARGET_ARCH), $(BINARIES_CONF)))
+
+define PLUGIN_MANIFEST_BINARY
+os: %os%
+arch: %arch%
+cmd: ./%filename%
+endef
+export PLUGIN_MANIFEST_BINARY
+
+define get_os_from_binary_file
+$(strip $(shell echo $(1) | awk '{n=split($$1,a,"-");print a[n-1]}'))
+endef
+
+define get_arch_from_binary_file
+$(strip $(patsubst %.exe, %,$(shell echo $(1) | awk '{n=split($$1,a,"-");print a[n]}')))
+endef
+
+define get_executor_path_from_binary_file
+$(strip $(patsubst dist/%, %, $(patsubst %-, %, $(shell echo $(1) |awk '{n=split($$1,a,"-");for (i = 2; i < n-1; i++) printf a[i] "-"}'))))
+endef
+
+## Prepare yml file for each os-arch
+$(CROSS_COMPILED_PLUGIN_CONF): $(GOFILES) $(TARGET_DIST)
+	$(info *** prepare conf $@)
+	@echo "$$PLUGIN_MANIFEST_BINARY" > $@; \
+	OS=$(call get_os_from_binary_file,$@); \
+	ARCH=$(call get_arch_from_binary_file,$@); \
+	perl -pi -e s,%os%,$$OS,g $@ ; \
+	perl -pi -e s,%arch%,$$ARCH,g $@ ; \
+	EXTENSION=""; \
+	if test "$(TARGET_NAME)" == *"windows"* ; then EXTENSION=".exe"; fi; \
+	FILENAME=$(TARGET_NAME)-$$OS-$$ARCH$$EXTENSION; \
+	perl -pi -e s,%filename%,$$FILENAME,g $@
+
+$(PLUGIN_CONF): $(TARGET_DIST)
+	$(info *** prepare conf $@)
+	@cp $(TARGET_NAME).yml $@;
+
+publish:
+	@echo "Updating plugin $(TARGET_NAME)..."
+	cdsctl admin plugins import $(TARGET_DIST)/$(TARGET_NAME).yml
+	@for GOOS in $(TARGET_OS); do \
+		for GOARCH in $(TARGET_ARCH); do \
+			EXTENSION=""; \
+			if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \
+			echo "Updating plugin binary $(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION"; \
+			cdsctl admin plugins binary-add $(TARGET_NAME) $(TARGET_DIST)/$(TARGET_NAME)-$$GOOS-$$GOARCH.yml $(TARGET_DIST)/$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \
+		done; \
+	done
+
+build: $(CROSS_COMPILED_PLUGIN_CONF) $(PLUGIN_CONF) $(CROSS_COMPILED_BINARIES) ## build action plugin and prepare configuration
+
+clean:
+	@rm -rf dist
diff --git a/contrib/grpcplugins/action/Makefile b/contrib/grpcplugins/action/Makefile
index b12a688c68..836a5bf59e 100644
--- a/contrib/grpcplugins/action/Makefile
+++ b/contrib/grpcplugins/action/Makefile
@@ -1,110 +1,41 @@
-.PHONY: clean
+##### =====> Commands <===== #####
 
-VERSION := $(if ${CDS_SEMVER},${CDS_SEMVER},snapshot${CDS_VERSION})
-GITHASH := $(if ${GIT_HASH},${GIT_HASH},`git log -1 --format="%H"`)
-BUILDTIME := `date "+%m/%d/%y-%H:%M:%S"`
+include ../../../.build/core.mk
 
-TARGET_DIR = dist
-
-define PLUGIN_MANIFEST_BINARY
-os: %os%
-arch: %arch%
-cmd: ./%filename%
-endef
-export PLUGIN_MANIFEST_BINARY
-
-GO_BUILD = go build
-DIRS = `ls -d */ | cut -f1 -d'/'`
-
-default: build
-
-clean:
-	@rm -rf $(TARGET_DIR)
-
-TARGET_DIR =  ./dist
-isWindows = $(filter $1,windows)
-
-TARGET_LDFLAGS = -ldflags "-X github.com/ovh/cds/sdk.VERSION=$(VERSION) -X github.com/ovh/cds/sdk.GOOS=$$GOOS -X github.com/ovh/cds/sdk.GOARCH=$$GOARCH -X github.com/ovh/cds/sdk.GITHASH=$(GITHASH) -X github.com/ovh/cds/sdk.BUILDTIME=$(BUILDTIME) -X github.com/ovh/cds/sdk.BINARY=$(TARGET_ENGINE) -X github.com/ovh/cds/sdk.DBMIGRATE=$(DBMIGRATE)"
-TARGET_OS = $(if ${OS},${OS},windows darwin linux freebsd)
-TARGET_ARCH = $(if ${ARCH},${ARCH},amd64 arm 386)
-
-ALL_PLUGINS := $(if ${TARGET_NAME},${TARGET_NAME}, $(filter-out $(TARGET_DIR), $(shell for plugin in $(DIRS); do echo $(basename "$$plugin"); done)))
-TARGET_PLUGINS := $(foreach PLUGIN, $(ALL_PLUGINS), $(TARGET_DIR)/plugin-$(PLUGIN))
+DIRS 			:= `ls -d plugin-* | cut -f1 -d'/'`
+ALL_PLUGINS 	:= $(if ${TARGET_NAME},${TARGET_NAME}, $(filter-out $(TARGET_DIST), $(shell for plugin in $(DIRS); do echo $(basename "$$plugin"); done)))
+TARGET_PLUGINS 	:= $(foreach PLUGIN, $(ALL_PLUGINS), dist/$(PLUGIN).yml)
 TARGET_PLUGINS_DIST := $(foreach TARGET_PLUGIN, $(TARGET_PLUGINS), $(foreach OS, $(TARGET_OS), $(foreach ARCH, $(TARGET_ARCH), $(TARGET_PLUGIN)-$(OS)-$(ARCH)$(if $(call isWindows, $(OS)),.exe))))
-TARGET_PLUGINS_MANIFEST_DIST := $(foreach TARGET_PLUGIN, $(TARGET_PLUGINS), $(TARGET_PLUGIN)-$(OS)-$(ARCH).yml)
+TARGET_DIST 		:= ./dist
 
-define get_os_from_binary_file
-$(strip $(shell echo $(1) | awk '{n=split($$1,a,"-");print a[n-1]}'))
+define get_plugin_name_from_conf
+$(strip $(patsubst dist/%.yml, %,$(shell echo $(1))))
 endef
 
-define get_arch_from_binary_file
-$(strip $(patsubst %.exe, %,$(shell echo $(1) | awk '{n=split($$1,a,"-");print a[n]}')))
-endef
+$(TARGET_PLUGINS): $(TARGET_DIST)
+	$(info building $(call get_plugin_name_from_conf,$@))
+	@P=$(call get_plugin_name_from_conf,$@); \
+	$(MAKE) build -C $$P
 
-define get_executor_path_from_binary_file
-$(strip $(patsubst dist/%, %, $(patsubst %-, %, $(shell echo $(1) |awk '{n=split($$1,a,"-");for (i = 2; i < n-1; i++) printf a[i] "-"}'))))
-endef
+build: $(TARGET_PLUGINS)
 
-build: $(TARGET_PLUGINS_DIST)
+.PHONY: dist
 
-$(TARGET_DIR):
-	@mkdir $(TARGET_DIR)
-
-$(TARGET_PLUGINS_DIST):
-	$(info Compiling $@: $(abspath $@))
-	$(MAKE) --no-print-directory gobuild PACKAGE=$(call get_executor_path_from_binary_file,$@) GOOS=$(call get_os_from_binary_file,$@) GOARCH=$(call get_arch_from_binary_file,$@) OUTPUT=$@
-	$(MAKE) --no-print-directory manifestbuild PACKAGE=$(call get_executor_path_from_binary_file,$@) GOOS=$(call get_os_from_binary_file,$@) GOARCH=$(call get_arch_from_binary_file,$@) OUTPUT=$@
-
-gobuild:
-	@if go tool dist list | grep "$$GOOS" | grep "$$GOARCH" > /dev/null; then \
-		if [ -f $(PACKAGE)/go.mod ]; then \
-			cd $(abspath $(PACKAGE)) && GOOS=$$GOOS GOARCH=$$GOARCH CGO_ENABLED=0 $(GO_BUILD) $(TARGET_LDFLAGS) -o $(abspath $(OUTPUT)); \
-		fi; \
-	fi
-
-manifestbuild:
-	@if go tool dist list | grep "$$GOOS" | grep "$$GOARCH" > /dev/null; then \
-		if [ -f $(PACKAGE)/go.mod ]; then \
-			echo "$$PLUGIN_MANIFEST_BINARY" > $(TARGET_DIR)/plugin-$$PACKAGE-$$GOOS-$$GOARCH.yml; \
-			perl -pi -e s,%os%,$$GOOS,g $(TARGET_DIR)/plugin-$$PACKAGE-$$GOOS-$$GOARCH.yml; \
-			perl -pi -e s,%arch%,$$GOARCH,g $(TARGET_DIR)/plugin-$$PACKAGE-$$GOOS-$$GOARCH.yml; \
-			EXTENSION=""; \
-			if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \
-			FILENAME=plugin-$$PACKAGE-$$GOOS-$$GOARCH$$EXTENSION; \
-			perl -pi -e s,%filename%,$$FILENAME,g $(TARGET_DIR)/plugin-$$PACKAGE-$$GOOS-$$GOARCH.yml; \
-			pluginname=$$PACKAGE; \
-			cp $$PACKAGE/$$pluginname.yml $(TARGET_DIR)/plugin-$$PACKAGE.yml; \
-		fi; \
-	fi
-
-display:
-	$(info $(TARGET_PLUGINS_DIST))
-
-publish-all:
-	@echo "Updating plugins..."
-	@for plugin in $(DIRS); do \
-		pluginname=$(basename "$$plugin"); \
-		if test "$$pluginname" = "examples" ; then continue; fi; \
-		if test "$$pluginname" = "dist" ; then continue; fi; \
-		cdsctl admin plugins import $(TARGET_DIR)/plugin-$$plugin.yml; \
-		for GOOS in $(TARGET_OS); do \
-			for GOARCH in $(TARGET_ARCH); do \
-			EXTENSION=""; \
-			if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \
-			echo "Updating plugin binary $$pluginname-$$GOOS-$$GOARCH$$EXTENSION"; \
-			cdsctl admin plugins binary-add plugin-$$pluginname $(TARGET_DIR)/plugin-$$pluginname-$$GOOS-$$GOARCH.yml $(TARGET_DIR)/plugin-$$pluginname-$$GOOS-$$GOARCH$$EXTENSION; \
-			done; \
+dist:
+	@mkdir -p dist
+	@for PLU in $(ALL_PLUGINS); do \
+		for F in `find $$PLU/dist -name "$$PLU*"`; do \
+			mv $$F dist/; \
 		done; \
 	done;
 
-publish:
-	@echo "Updating plugin $(TARGET_NAME)..."
-	cdsctl admin plugins import $(TARGET_DIR)/plugin-$(TARGET_NAME).yml
-	@for GOOS in $(TARGET_OS); do \
-		for GOARCH in $(TARGET_ARCH); do \
-			EXTENSION=""; \
-			if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \
-			echo "Updating plugin binary $(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION"; \
-			cdsctl admin plugins binary-add plugin-$(TARGET_NAME) $(TARGET_DIR)/plugin-$(TARGET_NAME)-$$GOOS-$$GOARCH.yml $(TARGET_DIR)/plugin-$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \
-		done; \
-	done
+publish: 
+	@for P in $(ALL_PLUGINS); do \
+		$(MAKE) publish -C $$P; \
+	done;
+
+clean:
+	@rm -rf $(TARGET_DIST)
+	@for P in $(ALL_PLUGINS); do \
+		$(MAKE) clean -C $$P; \
+	done;
diff --git a/contrib/grpcplugins/action/archive/.gitignore b/contrib/grpcplugins/action/plugin-archive/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/archive/.gitignore
rename to contrib/grpcplugins/action/plugin-archive/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-archive/Makefile b/contrib/grpcplugins/action/plugin-archive/Makefile
new file mode 100644
index 0000000000..7923507828
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-archive/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-archive
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/archive/go.mod b/contrib/grpcplugins/action/plugin-archive/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/archive/go.mod
rename to contrib/grpcplugins/action/plugin-archive/go.mod
diff --git a/contrib/grpcplugins/action/archive/go.sum b/contrib/grpcplugins/action/plugin-archive/go.sum
similarity index 99%
rename from contrib/grpcplugins/action/archive/go.sum
rename to contrib/grpcplugins/action/plugin-archive/go.sum
index 36cb5d3f5c..0bb0232c5e 100644
--- a/contrib/grpcplugins/action/archive/go.sum
+++ b/contrib/grpcplugins/action/plugin-archive/go.sum
@@ -242,6 +242,7 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
 github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
diff --git a/contrib/grpcplugins/action/archive/main.go b/contrib/grpcplugins/action/plugin-archive/main.go
similarity index 100%
rename from contrib/grpcplugins/action/archive/main.go
rename to contrib/grpcplugins/action/plugin-archive/main.go
diff --git a/contrib/grpcplugins/action/archive/archive.yml b/contrib/grpcplugins/action/plugin-archive/plugin-archive.yml
similarity index 100%
rename from contrib/grpcplugins/action/archive/archive.yml
rename to contrib/grpcplugins/action/plugin-archive/plugin-archive.yml
diff --git a/contrib/grpcplugins/action/archive/plugin_test.go b/contrib/grpcplugins/action/plugin-archive/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/archive/plugin_test.go
rename to contrib/grpcplugins/action/plugin-archive/plugin_test.go
diff --git a/contrib/grpcplugins/action/clair/.gitignore b/contrib/grpcplugins/action/plugin-clair/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/clair/.gitignore
rename to contrib/grpcplugins/action/plugin-clair/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-clair/Makefile b/contrib/grpcplugins/action/plugin-clair/Makefile
new file mode 100644
index 0000000000..9305ec5d3b
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-clair/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-clair
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/clair/clairctl/LICENSE b/contrib/grpcplugins/action/plugin-clair/clairctl/LICENSE
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/LICENSE
rename to contrib/grpcplugins/action/plugin-clair/clairctl/LICENSE
diff --git a/contrib/grpcplugins/action/clair/clairctl/clair/analyze.go b/contrib/grpcplugins/action/plugin-clair/clairctl/clair/analyze.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/clair/analyze.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/clair/analyze.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/clair/clair.go b/contrib/grpcplugins/action/plugin-clair/clairctl/clair/clair.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/clair/clair.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/clair/clair.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/clair/layering.go b/contrib/grpcplugins/action/plugin-clair/clairctl/clair/layering.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/clair/layering.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/clair/layering.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/clair/push.go b/contrib/grpcplugins/action/plugin-clair/clairctl/clair/push.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/clair/push.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/clair/push.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/config/config.go b/contrib/grpcplugins/action/plugin-clair/clairctl/config/config.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/config/config.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/config/config.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/docker/docker.go b/contrib/grpcplugins/action/plugin-clair/clairctl/docker/docker.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/docker/docker.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/docker/docker.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/docker/dockercli/dockercli.go b/contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockercli/dockercli.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/docker/dockercli/dockercli.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockercli/dockercli.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/docker/dockerdist/auth.go b/contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockerdist/auth.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/docker/dockerdist/auth.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockerdist/auth.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/docker/dockerdist/dockerdist.go b/contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockerdist/dockerdist.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/docker/dockerdist/dockerdist.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/docker/dockerdist/dockerdist.go
diff --git a/contrib/grpcplugins/action/clair/clairctl/xstrings/xstrings.go b/contrib/grpcplugins/action/plugin-clair/clairctl/xstrings/xstrings.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/clairctl/xstrings/xstrings.go
rename to contrib/grpcplugins/action/plugin-clair/clairctl/xstrings/xstrings.go
diff --git a/contrib/grpcplugins/action/clair/go.mod b/contrib/grpcplugins/action/plugin-clair/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/clair/go.mod
rename to contrib/grpcplugins/action/plugin-clair/go.mod
diff --git a/contrib/grpcplugins/action/clair/go.sum b/contrib/grpcplugins/action/plugin-clair/go.sum
similarity index 99%
rename from contrib/grpcplugins/action/clair/go.sum
rename to contrib/grpcplugins/action/plugin-clair/go.sum
index 64f1e58bbb..464dff4781 100644
--- a/contrib/grpcplugins/action/clair/go.sum
+++ b/contrib/grpcplugins/action/plugin-clair/go.sum
@@ -243,6 +243,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
 github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
 github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
diff --git a/contrib/grpcplugins/action/clair/main.go b/contrib/grpcplugins/action/plugin-clair/main.go
similarity index 100%
rename from contrib/grpcplugins/action/clair/main.go
rename to contrib/grpcplugins/action/plugin-clair/main.go
diff --git a/contrib/grpcplugins/action/clair/clair.yml b/contrib/grpcplugins/action/plugin-clair/plugin-clair.yml
similarity index 100%
rename from contrib/grpcplugins/action/clair/clair.yml
rename to contrib/grpcplugins/action/plugin-clair/plugin-clair.yml
diff --git a/contrib/grpcplugins/action/download/.gitignore b/contrib/grpcplugins/action/plugin-download/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/download/.gitignore
rename to contrib/grpcplugins/action/plugin-download/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-download/Makefile b/contrib/grpcplugins/action/plugin-download/Makefile
new file mode 100644
index 0000000000..56f07e8bba
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-download/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-download
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/download/go.mod b/contrib/grpcplugins/action/plugin-download/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/download/go.mod
rename to contrib/grpcplugins/action/plugin-download/go.mod
diff --git a/contrib/grpcplugins/action/download/go.sum b/contrib/grpcplugins/action/plugin-download/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/download/go.sum
rename to contrib/grpcplugins/action/plugin-download/go.sum
diff --git a/contrib/grpcplugins/action/download/main.go b/contrib/grpcplugins/action/plugin-download/main.go
similarity index 100%
rename from contrib/grpcplugins/action/download/main.go
rename to contrib/grpcplugins/action/plugin-download/main.go
diff --git a/contrib/grpcplugins/action/download/download.yml b/contrib/grpcplugins/action/plugin-download/plugin-download.yml
similarity index 100%
rename from contrib/grpcplugins/action/download/download.yml
rename to contrib/grpcplugins/action/plugin-download/plugin-download.yml
diff --git a/contrib/grpcplugins/action/download/plugin_test.go b/contrib/grpcplugins/action/plugin-download/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/download/plugin_test.go
rename to contrib/grpcplugins/action/plugin-download/plugin_test.go
diff --git a/contrib/grpcplugins/action/group-tmpl/.gitignore b/contrib/grpcplugins/action/plugin-group-tmpl/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/.gitignore
rename to contrib/grpcplugins/action/plugin-group-tmpl/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-group-tmpl/Makefile b/contrib/grpcplugins/action/plugin-group-tmpl/Makefile
new file mode 100644
index 0000000000..43c3cc9941
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-group-tmpl/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-group-tmpl
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/group-tmpl/applications.go b/contrib/grpcplugins/action/plugin-group-tmpl/applications.go
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/applications.go
rename to contrib/grpcplugins/action/plugin-group-tmpl/applications.go
diff --git a/contrib/grpcplugins/action/group-tmpl/applications_test.go b/contrib/grpcplugins/action/plugin-group-tmpl/applications_test.go
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/applications_test.go
rename to contrib/grpcplugins/action/plugin-group-tmpl/applications_test.go
diff --git a/contrib/grpcplugins/action/group-tmpl/go.mod b/contrib/grpcplugins/action/plugin-group-tmpl/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/go.mod
rename to contrib/grpcplugins/action/plugin-group-tmpl/go.mod
diff --git a/contrib/grpcplugins/action/group-tmpl/go.sum b/contrib/grpcplugins/action/plugin-group-tmpl/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/go.sum
rename to contrib/grpcplugins/action/plugin-group-tmpl/go.sum
diff --git a/contrib/grpcplugins/action/group-tmpl/main.go b/contrib/grpcplugins/action/plugin-group-tmpl/main.go
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/main.go
rename to contrib/grpcplugins/action/plugin-group-tmpl/main.go
diff --git a/contrib/grpcplugins/action/group-tmpl/group-tmpl.yml b/contrib/grpcplugins/action/plugin-group-tmpl/plugin-group-tmpl.yml
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/group-tmpl.yml
rename to contrib/grpcplugins/action/plugin-group-tmpl/plugin-group-tmpl.yml
diff --git a/contrib/grpcplugins/action/group-tmpl/plugin_test.go b/contrib/grpcplugins/action/plugin-group-tmpl/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/plugin_test.go
rename to contrib/grpcplugins/action/plugin-group-tmpl/plugin_test.go
diff --git a/contrib/grpcplugins/action/group-tmpl/templates.go b/contrib/grpcplugins/action/plugin-group-tmpl/templates.go
similarity index 100%
rename from contrib/grpcplugins/action/group-tmpl/templates.go
rename to contrib/grpcplugins/action/plugin-group-tmpl/templates.go
diff --git a/contrib/grpcplugins/action/kafka-publish/.gitignore b/contrib/grpcplugins/action/plugin-kafka-publish/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/.gitignore
rename to contrib/grpcplugins/action/plugin-kafka-publish/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-kafka-publish/Makefile b/contrib/grpcplugins/action/plugin-kafka-publish/Makefile
new file mode 100644
index 0000000000..436dfae457
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-kafka-publish/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-kafka-publish
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/kafka-publish/README.md b/contrib/grpcplugins/action/plugin-kafka-publish/README.md
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/README.md
rename to contrib/grpcplugins/action/plugin-kafka-publish/README.md
diff --git a/contrib/grpcplugins/action/kafka-publish/cli.go b/contrib/grpcplugins/action/plugin-kafka-publish/cli.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/cli.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/cli.go
diff --git a/contrib/grpcplugins/action/kafka-publish/cli_actions.go b/contrib/grpcplugins/action/plugin-kafka-publish/cli_actions.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/cli_actions.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/cli_actions.go
diff --git a/contrib/grpcplugins/action/kafka-publish/go.mod b/contrib/grpcplugins/action/plugin-kafka-publish/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/go.mod
rename to contrib/grpcplugins/action/plugin-kafka-publish/go.mod
diff --git a/contrib/grpcplugins/action/kafka-publish/go.sum b/contrib/grpcplugins/action/plugin-kafka-publish/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/go.sum
rename to contrib/grpcplugins/action/plugin-kafka-publish/go.sum
diff --git a/contrib/grpcplugins/action/kafka-publish/kafka.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafka.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafka.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafka.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafka_ack.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafka_ack.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafka_ack.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafka_ack.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafka_consumer.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafka_consumer.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafka_consumer.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafka_consumer.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafkapublisher/chunks.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/chunks.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafkapublisher/chunks.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/chunks.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafkapublisher/chunks_test.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/chunks_test.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafkapublisher/chunks_test.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/chunks_test.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafkapublisher/context.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/context.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafkapublisher/context.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/context.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafkapublisher/types.go b/contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/types.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafkapublisher/types.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/kafkapublisher/types.go
diff --git a/contrib/grpcplugins/action/kafka-publish/log.go b/contrib/grpcplugins/action/plugin-kafka-publish/log.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/log.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/log.go
diff --git a/contrib/grpcplugins/action/kafka-publish/main.go b/contrib/grpcplugins/action/plugin-kafka-publish/main.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/main.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/main.go
diff --git a/contrib/grpcplugins/action/kafka-publish/kafka-publish.yml b/contrib/grpcplugins/action/plugin-kafka-publish/plugin-kafka-publish.yml
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/kafka-publish.yml
rename to contrib/grpcplugins/action/plugin-kafka-publish/plugin-kafka-publish.yml
diff --git a/contrib/grpcplugins/action/kafka-publish/plugin_test.go b/contrib/grpcplugins/action/plugin-kafka-publish/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/kafka-publish/plugin_test.go
rename to contrib/grpcplugins/action/plugin-kafka-publish/plugin_test.go
diff --git a/contrib/grpcplugins/action/marathon/.gitignore b/contrib/grpcplugins/action/plugin-marathon/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/marathon/.gitignore
rename to contrib/grpcplugins/action/plugin-marathon/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-marathon/Makefile b/contrib/grpcplugins/action/plugin-marathon/Makefile
new file mode 100644
index 0000000000..14bc65e0d6
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-marathon/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-marathon
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/marathon/README.md b/contrib/grpcplugins/action/plugin-marathon/README.md
similarity index 100%
rename from contrib/grpcplugins/action/marathon/README.md
rename to contrib/grpcplugins/action/plugin-marathon/README.md
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon1.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon1.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon1.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon1.json
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon2.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon2.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon2.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon2.json
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon3.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon3.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon3.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon3.json
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon4.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon4.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon4.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon4.json
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon5.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon5.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon5.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon5.json
diff --git a/contrib/grpcplugins/action/marathon/fixtures/marathon6.json b/contrib/grpcplugins/action/plugin-marathon/fixtures/marathon6.json
similarity index 100%
rename from contrib/grpcplugins/action/marathon/fixtures/marathon6.json
rename to contrib/grpcplugins/action/plugin-marathon/fixtures/marathon6.json
diff --git a/contrib/grpcplugins/action/marathon/go.mod b/contrib/grpcplugins/action/plugin-marathon/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/marathon/go.mod
rename to contrib/grpcplugins/action/plugin-marathon/go.mod
diff --git a/contrib/grpcplugins/action/marathon/go.sum b/contrib/grpcplugins/action/plugin-marathon/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/marathon/go.sum
rename to contrib/grpcplugins/action/plugin-marathon/go.sum
diff --git a/contrib/grpcplugins/action/marathon/main.go b/contrib/grpcplugins/action/plugin-marathon/main.go
similarity index 100%
rename from contrib/grpcplugins/action/marathon/main.go
rename to contrib/grpcplugins/action/plugin-marathon/main.go
diff --git a/contrib/grpcplugins/action/marathon/marathon_schema.go b/contrib/grpcplugins/action/plugin-marathon/marathon_schema.go
similarity index 100%
rename from contrib/grpcplugins/action/marathon/marathon_schema.go
rename to contrib/grpcplugins/action/plugin-marathon/marathon_schema.go
diff --git a/contrib/grpcplugins/action/marathon/marathon.yml b/contrib/grpcplugins/action/plugin-marathon/plugin-marathon.yml
similarity index 100%
rename from contrib/grpcplugins/action/marathon/marathon.yml
rename to contrib/grpcplugins/action/plugin-marathon/plugin-marathon.yml
diff --git a/contrib/grpcplugins/action/marathon/plugin_test.go b/contrib/grpcplugins/action/plugin-marathon/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/marathon/plugin_test.go
rename to contrib/grpcplugins/action/plugin-marathon/plugin_test.go
diff --git a/contrib/grpcplugins/action/npm-audit-parser/.gitignore b/contrib/grpcplugins/action/plugin-npm-audit-parser/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/.gitignore
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-npm-audit-parser/Makefile b/contrib/grpcplugins/action/plugin-npm-audit-parser/Makefile
new file mode 100644
index 0000000000..2b2915e669
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-npm-audit-parser/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-npm-audit-parser
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/npm-audit-parser/go.mod b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/go.mod
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/go.mod
diff --git a/contrib/grpcplugins/action/npm-audit-parser/go.sum b/contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/go.sum
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/go.sum
diff --git a/contrib/grpcplugins/action/npm-audit-parser/main.go b/contrib/grpcplugins/action/plugin-npm-audit-parser/main.go
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/main.go
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/main.go
diff --git a/contrib/grpcplugins/action/npm-audit-parser/npm-audit-parser.yml b/contrib/grpcplugins/action/plugin-npm-audit-parser/plugin-npm-audit-parser.yml
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/npm-audit-parser.yml
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/plugin-npm-audit-parser.yml
diff --git a/contrib/grpcplugins/action/npm-audit-parser/types.go b/contrib/grpcplugins/action/plugin-npm-audit-parser/types.go
similarity index 100%
rename from contrib/grpcplugins/action/npm-audit-parser/types.go
rename to contrib/grpcplugins/action/plugin-npm-audit-parser/types.go
diff --git a/contrib/grpcplugins/action/ssh-cmd/.gitignore b/contrib/grpcplugins/action/plugin-ssh-cmd/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/ssh-cmd/.gitignore
rename to contrib/grpcplugins/action/plugin-ssh-cmd/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-ssh-cmd/Makefile b/contrib/grpcplugins/action/plugin-ssh-cmd/Makefile
new file mode 100644
index 0000000000..eafda45d25
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-ssh-cmd/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-ssh-cmd
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/ssh-cmd/go.mod b/contrib/grpcplugins/action/plugin-ssh-cmd/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/ssh-cmd/go.mod
rename to contrib/grpcplugins/action/plugin-ssh-cmd/go.mod
diff --git a/contrib/grpcplugins/action/ssh-cmd/go.sum b/contrib/grpcplugins/action/plugin-ssh-cmd/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/ssh-cmd/go.sum
rename to contrib/grpcplugins/action/plugin-ssh-cmd/go.sum
diff --git a/contrib/grpcplugins/action/ssh-cmd/main.go b/contrib/grpcplugins/action/plugin-ssh-cmd/main.go
similarity index 100%
rename from contrib/grpcplugins/action/ssh-cmd/main.go
rename to contrib/grpcplugins/action/plugin-ssh-cmd/main.go
diff --git a/contrib/grpcplugins/action/ssh-cmd/ssh-cmd.yml b/contrib/grpcplugins/action/plugin-ssh-cmd/plugin-ssh-cmd.yml
similarity index 100%
rename from contrib/grpcplugins/action/ssh-cmd/ssh-cmd.yml
rename to contrib/grpcplugins/action/plugin-ssh-cmd/plugin-ssh-cmd.yml
diff --git a/contrib/grpcplugins/action/tmpl/.gitignore b/contrib/grpcplugins/action/plugin-tmpl/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/.gitignore
rename to contrib/grpcplugins/action/plugin-tmpl/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-tmpl/Makefile b/contrib/grpcplugins/action/plugin-tmpl/Makefile
new file mode 100644
index 0000000000..f3a693d47a
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-tmpl/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-tmpl
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/tmpl/go.mod b/contrib/grpcplugins/action/plugin-tmpl/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/go.mod
rename to contrib/grpcplugins/action/plugin-tmpl/go.mod
diff --git a/contrib/grpcplugins/action/tmpl/go.sum b/contrib/grpcplugins/action/plugin-tmpl/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/go.sum
rename to contrib/grpcplugins/action/plugin-tmpl/go.sum
diff --git a/contrib/grpcplugins/action/tmpl/main.go b/contrib/grpcplugins/action/plugin-tmpl/main.go
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/main.go
rename to contrib/grpcplugins/action/plugin-tmpl/main.go
diff --git a/contrib/grpcplugins/action/tmpl/tmpl.yml b/contrib/grpcplugins/action/plugin-tmpl/plugin-tmpl.yml
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/tmpl.yml
rename to contrib/grpcplugins/action/plugin-tmpl/plugin-tmpl.yml
diff --git a/contrib/grpcplugins/action/tmpl/plugin_test.go b/contrib/grpcplugins/action/plugin-tmpl/plugin_test.go
similarity index 100%
rename from contrib/grpcplugins/action/tmpl/plugin_test.go
rename to contrib/grpcplugins/action/plugin-tmpl/plugin_test.go
diff --git a/contrib/grpcplugins/action/venom/.gitignore b/contrib/grpcplugins/action/plugin-venom/.gitignore
similarity index 100%
rename from contrib/grpcplugins/action/venom/.gitignore
rename to contrib/grpcplugins/action/plugin-venom/.gitignore
diff --git a/contrib/grpcplugins/action/plugin-venom/Makefile b/contrib/grpcplugins/action/plugin-venom/Makefile
new file mode 100644
index 0000000000..88e4978536
--- /dev/null
+++ b/contrib/grpcplugins/action/plugin-venom/Makefile
@@ -0,0 +1,9 @@
+
+TARGET_NAME 			= plugin-venom
+
+##### ^^^^^^ EDIT ABOVE ^^^^^^ #####
+
+include ../../../../.build/core.mk
+include ../../../../.build/go.mk
+include ../../../../.build/plugin.mk
+
diff --git a/contrib/grpcplugins/action/venom/go.mod b/contrib/grpcplugins/action/plugin-venom/go.mod
similarity index 100%
rename from contrib/grpcplugins/action/venom/go.mod
rename to contrib/grpcplugins/action/plugin-venom/go.mod
diff --git a/contrib/grpcplugins/action/venom/go.sum b/contrib/grpcplugins/action/plugin-venom/go.sum
similarity index 100%
rename from contrib/grpcplugins/action/venom/go.sum
rename to contrib/grpcplugins/action/plugin-venom/go.sum
diff --git a/contrib/grpcplugins/action/venom/main.go b/contrib/grpcplugins/action/plugin-venom/main.go
similarity index 100%
rename from contrib/grpcplugins/action/venom/main.go
rename to contrib/grpcplugins/action/plugin-venom/main.go
diff --git a/contrib/grpcplugins/action/venom/venom.yml b/contrib/grpcplugins/action/plugin-venom/plugin-venom.yml
similarity index 100%
rename from contrib/grpcplugins/action/venom/venom.yml
rename to contrib/grpcplugins/action/plugin-venom/plugin-venom.yml
diff --git a/contrib/grpcplugins/action/venom/tests/file1.yml b/contrib/grpcplugins/action/plugin-venom/tests/file1.yml
similarity index 100%
rename from contrib/grpcplugins/action/venom/tests/file1.yml
rename to contrib/grpcplugins/action/plugin-venom/tests/file1.yml
diff --git a/contrib/grpcplugins/action/venom/tests/file2.yml b/contrib/grpcplugins/action/plugin-venom/tests/file2.yml
similarity index 100%
rename from contrib/grpcplugins/action/venom/tests/file2.yml
rename to contrib/grpcplugins/action/plugin-venom/tests/file2.yml
diff --git a/contrib/grpcplugins/action/venom/tests/subtest/file3.yml b/contrib/grpcplugins/action/plugin-venom/tests/subtest/file3.yml
similarity index 100%
rename from contrib/grpcplugins/action/venom/tests/subtest/file3.yml
rename to contrib/grpcplugins/action/plugin-venom/tests/subtest/file3.yml
diff --git a/contrib/grpcplugins/action/venom/venom_test.go b/contrib/grpcplugins/action/plugin-venom/venom_test.go
similarity index 100%
rename from contrib/grpcplugins/action/venom/venom_test.go
rename to contrib/grpcplugins/action/plugin-venom/venom_test.go