[INF-146]
Unify mechanism across multiple ci-management repos
- move converted per-repo jobs into the jjb/repos hierarchy
- Pull in macros (with onf- prefix) and common scripts from ONOS/Aether
ci-management repos, unifying behavior
- Update tagging scripts to unify changes
- Update gerrit repo multi-checkout and patch script
- Change over to newer static host for publishing charts/docs
- use python3 venv instead of virtualenv
Change-Id: Id46fdc23679b8854c54e294a7fb022e69d6d28f9
diff --git a/jjb/shell/helm-lint.sh b/jjb/shell/helm-lint.sh
new file mode 100644
index 0000000..e2f9e23
--- /dev/null
+++ b/jjb/shell/helm-lint.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# SPDX-FileCopyrightText: 2020-2022 Open Networking Foundation <info@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+set -eu -o pipefail
+
+export OLD_REPO_DIR="cord-charts-repo"
+
+# Setup helm and external repos
+helm repo add stable https://charts.helm.sh/stable
+helm repo add rook-release https://charts.rook.io/release
+helm repo add cord https://charts.opencord.org
+
+git clone ssh://jenkins@gerrit.opencord.org:29418/helm-repo-tools.git
+./helm-repo-tools/helmlint.sh clean
+echo "*.lock" >> .gitignore
+
+# Specify the remote branch to compare against
+export COMPARISON_BRANCH="origin/$GERRIT_BRANCH"
+./helm-repo-tools/chart_version_check.sh
+
+# Configure git
+git config --global user.email "do-not-reply@opennetworking.org"
+git config --global user.name "Jenkins"
+
+# Check for chart version conflicts by building the repo (don't upload)
+git clone "ssh://jenkins@gerrit.opencord.org:29418/$OLD_REPO_DIR.git"
+./helm-repo-tools/helmrepo.sh
diff --git a/jjb/shell/jflint.sh b/jjb/shell/jflint.sh
index 18c5b40..cef7b91 100755
--- a/jjb/shell/jflint.sh
+++ b/jjb/shell/jflint.sh
@@ -1,18 +1,7 @@
#!/usr/bin/env bash
-# Copyright 2017-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.
+# SPDX-FileCopyrightText: 2017-present Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
# jflint.sh - lint for Jenkins declarative pipeline jobs
#
diff --git a/jjb/shell/publish-helm-repo.sh b/jjb/shell/publish-helm-repo.sh
new file mode 100644
index 0000000..386ff39
--- /dev/null
+++ b/jjb/shell/publish-helm-repo.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+# SPDX-FileCopyrightText: 2020-2022 Open Networking Foundation <info@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+set -eu -o pipefail
+
+echo "git version: $(git --version)"
+
+# Variables used in this and child scripts
+export PUBLISH_URL="charts.opencord.org"
+export OLD_REPO_DIR="cord-charts-repo"
+export NEW_REPO_DIR="chart_repo"
+
+# Configure git
+git config --global user.email "do-not-reply@opennetworking.org"
+git config --global user.name "Jenkins"
+
+# Checkout 'cord-charts-repo' repo that contains updated charts
+git clone "ssh://jenkins@gerrit.opencord.org:29418/$OLD_REPO_DIR.git"
+
+# Clone the `helm-repo-tools` which contains scripts
+git clone ssh://jenkins@gerrit.opencord.org:29418/helm-repo-tools.git
+
+# Setup helm and external repos
+helm repo add stable https://charts.helm.sh/stable
+helm repo add rook-release https://charts.rook.io/release
+helm repo add cord https://charts.opencord.org
+helm repo add elastic https://helm.elastic.co
+helm repo add kiwigrid https://kiwigrid.github.io
+
+# Update the repo
+./helm-repo-tools/helmrepo.sh
+
+# Tag and push to git the charts repo
+pushd "$OLD_REPO_DIR"
+
+ # only update if charts are changed
+ set +e
+ if git diff --exit-code index.yaml > /dev/null; then
+ echo "No changes to charts in patchset $GERRIT_CHANGE_NUMBER on project: $GERRIT_PROJECT, exiting."
+ exit 0
+ fi
+ set -e
+
+ # version tag is the current date in RFC3339 format
+ NEW_VERSION=$(date -u +%Y%m%dT%H%M%SZ)
+
+ # Add changes and create commit
+ git add -A
+ git commit -m "Changed by CORD Jenkins publish-helm-repo job: $BUILD_NUMBER, for project: $GERRIT_PROJECT, patchset: $GERRIT_CHANGE_NUMBER"
+
+ # create tag on new commit
+ git tag "$NEW_VERSION"
+
+ echo "Tags including new tag:"
+ git tag -n
+
+ # push new commit and tag back into repo
+ git push origin
+ git push origin "$NEW_VERSION"
+popd
+
+rsync -rvzh --delete-after --exclude=.git "$OLD_REPO_DIR/" "static.opennetworking.org:/srv/sites/$PUBLISH_URL/"
diff --git a/jjb/shell/repo-patch.sh b/jjb/shell/repo-patch.sh
new file mode 100644
index 0000000..4176df0
--- /dev/null
+++ b/jjb/shell/repo-patch.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+# SPDX-FileCopyrightText: 2018-2022 Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
+
+# repo-patch.sh
+# downloads a patch to within an already checked out repo tree
+
+set -eu -o pipefail
+
+# verify that we have repo installed
+command -v repo >/dev/null 2>&1 || { echo "repo not found, please install it" >&2; exit 1; }
+
+echo "BASEDIR: ${BASEDIR}"
+echo "GERRIT_PROJECT: ${GERRIT_PROJECT}"
+echo "GERRIT_CHANGE_NUMBER: ${GERRIT_CHANGE_NUMBER}"
+echo "GERRIT_PATCHSET_NUMBER: ${GERRIT_PATCHSET_NUMBER}"
+
+pushd "${BASEDIR}"
+echo "Checking out a patchset with repo, using repo version:"
+repo version
+
+PROJECT_PATH=$(xmllint --xpath "string(//project[@name=\"${GERRIT_PROJECT}\"]/@path)" .repo/manifests/default.xml)
+
+if [ -z "$PROJECT_PATH" ]
+then
+ echo "WARNING: Project not in repo! Not downloading the changeset."
+else
+ echo "Project Path: $PROJECT_PATH"
+ repo download "${PROJECT_PATH}" "$GERRIT_CHANGE_NUMBER/${GERRIT_PATCHSET_NUMBER}"
+fi
+
+popd
diff --git a/jjb/shell/repopatch.sh b/jjb/shell/repopatch.sh
deleted file mode 100755
index 1ce911e..0000000
--- a/jjb/shell/repopatch.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/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.
-
-# repopatch.sh
-# downloads a patch to within an already checked out repo tree
-
-set -eu -o pipefail
-
-# verify that we have repo installed
-command -v repo >/dev/null 2>&1 || { echo "repo not found, please install it" >&2; exit 1; }
-
-echo "DESTINATION_DIR: ${DESTINATION_DIR}"
-echo "GERRIT_PROJECT: ${GERRIT_PROJECT}"
-echo "GERRIT_CHANGE_NUMBER: ${GERRIT_CHANGE_NUMBER}"
-echo "GERRIT_PATCHSET_NUMBER: ${GERRIT_PATCHSET_NUMBER}"
-
-pushd "${DESTINATION_DIR}"
-echo "Checking out a patchset with repo, using repo version:"
-repo version
-
-PROJECT_PATH=$(xmllint --xpath "string(//project[@name=\"${GERRIT_PROJECT}\"]/@path)" .repo/manifests/default.xml)
-
-if [ -z "$PROJECT_PATH" ]
-then
- echo "WARNING: Project not in repo! Not downloading the changeset."
-else
- echo "Project Path: $PROJECT_PATH"
- repo download "${PROJECT_PATH}" "$GERRIT_CHANGE_NUMBER/${GERRIT_PATCHSET_NUMBER}"
-fi
-
-popd
-
diff --git a/jjb/shell/tagcollisionreject.sh b/jjb/shell/tag-check.sh
similarity index 64%
rename from jjb/shell/tagcollisionreject.sh
rename to jjb/shell/tag-check.sh
index 01772c5..c5b4b13 100755
--- a/jjb/shell/tagcollisionreject.sh
+++ b/jjb/shell/tag-check.sh
@@ -1,21 +1,7 @@
#!/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
+# SPDX-FileCopyrightText: 2018-2022 Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
set -eu -o pipefail
@@ -24,12 +10,17 @@
TAG_VERSION="" # version file that might have a leading v to work around go mod funkyness
SEMVER_STRICT=${SEMVER_STRICT:-0} # require semver versions
+DOCKERPARENT_STRICT=${DOCKERPARENT_STRICT:-1} # require semver versions on parent images in dockerfiles
releaseversion=0
fail_validation=0
# when not running under Jenkins, use current dir as workspace
WORKSPACE=${WORKSPACE:-.}
+BASEDIR=${BASEDIR:-}
+
+# cd to the code checkout location
+cd "$WORKSPACE/$BASEDIR"
# find the version string in the repo, read into NEW_VERSION
# Add additional places NEW_VERSION could be found to this function
@@ -168,68 +159,74 @@
# check if Dockerfiles have a released version as their parent
function dockerfile_parentcheck {
- while IFS= read -r -d '' dockerfile
- do
- echo "Checking dockerfile: '$dockerfile'"
-
- # split on newlines
- IFS=$'\n'
- df_parents=($(grep "^FROM" "$dockerfile"))
-
- # check all parents in the Dockerfile
- for df_parent in "${df_parents[@]}"
+ if [ "$DOCKERPARENT_STRICT" -eq "0" ];
+ then
+ echo "DOCKERPARENT_STRICT is disabled - skipping parent checks"
+ else
+ while IFS= read -r -d '' dockerfile
do
+ echo "Checking dockerfile: '$dockerfile'"
- df_pattern="[FfRrOoMm] +(--platform=[^ ]+ +)?([^@: ]+)(:([^: ]+)|@sha[^ ]+)?"
- if [[ "$df_parent" =~ $df_pattern ]]
- then
+ # split on newlines
+ IFS=$'\n'
+ df_parents=($(grep "^FROM" "$dockerfile"))
- p_image="${BASH_REMATCH[2]}"
- p_sha=${BASH_REMATCH[3]}
- p_version="${BASH_REMATCH[4]}"
+ # check all parents in the Dockerfile
+ for df_parent in "${df_parents[@]}"
+ do
- echo "IMAGE: '${p_image}'"
- echo "VERSION: '$p_version'"
- echo "SHA: '$p_sha'"
+ df_pattern="[FfRrOoMm] +(--platform=[^ ]+ +)?([^@: ]+)(:([^: ]+)|@sha[^ ]+)?"
+ if [[ "$df_parent" =~ $df_pattern ]]
+ then
- if [[ "${p_image}" == "scratch" ]]
- then
- echo " OK: Using the versionless 'scratch' parent: '$df_parent'"
- elif [[ "${p_image}:${p_version}" == "gcr.io/distroless/static:nonroot" ]]
- then
- echo " OK: Using static distroless image with nonroot: '${p_image}:${p_version}'"
- elif [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
- then
- echo " OK: Parent '$p_image:$p_version' is a released SemVer version"
- elif [[ "${p_sha}" =~ ^@sha256:[0-9a-f]{64}.*$ ]]
- then
- # allow sha256 hashes to be used as version specifiers
- echo " OK: Parent '$p_image$p_sha' is using a specific sha256 hash as a version"
- elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
- then
- # handle non-SemVer versions that have a Major.Minor version specifier in the name
- # 'ubuntu:16.04'
- # 'postgres:10.3-alpine'
- # 'openjdk:8-jre-alpine3.8'
- echo " OK: Parent '$p_image:$p_version' is using a non-SemVer, but sufficient, version"
- elif [[ -z "${p_version}" ]]
- then
- echo " ERROR: Parent '$p_image' is NOT using a specific version"
- fail_validation=1
+ p_image="${BASH_REMATCH[2]}"
+ p_sha=${BASH_REMATCH[3]}
+ p_version="${BASH_REMATCH[4]}"
+
+ echo "IMAGE: '${p_image}'"
+ echo "VERSION: '$p_version'"
+ echo "SHA: '$p_sha'"
+
+ if [[ "${p_image}" == "scratch" ]]
+ then
+ echo " OK: Using the versionless 'scratch' parent: '$df_parent'"
+ elif [[ "${p_image}:${p_version}" == "gcr.io/distroless/static:nonroot" ]]
+ then
+ echo " OK: Using static distroless image with nonroot: '${p_image}:${p_version}'"
+ elif [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
+ then
+ echo " OK: Parent '$p_image:$p_version' is a released SemVer version"
+ elif [[ "${p_sha}" =~ ^@sha256:[0-9a-f]{64}.*$ ]]
+ then
+ # allow sha256 hashes to be used as version specifiers
+ echo " OK: Parent '$p_image$p_sha' is using a specific sha256 hash as a version"
+ elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
+ then
+ # handle non-SemVer versions that have a Major.Minor version specifier in the name
+ # 'ubuntu:16.04'
+ # 'postgres:10.3-alpine'
+ # 'openjdk:8-jre-alpine3.8'
+ echo " OK: Parent '$p_image:$p_version' is using a non-SemVer, but sufficient, version"
+ elif [[ -z "${p_version}" ]]
+ then
+ echo " ERROR: Parent '$p_image' is NOT using a specific version"
+ fail_validation=1
+ else
+ echo " ERROR: Parent '$p_image:$p_version' is NOT using a specific version"
+ fail_validation=1
+ fi
+
else
- echo " ERROR: Parent '$p_image:$p_version' is NOT using a specific version"
- fail_validation=1
+ echo " ERROR: Couldn't find a parent image in $df_parent"
fi
- else
- echo " ERROR: Couldn't find a parent image in $df_parent"
- fi
+ done
- done
-
- done < <( find "${WORKSPACE}" -name 'Dockerfile*' ! -path "*/vendor/*" ! -name "*dockerignore" -print0 )
+ done < <( find "${WORKSPACE}" -name 'Dockerfile*' ! -path "*/vendor/*" ! -name "*dockerignore" -print0 )
+ fi
}
+# Start of actual code
echo "Checking git repo with remotes:"
git remote -v
diff --git a/jjb/shell/version-tag.sh b/jjb/shell/version-tag.sh
new file mode 100755
index 0000000..dcfa756
--- /dev/null
+++ b/jjb/shell/version-tag.sh
@@ -0,0 +1,199 @@
+#!/usr/bin/env bash
+
+# Copyright 2018-2022 Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# version-tag.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
+
+VERSIONFILE="" # file path to file containing version number
+NEW_VERSION="" # version number found in $VERSIONFILE
+TAG_VERSION="" # version file that might have a leading v to work around go mod funkyness
+
+SEMVER_STRICT=${SEMVER_STRICT:-0} # require semver versions
+DOCKERPARENT_STRICT=${DOCKERPARENT_STRICT:-1} # require semver versions on parent images in dockerfiles
+
+releaseversion=0
+fail_validation=0
+
+# when not running under Jenkins, use current dir as workspace
+WORKSPACE=${WORKSPACE:-.}
+
+# 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"
+
+ # If this is a golang project, use funky v-prefixed versions
+ if [ -f "Gopkg.toml" ] || [ -f "go.mod" ]
+ then
+ echo "go-based project found, using v-prefixed version for git tags: v${NEW_VERSION}"
+ TAG_VERSION=v${NEW_VERSION}
+ else
+ TAG_VERSION=${NEW_VERSION}
+ fi
+
+ elif [ -f "package.json" ]
+ then
+ NEW_VERSION=$(python -c 'import json,sys;obj=json.load(sys.stdin); print obj["version"]' < package.json)
+ TAG_VERSION=$NEW_VERSION
+ VERSIONFILE="package.json"
+ elif [ -f "pom.xml" ]
+ then
+ NEW_VERSION=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml)
+ TAG_VERSION=$NEW_VERSION
+ VERSIONFILE="pom.xml"
+ else
+ echo "ERROR: No versioning file found!"
+ exit 1
+ fi
+}
+
+# check if the version is a released version
+function check_if_releaseversion {
+ 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
+ if [ "$SEMVER_STRICT" -eq "1" ]
+ then
+ echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, SEMVER_STRICT enabled, failing!"
+ fail_validation=1
+ else
+ echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, skipping."
+ fi
+ fi
+}
+
+# check if the version is already a tag in git
+function is_git_tag_duplicated {
+ for existing_tag in $(git tag)
+ do
+ if [ "$TAG_VERSION" = "$existing_tag" ]
+ then
+ echo "ERROR: Duplicate tag: $existing_tag"
+ exit 2
+ fi
+ done
+}
+
+# check if Dockerfiles have a released version as their parent
+function dockerfile_parentcheck {
+ if [ "$DOCKERPARENT_STRICT" -eq "0" ];
+ then
+ echo "DOCKERPARENT_STRICT is disabled - skipping parent checks"
+ else
+ while IFS= read -r -d '' dockerfile
+ do
+ echo "Checking dockerfile: '$dockerfile'"
+
+ # split on newlines
+ IFS=$'\n'
+ df_parents=($(grep "^FROM" "$dockerfile"))
+
+ # check all parents in the Dockerfile
+ for df_parent in "${df_parents[@]}"
+ do
+
+ df_pattern="[FfRrOoMm] +(--platform=[^ ]+ +)?([^@: ]+)(:([^: ]+)|@sha[^ ]+)?"
+ if [[ "$df_parent" =~ $df_pattern ]]
+ then
+
+ p_image="${BASH_REMATCH[2]}"
+ p_sha=${BASH_REMATCH[3]}
+ p_version="${BASH_REMATCH[4]}"
+
+ echo "IMAGE: '${p_image}'"
+ echo "VERSION: '$p_version'"
+ echo "SHA: '$p_sha'"
+
+ if [[ "${p_image}" == "scratch" ]]
+ then
+ echo " OK: Using the versionless 'scratch' parent: '$df_parent'"
+ elif [[ "${p_image}:${p_version}" == "gcr.io/distroless/static:nonroot" ]]
+ then
+ echo " OK: Using static distroless image with nonroot: '${p_image}:${p_version}'"
+ elif [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
+ then
+ echo " OK: Parent '$p_image:$p_version' is a released SemVer version"
+ elif [[ "${p_sha}" =~ ^@sha256:[0-9a-f]{64}.*$ ]]
+ then
+ # allow sha256 hashes to be used as version specifiers
+ echo " OK: Parent '$p_image$p_sha' is using a specific sha256 hash as a version"
+ elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
+ then
+ # handle non-SemVer versions that have a Major.Minor version specifier in the name
+ # 'ubuntu:16.04'
+ # 'postgres:10.3-alpine'
+ # 'openjdk:8-jre-alpine3.8'
+ echo " OK: Parent '$p_image:$p_version' is using a non-SemVer, but sufficient, version"
+ elif [[ -z "${p_version}" ]]
+ then
+ echo " ERROR: Parent '$p_image' is NOT using a specific version"
+ fail_validation=1
+ else
+ echo " ERROR: Parent '$p_image:$p_version' is NOT using a specific version"
+ fail_validation=1
+ fi
+
+ else
+ echo " ERROR: Couldn't find a parent image in $df_parent"
+ fi
+
+ done
+
+ done < <( find "${WORKSPACE}" -name 'Dockerfile*' ! -path "*/vendor/*" ! -name "*dockerignore" -print0 )
+ fi
+}
+
+# create a git tag
+function create_git_tag {
+ echo "Creating git tag: $TAG_VERSION"
+ git checkout "$GERRIT_PATCHSET_REVISION"
+
+ git config --global user.email "do-not-reply@opennetworking.org"
+ git config --global user.name "Jenkins"
+
+ git tag -a "$TAG_VERSION" -m "Tagged by CORD Jenkins version-tag job: $BUILD_NUMBER, for Gerrit patchset: $GERRIT_CHANGE_NUMBER"
+
+ echo "Tags including new tag:"
+ git tag -n
+
+ git push origin "$TAG_VERSION"
+}
+
+echo "Checking git repo with remotes:"
+git remote -v
+
+echo "Branches:"
+git branch -v
+
+echo "Existing git tags:"
+git tag -n
+
+read_version
+check_if_releaseversion
+
+# perform checks if a released version
+if [ "$releaseversion" -eq "1" ]
+then
+ is_git_tag_duplicated
+ dockerfile_parentcheck
+
+ if [ "$fail_validation" -eq "0" ]
+ then
+ create_git_tag
+ else
+ echo "ERROR: commit merged but failed validation, not tagging!"
+ fi
+fi
+
+exit $fail_validation
diff --git a/jjb/shell/versiontag.sh b/jjb/shell/versiontag.sh
deleted file mode 100755
index 8c14ddd..0000000
--- a/jjb/shell/versiontag.sh
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/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
-
-VERSIONFILE="" # file path to file containing version number
-NEW_VERSION="" # version number found in $VERSIONFILE
-TAG_VERSION="" # version file that might have a leading v to work around go mod funkyness
-
-SEMVER_STRICT=${SEMVER_STRICT:-0} # require semver versions
-
-releaseversion=0
-fail_validation=0
-
-# when not running under Jenkins, use current dir as workspace
-WORKSPACE=${WORKSPACE:-.}
-
-# 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"
-
- # If this is a golang project, use funky v-prefixed versions
- if [ -f "Gopkg.toml" ] || [ -f "go.mod" ]
- then
- echo "go-based project found, using v-prefixed version for git tags: v${NEW_VERSION}"
- TAG_VERSION=v${NEW_VERSION}
- else
- TAG_VERSION=${NEW_VERSION}
- fi
-
- elif [ -f "package.json" ]
- then
- NEW_VERSION=$(python -c 'import json,sys;obj=json.load(sys.stdin); print obj["version"]' < package.json)
- TAG_VERSION=$NEW_VERSION
- VERSIONFILE="package.json"
- elif [ -f "pom.xml" ]
- then
- NEW_VERSION=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml)
- TAG_VERSION=$NEW_VERSION
- VERSIONFILE="pom.xml"
- else
- echo "ERROR: No versioning file found!"
- exit 1
- fi
-}
-
-# check if the version is a released version
-function check_if_releaseversion {
- 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
- if [ "$SEMVER_STRICT" -eq "1" ]
- then
- echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, SEMVER_STRICT enabled, failing!"
- fail_validation=1
- else
- echo "Version string '$NEW_VERSION' in '$VERSIONFILE' is not a SemVer released version, skipping."
- fi
- fi
-}
-
-# check if the version is already a tag in git
-function is_git_tag_duplicated {
- for existing_tag in $(git tag)
- do
- if [ "$TAG_VERSION" = "$existing_tag" ]
- then
- echo "ERROR: Duplicate tag: $existing_tag"
- exit 2
- fi
- done
-}
-
-# check if Dockerfiles have a released version as their parent
-function dockerfile_parentcheck {
- while IFS= read -r -d '' dockerfile
- do
- echo "Checking dockerfile: '$dockerfile'"
-
- # split on newlines
- IFS=$'\n'
- df_parents=($(grep "^FROM" "$dockerfile"))
-
- # check all parents in the Dockerfile
- for df_parent in "${df_parents[@]}"
- do
-
- df_pattern="[FfRrOoMm] +(--platform=[^ ]+ +)?([^@: ]+)(:([^: ]+)|@sha[^ ]+)?"
- if [[ "$df_parent" =~ $df_pattern ]]
- then
-
- p_image="${BASH_REMATCH[2]}"
- p_sha=${BASH_REMATCH[3]}
- p_version="${BASH_REMATCH[4]}"
-
- echo "IMAGE: '${p_image}'"
- echo "VERSION: '$p_version'"
- echo "SHA: '$p_sha'"
-
- if [[ "${p_image}" == "scratch" ]]
- then
- echo " OK: Using the versionless 'scratch' parent: '$df_parent'"
- elif [[ "${p_image}:${p_version}" == "gcr.io/distroless/static:nonroot" ]]
- then
- echo " OK: Using static distroless image with nonroot: '${p_image}:${p_version}'"
- elif [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
- then
- echo " OK: Parent '$p_image:$p_version' is a released SemVer version"
- elif [[ "${p_sha}" =~ ^@sha256:[0-9a-f]{64}.*$ ]]
- then
- # allow sha256 hashes to be used as version specifiers
- echo " OK: Parent '$p_image$p_sha' is using a specific sha256 hash as a version"
- elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
- then
- # handle non-SemVer versions that have a Major.Minor version specifier in the name
- # 'ubuntu:16.04'
- # 'postgres:10.3-alpine'
- # 'openjdk:8-jre-alpine3.8'
- echo " OK: Parent '$p_image:$p_version' is using a non-SemVer, but sufficient, version"
- elif [[ -z "${p_version}" ]]
- then
- echo " ERROR: Parent '$p_image' is NOT using a specific version"
- fail_validation=1
- else
- echo " ERROR: Parent '$p_image:$p_version' is NOT using a specific version"
- fail_validation=1
- fi
-
- else
- echo " ERROR: Couldn't find a parent image in $df_parent"
- fi
-
- done
-
- done < <( find "${WORKSPACE}" -name 'Dockerfile*' ! -path "*/vendor/*" ! -name "*dockerignore" -print0 )
-}
-
-
-# create a git tag
-function create_git_tag {
- echo "Creating git tag: $TAG_VERSION"
- git checkout "$GERRIT_PATCHSET_REVISION"
-
- git config --global user.email "do-not-reply@opennetworking.org"
- git config --global user.name "Jenkins"
-
- git tag -a "$TAG_VERSION" -m "Tagged by CORD Jenkins version-tag job: $BUILD_NUMBER, for Gerrit patchset: $GERRIT_CHANGE_NUMBER"
-
- echo "Tags including new tag:"
- git tag -n
-
- git push origin "$TAG_VERSION"
-}
-
-echo "Checking git repo with remotes:"
-git remote -v
-
-echo "Branches:"
-git branch -v
-
-echo "Existing git tags:"
-git tag -n
-
-read_version
-check_if_releaseversion
-
-# perform checks if a released version
-if [ "$releaseversion" -eq "1" ]
-then
- is_git_tag_duplicated
- dockerfile_parentcheck
-
- if [ "$fail_validation" -eq "0" ]
- then
- create_git_tag
- else
- echo "ERROR: commit merged but failed validation, not tagging!"
- fi
-fi
-
-exit $fail_validation