[SEBA-230]
add chart_version_check.sh verification script
improve failure messages in helmlint.sh
improve helmrepo.sh script to update index properly
Change-Id: I69e31a8671e9962252f2ef9a6b900bfe5df282a2
diff --git a/chart_version_check.sh b/chart_version_check.sh
new file mode 100755
index 0000000..cca7874
--- /dev/null
+++ b/chart_version_check.sh
@@ -0,0 +1,134 @@
+#!/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.
+
+# chart_version_check.sh
+# checks that changes to a chart include a change to the chart version
+
+set -u
+
+echo "# chart_version_check.sh, using git: $(git --version) #"
+
+# Collect success/failure, and list/types of failures
+fail_version=0
+failed_charts=""
+
+# when not running under Jenkins, use current dir as workspace
+WORKSPACE=${WORKSPACE:-.}
+
+# branch to compare against, defaults to master
+GERRIT_BRANCH=${GERRIT_BRANCH:-opencord/master}
+
+# Create list of changed files compared to branch
+changed_files=$(git diff --name-only "${GERRIT_BRANCH}")
+
+# Create list of untracked by git files
+untracked_files=$(git ls-files -o --exclude-standard)
+
+# Print lists of files that are changed/untracked
+if [ -z "$changed_files" ] && [ -z "$untracked_files" ]
+then
+ echo "# chart_version_check.sh - No changes, Success! #"
+ exit 0
+else
+ if [ -n "$changed_files" ]
+ then
+ echo "Changed files compared with $GERRIT_BRANCH:"
+ # Search and replace per SC2001 doesn't recognize ^ (beginning of line)
+ # shellcheck disable=SC2001
+ echo "${changed_files}" | sed 's/^/ /'
+ fi
+ if [ -n "$untracked_files" ]
+ then
+ echo "Untracked files:"
+ # shellcheck disable=SC2001
+ echo "${untracked_files}" | sed 's/^/ /'
+ fi
+fi
+
+# combine lists
+if [ -n "$changed_files" ]
+then
+ if [ -n "$untracked_files" ]
+ then
+ changed_files+=$'\n'
+ changed_files+="${untracked_files}"
+ fi
+else
+ changed_files="${untracked_files}"
+fi
+
+# For all the charts, fail on changes within a chart without a version change
+# loop on result of 'find -name Chart.yaml'
+while IFS= read -r -d '' chart
+do
+ chartdir=$(dirname "${chart#./}")
+ chart_changed_files=""
+ version_updated=0
+
+ # create a list of files that were changed in the chart
+ for file in $changed_files; do
+ if [[ $file =~ $chartdir ]]
+ then
+ chart_changed_files+=$'\n'
+ chart_changed_files+=" ${file}"
+ fi
+ done
+
+ # See if chart version changed using 'git diff', and is SemVer
+ chart_yaml_diff=$(git diff -p "$GERRIT_BRANCH" "${chartdir}/Chart.yaml")
+
+ if [ -n "$chart_yaml_diff" ]
+ then
+ echo "Changes to Chart.yaml in '$chartdir'"
+ old_version_string=$(echo "$chart_yaml_diff" | grep -E '\-version:\s*\d+\.\d+\.\d+$')
+ new_version_string=$(echo "$chart_yaml_diff" | grep -E '\+version:\s*\d+\.\d+\.\d+$')
+
+ if [ -n "$new_version_string" ]
+ then
+ version_updated=1
+ echo " Old version string:${old_version_string//-version:/}"
+ echo " New version string:${new_version_string//+version:/}"
+ fi
+ fi
+
+ # if there are any changed files
+ if [ -n "$chart_changed_files" ]
+ then
+ # and version updated, print changed files
+ if [ $version_updated -eq 1 ]
+ then
+ echo " Files changed:${chart_changed_files}"
+ else
+ # otherwise fail this chart
+ echo "Changes to chart but no version update in '$chartdir':${chart_changed_files}"
+ fail_version=1
+ failed_charts+=$'\n'
+ failed_charts+=" $chartdir"
+ fi
+ fi
+
+done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
+
+if [[ $fail_version != 0 ]]; then
+ echo "# chart_version_check.sh Failure! #"
+ echo "Charts that need to be fixed:$failed_charts"
+ exit 1
+fi
+
+echo "# chart_version_check.sh Success! - all charts have updated versions #"
+
+exit 0
+
diff --git a/helmlint.sh b/helmlint.sh
index aabdca0..c068c28 100755
--- a/helmlint.sh
+++ b/helmlint.sh
@@ -22,9 +22,12 @@
# verify that we have helm installed
command -v helm >/dev/null 2>&1 || { echo "helm not found, please install it" >&2; exit 1; }
-echo "helmlint.sh, using helm version: $(helm version -c --short)"
+echo "# helmlint.sh, using helm version: $(helm version -c --short) #"
+# Collect success/failure, and list/types of failures
fail_lint=0
+failed_lint=""
+failed_req=""
# when not running under Jenkins, use current dir as workspace
WORKSPACE=${WORKSPACE:-.}
@@ -32,21 +35,27 @@
# cleanup repos if `clean` option passed as parameter
if [ "$1" = "clean" ]
then
- echo "Removing dependent charts"
- find "${WORKSPACE}" -name 'charts' -exec rm -rf {} \;
+ echo "Removing any downloaded charts"
+ find "${WORKSPACE}" -type d -name 'charts' -exec rm -rf {} \;
fi
+# now that $1 is checked, error on undefined vars
+set -u
+
+# loop on result of 'find -name Chart.yaml'
while IFS= read -r -d '' chart
do
chartdir=$(dirname "${chart}")
- # only update dependencies for profiles
+ echo "Checking chart: $chartdir"
+
+ # update dependencies for profiles/workflows, as they include TOSCA from required charts
if [[ $chartdir =~ xos-profiles || $chartdir =~ workflows ]] && [ -f "${chartdir}/requirements.yaml" ]
then
helm dependency update "${chartdir}"
fi
- # lint with values.yaml if it exists
+ # lint the chart (with values.yaml if it exists)
if [ -f "${chartdir}/values.yaml" ]; then
helm lint --strict --values "${chartdir}/values.yaml" "${chartdir}"
else
@@ -56,11 +65,34 @@
rc=$?
if [[ $rc != 0 ]]; then
fail_lint=1
+ failed_lint+="${chartdir} "
fi
+
+ # check that requirements are available if they're specified
+ if [ -f "${chartdir}/requirements.yaml" ]
+ then
+ echo "Chart has requirements.yaml, checking availability"
+ helm dependency update "${chartdir}"
+ rc=$?
+ if [[ $rc != 0 ]]; then
+ fail_lint=1
+ failed_req+="${chartdir} "
+ fi
+
+ # remove charts dir after checking for availability, as this chart might be
+ # required by other charts in the next loop
+ rm -rf "${chartdir}/charts"
+ fi
+
done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
if [[ $fail_lint != 0 ]]; then
+ echo "# helmlint.sh Failure! #"
+ echo "Charts that failed to lint: $failed_lint"
+ echo "Charts with failures in requirements.yaml: $failed_req"
exit 1
fi
+echo "# helmlint.sh Success! - all charts linted and have valid requirements.yaml #"
+
exit 0
diff --git a/helmrepo.sh b/helmrepo.sh
index 3c94aa0..fd59ca6 100755
--- a/helmrepo.sh
+++ b/helmrepo.sh
@@ -15,37 +15,91 @@
# limitations under the License.
# helmrepo.sh
-# creates a helm repo for publishing on guide website
+# creates or updates a helm repo for publishing on the guide website
+# Reference: https://github.com/helm/charts/blob/master/test/repo-sync.sh
set -eu -o pipefail
+echo "# helmrepo.sh, using helm: $(helm version -c) #"
+
# when not running under Jenkins, use current dir as workspace
WORKSPACE=${WORKSPACE:-.}
-REPO_DIR="${REPO_DIR:-chart_repo}"
+# branch to compare against, defaults to master
+GERRIT_BRANCH=${GERRIT_BRANCH:-opencord/master}
+
+# directory to compare against, doesn't need to be present
+OLD_REPO_DIR="${OLD_REPO_DIR:-cord-charts-repo}"
+NEW_REPO_DIR="${NEW_REPO_DIR:-chart_repo}"
GERRIT_BRANCH="${GERRIT_BRANCH:-$(git symbolic-ref --short HEAD)}"
PUBLISH_URL="${PUBLISH_URL:-charts.opencord.org}"
-ORIGINAL_INDEX_YAML="${ORIGINAL_INDEX_YAML:-/var/www/charts/index.yaml}"
+# create and clean NEW_REPO_DIR
+mkdir -p "${NEW_REPO_DIR}"
+rm -f "${NEW_REPO_DIR}"/*
-mkdir -p "${REPO_DIR}"
+# if OLD_REPO_DIR doesn't exist, generate packages and index in NEW_REPO_DIR
+if [ ! -d "${OLD_REPO_DIR}" ]
+then
+ echo "Creating new helm repo: ${NEW_REPO_DIR}"
-while IFS= read -r -d '' chart
-do
- chartdir=$(dirname "${chart}")
+ while IFS= read -r -d '' chart
+ do
+ chartdir=$(dirname "${chart#./}")
+ helm package --dependency-update --destination "${NEW_REPO_DIR}" "${chartdir}"
- echo "Adding ${chartdir}"
+ done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
- helm package --dependency-update --destination "${REPO_DIR}" "${chartdir}"
+ helm repo index "${NEW_REPO_DIR}" --url https://"${PUBLISH_URL}"
+ echo "# helmrepo.sh Success! Generated new repo index in ${NEW_REPO_DIR}"
-done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
+else
+ # OLD_REPO_DIR exists, check for new charts and update only with changes
+ echo "Found existing helm repo: ${OLD_REPO_DIR}, attempting update"
-echo "Generating repo index"
+ # Loop and create chart packages, only if changed
+ while IFS= read -r -d '' chart
+ do
+ chartdir=$(dirname "${chart#./}")
-scp -o StrictHostKeyChecking=no "${PUBLISH_URL}":"${ORIGINAL_INDEX_YAML}" .
+ # See if chart version changed from previous HEAD commit
+ chart_yaml_diff=$(git diff -p HEAD^ "${chartdir}/Chart.yaml")
-helm repo index "${REPO_DIR}" --url https://"${PUBLISH_URL}" --merge index.yaml
+ if [ -n "$chart_yaml_diff" ]
+ then
+ # assumes that helmlint.sh and chart_version_check.sh have been run
+ # pre-merge, which ensures that all charts are valid and have their
+ # version updated in Chart.yaml
+ new_version_string=$(echo "$chart_yaml_diff" | grep -E '\+version:\s*\d+\.\d+\.\d+$')
+ echo "New version of chart ${chartdir}, creating package: ${new_version_string//+version:/}"
+ helm package --dependency-update --destination "${NEW_REPO_DIR}" "${chartdir}"
+ else
+ echo "Chart unchanged, not packaging: '${chartdir}'"
+ fi
-echo "Finished, chart repo generated: ${REPO_DIR}"
+ done < <(find "${WORKSPACE}" -name Chart.yaml -print0)
+ # Check for collisions between old/new packages
+ while IFS= read -r -d '' package_path
+ do
+ package=$(basename "${package_path}")
+
+ if [ -f "${OLD_REPO_DIR}/${package}" ]
+ then
+ echo "# helmrepo.sh Failure! Package: ${package} with same version already exists in ${OLD_REPO_DIR}"
+ exit 1
+ fi
+ done < <(find "${NEW_REPO_DIR}" -name '*.tgz' -print0)
+
+ # Create updated index.yaml (new version created in NEW_REPO_DIR)
+ helm repo index --url "https://${PUBLISH_URL}" --merge "${OLD_REPO_DIR}/index.yaml" "${NEW_REPO_DIR}"
+
+ # move over packages and index.yaml
+ mv "${NEW_REPO_DIR}"/*.tgz "${OLD_REPO_DIR}/"
+ mv "${NEW_REPO_DIR}/index.yaml" "${OLD_REPO_DIR}/index.yaml"
+
+ echo "# helmrepo.sh Success! Updated existing repo index in ${OLD_REPO_DIR}"
+fi
+
+exit 0