[CORD-3117]

Scripts for verifying and tagging git commits with versions

Change-Id: I9481b4a3a6ef7ef0c676cb3ed4a121a0ea53e85d
diff --git a/jjb/imagebuilder.yaml b/jjb/imagebuilder.yaml
index d26d7f8..a03db4d 100644
--- a/jjb/imagebuilder.yaml
+++ b/jjb/imagebuilder.yaml
@@ -1,5 +1,5 @@
 ---
-# CORD helm chart publishing tasks
+# CORD docker image building + dockerhub publishing tasks
 
 - project:
     name: imagebuilder
@@ -9,7 +9,7 @@
       - 'publish-imagebuilder':
           project-regexp: '{imagebuilder-projects-regexp}'
           branch-regexp: '{supported-branches-regexp}'
-
+#          dependency-jobs: 'version-tag'
 
 - job-template:
     id: publish-imagebuilder
@@ -51,6 +51,9 @@
           default: '$GERRIT_BRANCH'
           description: 'Name of the repo branch to use'
 
+# NOTE: May need to parameters that give the ability to rebuild from a specific
+# tag or commit on a branch.
+
       - bool:
           name: build
           default: false
diff --git a/jjb/shell/repopatch.sh b/jjb/shell/repopatch.sh
old mode 100644
new mode 100755
diff --git a/jjb/shell/tagcollisionreject.sh b/jjb/shell/tagcollisionreject.sh
new file mode 100755
index 0000000..c9523e0
--- /dev/null
+++ b/jjb/shell/tagcollisionreject.sh
@@ -0,0 +1,62 @@
+#!/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.
+
+# tagcollisionreject.sh
+# checks that there isn't an existing tag in the repo that has this tag
+
+set -eu -o pipefail
+
+NEW_VERSION=""
+
+# find the version string in the repo, read into NEW_VERSION
+# Add additional places NEW_VERSION could be found to this function
+function read_version {
+  if [ -f "VERSION" ]
+  then
+    NEW_VERSION=$(head -n1 "VERSION")
+    echo "New version: $NEW_VERSION"
+  else
+    echo "ERROR: No versioning file found!"
+    exit 1
+  fi
+}
+
+# check if the version is already a tag in git
+function is_git_tag_duplicated {
+  for existing_tag in $(git tag)
+  do
+    if [ "$NEW_VERSION" = "$existing_tag" ]
+    then
+      echo "ERROR: Duplicate tag: $existing_tag"
+      exit 2
+    fi
+  done
+}
+
+echo "Checking git repo with remotes:"
+git remote -v
+
+echo "Branches:"
+git branch -v
+
+echo "Existing git tags:"
+git tag -n
+
+read_version
+is_git_tag_duplicated
+
+exit 0
+
diff --git a/jjb/shell/versiontag.sh b/jjb/shell/versiontag.sh
new file mode 100755
index 0000000..8636cd4
--- /dev/null
+++ b/jjb/shell/versiontag.sh
@@ -0,0 +1,91 @@
+#!/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.
+
+# versiontag.sh
+# Tags a git commit with the SemVer version discovered within the commit,
+# if the tag doesn't already exist. Ignore non-SemVer commits.
+
+set -eu -o pipefail
+
+NEW_VERSION=""
+VERSIONFILE=""
+
+releaseversion=0
+
+# find the version string in the repo, read into NEW_VERSION
+# Add additional places NEW_VERSION could be found to this function
+function read_version {
+  if [ -f "VERSION" ]
+  then
+    NEW_VERSION=$(head -n1 "VERSION")
+    VERSIONFILE="VERSION"
+    echo "New version: $NEW_VERSION"
+  else
+    echo "ERROR: No versioning file found!"
+    exit 1
+  fi
+}
+
+# check if the version is already a tag in git
+function is_git_tag_duplicated {
+  for existing_tag in $(git tag)
+  do
+    if [ "$NEW_VERSION" = "$existing_tag" ]
+    then
+      echo "ERROR: Duplicate tag: $existing_tag"
+      exit 2
+    fi
+  done
+}
+
+# check if the version is a released version
+function check_if_releasever {
+  if [[ "$NEW_VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
+  then
+    echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is a SemVer released version!"
+    releaseversion=1
+  else
+    echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, skipping."
+  fi
+}
+
+# create a git tag
+function create_git_tag {
+  echo "Creating git tag: $NEW_VERSION"
+  git checkout "$GERRIT_PATCHSET_REVISION"
+  git tag -a "$NEW_VERSION" -m "Tagged by CORD Jenkins version-tag job: $BUILD_NUMBER, for Gerrit patchset: $GERRIT_CHANGE_NUMBER"
+  git push origin "$NEW_VERSION"
+}
+
+echo "Checking git repo with remotes:"
+git remote -v
+
+echo "Branches:"
+git branch -v
+
+echo "Existing git tags:"
+git tag -n
+
+read_version
+is_git_tag_duplicated
+check_if_releasever
+
+if $releaseversion
+then
+  create_git_tag
+fi
+
+exit 0
diff --git a/jjb/versioning.yaml b/jjb/versioning.yaml
new file mode 100644
index 0000000..d51efdb
--- /dev/null
+++ b/jjb/versioning.yaml
@@ -0,0 +1,115 @@
+---
+# CORD versioning jobs for tagging/releasing software
+
+# CORD versioning conventions:
+#
+# 1. There is a 1:1 relationship between SemVer _release_ versions described
+#    in the commit and the git tag applied to that commit by Jenkins.
+#
+# 2. Non-release versions (ex: 1.0.1-dev3, etc.) can exist in multiple
+#    commits, and don't trigger creation of git tags.
+#
+# 3. Git history is public, and therefore shouldn't be rewritten to abandon
+#    already merged commits
+#
+# 4. Reverting a commit leaves it in history, so if a broken version is
+#    released, the correct action is to make a new fixed version, not try to
+#    fix the released version
+#
+# See also: https://jira.opencord.org/browse/CORD-3117
+
+- project:
+    name: versioning-jobs
+
+    branch-regexp: '{modern-branches-regexp}'
+    project: '^bogus-project$'
+
+    jobs:
+      - 'tag-collision-reject'
+      - 'version-tag'
+
+- job-template:
+    id: tag-collision-reject
+    name: "tag-collision-reject"
+    description: |
+      Created by {id} job-template from ci-management/jjb/versioning.yaml
+      Checks for changes to version files, and that they don't duplicate tags
+      already in the git repo.
+
+    triggers:
+      - cord-infra-gerrit-trigger-patchset:
+          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:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    scm:
+      - lf-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}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+    builders:
+      - shell: !include-raw-escape: shell/tagcollisionreject.sh
+
+
+- job-template:
+    id: version-tag
+    name: "version-tag"
+    description: |
+      Created by {id} job-template from ci-management/jjb/release.yaml
+      When a patch is merged, check if it contains a SemVer released version
+      file and if so tags the commit in git with that same version.
+
+    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:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    scm:
+      - lf-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}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+    builders:
+      - shell: !include-raw-escape: shell/versiontag.sh
+