[SEBA-682]

GitHub release artifact generation/upload automation

Change-Id: I72978adaef5640e67265abf1309cd85af1f5305c
diff --git a/jjb/defaults.yaml b/jjb/defaults.yaml
index f6737a5..79026b8 100644
--- a/jjb/defaults.yaml
+++ b/jjb/defaults.yaml
@@ -151,8 +151,20 @@
     dest-gopath: ''
 
     # github organization
-    # Used to pull list of all repos from a specific github organization
-    # Currently used with: synopsys detect
-    # Default is blank, which implies using gerrit instead
+    # Specifies the github organization to operate on.  Default is blank which
+    # may either be invalid, or specify that gerrit should be used instead.
+    # Currently used with: synopsys detect, github-release
     github-organization: ''
 
+    # release targets
+    # List of targets run when creating a software release, run with make or
+    # similar. Default is "release", multiple targets may be space separated
+    # (when using make).
+    release-targets: 'release'
+
+    # artifact glob
+    # Shell glob expression used to select which files are included as binaries
+    # in a release.
+    # Currently used with: github-release
+    artifact-glob: ''
+
diff --git a/jjb/github-release.yaml b/jjb/github-release.yaml
new file mode 100644
index 0000000..2b5a4a9
--- /dev/null
+++ b/jjb/github-release.yaml
@@ -0,0 +1,55 @@
+---
+# publishing artifacts to GitHub releases
+
+- job-template:
+    id: github-release
+    name: 'github-release_{project}'
+    description: |
+      Created by {id} job-template from ci-management/jjb/github-release.yaml<br/>
+      Build and publish artifacts to GitHub as a release, with checksums
+
+    triggers:
+      - cord-infra-gerrit-trigger-merge:
+          gerrit-server-name: '{gerrit-server-name}'
+          project-regexp: '^{project}$'
+          branch-regexp: '{branch-regexp}'
+          file-include-regexp: '{all-files-regexp}'
+          dependency-jobs: '{dependency-jobs}'
+
+    properties:
+      - cord-infra-properties:
+          build-days-to-keep: '{build-days-to-keep}'
+          artifact-num-to-keep: '{artifact-num-to-keep}'
+
+    wrappers:
+      - cord-pypi-wrapper:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{gerrit-ssh-credential}'
+      - credentials-binding:
+          - text:
+              credential-id: github-release-token
+              variable: GITHUB_TOKEN
+
+    scm:
+      - cord-infra-gerrit-scm:
+          git-url: '$GIT_URL/$GERRIT_PROJECT'
+          refspec: '$GERRIT_REFSPEC'
+          branch: '$GERRIT_BRANCH'
+          submodule-recursive: 'false'
+          choosing-strategy: gerrit
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+          basedir: '{project}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+    builders:
+      - inject:
+          properties-content: |
+            DEST_GOPATH={dest-gopath}
+            RELEASE_TARGETS={release-targets}
+            ARTIFACT_GLOB={artifact-glob}
+            GITHUB_ORGANIZATION={github-organization}
+
+      - shell: !include-raw-escape: shell/github-release.sh
diff --git a/jjb/shell/github-release.sh b/jjb/shell/github-release.sh
new file mode 100644
index 0000000..57e6fae
--- /dev/null
+++ b/jjb/shell/github-release.sh
@@ -0,0 +1,119 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-present 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.
+
+# github-release.sh
+# builds (with make) and uploads release artifacts (binaries, etc.) to github
+# given a tag also create checksums files and release notes from the commit
+# message
+
+set -eu -o pipefail
+
+# when not running under Jenkins, use current dir as workspace and a blank
+# project name
+WORKSPACE=${WORKSPACE:-.}
+GERRIT_PROJECT=${GERRIT_PROJECT:-}
+
+# Github organization (or user) this project is published on.  Project name should
+# be the same on both Gerrit and GitHub
+GITHUB_ORGANIZATION=${GITHUB_ORGANIZATION:-}
+
+# glob pattern relative to project dir matching release artifacts
+ARTIFACT_GLOB=${ARTIFACT_GLOB:-"release/*"}
+
+# Temporary staging directory to copy artifacts to
+RELEASE_TEMP="$WORKSPACE/release"
+
+# Use "release" as the default makefile target, can be a space separated list
+RELEASE_TARGETS=${RELEASE_TARGETS:-release}
+
+# check that we're on a semver released version, or exit
+pushd "$GERRIT_PROJECT"
+  GIT_VERSION=$(git tag -l --points-at HEAD)
+
+  if [[ "$GIT_VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
+  then
+    echo "git has a SemVer released version tag: '$GIT_VERSION'"
+    echo "Building artifacts for GitHub release."
+  else
+    echo "No SemVer released version tag found, exiting..."
+    exit 0
+  fi
+popd
+
+# To support golang projects create a GOPATH
+# If $DEST_GOPATH is not an empty string:
+# - set create GOPATH, and destination directory within in
+# - set PATH to include $GOPATH/bin and the system go binaries
+# - symlink from $WORKSPACE/$GERRIT_PROJECT to new location in $GOPATH
+# - start release from that directory
+
+DEST_GOPATH=${DEST_GOPATH:-}
+if [ ! -z "$DEST_GOPATH" ]; then
+  export GOPATH=${GOPATH:-~/go}
+  mkdir -p "$GOPATH/src/$DEST_GOPATH"
+  export PATH=$PATH:/usr/lib/go-1.12/bin:/usr/local/go/bin:$GOPATH/bin
+  release_path="$GOPATH/src/$DEST_GOPATH/$GERRIT_PROJECT"
+  ln -r -s "$WORKSPACE/$GERRIT_PROJECT" "$release_path"
+else
+  release_path="$WORKSPACE/$GERRIT_PROJECT"
+fi
+
+if [ ! -f "$release_path/Makefile" ]; then
+  echo "Makefile not found at $release_path!"
+  exit 1
+else
+  pushd "$release_path"
+
+  # Release description is sanitized version of the log message
+  RELEASE_DESCRIPTION=$(git log -1 --pretty=%B | tr -dc "[:alnum:]\n\r\.\[\]\:\-\\\/\`\' ")
+
+  # build the release, can be multiple space separated targets
+  # shellcheck disable=SC2086
+  make $RELEASE_TARGETS
+
+  # Copy artifacts into the release temp dir
+  # shellcheck disable=SC2086
+  cp $ARTIFACT_GLOB "$RELEASE_TEMP"
+
+  # create release
+  gothub release \
+    --user "$GITHUB_ORGANIZATION" \
+    --repo "$GERRIT_PROJECT" \
+    --tag  "$GIT_VERSION" \
+    --name "$GERRIT_PROJECT - $GIT_VERSION" \
+    --description "$RELEASE_DESCRIPTION"
+
+  # handle release files
+  pushd "$RELEASE_TEMP"
+
+    # Generate and check checksums
+    sha256sum ./* > checksum.SHA256
+    sha256sum -c < checksum.SHA256
+
+    # upload all files to the release
+    for rel_file in ./*
+    do
+      gothub upload \
+        --user "$GITHUB_ORGANIZATION" \
+        --repo "$GERRIT_PROJECT" \
+        --tag  "$GIT_VERSION" \
+        --name "$rel_file" \
+        --file "$rel_file"
+    done
+  popd
+
+  popd
+fi
diff --git a/jjb/verify/cordctl.yaml b/jjb/verify/cordctl.yaml
index 480ad86..feca456 100644
--- a/jjb/verify/cordctl.yaml
+++ b/jjb/verify/cordctl.yaml
@@ -5,9 +5,13 @@
     name: cordctl
     project: '{name}'
 
+    dest-gopath: "github.com/opencord"
+
     jobs:
       - 'verify-cordctl-jobs':
           branch-regexp: '{supported-branches-regexp}'
+      - 'post-submit-cordctl-jobs':
+          branch-regexp: '{supported-branches-regexp}'
 
 - job-group:
     name: 'verify-cordctl-jobs'
@@ -16,7 +20,14 @@
       - 'tag-collision-reject':
           dependency-jobs: 'verify_cordctl_licensed'
       - 'make-unit-test':
-          dest-gopath: "github.com/opencord"
           unit-test-targets: 'lint test'
           unit-test-keep-going: 'true'
           dependency-jobs: 'verify_cordctl_tag-collision'
+
+- job-group:
+    name: 'post-submit-cordctl-jobs'
+    jobs:
+      - 'github-release':
+          dependency-jobs: 'version-tag'
+          github-organization: 'opencord'
+          artifact-glob: 'release/*'
diff --git a/packer/provision/basebuild.sh b/packer/provision/basebuild.sh
index 92ce889..d31da0e 100644
--- a/packer/provision/basebuild.sh
+++ b/packer/provision/basebuild.sh
@@ -189,6 +189,9 @@
     go get -v github.com/t-yuki/gocover-cobertura
     go get -v github.com/jstemmer/go-junit-report
 
+    # gothub - uploader for github artifacts
+    go get -v github.com/itchio/gothub
+
     # dep for go package dependencies w/versioning, version 0.5.2, adapted from:
     #  https://golang.github.io/dep/docs/installation.html#install-from-source
     go get -d -u github.com/golang/dep