Remove redundant script from Travis build and improve log information (#1140)

* Improve Travis build log information

* Improve Travis build log information

* Improve Travis build log information

* Improve Travis builds

* Improve Travis builds

* improve task information for logs

* improve task information for logs

* improve task information for logs

* Add spew for export commands that get SIGINT faults

* Add spew for export commands that get SIGINT faults

* Add trace around intermittent failings on export project

* Cleanup changes and add comments and TODOs
diff --git a/.gitignore b/.gitignore
index b2b8683..d7b11b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,7 +24,7 @@
 *.prof
 
 
-#OS X
+# OS X
 **/.DS_Store
 
 #binaries
@@ -43,6 +43,7 @@
 .gradle
 .gogradle
 build/
+release/
 
 #emacs
 *~
diff --git a/.travis.yml b/.travis.yml
index 79555d2..93568a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,12 +36,37 @@
       # travis2slack webhook to enable DMs on openwhisk-team.slack.com to PR authors with TravisCI results
       secure: "NaDCtHwbFUEy0h0u/QrAt395o0/9FstJ5/Tv4uBSLCBdaUNU+0q6/RXVH76dKbujoxrLded2gyeJSAbI4kl4SM7FyilSHzKTikF0VsgM3G5veh65tVY5ztsvl40hDmK2E/PmWI3HkZNeWJO32WjraqPmhSWL0BZOWhA/4gJSCIsLnNRQXmpZoDqC7V8IG1BWYGwd5qcNkEjItLjYCUy1s2K8bj3QmhshYRVLTNbXxh0yJVKjM04I+bWhMXqvL8GS55qeicJ3fUwm5g1PDVCtzxLwAHCPo2jusjtNSnV+BaZgMBSahv3MD7ApxfF58e1buejggH3qZAhNGccC4bYJCahqVv/KKoA10kO6exH5iGwlHPWQTjMuF++PHmAk+FeQ1jh+JoUSBnIHExPnaD4CQIArHvUuQom+WJBnOz+L1H755VyPGzeDQ+ZUDlhOiQ6CDP/sqaRH3Wmo4IzhsqTsLaQs0dS1YeEWOS8gcawwNTVf/WtqiedYu24rQN9RiUXelRoEaXJy/pldb2KpyQRo2hbKoStDDB5fEij1xyGsj4kSXZ8uk5G10oDGnZYd+okduzJazN8wr0flrLvH32DRgDZDcG/D90I19JmqqfqbcG/SEmhxTikHZeVQd5DfWcqssLvWNrtQa/EJgAQkmZ2gaSsZ73AvPk/KyMV30+m8xTU="
 
+# The complete sequence of phases of the lifecycle:
+# ---------------------------------------------------------
+# before_install
+# install
+# before_script
+# script
+# before_cache (OPTIONAL) (if and only if caching is effective)
+# after_success (or after_failure)
+# before_deploy (OPTIONAL) (if and only if deployment is active)
+# deploy (OPTIONAL)
+# after_deploy (OPTIONAL) (if and only if deployment is active)
+# after_script
+
 before_install:
   - "./tools/travis/cloneutils.sh"
+  - sudo apt-get install tree
+
+# Install tools we use for linting and unit/integration testing
+# TODO: build.gradle (gradlew) already installs 'golint' and runs linting
+#       in the `goLint` task; see if we can remove here.
+# TODO: The "gogradle" plugin in build.gradle (gradlew) already provides a
+#       task called "goTest" which runs all `unit` tests.  See if we can use that
+#       instead and only run `integration` tests here.
 install:
   - export DEPLOY_BUILD_READY=false
   - go get -u golang.org/x/lint/golint
   - go get -u github.com/stretchr/testify
+
+# Identify Golang files that are not properly formatted
+# TODO: See if we can create custom tasks to perform this in build.gradle
+#       as a custom `goFmt` task
 before_script:
   - GO_FILES=$(find . -iname '*.go' -type f -not -path "./wski18n/i18n_resources.go")
   - export BAD_GO=$(gofmt -s -l $(echo $GO_FILES))
@@ -49,20 +74,26 @@
 #- test -z "$BAD_GO"
 #- test -z "$(gofmt -s -l $(echo $GO_FILES))"
 
+# Clone and build the OpenWhisk platform (i.e., apache/openwhisk)
+# and then use Ansible to deploy it and prepare it to run our
+# integration tests.
+# TODO: Do not use Makefile for running integration tests (in script.sh);
+#       change to using gradle wrapper
 script:
-  - echo $TRAVIS
-  - echo $TRAVIS_PULL_REQUEST
-  - echo $TRAVIS_SECURE_ENV_VARS
-  - printenv
+  - echo "Installing and building OpenWhisk platform using Ansible..."
+  - "./tools/travis/showenv.sh"
   - "./tools/travis/script.sh"
+
 after_success:
   - DEPLOY_BUILD_READY=true
   - if [ "$TRAVIS_EVENT_TYPE" == "cron" ] ; then
     export DEPLOY_BUILD_READY=false;
     fi
 
-after_script:
-  - make clean
+# If this is a "tagged" GitHub build, then use Gradle Wrapper
+# to build binaries for all supported OS platforms and architectures.
+# The result would be a "/build" directory that has a subdirectory named
+# for each supported GOOS/GOARCH
 before_deploy:
   - export build_file_name=wskdeploy
   - go get github.com/inconshreveable/mousetrap
@@ -72,10 +103,14 @@
     export GIT_TAG=$TRAVIS_TAG;
     export TAG=true;
     fi
+  - echo "Calling Gradle Wrapper task to build and 'releaseBinaries'..."
+  - "./tools/travis/showenv.sh"
   - ./gradlew --console=plain releaseBinaries -PpackageVersion=$GIT_TAG -PgitCommit=$(git rev-parse HEAD) -PbuildDate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
-  - "./tools/travis/build_tag_releases.sh $build_file_name $GIT_TAG"
+  - echo "Build binaries and release archives created:"
+  - tree /build
+  - tree /release
   - export RELEASE_PKG_FILE="$(cd "$TRAVIS_BUILD_DIR/release" && ls ${zip_file_name}-*.tgz ${zip_file_name}-*.zip)"
-  - echo "Deploying $RELEASE_PKG_FILE to GitHub releases."
+  - echo "Deploying "$RELEASE_PKG_FILE" to GitHub releases..."
   - if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_EVENT_TYPE" == "push" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
     git config --global user.email "builds@travis-ci.com";
     git config --global user.name "Travis CI";
@@ -84,11 +119,11 @@
     GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag $GIT_TAG -a -m "Generated tag from Travis CI build $TRAVIS_BUILD_NUMBER";
     git push -f -q https://$API_KEY@github.com/apache/openwhisk-wskdeploy $GIT_TAG;
     fi
-  - echo "TRAVIS_EVENT_TYPE is "
-  - echo $TRAVIS_EVENT_TYPE
-  - echo "GIT_TAG is "
-  - echo $GIT_TAG
+  - echo "Completing before_deploy stage"
 
+# Utilize two providers to create a github release and publish a docker image.
+# For information on the "releases" provider,
+# see https://docs.travis-ci.com/user/deployment/releases/
 deploy:
   - provider: releases
     api_key:
@@ -112,6 +147,18 @@
       repo: apache/openwhisk-wskdeploy
       tags: true
       condition: "$DEPLOY_BUILD_READY = true"
+
+# Clean up wskdeploy binary (single)
+# Fundamentally, remove both /build and /release directory trees and contents
+# TODO: See if this is really needed in Travis environments as the
+# Makefile is not used elsewhere here (especially if we do not use th
+# build_tag_release.sh script) as it is for Windows developers primarily
+# and we are building using Linux.
+after_script:
+  - make clean
+  - tree /build
+  - tree /release
+
 env:
   global:
     - BLUEMIX_APIHOST=openwhisk.ng.bluemix.net
diff --git a/build.gradle b/build.gradle
index 4c9ce40..9283422 100644
--- a/build.gradle
+++ b/build.gradle
@@ -73,7 +73,7 @@
     storage is in "GO" format:
 
         OS: linux, darwin, windows
-        Arch: 386, amd64, s390x, ppc64le, arm
+        Arch: 386, amd64, s390x, ppc64le, arm, arm64
 
     TODO - It may be appropriate to refactor into a general purpose Platform
            class for all builds, then to extend with specifics needed for
diff --git a/cmd/export.go b/cmd/export.go
index 4020075..aa8ee7d 100644
--- a/cmd/export.go
+++ b/cmd/export.go
@@ -29,8 +29,10 @@
 	"github.com/apache/openwhisk-wskdeploy/parsers"
 	"github.com/apache/openwhisk-wskdeploy/runtimes"
 	"github.com/apache/openwhisk-wskdeploy/utils"
+	"github.com/apache/openwhisk-wskdeploy/wskderrors"
 	"github.com/apache/openwhisk-wskdeploy/wski18n"
 	"github.com/apache/openwhisk-wskdeploy/wskprint"
+	"github.com/davecgh/go-spew/spew"
 	"github.com/spf13/cobra"
 )
 
@@ -117,9 +119,6 @@
 
 func exportProject(projectName string, targetManifest string) error {
 
-	whisk.SetVerbose(utils.Flags.Verbose)
-	whisk.SetDebug(utils.Flags.Trace)
-
 	maniyaml := &parsers.YAML{}
 	maniyaml.Project.Name = projectName
 
@@ -129,6 +128,11 @@
 		return err
 	}
 
+	// Emit additional trace data (primarily in Travis)
+	if utils.Flags.Trace {
+		spew.Dump(packages)
+	}
+
 	var bindings = make(map[string]whisk.Binding)
 
 	// iterate over each package to find managed annotations
@@ -136,6 +140,7 @@
 	// add to export when managed project name matches with the
 	// specified project name
 	for _, pkg := range packages {
+
 		if a := pkg.Annotations.GetValue(utils.MANAGED); a != nil {
 			// decode the JSON blob and retrieve __OW_PROJECT_NAME
 			pa := a.(map[string]interface{})
@@ -199,59 +204,66 @@
 
 	// iterate over the list of triggers to determine whether any of them part of specified managed project
 	for _, trg := range triggers {
+
 		// trigger has attached managed annotation
-		if a := trg.Annotations.GetValue(utils.MANAGED); a != nil {
-			// decode the JSON blob and retrieve __OW_PROJECT_NAME
-			ta := a.(map[string]interface{})
-			if ta[utils.OW_PROJECT_NAME] == projectName {
+		if trg.Annotations != nil {
+			if a := trg.Annotations.GetValue(utils.MANAGED); a != nil {
+				// decode the JSON blob and retrieve __OW_PROJECT_NAME
+				ta := a.(map[string]interface{})
+				if ta[utils.OW_PROJECT_NAME] == projectName {
 
-				for pkgName := range maniyaml.Packages {
-					if maniyaml.Packages[pkgName].Namespace == trg.Namespace {
-						if maniyaml.Packages[pkgName].Triggers == nil {
-							pkg := maniyaml.Packages[pkgName]
-							pkg.Triggers = make(map[string]parsers.Trigger)
-							maniyaml.Packages[pkgName] = pkg
-						}
-
-						// export trigger to manifest
-
-						if feedname, isFeed := utils.IsFeedAction(&trg); isFeed {
-							// check if feed name starts with namespace and workaround it
-							// the current problem is that client has user namespace and when feed specified with different namespace it will fail to invoke the feed action
-							// we need to transform the path from e.g.
-							// /api/v1/namespaces/kpavel@il.ibm.com_uspace/actions//whisk.system/alarms/interval?blocking=true
-							// in to
-							// /api/v1/namespaces/kpavel@il.ibm.com_uspace/actions/../../whisk.system/actions/alarms/interval?blocking=true
-							if strings.HasPrefix(feedname, "/") {
-								//  /whisk.system/alarms/interval  ->  ../../whisk.system/actions/alarms/interval
-								prts := strings.SplitN(feedname, "/", 3)
-								feedname = "../../" + prts[1] + "/actions/" + prts[2]
+					for pkgName := range maniyaml.Packages {
+						if maniyaml.Packages[pkgName].Namespace == trg.Namespace {
+							if maniyaml.Packages[pkgName].Triggers == nil {
+								pkg := maniyaml.Packages[pkgName]
+								pkg.Triggers = make(map[string]parsers.Trigger)
+								maniyaml.Packages[pkgName] = pkg
 							}
 
-							// export feed input parameters
-							params := make(map[string]interface{})
-							params["authKey"] = client.Config.AuthToken
-							params["lifecycleEvent"] = "READ"
-							params["triggerName"] = "/" + client.Namespace + "/" + trg.Name
-							res, _, err := client.Actions.Invoke(feedname, params, true, true)
-							if err != nil {
-								return err
-							}
-							feedConfig := res["config"]
+							// export trigger to manifest
 
-							if feedConfig != nil {
-								for key, val := range feedConfig.(map[string]interface{}) {
-									if key != "startDate" {
-										trg.Parameters = trg.Parameters.AddOrReplace(&whisk.KeyValue{Key: key, Value: val})
+							if feedname, isFeed := utils.IsFeedAction(&trg); isFeed {
+								// check if feed name starts with namespace and workaround it
+								// the current problem is that client has user namespace and when feed specified with different namespace it will fail to invoke the feed action
+								// we need to transform the path from e.g.
+								// /api/v1/namespaces/kpavel@il.ibm.com_uspace/actions//whisk.system/alarms/interval?blocking=true
+								// in to
+								// /api/v1/namespaces/kpavel@il.ibm.com_uspace/actions/../../whisk.system/actions/alarms/interval?blocking=true
+								if strings.HasPrefix(feedname, "/") {
+									//  /whisk.system/alarms/interval  ->  ../../whisk.system/actions/alarms/interval
+									prts := strings.SplitN(feedname, "/", 3)
+									feedname = "../../" + prts[1] + "/actions/" + prts[2]
+								}
+
+								// export feed input parameters
+								params := make(map[string]interface{})
+								params["authKey"] = client.Config.AuthToken
+								params["lifecycleEvent"] = "READ"
+								params["triggerName"] = "/" + client.Namespace + "/" + trg.Name
+								res, _, err := client.Actions.Invoke(feedname, params, true, true)
+								if err != nil {
+									return err
+								}
+								feedConfig := res["config"]
+
+								if feedConfig != nil {
+									for key, val := range feedConfig.(map[string]interface{}) {
+										if key != "startDate" {
+											trg.Parameters = trg.Parameters.AddOrReplace(&whisk.KeyValue{Key: key, Value: val})
+										}
 									}
 								}
 							}
-						}
 
-						maniyaml.Packages[pkgName].Triggers[trg.Name] = *maniyaml.ComposeParsersTrigger(trg)
+							maniyaml.Packages[pkgName].Triggers[trg.Name] = *maniyaml.ComposeParsersTrigger(trg)
+						}
 					}
 				}
 			}
+		} else {
+			// Emit additional trace data on common Travis failures
+			spew.Dump(trg)
+			return wskderrors.NewCommandError("Export", "Trigger missing annotations.")
 		}
 	}
 
@@ -263,29 +275,36 @@
 
 	// iterate over the list of rules to determine whether any of them is part of the manage dproject
 	for _, rule := range rules {
+
 		// get rule from OW
 		wskRule, _, _ := client.Rules.Get(rule.Name)
-		// rule has attached managed annotation
-		if a := wskRule.Annotations.GetValue(utils.MANAGED); a != nil {
-			// decode the JSON blob and retrieve __OW_PROJECT_NAME
-			ta := a.(map[string]interface{})
-			if ta[utils.OW_PROJECT_NAME] == projectName {
 
-				for pkgName := range maniyaml.Packages {
-					if maniyaml.Packages[pkgName].Namespace == wskRule.Namespace {
-						if maniyaml.Packages[pkgName].Rules == nil {
-							pkg := maniyaml.Packages[pkgName]
-							pkg.Rules = make(map[string]parsers.Rule)
-							maniyaml.Packages[pkgName] = pkg
+		if wskRule.Annotations != nil {
+			// rule has attached managed annotation
+			if a := wskRule.Annotations.GetValue(utils.MANAGED); a != nil {
+				// decode the JSON blob and retrieve __OW_PROJECT_NAME
+				ta := a.(map[string]interface{})
+				if ta[utils.OW_PROJECT_NAME] == projectName {
+
+					for pkgName := range maniyaml.Packages {
+						if maniyaml.Packages[pkgName].Namespace == wskRule.Namespace {
+							if maniyaml.Packages[pkgName].Rules == nil {
+								pkg := maniyaml.Packages[pkgName]
+								pkg.Rules = make(map[string]parsers.Rule)
+								maniyaml.Packages[pkgName] = pkg
+							}
+
+							// export rule to manifest
+							maniyaml.Packages[pkgName].Rules[wskRule.Name] = *maniyaml.ComposeParsersRule(*wskRule)
 						}
-
-						// export rule to manifest
-						maniyaml.Packages[pkgName].Rules[wskRule.Name] = *maniyaml.ComposeParsersRule(*wskRule)
 					}
 				}
 			}
+		} else {
+			// Emit additional trace data on common Travis failures
+			spew.Dump(wskRule)
+			return wskderrors.NewCommandError("Export", "Rule missing annotations.")
 		}
-
 	}
 
 	// API Gateway is an optional component. Export APIs only when ApigwAccessToken is configured
@@ -386,7 +405,14 @@
 
 	// find exported manifest parent directory
 	manifestDir := filepath.Dir(utils.Flags.ManifestPath)
-	os.MkdirAll(manifestDir, os.ModePerm)
+	errMkDir := os.MkdirAll(manifestDir, os.ModePerm)
+
+	// Exit if unable to create export dir. structure
+	// TODO: This sometimes fails in Travis, perhaps retry?
+	if errMkDir != nil {
+		wskprint.PrintOpenWhiskError(errMkDir.Error())
+		return errMkDir
+	}
 
 	// export manifest to file
 	parsers.Write(maniyaml, targetManifest)
diff --git a/go.mod b/go.mod
index 998c63d..26048ad 100644
--- a/go.mod
+++ b/go.mod
@@ -5,16 +5,15 @@
 require (
 	github.com/apache/openwhisk-client-go v0.0.0-20210311185314-87edc2364717
 	github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
 	github.com/fatih/color v1.10.0
 	github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
-	github.com/google/go-querystring v1.0.0 // indirect
 	github.com/hokaccha/go-prettyjson v0.0.0-20210113012101-fb4e108d2519
 	github.com/magiconair/properties v1.8.4 // indirect
 	github.com/mattn/go-colorable v0.1.8
 	github.com/mitchellh/mapstructure v1.4.1 // indirect
 	github.com/nicksnyder/go-i18n v1.10.1
 	github.com/nxadm/tail v1.4.8 // indirect
-	github.com/onsi/ginkgo v1.15.0 // indirect
 	github.com/pelletier/go-toml v1.8.1 // indirect
 	github.com/spf13/afero v1.5.1 // indirect
 	github.com/spf13/cast v1.3.1 // indirect
@@ -26,5 +25,4 @@
 	golang.org/x/text v0.3.5 // indirect
 	gopkg.in/ini.v1 v1.62.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0
-	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 )
diff --git a/go.sum b/go.sum
index 514be3d..da67724 100644
--- a/go.sum
+++ b/go.sum
@@ -16,10 +16,6 @@
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/apache/openwhisk-client-go v0.0.0-20200927152356-49c58e00354d h1:eRcVp/TIKFqI7adU1egUr4IYGhOA1PYu4B5C1IvwSgI=
-github.com/apache/openwhisk-client-go v0.0.0-20200927152356-49c58e00354d/go.mod h1:jLLKYP7+1+LFlIJW1n9U1gqeveLM1HIwa4ZHNOFxjPw=
-github.com/apache/openwhisk-client-go v0.0.0-20210308161059-5cd1006dc35f h1:SVXVE9+snbgp5vtxfOQ7QrANTZQ/bcP9IFev6HXrtWc=
-github.com/apache/openwhisk-client-go v0.0.0-20210308161059-5cd1006dc35f/go.mod h1:SAQU4bHGJ0sg6c1vQ8ojmQKXgGaneVnexWX4+2/KMr8=
 github.com/apache/openwhisk-client-go v0.0.0-20210311185314-87edc2364717 h1:7MsAB3W6JH0d9TZ4UJ55rwV8AR9jXXZf97Uzk+CJqqs=
 github.com/apache/openwhisk-client-go v0.0.0-20210311185314-87edc2364717/go.mod h1:SAQU4bHGJ0sg6c1vQ8ojmQKXgGaneVnexWX4+2/KMr8=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -43,6 +39,7 @@
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
@@ -180,6 +177,7 @@
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
 github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
@@ -191,6 +189,7 @@
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -302,6 +301,7 @@
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
diff --git a/main.go b/main.go
index 5a4fe1c..784d885 100644
--- a/main.go
+++ b/main.go
@@ -26,10 +26,15 @@
 	cmd.Execute()
 }
 
+// Struct used to hold tagged (release) build information
+// Which is displayed by the `version` command.
+// Added automatically for CI/CD Travis builds in GitHub
 var (
-	//Version ...The Version of the tool
-	Version   = "unset"
+	// Apache OpenWhisk Whisk Deploy release/build version
+	Version = "unset"
+	// Git source code commit # that initiated the build
 	GitCommit = "unset"
+	// Date stamp indicating when build was initiated
 	BuildDate = "unset"
 )
 
diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go
index 0777320..8c3908a 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -26,6 +26,7 @@
 	"path"
 	"path/filepath"
 	"strings"
+	"time"
 
 	"github.com/apache/openwhisk-client-go/whisk"
 	"github.com/apache/openwhisk-wskdeploy/dependencies"
@@ -194,11 +195,23 @@
 	return Wskdeploy.RunCommand("sync", "-m", manifestPath, "-d", deploymentPath, "--projectname", name)
 }
 
+// Note: this test often fails due to server-related issues trying to access
+// newly created objects (e.g., primarily Rules) too quickly which often lose Annotations.
+// causing SIGSEGV errors.
+// It also sometimes fails accessing local storage (for tmp directories and files
+// that are created in Travis (constrained, shared environments).
+// You can add the "-t" or "--trace" to the RunCommand to get extensive trace on all HTTP calls
 func (wskdeploy *Wskdeploy) ExportProject(projectName string, targetManifestPath string) (string, error) {
+	// TODO: There is a server-side timing issue with Annotations being
+	// retrieved too soon after creation; need to explore in OW main
+	time.Sleep(3 * time.Second) // should it sleep for few seconds before export?!
 	return wskdeploy.RunCommand("export", "-m", targetManifestPath, "--projectname", projectName)
 }
 
 func (wskdeploy *Wskdeploy) ExportProjectWithCredentials(projectName string, targetManifestPath string, wskprops *whisk.Wskprops) (string, error) {
+	// TODO: There is a server-side timing issue with Annotations being
+	// retrieved too soon after creation; need to explore in OW main
+	time.Sleep(3 * time.Second) // should it sleep for few seconds before export?!
 	return wskdeploy.RunCommand("export", "-m", targetManifestPath, "--projectname", projectName, "--auth", wskprops.AuthKey,
 		"--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion)
 }
diff --git a/tests/src/integration/export/export_test.go b/tests/src/integration/export/export_test.go
index bdcbd43..2ec86c6 100644
--- a/tests/src/integration/export/export_test.go
+++ b/tests/src/integration/export/export_test.go
@@ -25,7 +25,6 @@
 	"os"
 	"strconv"
 	"testing"
-	"time"
 
 	"github.com/apache/openwhisk-wskdeploy/tests/src/integration/common"
 	"github.com/stretchr/testify/assert"
@@ -54,8 +53,6 @@
 	_, err = wskdeploy.ManagedDeploymentOnlyManifest(manifestExtPath)
 	assert.Equal(t, nil, err, "Failed to deploy the ext manifest file.")
 
-	time.Sleep(2 * time.Second) // should it sleep for few seconds before export?!
-
 	_, err = wskdeploy.ExportProject(projectName, targetManifestPath)
 	assert.Equal(t, nil, err, "Failed to export project.")
 
@@ -127,7 +124,6 @@
 	_, err := wskdeploy.ManagedDeploymentOnlyManifest(manifest2PackPath)
 	assert.Equal(t, nil, err, "Failed to deploy the 2pack manifest file.")
 
-	time.Sleep(2 * time.Second) // should it sleep for few seconds before export?!
 	_, err = wskdeploy.ExportProject(projectName, target2PackManifestPath)
 	assert.Equal(t, nil, err, "Failed to export project.")
 
@@ -153,7 +149,6 @@
 	_, err := wskdeploy.ManagedDeploymentManifestAndProject(manifestApiExpPath, projectName)
 	assert.Equal(t, nil, err, "Failed to deploy the ApiExp manifest file.")
 
-	time.Sleep(2 * time.Second) // should it sleep for few seconds before export?!
 	_, err = wskdeploy.ExportProject(projectName, targetApiExpManifestPath)
 	assert.Equal(t, nil, err, "Failed to export project.")
 
@@ -189,7 +184,6 @@
 		_, err = wskdeploy.ManagedDeploymentManifestAndProjectWithCredentials(manifestFeedExpPath, projectName, wskprops)
 		assert.Equal(t, nil, err, "Failed to deploy the FeedExp manifest file.")
 
-		time.Sleep(2 * time.Second) // should it sleep for few seconds before export?!
 		_, err = wskdeploy.ExportProjectWithCredentials(projectName, targetFeedExpManifestPath, wskprops)
 		assert.Equal(t, nil, err, "Failed to export project with trigger feed.")
 
diff --git a/tools/travis/build_tag_releases.sh b/tools/travis/build_tag_releases.sh
index 074dd27..8772692 100755
--- a/tools/travis/build_tag_releases.sh
+++ b/tools/travis/build_tag_releases.sh
@@ -15,13 +15,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-
+set -x
 declare -a os_list=("linux" "darwin" "windows")
 declare -a arc_list=("amd64" "386")
 build_file_name=${1:-"wskdeploy"}
 build_version=${2:-"$TRAVIS_TAG"}
-gitCommit=$(git rev-parse HEAD)
 buildDate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
+gitCommit=$(git rev-parse HEAD)
+
+echo "build_file_name: ["$build_file_name"]"
+echo "build_version: ["$build_version"]"
+echo "buildDate: ["$buildDate"]"
+echo "gitCommit: ["$gitCommit"]"
+echo "TRAVIS_TAG: ["$TRAVIS_TAG"]"
 
 for os in "${os_list[@]}"
 do
diff --git a/tools/travis/script.sh b/tools/travis/script.sh
index 12d534b..80de247 100755
--- a/tools/travis/script.sh
+++ b/tools/travis/script.sh
@@ -59,5 +59,9 @@
 
 export OPENWHISK_HOME="$(dirname "$TRAVIS_BUILD_DIR")/openwhisk"
 
+# TODO: Implement integration tests in GradleWrapper as new task
+# then use that version instead of invoking from the makefile
+echo "Running Golang integration tests"
+tree tests/src/integration/
 cd $TRAVIS_BUILD_DIR
 make integration_test
diff --git a/tools/travis/showenv.sh b/tools/travis/showenv.sh
new file mode 100755
index 0000000..67f10d9
--- /dev/null
+++ b/tools/travis/showenv.sh
@@ -0,0 +1,30 @@
+  #!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+set -e
+
+echo "================================================"
+echo "TRAVIS = ["$TRAVIS"]"
+echo "TRAVIS_PULL_REQUEST = ["$TRAVIS_PULL_REQUEST"]"
+echo "TRAVIS_SECURE_ENV_VARS = ["$TRAVIS_SECURE_ENV_VARS"]"
+echo "TRAVIS_BRANCH = ["$TRAVIS_BRANCH"]"
+echo "TRAVIS_EVENT_TYPE = ["$TRAVIS_EVENT_TYPE"]"
+echo "GIT_TAG = ["$GIT_TAG"]"
+echo "TAG = ["$TAG"]"
+echo "================================================"
+
+printenv | sort
diff --git a/wskprint/console.go b/wskprint/console.go
index 91ee593..8367eb5 100644
--- a/wskprint/console.go
+++ b/wskprint/console.go
@@ -19,13 +19,14 @@
 
 import (
 	"fmt"
-	"github.com/apache/openwhisk-wskdeploy/wski18n"
-	"github.com/fatih/color"
-	"github.com/mattn/go-colorable"
 	"os"
 	"path/filepath"
 	"runtime"
 	"strings"
+
+	"github.com/apache/openwhisk-wskdeploy/wski18n"
+	"github.com/fatih/color"
+	"github.com/mattn/go-colorable"
 )
 
 const (