VOL-4883 - Publish a new bbsim release

https://github.com/opencord/bbsim/releases/tag/untagged-6d947de2a6078a1fe175
----------------------------------------------------------------------------
  o Draft bbsim release v2.96.8572 created by this patch set.
  o All 6cross-compile binaries are now included.
  o Change ID + commit message document the release.
  o Binaries downloaded/tested using {bbr,bbsim,bbsimctl} --help

Makefile
--------
  o Makefile release target is now able to cross compile all binaries:
    - bbsimctl cross compiled to arm, darwin, linux and windows.
    - release-{bbr, bbsim} only built *-linux-amd64
  o Refactor targets into a more modular and hierarchial setup.
  o Be sure to create RELEASE_DIR early on localhost so docker
    container can create a volume (NFS mount) for building into.
  o Display banners when building targets to improve log readability.
  o Clean targets updated to remove everything generated.
  o Help targets added to document indvidual target logic.
  o Makefile logic heavily commented.

makefiles/release/bbr.mk
makefiles/release/bbsim.mk
makefiles/release/bbsimctl.mk
-----------------------------
  o Relocate build-* and release-* target logic into named makefiles.
  o Update SHELL to set -euo pipefail to detect uninit shell vars.
  o Replaced shell/looping logic with true makefile target dependencies:
    - shell/loop replaced with a target rule that builds one platform binary.
    - Derive a list of targets release/{bbr,bbsim,bbsimctl}-{os}-{arch}
    - release: depends on all buildable targets
    - release rule can extract arch= and os= from target path being built.
    - To simplify logic construct env vars separately into a response file.
    - passed as "docker --env-file [x]" VS appending to an ever growing command line.
  o Marked more targets as .PHONY so they will always build.
  o Added helper target 'onf-publish' for exercising changes in the github-release script.

makefiles/include.mk
--------------------
  o Single include for importing all library makefiles.

makefiles/consts.mk
-------------------
  o Include fixed values, esp $(quote-single) which is now used to document
  o Refactor duplication in GO_* macros into named/reused values to shorten lines.

makefiles/lint
--------------
  o Moved lint::docker (hadolint target) into makefiles/lint/docker/*.mk.
  o Added makefiles/lint library targets for ability to lint more sources.

makefiles/tools.mk
------------------
  o Refactor DOCKER_* and GO_* macros into a named includable makefile.q

Change-Id: I8791317ba0c3f01d047f363e69f8885a03f1a1a1
diff --git a/.gitignore b/.gitignore
index 7593b82..2e825d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,10 @@
+.*.swp
 .idea
 /bbr
 /bbsim
 /bbsimctl
 logs/*
-release
+/release
 .DS_Store
 *.logs
 *.trace
diff --git a/Makefile b/Makefile
index 68e2183..fdd1d01 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,8 @@
 # limitations under the License.
 # -----------------------------------------------------------------------
 
+$(if $(DEBUG),$(warning ENTER))
+
 .DEFAULT_GOAL   := help
 MAKECMDGOALS    ?= help
 
@@ -24,6 +26,12 @@
 ##--------------------##
 ##---]  INCLUDES  [---##
 ##--------------------##
+include $(MAKEDIR)/include.mk
+include $(MAKEDIR)/release/include.mk
+
+##--------------------##
+##---]  INCLUDES  [---##
+##--------------------##
 help-targets := help-all help HELP
 $(if $(filter $(help-targets),$(MAKECMDGOALS))\
     ,$(eval include $(MAKEDIR)/help.mk))
@@ -31,29 +39,11 @@
 ##-------------------##
 ##---]  GLOBALS  [---##
 ##-------------------##
-SHELL           = bash -e -o pipefail
 VERSION         ?= $(shell cat ./VERSION)
 DIFF		?= $(git diff --shortstat 2> /dev/null | tail -n1)
 GIT_STATUS	?= $(shell [ -z "$DIFF" ] && echo "Dirty" || echo "Clean")
 
-## Docker related -- are these ${shell vars} or $(make macros) ?
-DOCKER_TAG  			?= ${VERSION}
-DOCKER_REPOSITORY  		?=
-DOCKER_REGISTRY 		?=
-DOCKER_RUN_ARGS			?=
-DOCKER_PORTS			?= -p 50070:50070 -p 50060:50060 -p 50071:50071 -p 50072:50072 -p 50073:50073 -p 50074:50074 -p 50075:50075
-TYPE                            ?= minimal
-
-# tool containers
-VOLTHA_TOOLS_VERSION ?= 2.3.1
-
-GO                = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golang go
-GO_SH             = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golang sh -c '# fix-editor-colorization-quote(')
-GO_JUNIT_REPORT   = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app -i voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-go-junit-report go-junit-report
-GOCOVER_COBERTURA = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app/src/github.com/opencord/bbsim -i voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-gocover-cobertura gocover-cobertura
-GOLANGCI_LINT     = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golangci-lint golangci-lint
-HADOLINT          = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-hadolint hadolint
-PROTOC            = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-protoc protoc
+include $(MAKEDIR)/tools.mk   # Command macros for DOCKER_*, GO_*
 
 ## use local vars to shorten paths
 bbsim-tag = ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}bbsim:${DOCKER_TAG}
@@ -66,16 +56,37 @@
 
 protos: api/bbsim/bbsim.pb.go api/bbsim/bbsim.pb.gw.go api/legacy/bbsim.pb.go api/legacy/bbsim.pb.gw.go api/bbsim/bbsim_dmi.pb.go # @HELP Build proto files
 
-.PHONY: build
-build: protos build-bbsim build-bbsimctl build-bbr
+## -----------------------------------------------------------------------
+## Intent: Build tools for use on localhost
+## -----------------------------------------------------------------------
+build-target-deps += build-bbsim
+build-target-deps += build-bbsimctl
+build-target-deps += build-bbr
+
+.PHONY: build $(build-target-deps)
+build: protos $(build-target-deps)
+
+## -----------------------------------------------------------------------
+## Intent: Cross-compile binaries for release
+## -----------------------------------------------------------------------
+release-target-deps += release-bbr
+release-target-deps += release-bbsim
+release-target-deps += release-bbsimctl
+
+.PHONY: release $(release-target-deps)
+release: $(release-target-deps)
 
 ## lint and unit tests
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 lint-dockerfile:
 	@echo "Running Dockerfile lint check..."
 	@${HADOLINT} $$(find ./build -name "Dockerfile*")
 	@echo "Dockerfile lint check OK"
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 lint-mod:
 	@echo "Running dependency check..."
 	@${GO} mod verify
@@ -90,8 +101,12 @@
 	@[[ `git ls-files --exclude-standard --others go.mod go.sum vendor` == "" ]] || (echo "ERROR: Untracked files detected after running go mod tidy / go mod vendor" && git status -- go.mod go.sum vendor && git checkout -- go.mod go.sum vendor && exit 1)
 	@echo "Vendor check OK."
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 lint: lint-mod lint-dockerfile
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 sca:
 	@$(RM) -r ./sca-report
 	@mkdir -p ./sca-report
@@ -100,8 +115,12 @@
 	@echo ""
 	@echo "Static code analysis OK"
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 test: docs-lint test-unit test-bbr
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 test-unit: clean local-omci-lib-go # @HELP Execute unit tests
 	@echo "Running unit tests..."
 	@mkdir -p ./tests/results
@@ -111,23 +130,34 @@
 	${GOCOVER_COBERTURA} < ./tests/results/go-test-coverage.out > ./tests/results/go-test-coverage.xml ;\
 	exit $$RETURN
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 test-bbr: release-bbr docker-build # @HELP Validate that BBSim and BBR are working together
 	DOCKER_RUN_ARGS="-pon 2 -onu 2" $(MAKE) docker-run
 	sleep 5
 	./$(RELEASE_DIR)/$(RELEASE_BBR_NAME)-linux-amd64 -pon 2 -onu 2 -logfile tmp.logs
 	docker $(RM) -f bbsim
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 mod-update: # @HELP Download the dependencies to the vendor folder
 	${GO} mod tidy
 	${GO} mod vendor
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docker-build: local-omci-lib-go local-protos# @HELP Build the BBSim docker container (contains BBSimCtl too)
 	docker build \
 	  -t "$(bbsim-tag)" \
 	  -f build/package/Dockerfile .
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docker-push: # @HELP Push the docker container to a registry
 	docker push "$(bbsim-tag)"
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docker-kind-load:
 	@if [ "`kind get clusters | grep voltha-$(TYPE)`" = '' ]; then echo "no voltha-$(TYPE) cluster found" && exit 1; fi
 	kind load docker-image "$(bbsim-tag)" --name=voltha-$(TYPE) --nodes $(shell kubectl get nodes --template='{{range .items}}{{.metadata.name}},{{end}}' | sed 's/,$$//')
@@ -149,10 +179,14 @@
 docker-run-cmd += "$(bbsim-tag)" /app/bbsim
 docker-run-cmd += ${DOCKER_RUN_ARGS}
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docker-run: # @HELP Runs the container locally (available options: DOCKER_RUN_ARGS="-pon 2 -onu 2" make docker-run)
 	docker ps
 	$(docker-run-cmd)
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docker-run-dev: # @HELP Runs the container locally (intended for development purposes, not in detached mode)
 	$(docker-run-cmd)
 
@@ -164,68 +198,11 @@
 	$(MAKE) -C docs html
 	@echo -e "\nBBSim documentation generated in file://${PWD}/docs/build/html/index.html"
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docs-lint:
 	$(MAKE) -C docs lint
 
-# Release related items
-# Generates binaries in $RELEASE_DIR with name $RELEASE_NAME-$RELEASE_OS_ARCH
-# Inspired by: https://github.com/kubernetes/minikube/releases
-RELEASE_DIR     ?= release
-RELEASE_OS_ARCH ?= linux-amd64 linux-arm64 windows-amd64 darwin-amd64
-
-RELEASE_BBR_NAME      ?= bbr
-RELEASE_BBSIM_NAME    ?= bbsim
-RELEASE_BBSIMCTL_NAME ?= bbsimctl
-
-release-bbr:
-	@echo "$(RELEASE_BBR_NAME)-linux-amd64"
-	${GO} build -mod vendor \
-	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-	    -X main.gitStatus=${GIT_STATUS} \
-	    -X main.version=${VERSION}" \
-	  -o "$(RELEASE_DIR)/$(RELEASE_BBR_NAME)-linux-amd64" ./cmd/bbr
-
-release-bbsim:
-	@echo "$(RELEASE_BBSIM_NAME)-linux-amd64"
-	${GO} build -mod vendor \
-	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-	    -X main.gitStatus=${GIT_STATUS} \
-	    -X main.version=${VERSION}" \
-	  -o "$(RELEASE_DIR)/$(RELEASE_BBSIM_NAME)-linux-amd64" ./cmd/bbsim
-
-release-bbsimctl:	
-	@echo "** $(MAKE): processing target [$@]"
-	${GO_SH} set -eo pipefail; \
-  for os_arch in ${RELEASE_OS_ARCH}; do \
-	    echo "$(RELEASE_BBSIMCTL_NAME)-$$os_arch"; \
-	    GOOS="$${os_arch%-*}" GOARCH="$${os_arch#*-}" go build -mod vendor \
-	      -ldflags "-w -X github.com/opencord/bbsim/internal/bbsimctl/config.BuildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	      -X github.com/opencord/bbsim/internal/bbsimctl/config.CommitHash=$(shell git log --pretty=format:%H -n 1) \
-	      -X github.com/opencord/bbsim/internal/bbsimctl/config.GitStatus=${GIT_STATUS} \
-	      -X github.com/opencord/bbsim/internal/bbsimctl/config.Version=${VERSION}" \
-	    -o "$(RELEASE_DIR)/$(RELEASE_BBSIMCTL_NAME)-$$os_arch" ./cmd/bbsimctl; \
-	  done'
-# fix-editor-colorization-quote(')
-
-## -----------------------------------------------------------------------
-## -----------------------------------------------------------------------
-release-deps += release-bbr
-release-deps += release-bbsim
-release-deps += release-bbsimctl
-.PHONY: release $(release-deps)
-release: release-init $(release-deps) # @HELP Creates release ready bynaries for BBSimctl and BBR artifacts
-
-$(release-deps) : release-init
-
-release-init:
-	@echo "** $(MAKE): processing target [$@]"
-	${GO_SH} set -eo pipefail\
-; echo "PWD: $$(/bin/pwd)"\
-; mkdir -p $(RELEASE_DIR)'
-# fix-editor-colorization-quote(')
-
 ## -----------------------------------------------------------------------
 ## -----------------------------------------------------------------------
 swagger-deps += docs/swagger/bbsim/bbsim.swagger.json
@@ -242,6 +219,8 @@
 	cp -r ${LOCAL_OMCI_LIB_GO}/* vendor/github.com/opencord/omci-lib-go
 endif
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 local-protos: ## Copies a local version of the voltha-protos dependency into the vendor directory
 ifdef LOCAL_PROTOS
 	$(RM) -r vendor/github.com/opencord/voltha-protos/v5/go
@@ -250,44 +229,26 @@
 	$(RM) -r vendor/github.com/opencord/voltha-protos/v5/go/vendor
 endif
 
-# Internals
-
-clean:
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+clean ::
 	@$(RM) -f bbsim
 	@$(RM) -f bbsimctl
 	@$(RM) -f bbr
 	@$(RM) -r tools/bin
-	@$(RM) -r release/*
+	@$(RM) -r release
 
-build-bbr: local-omci-lib-go local-protos
-	@go build -mod vendor \
-	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-	    -X main.gitStatus=${GIT_STATUS} \
-	    -X main.version=${VERSION}" \
-	  ./cmd/bbr
+sterile :: clean
 
-build-bbsim:
-	@go build -mod vendor \
-	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
-	    -X main.gitStatus=${GIT_STATUS} \
-	    -X main.version=${VERSION}" \
-	  ./cmd/bbsim
-
-build-bbsimctl:
-	@go build -mod vendor \
-	  -ldflags "-w -X github.com/opencord/bbsim/internal/bbsimctl/config.BuildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
-	    -X github.com/opencord/bbsim/internal/bbsimctl/config.CommitHash=$(shell git log --pretty=format:%H -n 1) \
-	    -X github.com/opencord/bbsim/internal/bbsimctl/config.GitStatus=${GIT_STATUS} \
-	    -X github.com/opencord/bbsim/internal/bbsimctl/config.Version=${VERSION}" \
-	  ./cmd/bbsimctl
-
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 setup_tools:
 	@echo "Downloading dependencies..."
 	@${GO} mod download github.com/grpc-ecosystem/grpc-gateway github.com/opencord/voltha-protos/v5
 	@echo "Dependencies downloaded OK"
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 VOLTHA_PROTOS ?= $(shell ${GO} list -f '{{ .Dir }}' -m github.com/opencord/voltha-protos/v5)
 GOOGLEAPI     ?= $(shell ${GO} list -f '{{ .Dir }}' -m github.com/grpc-ecosystem/grpc-gateway)
 
@@ -299,6 +260,8 @@
       --go_out=plugins=grpc:./ --go_opt=paths=source_relative \
       $<
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 api/bbsim/bbsim_dmi.pb.go: api/bbsim/bbsim_dmi.proto setup_tools
 	@echo $@
 	@${PROTOC} -I. \
@@ -306,6 +269,8 @@
       --go_out=plugins=grpc:./ --go_opt=paths=source_relative \
       $<
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 api/bbsim/bbsim.pb.go api/bbsim/bbsim.pb.gw.go: api/bbsim/bbsim.proto api/bbsim/bbsim.yaml setup_tools
 	@echo $@
 	@${PROTOC} -I. \
@@ -315,6 +280,8 @@
 	  --grpc-gateway_out=logtostderr=true,paths=source_relative,grpc_api_configuration=api/bbsim/bbsim.yaml,allow_delete_body=true:./ \
       $<
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 api/legacy/bbsim.pb.go api/legacy/bbsim.pb.gw.go: api/legacy/bbsim.proto setup_tools
 	@echo $@
 	@${PROTOC} -I. \
@@ -325,6 +292,8 @@
 	  --grpc-gateway_out=logtostderr=true,paths=source_relative,allow_delete_body=true:./ \
       $<
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docs/swagger/bbsim/bbsim.swagger.json: api/bbsim/bbsim.yaml setup_tools
 	@echo $@
 	@${PROTOC} -I ./api \
@@ -333,6 +302,8 @@
 	  --swagger_out=logtostderr=true,allow_delete_body=true,disable_default_errors=true,grpc_api_configuration=$<:docs/swagger/ \
 	  api/bbsim/bbsim.proto
 
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
 docs/swagger/leagacy/bbsim.swagger.json: api/legacy/bbsim.proto setup_tools
 	@echo $@
 	@${PROTOC} -I ./api \
@@ -341,4 +312,20 @@
 	  --swagger_out=logtostderr=true,allow_delete_body=true,disable_default_errors=true:docs/swagger/ \
 	  $<
 
+## -----------------------------------------------------------------------
+## Intent: Helper target used to exercise release script changes
+## -----------------------------------------------------------------------
+onf-publish-args := $(null)
+onf-publish-args += --draft
+onf-publish-args += --gen-version
+onf-publish-args += --repo-org opencord
+onf-publish-args += --repo-name bbsim
+onf-publish-args += --git-hostname github.com
+onf-publish-args += --pac $(HOME)/.ssh/github.com/pacs/onf-voltha
+# onf-publish-args += --notes-file "$(PWD)/release-notes"
+onf-publish:
+	../ci-management/jjb/shell/github-release.sh $(onf-publish-args) 2>&1 | tee $@.log
+
+$(if $(DEBUG),$(warning LEAVE))
+
 # [EOF]
diff --git a/VERSION b/VERSION
index 141f2e8..ace4423 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.15.0
+1.15.1
diff --git a/makefiles/commands.mk b/makefiles/commands.mk
new file mode 100644
index 0000000..f1c512c
--- /dev/null
+++ b/makefiles/commands.mk
@@ -0,0 +1,31 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2022-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2022-2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+# ONF.makefile.version = 1.0
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+GITS     ?= $(shell which -a git)
+GIT      ?= $(firstword $(GITS))
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
+
diff --git a/makefiles/consts.mk b/makefiles/consts.mk
new file mode 100644
index 0000000..941df38
--- /dev/null
+++ b/makefiles/consts.mk
@@ -0,0 +1,54 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2022-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2022-2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+# ONF.makefile.version = 1.0
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+# include makefiles/constants.mk
+export dot          :=.
+export null         :=#
+export space        := $(null) $(null)
+export quote-single := $(null)'$(null)# colorization-closing-quote(')
+export quote-double := $(null)"$(null)# colorization-closing-quote(")
+
+# [DEBUG] make {target} HIDE=
+HIDE        ?= @
+
+env-clean      ?= /usr/bin/env --ignore-environment
+xargs-n1       := xargs -0 -t -n1 --no-run-if-empty
+xargs-n1-clean := $(env-clean) $(xargs-n1)
+
+## -----------------------------------------------------------------------
+## Default shell:
+##   o set -e            enable error checking
+##   o set -u            report undefined errors
+##   o set -o pipefail   propogate shell pipeline failures.
+## -----------------------------------------------------------------------
+SHELL ?= /bin/bash
+have-shell-bash := $(filter bash,$(subst /,$(space),$(SHELL)))
+$(if $(have-shell-bash),$(null),\
+  $(eval export SHELL := bash -euo pipefail))
+
+export SHELL ?= bash -euo pipefail
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/include.mk b/makefiles/include.mk
new file mode 100644
index 0000000..1255f45
--- /dev/null
+++ b/makefiles/include.mk
@@ -0,0 +1,38 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+MAKEDIR ?= $(error MAKEDIR= is required)
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+help::
+	@echo "USAGE: $(MAKE) [options] [target] ..."
+        # @echo "  test                          Sanity check chart versions"
+
+include $(MAKEDIR)/consts.mk
+include $(MAKEDIR)/commands.mk
+include $(MAKEDIR)/todo.mk
+include $(MAKEDIR)/lint/include.mk
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/lint/docker/get.sh b/makefiles/lint/docker/get.sh
new file mode 100644
index 0000000..4e4a7f6
--- /dev/null
+++ b/makefiles/lint/docker/get.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# -----------------------------------------------------------------------
+# Copyright 2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+
+## -----------------------------------------------------------------------
+## Intent: Install a bbsim binary for local development use.
+## -----------------------------------------------------------------------
+## Note: A python or golang script may be a simpler answer.
+##       Interpreter modules provide answers for uname -{a,m,o}
+##       with dictionary translation into needed values.
+## -----------------------------------------------------------------------
+
+# import platform
+# platform.processor()
+# platform.system        # Windows
+
+# lshw:    width: 64 bits
+
+# >>> import platform
+# >>> platform.machine()
+# 'x86'
+
+
+# $ uname -m
+# armv7l
+
+## which arch
+# https://github.com/hadolint/hadolint/releases/tag/v2.12.0
+case "$(uname -a)" in
+    *x86_64*)
+esac
+
+os=''
+case "$(uname -o)" in
+    *Linux*) os='Linux'
+esac
+
+
+# hadolint-Darwin-x86_64
+# hadolint-Darwin-x86_64.sha256
+# hadolint-Linux-arm64
+# hadolint-Linux-arm64.sha256
+# hadolint-Linux-x86_64
+# hadolint-Linux-x86_64.sha256
+# hadolint-Windows-x86_64.exe
+# hadolint-Windows-x86_64.exe.sha256
+# Source code (zip)
+# Source code (tar.gz)
diff --git a/makefiles/lint/docker/hadolint.mk b/makefiles/lint/docker/hadolint.mk
new file mode 100644
index 0000000..eb182f7
--- /dev/null
+++ b/makefiles/lint/docker/hadolint.mk
@@ -0,0 +1,80 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+
+HADOLINT = $(docker-run-app) $(is-stdin) $(vee-citools)-hadolint hadolint
+
+ifdef LOCAL_LINT
+  lint-hadolint-dep = lint-hadolint-local
+else
+  lint-hadolint-dep = lint-hadolint
+endif
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+.PHONY: $(lint-hadolint-dep)
+
+lint : $(lint-hadolint-dep)
+
+lint-dockerfile : $(lint-hadolint-dep)
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+lint-hadolint:
+
+	@echo
+	@echo '** -------------------------------------------------------------'
+	@echo "** $(MAKE): processing target [$@]"
+	@echo '** -------------------------------------------------------------'
+	$(HIDE)${HADOLINT} $$(find ./build -name "Dockerfile*")
+	@echo "Dockerfile lint check OK"
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+hadolint-cmd := ./hadolint-Linux-x86_64
+
+lint-hadolint-local: hadolint-get
+	$(hadolint-cmd) $$(find ./build -name "Dockerfile*")
+
+## -----------------------------------------------------------------------
+## Intent: Retrieve the hadolint tool
+## https://github.com/hadolint/hadolint/releases/tag/v2.12.0
+## -----------------------------------------------------------------------
+hadolint-get:
+	true
+#	$(MAKECMDGOALS)/lint/docker/get.sh
+#	$(GIT) clone https://github.com/hadolint/hadolint.git
+#	wget https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+help ::
+	@echo '  lint-dockerfile      Perform all dockerfile lint checks'
+	@echo '  lint-hadolint        Dockerfile lint check'
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+todo ::
+	@echo '  o Update lint-dockerfile to run all dockerfile lint checks'
+
+# [SEE ALSO]
+# https://github.com/hadolint/hadolint
+
+# [EOF]
diff --git a/makefiles/lint/docker/include.mk b/makefiles/lint/docker/include.mk
new file mode 100644
index 0000000..4a9a9f6
--- /dev/null
+++ b/makefiles/lint/docker/include.mk
@@ -0,0 +1,26 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+help::
+	@echo
+	@echo "[LINT]"
+	@echo "  lint                       Static code analysis/syntax checking"
+	@echo "    LOCAL_LINT=1             Enable local linting w/o docker & jenkins overhead"
+
+include $(MAKEDIR)/lint/docker/hadolint.mk
+
+# [EOF]
diff --git a/makefiles/lint/golang/sca.mk b/makefiles/lint/golang/sca.mk
new file mode 100644
index 0000000..eeecc42
--- /dev/null
+++ b/makefiles/lint/golang/sca.mk
@@ -0,0 +1,60 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+GOLANG_FILES ?= $(error PYTHON_FILES= is required)
+
+.PHONY: lint-golang-sca
+
+lint : lint-golang-sca
+
+## -----------------------------------------------------------------------
+## Intent: Run goformat on files on sandbox files.
+##   1) find . -name '*.go' -print0
+##      - gather all *.go sources (-name '*.go')
+##      - pass as a list of null terminated items (-print0)
+##   2) xargs --null --max-args=[n] --no-run-if-empty gofmt -d
+##      - Iterate over the list (xargs --null)
+##      - process one item per line (--max-args=1)
+##      - display filename-to-check (--verbose)
+##      - display content when diffs are detected:
+##           gofmt -d
+##           gofmt -d -s
+## -----------------------------------------------------------------------
+lint-golang-sca-xargs := $(null)
+lint-golang-sca-xargs += --null#+           # Source paths are null terminated
+lint-golang-sca-xargs += --max-args=1#+     # Check one file at a time
+lint-golang-sca-xargs += --no-run-if-empty
+lint-golang-sca-xargs += --verbose#+        # Display source path to check
+
+## [INPLACE-EDITS] make lint-golang-sca FIX=1
+ifdef FIX
+  lint-golang-sca-args += -w
+endif
+
+lint-golang-sca:
+	find . -name '*.go' -print0 \
+	    | xargs $(lint-golang-sca-xargs) gofmt -d -s
+
+help::
+	@echo "  lint-golang-sca            Syntax check golang sources"
+	@echo "    MODIFIER: FIX=1          Correct problems (gofmt -d -s -w)"
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/lint/include.mk b/makefiles/lint/include.mk
new file mode 100644
index 0000000..d1a5a16
--- /dev/null
+++ b/makefiles/lint/include.mk
@@ -0,0 +1,36 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+help::
+	@echo
+	@echo "[LINT]"
+	@echo "  lint                       Static code analysis/syntax checking"
+	@echo "    LOCAL_LINT=1             Enable local linting w/o docker & jenkins overhead"
+
+include $(MAKEDIR)/lint/docker/include.mk
+
+ifdef LOCAL_LINT
+  # include $(MAKEDIR)/lint/json.mk              # venv dependency
+  # include $(MAKEDIR)/lint/golang/sca.mk
+  # include $(MAKEDIR)/lint/license/include.mk   # exclusions needed
+  # include $(MAKEDIR)/lint/python.mk
+  # include $(MAKEDIR)/lint/robot.mk             # venv dependency
+  # include $(MAKEDIR)/lint/shell.mk             # cleanup needed
+  # include $(MAKEDIR)/lint/yaml.mk              # venv needed -- alt: yamllint
+endif
+
+# [EOF]
diff --git a/makefiles/lint/json.mk b/makefiles/lint/json.mk
new file mode 100644
index 0000000..cc9ecfa
--- /dev/null
+++ b/makefiles/lint/json.mk
@@ -0,0 +1,35 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+JSON_FILES ?= $(error JSON_FILES= is required)
+
+.PHONY: lint-json
+
+lint : lint-json
+
+lint-json: vst_venv
+	source ./$</bin/activate \
+	    ; set -u \
+	    ; for jsonfile in $(JSON_FILES); do \
+		echo "Validating json file: $$jsonfile" ;\
+		python -m json.tool $$jsonfile > /dev/null ;\
+	done
+
+help::
+	@echo "  lint-json            Syntax check json sources"
+
+# [EOF]
diff --git a/makefiles/lint/license/include.mk b/makefiles/lint/license/include.mk
new file mode 100644
index 0000000..aaf6e47
--- /dev/null
+++ b/makefiles/lint/license/include.mk
@@ -0,0 +1,88 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+# JSON_FILES ?= $(error JSON_FILES= is required)
+
+.PHONY: lint-license
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+lint : lint-license
+
+lint-license-gargs += --recursive
+
+# ignore: png, xlsx
+# will utf8 be excluded(?)
+lint-license-gargs += --binary-files=without-match
+lint-license-gargs += --files-without-match
+
+# [TODO] license checking accepts either Copy or Apache.
+# [TODO] At least Copyright should be required (both?)
+lint-license-gargs += --extended-regexp
+lint-license-gargs += -e 'Copyright[[:space:]]+[[:digit:]]{4}'
+lint-license-gargs += -e 'Apache License'
+
+# [TODO] --strict, --strict-dates
+
+# Editor temp files
+lint-license-gargs += --exclude='*.~'
+lint-license-gargs += --exclude='*.swp'
+
+lint-license-gargs += --exclude-dir='.git'
+
+# TODO: Normalize into .venv for consistent filtering across projects.
+lint-license-gargs += --exclude-dir='vst_venv'
+lint-license-gargs += --exclude-dir='flog'
+
+lint-license-gargs += --exclude='*.json'
+lint-license-gargs += --exclude='*.md'
+lint-license-gargs += --exclude='*.out'
+lint-license-gargs += --exclude='*.pyc'
+lint-license-gargs += --exclude='*.xml'
+
+# [FILE(s)]
+lint-license-gargs += --exclude='VERSION'
+
+# [GIT]
+# lint-license-gargs += --exclude='.gitignore'
+# lint-license-gargs += --exclude='.gitreview'
+lint-license-gargs += --exclude='\.*'
+
+# [PYTHON]
+lint-license-gargs += --exclude='requirements.txt'
+
+# [WIP]
+lint-license-gargs += --exclude='patch'
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+lint-license-new:
+	grep $(lint-license-gargs) $(dot)
+
+## -----------------------------------------------------------------------
+## Jenkins job checking logic.
+## -----------------------------------------------------------------------
+lint-license:
+	$(MAKEDIR)/lint/license/license-check.sh
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+help ::
+	@echo "  lint-license         Verify sources contain a license block."
+	@echo "  lint-license-new     Grep driven replacement logic."
+
+# [EOF]
diff --git a/makefiles/lint/license/license-check.sh b/makefiles/lint/license/license-check.sh
new file mode 100755
index 0000000..d49faf0
--- /dev/null
+++ b/makefiles/lint/license/license-check.sh
@@ -0,0 +1,159 @@
+#!/usr/bin/env bash
+
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+# licensecheck.sh
+# checks for copyright/license headers on files
+# excludes filename extensions where this check isn't pertinent
+
+# --strict
+# --strict-dates
+#    see https://github...
+
+## ---------------------------------------------------------------------------
+## find: warning: ‘-name’ matches against basenames only, but the given pattern
+## contains a directory separator (‘/’), thus the expression will evaluate to
+## false all the time.  Did you mean ‘-wholename’?
+##
+## [TODO] find and fix plugin script, change --name to --path:
+##    find ! -name "*/docs/*"
+## ---------------------------------------------------------------------------
+## [TODO] see license/include.mk, grep -L will ignore binaries so no need to
+## explicitly filter images, spreadsheets, etc.  Files containing utf-8 are
+## the only question mark.
+## ---------------------------------------------------------------------------
+
+set +e -u -o pipefail
+fail_licensecheck=0
+
+declare -a gargs=()
+gargs+=('--extended-regexp')
+
+# Evil regex -- scripts detecting pattern are excluded from checking.
+gargs+=('-e' 'Apache License')
+
+# Good regex -- no false positives.
+gargs+=('-e' 'Copyright[[:space:]]+[[:digit:]]{4}')
+
+while IFS= read -r -d '' path
+do
+    if ! grep -q "${gargs[@]}" "${path}";
+    then
+	echo "ERROR: $path does not contain License Header"
+	fail_licensecheck=1
+    fi
+done < <(find . -name ".git" -prune -o -type f \
+  ! -iname "*.png" \
+  ! -name "*.asc" \
+  ! -name "*.bat" \
+  ! -name "*.bin" \
+  ! -name "*.cert" \
+  ! -name "*.cfg" \
+  ! -name "*.cnf" \
+  ! -name "*.conf" \
+  ! -name "*.cql" \
+  ! -name "*.crt" \
+  ! -name "*.csar" \
+  ! -name "*.csr" \
+  ! -name "*.csv" \
+  ! -name "*.ctmpl" \
+  ! -name "*.curl" \
+  ! -name "*.db" \
+  ! -name "*.der" \
+  ! -name "*.desc" \
+  ! -name "*.diff" \
+  ! -name "*.dnsmasq" \
+  ! -name "*.do" \
+  ! -name "*.docx" \
+  ! -name "*.eot" \
+  ! -name "*.gif" \
+  ! -name "*.gpg" \
+  ! -name "*.graffle" \
+  ! -name "*.ico" \
+  ! -name "*.iml" \
+  ! -name "*.in" \
+  ! -name "*.inc" \
+  ! -name "*.install" \
+  ! -name "*.j2" \
+  ! -name "*.jar" \
+  ! -name "*.jks" \
+  ! -name "*.jpg" \
+  ! -name "*.json" \
+  ! -name "*.jsonld" \
+  ! -name "*.JSON" \
+  ! -name "*.key" \
+  ! -name "*.list" \
+  ! -name "*.local" \
+  ! -path "*.lock" \
+  ! -name "*.log" \
+  ! -name "*.mak" \
+  ! -name "*.md" \
+  ! -name "*.MF" \
+  ! -name "*.oar" \
+  ! -name "*.p12" \
+  ! -name "*.patch" \
+  ! -name "*.pb.go" \
+  ! -name "*.pb.gw.go" \
+  ! -name "*.pdf" \
+  ! -name "*.pcap" \
+  ! -name "*.pem" \
+  ! -name "*.properties" \
+  ! -name "*.proto" \
+  ! -name "*.protoset" \
+  ! -name "*.pyc" \
+  ! -name "*.repo" \
+  ! -name "*.robot" \
+  ! -name "*.rst" \
+  ! -name "*.rules" \
+  ! -name "*.service" \
+  ! -name "*.svg" \
+  ! -name "*.swp" \
+  ! -name "*.tar" \
+  ! -name "*.tar.gz" \
+  ! -name "*.toml" \
+  ! -name "*.ttf" \
+  ! -name "*.txt" \
+  ! -name "*.woff" \
+  ! -name "*.xproto" \
+  ! -name "*.xtarget" \
+  ! -name "*ignore" \
+  ! -name "*rc" \
+  ! -name "*_pb2.py" \
+  ! -name "*_pb2_grpc.py" \
+  ! -name "Dockerfile" \
+  ! -name "Dockerfile.*" \
+  ! -name "go.mod" \
+  ! -name "go.sum" \
+  ! -name "README" \
+  ! -path "*/vendor/*" \
+  ! -path "*conf*" \
+  ! -path "*git*" \
+  ! -path "*swagger*" \
+  ! -path "*.drawio" \
+  ! -name "*.pb.h" \
+  ! -name "*.pb.cc" \
+  ! -path "*/docs/*" \
+  ! -name 'output.xml' \
+  ! -path "*/vst_venv/*" \
+  ! -name '*#*' \
+  ! -path '*scripts/flog/*' \
+  ! -name '*~' \
+  ! -name 'VERSION' \
+  ! -name 'patch' \
+  -print0 )
+
+exit ${fail_licensecheck}
diff --git a/makefiles/lint/license/license-helper.sh b/makefiles/lint/license/license-helper.sh
new file mode 100755
index 0000000..499f854
--- /dev/null
+++ b/makefiles/lint/license/license-helper.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# -----------------------------------------------------------------------
+# Copyright 2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+declare -i status=$#
+
+while [ $# -gt 0 ]; do
+    arg="$1"; shift
+    echo "ERROR: Detected missing license header: ${arg}"
+done
+
+if [ $status -ne 0 ]; then
+    exit 1
+fi
+
+/bin/true # set $?
+
+# [EOF]
diff --git a/makefiles/lint/python.mk b/makefiles/lint/python.mk
new file mode 100644
index 0000000..86503a7
--- /dev/null
+++ b/makefiles/lint/python.mk
@@ -0,0 +1,33 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+PYTHON_FILES ?= $(error PYTHON_FILES= is required)
+
+.PHONY: lint-python
+
+lint : lint-python
+
+lint-python: vst_venv
+	-source ./$</bin/activate \
+	    && set -u \
+	    && pylint $(PYTHON_FILES) \
+	    && flake8 --max-line-length=99 --count $(PYTHON_FILES)
+
+help::
+	@echo "  lint-python          Syntax check using pylint and flake8"
+
+# [EOF]
diff --git a/makefiles/lint/robot.mk b/makefiles/lint/robot.mk
new file mode 100644
index 0000000..9808602
--- /dev/null
+++ b/makefiles/lint/robot.mk
@@ -0,0 +1,41 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+ROBOT_FILES ?= $(error ROBOT_FILES= is required)
+
+LINT_ARGS ?= --verbose --configure LineTooLong:130 -e LineTooLong \
+             --configure TooManyTestSteps:65 -e TooManyTestSteps \
+             --configure TooManyTestCases:50 -e TooManyTestCases \
+             --configure TooFewTestSteps:1 \
+             --configure TooFewKeywordSteps:1 \
+             --configure FileTooLong:2000 -e FileTooLong \
+             -e TrailingWhitespace
+
+
+.PHONY: lint-robot
+
+lint : lint-robot
+
+lint-robot: vst_venv
+	source ./$</bin/activate \
+	    && set -u \
+	    && rflint $(LINT_ARGS) $(ROBOT_FILES)
+
+help::
+	@echo "  lint-robot           Syntax check robot sources using rflint"
+
+# [EOF]
diff --git a/makefiles/lint/shell.mk b/makefiles/lint/shell.mk
new file mode 100644
index 0000000..da92921
--- /dev/null
+++ b/makefiles/lint/shell.mk
@@ -0,0 +1,33 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+JSON_FILES ?= $(error JSON_FILES= is required)
+
+.PHONY: lint-shell
+
+lint : lint-shell
+
+lint-shell:
+	shellcheck --version
+	find . \( -name 'staging' -o -name 'vst_venv' \) -prune \
+	    -o -name '*.sh' ! -name 'activate.sh' -print0 \
+	| xargs -0 -n1 shellcheck
+
+help::
+	@echo "  lint-shell           Syntax check bash,bourne,etc sources"
+
+# [EOF]
diff --git a/makefiles/lint/yaml.mk b/makefiles/lint/yaml.mk
new file mode 100644
index 0000000..c9cb392
--- /dev/null
+++ b/makefiles/lint/yaml.mk
@@ -0,0 +1,32 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2022 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+YAML_FILES ?= $(error YAML_FILES= is required)
+
+.PHONY: lint-yaml
+
+lint : lint-yaml
+
+lint-yaml: vst_venv
+	source ./$</bin/activate \
+	    ; set -u \
+	    ; yamllint -s $(YAML_FILES)
+
+help::
+	@echo "  lint-yaml            Syntax check yaml source using yamllint"
+
+# [EOF]
diff --git a/makefiles/nop b/makefiles/nop
new file mode 100644
index 0000000..ba2b114
--- /dev/null
+++ b/makefiles/nop
@@ -0,0 +1 @@
+Thu Apr 13 10:18:26 AM EDT 2023
diff --git a/makefiles/release/bbr.mk b/makefiles/release/bbr.mk
new file mode 100644
index 0000000..02bb0e4
--- /dev/null
+++ b/makefiles/release/bbr.mk
@@ -0,0 +1,121 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+RELEASE_BBR_NAME      ?= bbr
+
+# release-target-deps += release-bbr
+
+# -----------------------------
+# release/bbsimctl-darwin-amd64
+# release/bbsimctl-linux-amd64
+# release/bbsimctl-windows-amd64
+# -----------------------------
+release-bbr-deps :=\
+  $(call release-gen-deps,RELEASE_BBR_NAME,RELEASE_OS_ARCH,RELEASE_DIR)
+
+## -----------------------------------------------------------------------
+## Intent: Cross-compile bbr binaries as dependency targets
+##   o target: release/bbr-linux-amd64
+##   o create release/ for VOLUME mounting by docker container
+##   o create a response file for passing docker env vars
+##   o cross-compile: GOOS= GOARCH= go build
+## -----------------------------------------------------------------------
+tans release-bbr: $(release-bbr-deps)
+
+.PHONY: $(release-bbr-deps)
+$(release-bbr-deps):
+
+	@echo
+	@echo "** -----------------------------------------------------------------------"
+	@echo "** $(MAKE): processing target [$@]"
+	@echo "** -----------------------------------------------------------------------"
+
+        # Docker container is responsible for compiling
+        # Release target will publish from localhost:release/
+        # Binaries are built into mounted docker volume /app/release => localhost:release/
+	$(HIDE)mkdir -vp "$(RELEASE_DIR)"
+	$(HIDE)umask 000 && chmod 777 "$(RELEASE_DIR)"
+
+        # -----------------------------------------------------------------------
+        # Create a response file for passing environment vars to docker
+        # -----------------------------------------------------------------------
+	$(HIDE)$(RM) $(notdir $@).env
+	$(HIDE)echo -e '#!/bin/bash\n' \
+	  'GOOS=$(call get-hyphen-field,2,$@)\n' \
+	  'GOARCH=$(call get-hyphen-field,3,$@)\n' \
+	  >> "$(notdir $@).env"
+
+        # -----------------------------------------------------------------------
+        # Compile a platform binary
+        # -----------------------------------------------------------------------
+	$(HIDE) \
+	umask 022 \
+\
+	&& echo "** Building: $@" \
+	&& set -x \
+	&& $(call my-go-sh,$(notdir $@).env) \
+    $(quote-single) \
+      go build -mod vendor \
+	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X main.gitStatus=${GIT_STATUS} \
+	    -X main.version=${VERSION}" \
+	  -o "$@" ./cmd/bbr \
+    $(quote-single)
+
+        # -----------------------------------------------------------------------
+        # Cleanup and display results
+        # -----------------------------------------------------------------------
+	@$(RM) $(notdir $@).env	
+	$(HIDE)umask 000 && chmod 755 "$(RELEASE_DIR)"
+	$(HIDE)file "$@"
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+build-bbr: local-omci-lib-go local-protos
+	@go build -mod vendor \
+	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X main.gitStatus=${GIT_STATUS} \
+	    -X main.version=${VERSION}" \
+	  ./cmd/bbr
+
+## -----------------------------------------------------------------------
+## Intent: Remove generated targets
+## -----------------------------------------------------------------------
+clean ::
+	$(RM) $(release-bbr-deps)
+	$(RM) *.env
+	$(RM) $(RELEASE_BBR_NAME)
+
+## -----------------------------------------------------------------------
+## Intent: Display target help#
+# -----------------------------------------------------------------------
+help ::
+	@echo
+	@echo '[bbr]'
+	@echo '  build-bbr      Compile bbr on localhost'
+	@echo '  release-bbr    Cross-compile bbr binary for release'
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/release/bbsim.mk b/makefiles/release/bbsim.mk
new file mode 100644
index 0000000..87b8673
--- /dev/null
+++ b/makefiles/release/bbsim.mk
@@ -0,0 +1,132 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+RELEASE_BBSIM_NAME    ?= bbsim
+
+# release-target-deps += release-bbsim
+
+# -----------------------------
+# release/bbsim-darwin-amd64
+# release/bbsim-linux-amd64
+# release/bbsim-windows-amd64
+# -----------------------------
+release-bbsim-deps :=\
+  $(call release-gen-deps,RELEASE_BBSIM_NAME,RELEASE_OS_ARCH,RELEASE_DIR)
+
+## -----------------------------------------------------------------------
+## Intent: Cross-compile bbsim binaries as dependency targets
+##   o target: release/bbsim-linux-amd64
+##   o create release/ for VOLUME mounting by docker container
+##   o create a response file for passing docker env vars
+##   o cross-compile: GOOS= GOARCH= go build
+## -----------------------------------------------------------------------
+release-bbsim: $(release-bbsim-deps)
+
+.PHONY: $(release-bbsim-deps)
+$(release-bbsim-deps):
+
+	@echo
+	@echo "** -----------------------------------------------------------------------"
+	@echo "** $(MAKE): processing target [$@]"
+	@echo "** -----------------------------------------------------------------------"
+
+        # Docker container is responsible for compiling
+        # Release target will publish from localhost:release/
+        # Binaries are built into mounted docker volume /app/release => localhost:release/
+	$(HIDE)mkdir -vp "$(RELEASE_DIR)"
+	$(HIDE)umask 000 && chmod 777 "$(RELEASE_DIR)"
+
+        # -----------------------------------------------------------------------
+        # Create a response file for passing environment vars to docker
+        # -----------------------------------------------------------------------
+	$(HIDE)$(RM) $(notdir $@).env
+	$(HIDE)echo -e '#!/bin/bash\n' \
+	  'GOOS=$(call get-hyphen-field,2,$@)\n' \
+	  'GOARCH=$(call get-hyphen-field,3,$@)\n' \
+	  >> "$(notdir $@).env"
+
+        # -----------------------------------------------------------------------
+        # Compile a platform binary
+        # -----------------------------------------------------------------------
+	$(HIDE) \
+	umask 022 \
+\
+	&& echo "** Building: $@" \
+	&& set -x \
+	&& $(call my-go-sh,$(notdir $@).env) \
+    $(quote-single) \
+      go build -mod vendor \
+	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X main.gitStatus=${GIT_STATUS} \
+	    -X main.version=${VERSION}" \
+	  -o "$@" ./cmd/bbsim \
+    $(quote-single)
+
+        # -----------------------------------------------------------------------
+        # Cleanup and display results
+        # -----------------------------------------------------------------------
+	@$(RM) $(notdir $@).env
+	$(HIDE)umask 000 && chmod 755 "$(RELEASE_DIR)"
+	$(HIDE)file "$@"
+
+
+release-bbsim-x:
+	@echo "$(RELEASE_BBSIM_NAME)-linux-amd64"
+	${GO} build -mod vendor \
+	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X main.gitStatus=${GIT_STATUS} \
+	    -X main.version=${VERSION}" \
+	  -o "$(RELEASE_DIR)/$(RELEASE_BBSIM_NAME)-linux-amd64" ./cmd/bbsim
+
+## -----------------------------------------------------------------------
+## Intent: Build bbsimctl on localhost
+## -----------------------------------------------------------------------
+build-bbsim:
+	@go build -mod vendor \
+	  -ldflags "-w -X main.buildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X main.gitStatus=${GIT_STATUS} \
+	    -X main.version=${VERSION}" \
+	  ./cmd/bbsim
+
+## -----------------------------------------------------------------------
+## Intent: Remove generated targets
+## -----------------------------------------------------------------------
+clean ::
+	$(RM) $(release-bbsim-deps)
+	$(RM) *.env
+	$(RM) $(RELEASE_BBSIM_NAME)
+
+## -----------------------------------------------------------------------
+## Intent: Display target help#
+# -----------------------------------------------------------------------
+help ::
+	@echo
+	@echo '[bbsim]'
+	@echo '  build-bbsim      Compile bbsim on localhost'
+	@echo '  release-bbsim    Cross-compile bbsim binaries into a docker mounted filesystem'
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/release/bbsimctl.mk b/makefiles/release/bbsimctl.mk
new file mode 100644
index 0000000..550cd20
--- /dev/null
+++ b/makefiles/release/bbsimctl.mk
@@ -0,0 +1,124 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+RELEASE_BBSIMCTL_NAME ?= bbsimctl
+
+bbsimctl-config := github.com/opencord/bbsim/internal/bbsimctl/config
+
+# release-target-deps += release-bbsimctl
+
+# -----------------------------
+# release/bbsimctl-darwin-amd64
+# release/bbsimctl-linux-amd64
+# release/bbsimctl-windows-amd64
+# -----------------------------
+release-bbsimctl-deps :=\
+  $(call release-gen-deps,RELEASE_BBSIMCTL_NAME,RELEASE_OS_ARCH,RELEASE_DIR)
+
+## -----------------------------------------------------------------------
+## Intent: Cross-compile bbsimctl binaries as dependency targets
+##   o target: release/bbsimctl-linux-amd64
+##   o create release/ for VOLUME mounting by docker container
+##   o create a response file for passing docker env vars
+##   o cross-compile: GOOS= GOARCH= go build
+## -----------------------------------------------------------------------
+release-bbsimctl: $(release-bbsimctl-deps)
+
+.PHONY: $(release-bbsimctl-deps)
+$(release-bbsimctl-deps):
+
+	@echo
+	@echo "** -----------------------------------------------------------------------"
+	@echo "** $(MAKE): processing target [$@]"
+	@echo "** -----------------------------------------------------------------------"
+
+        # Docker container is responsible for compiling
+        # Release target will publish from localhost:release/
+        # Binaries are built into mounted docker volume /app/release=> localhost:release/
+	$(HIDE)mkdir -vp "$(RELEASE_DIR)"
+	$(HIDE)umask 000 && chmod 777 "$(RELEASE_DIR)"
+
+        # -----------------------------------------------------------------------
+        # Create a response file for passing environment vars to docker
+        # -----------------------------------------------------------------------
+	$(HIDE)$(RM) $(notdir $@).env
+	$(HIDE)echo -e '#!/bin/bash\n' \
+	  'GOOS=$(call get-hyphen-field,2,$@)\n' \
+	  'GOARCH=$(call get-hyphen-field,3,$@)\n' \
+	  >> "$(notdir $@).env"
+
+        # -----------------------------------------------------------------------
+        # Compile a platform binary
+        # -----------------------------------------------------------------------
+	$(HIDE) \
+	umask 022 \
+\
+	&& echo "** Building: $@" \
+	&& set -x \
+	&& $(call my-go-sh,$(notdir $@).env) \
+    $(quote-single) \
+      go build -mod vendor \
+	 -ldflags "-w -X $(bbsimctl-config).BuildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X $(bbsimctl-config).CommitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X $(bbsimctl-config).GitStatus=${GIT_STATUS} \
+	    -X $(bbsimctl-config).Version=${VERSION}" \
+	  -o "$@" ./cmd/bbsimctl \
+    $(quote-single)
+
+        # -----------------------------------------------------------------------
+        # Cleanup and display results
+        # -----------------------------------------------------------------------
+	@$(RM) $(notdir $@).env
+	$(HIDE)umask 000 && chmod 755 "$(RELEASE_DIR)"
+	$(HIDE)file "$@"
+
+## -----------------------------------------------------------------------
+## Intent: Build bbsimctl on localhost
+## -----------------------------------------------------------------------
+build-bbsimctl:
+	@go build -mod vendor \
+	  -ldflags "-w -X github.com/opencord/bbsim/internal/bbsimctl/config.BuildTime=$(shell date +%Y/%m/%d-%H:%M:%S) \
+	    -X github.com/opencord/bbsim/internal/bbsimctl/config.CommitHash=$(shell git log --pretty=format:%H -n 1) \
+	    -X github.com/opencord/bbsim/internal/bbsimctl/config.GitStatus=${GIT_STATUS} \
+	    -X github.com/opencord/bbsim/internal/bbsimctl/config.Version=${VERSION}" \
+	  ./cmd/bbsimctl
+
+## -----------------------------------------------------------------------
+## Intent: Remove generated targets
+## -----------------------------------------------------------------------
+clean ::
+	$(RM) $(release-bbsimctl-deps)
+	$(RM) *.env
+	$(RM) bbsimclt
+
+## -----------------------------------------------------------------------
+## Intent: Display target help#
+# -----------------------------------------------------------------------
+help ::
+	@echo
+	@echo '[bbsimctl]'
+	@echo '  build-bbsimctl      Compile bbsimctl on localhost'
+	@echo '  release-bbsimctl    Cross-compile bbsimctl binaries into a docker mounted filesystem'
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/release/consts.mk b/makefiles/release/consts.mk
new file mode 100644
index 0000000..ba019b6
--- /dev/null
+++ b/makefiles/release/consts.mk
@@ -0,0 +1,32 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+# Release related items
+# Generates binaries in $RELEASE_DIR with name $RELEASE_NAME-$RELEASE_OS_ARCH
+# Inspired by: https://github.com/kubernetes/minikube/releases
+RELEASE_DIR     ?= release
+RELEASE_OS_ARCH ?= linux-amd64 linux-arm64 windows-amd64 darwin-amd64
+
+RELEASE_BBR_NAME      ?= bbr
+RELEASE_BBSIM_NAME    ?= bbsim
+RELEASE_BBSIMCTL_NAME ?= bbsimctl
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/release/include.mk b/makefiles/release/include.mk
new file mode 100644
index 0000000..d7c6ca8
--- /dev/null
+++ b/makefiles/release/include.mk
@@ -0,0 +1,86 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+##--------------------##
+##---]  INCLUDES  [---##
+##--------------------##
+include $(MAKEDIR)/release/consts.mk
+include $(MAKEDIR)/release/macros.mk
+
+## -----------------------------------------------------------------------
+## Intent: Dispaly a help section for release targets
+## -----------------------------------------------------------------------
+help::
+	@echo
+	@echo '[RELEASE]'
+	@echo '  release             Creates release ready binaries for BBSimctl and BBR artifacts'
+
+##--------------------##
+##---]  INCLUDES  [---##
+##--------------------##
+include $(MAKEDIR)/release/bbr.mk
+include $(MAKEDIR)/release/bbsim.mk
+include $(MAKEDIR)/release/bbsimctl.mk
+
+## -----------------------------------------------------------------------
+## Intent: Cross-compile binaries for release
+## -----------------------------------------------------------------------
+release-target-deps += release-bbr
+release-target-deps += release-bbsim
+# release-deps += release-bbsimctl
+
+## -----------------------------------------------------------------------
+## Intent: Create a release from targets release-{bbr,bbsim,bbsimctl}
+## Debug: $(foreach tgt,$(release-target-deps),$(info ** release-target-deps=$(tgt)))
+## -----------------------------------------------------------------------
+.PHONY: release
+release: $(release-target-deps)
+
+## -----------------------------------------------------------------------
+## Intent: Initialize storage then build release target groups (bbr, bbsim)
+## -----------------------------------------------------------------------
+.PHONY: $(release-targetdeps)
+$(release-target-deps) : release-init-mkdir
+
+## -----------------------------------------------------------------------
+## Intent: Prepare for a clean release build
+## -----------------------------------------------------------------------
+release-init:
+	@echo
+	@echo "** -----------------------------------------------------------------------"
+	@echo "** $(MAKE): processing target [$@]"
+	@echo "** -----------------------------------------------------------------------"
+
+	@echo -e "\n** Create filesystem target for docker volume: $(RELEASE_DIR)"
+	$(RM) -r "./$(RELEASE_DIR)"
+	mkdir -vp "$(RELEASE_DIR)"
+
+## -----------------------------------------------------------------------
+## Intent: Create storage for release binaries and docker volume mount
+## -----------------------------------------------------------------------
+.PHONY: release-init
+release-init-mkdir:
+	mkdir -vp "$(RELEASE_DIR)"
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/release/macros.mk b/makefiles/release/macros.mk
new file mode 100644
index 0000000..7a63529
--- /dev/null
+++ b/makefiles/release/macros.mk
@@ -0,0 +1,102 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+## -----------------------------------------------------------------------
+## Intent: Given a hyphen separated list of values return item [n]
+## -----------------------------------------------------------------------
+## Usage:
+##   value    := foo-bar-tans-fans
+##   tans-val = $(call get-hyphen-field,value,3)
+## -----------------------------------------------------------------------
+get-hyphen-field = $(word $(1),$(subst -,$(space),$(notdir $(2))))
+
+## -----------------------------------------------------------------------
+## Intent: Construct a parameterized $(GO_SH) command
+## Given:
+##   argv[1] Response file containing environment vars passed to docker.
+## Usage:
+##   cmd = $(my-go-sh,./env-vars)
+## Debug: view arguments passed
+##   make DEBUG=1
+## -----------------------------------------------------------------------
+my-go-sh=$(strip                   \
+  $(docker-run-app)                \
+	$(is-stdin)                \
+	$(if $(1),--env-file $(1)) \
+	-v gocache:/.cache         \
+	$(vee-golang)              \
+	$(vee-citools)-golang      \
+	sh -c                      \
+)
+
+## -----------------------------------------------------------------------
+## Intent: Derive a list of release platform binaries by name
+## -----------------------------------------------------------------------
+## Given:
+##   $1 (scalar:name)      $(RELEASE_BBSIM_NAME)
+##   $2 (indirect:arches)  $(RELEASE_OS_ARCH)
+## -----------------------------------------------------------------------
+## Usage: deps = $(call release-gen-deps-name,tool-name,tool-arches)
+## -----------------------------------------------------------------------
+release-gen-deps-name=$(strip \
+\
+  $(if $($(1)),$(null),$(error name= is required))\
+  $(if $($(2)),$(null),$(error arches= is required))\
+\
+  $(foreach name,$($(1)),\
+     $(if $(DEBUG),$(info name=$(name)))\
+  $(foreach arches,$(2),\
+     $(if $(DEBUG),$(info arches=$(arches)))\
+     $(foreach arch,$($(arches)),\
+        $(if $(DEBUG),$(info arch=$(arch): $(name)-$(arch)))\
+        $(name)-$(arch)\
+     )\
+  ))\
+)
+
+## -----------------------------------------------------------------------
+## Intent: Derive a list of release binary dependencies
+## -----------------------------------------------------------------------
+## Returns:
+##    release/bbsim-darwin-amd64
+##    release/bbsim-linux-amd64
+##    release/bbsim-windows-amd64
+## -----------------------------------------------------------------------
+## Usage:
+##    tool-name   = bbsim
+##    tool-arches = darwin linux windows
+##    release-dir = release
+##    deps = $(call release-gen-deps,tool-name,tool-arches,release-dir)
+##    $(foreach val,$(deps),$(info ** deps=$(val)))
+## -----------------------------------------------------------------------
+release-gen-deps=$(strip \
+\
+  $(if $($(1)),$(null),$(error name= is required))\
+  $(if $($(2)),$(null),$(error arches= is required))\
+  $(if $($(3)),$(null),$(error release-dir= is required))\
+\
+  $(if $(DEBUG),$(info release-dir=$(3)))\
+  $(foreach release-dir,$($(3)),\
+    $(addprefix $(release-dir)/,$(call release-gen-deps-name,$(1),$(2)))\
+  )\
+)
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/todo.mk b/makefiles/todo.mk
new file mode 100644
index 0000000..19e2272
--- /dev/null
+++ b/makefiles/todo.mk
@@ -0,0 +1,34 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-FileCopyrightText: 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+# SPDX-License-Identifier: Apache-2.0
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+help::
+	@echo "  todo                       Display future enhancement list"
+
+todo ::
+	@echo
+	@echo "[TODO: bbsim]"
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/makefiles/tools.mk b/makefiles/tools.mk
new file mode 100644
index 0000000..4aafcbd
--- /dev/null
+++ b/makefiles/tools.mk
@@ -0,0 +1,48 @@
+# -*- makefile -*-
+# -----------------------------------------------------------------------
+# Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.d
+# -----------------------------------------------------------------------
+
+$(if $(DEBUG),$(warning ENTER))
+
+## Docker related -- are these ${shell vars} or $(make macros) ?
+DOCKER_TAG  			?= ${VERSION}
+DOCKER_REPOSITORY  		?=
+DOCKER_REGISTRY 		?=
+DOCKER_RUN_ARGS			?=
+DOCKER_PORTS			?= -p 50070:50070 -p 50060:50060 -p 50071:50071 -p 50072:50072 -p 50073:50073 -p 50074:50074 -p 50075:50075
+TYPE                            ?= minimal
+
+# tool containers
+VOLTHA_TOOLS_VERSION ?= 2.3.1
+
+docker-run     = docker run --rm --user $$(id -u):$$(id -g)#   # Docker command stem
+docker-run-app = $(docker-run) -v ${CURDIR}:/app#              # w/filesystem mount
+is-stdin       = $(shell test -t 0 && echo "-it")
+
+# Docker volume mounts: container:/app/release <=> localhost:{pwd}/release
+vee-golang     = -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg
+vee-citools    = voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}
+
+GO                = $(docker-run-app) $(is-stdin) -v gocache:/.cache $(vee-golang) $(vee-citools)-golang go
+GO_SH             = $(docker-run-app) $(is-stdin) --env-file ./foobar -v gocache:/.cache $(vee-golang) $(vee-citools)-golang sh -c
+GO_JUNIT_REPORT   = $(docker-run-app) -i $(vee-citools)-go-junit-report go-junit-report
+GOCOVER_COBERTURA = $(docker-run) -v ${CURDIR}:/app/src/github.com/opencord/bbsim -i $(vee-citools)-gocover-cobertura gocover-cobertura
+GOLANGCI_LINT     = $(docker-run-app) $(is-stdin) -v gocache:/.cache $(vee-golang) $(vee-citools)-golangci-lint golangci-lint
+PROTOC            = $(docker-run-app) $(is-stdin) $(vee-golang) $(vee-citools)-protoc protoc
+
+$(if $(DEBUG),$(warning LEAVE))
+
+# [EOF]
diff --git a/msg b/msg
new file mode 100644
index 0000000..17c92c6
--- /dev/null
+++ b/msg
@@ -0,0 +1,55 @@
+VOL-4883 - Publish a new bbsim release
+
+https://github.com/opencord/bbsim/releases/tag/untagged-6d947de2a6078a1fe175
+----------------------------------------------------------------------------
+  o Draft bbsim release v2.96.8572 created by this patch set.
+  o All 6cross-compile binaries are now included.
+  o Change ID + commit message document the release.
+  o Binaries downloaded/tested using {bbr,bbsim,bbsimctl} --help
+
+Makefile
+--------
+  o Makefile release target is now able to cross compile all binaries:
+    - bbsimctl cross compiled to arm, darwin, linux and windows.
+    - release-{bbr, bbsim} only built *-linux-amd64
+  o Refactor targets into a more modular and hierarchial setup.
+  o Be sure to create RELEASE_DIR early on localhost so docker
+    container can create a volume (NFS mount) for building into.
+  o Display banners when building targets to improve log readability.
+  o Clean targets updated to remove everything generated.
+  o Help targets added to document indvidual target logic.
+  o Makefile logic heavily commented.
+
+makefiles/release/bbr.mk
+makefiles/release/bbsim.mk
+makefiles/release/bbsimctl.mk
+-----------------------------
+  o Relocate build-* and release-* target logic into named makefiles.
+  o Update SHELL to set -euo pipefail to detect uninit shell vars.
+  o Replaced shell/looping logic with true makefile target dependencies:
+    - shell/loop replaced with a target rule that builds one platform binary.
+    - Derive a list of targets release/{bbr,bbsim,bbsimctl}-{os}-{arch}
+    - release: depends on all buildable targets
+    - release rule can extract arch= and os= from target path being built.
+    - To simplify logic construct env vars separately into a response file.
+    - passed as "docker --env-file [x]" VS appending to an ever growing command line.
+  o Marked more targets as .PHONY so they will always build.
+  o Added helper target 'onf-publish' for exercising changes in the github-release script.
+
+makefiles/include.mk
+--------------------
+  o Single include for importing all library makefiles.
+
+makefiles/consts.mk
+-------------------
+  o Include fixed values, esp $(quote-single) which is now used to document
+  o Refactor duplication in GO_* macros into named/reused values to shorten lines.
+
+makefiles/lint
+--------------
+  o Moved lint::docker (hadolint target) into makefiles/lint/docker/*.mk.
+  o Added makefiles/lint library targets for ability to lint more sources.
+
+makefiles/tools.mk
+------------------
+  o Refactor DOCKER_* and GO_* macros into a named includable makefile.q
\ No newline at end of file