Skip to content

Instantly share code, notes, and snippets.

@tlawrie
Last active May 30, 2020 09:31
Show Gist options
  • Save tlawrie/52b82ed88c0ccf733093171bd6c47734 to your computer and use it in GitHub Desktop.
Save tlawrie/52b82ed88c0ccf733093171bd6c47734 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Relies on github API: https://developer.github.com/v3/repos/releases
# You can call this script with the following command
# ./helm-validate-and-publish.sh '<helm_url>' '<git_token>' '<git_owner>' '<github_repository>' '<git_commit_id>' '<index_branch>'
# Requires Helm v2 to already be installed
#############
# Inputs #
#############
HELM_REPO_URL=$1
HELM_REPO_TOKEN=$2
GIT_OWNER=$3
GIT_REPO=$4
GIT_COMMIT_ID=$5
HELM_INDEX_BRANCH=$6
if [ "$HELM_INDEX_BRANCH" == "" ]; then
HELM_INDEX_BRANCH="index"
fi
GIT_API_URL=https://api.github.com
CHART_STABLE_DIR=/data/charts/stable
CHART_CURRENT_DIR=/data/charts/current
CHART_INDEX_DIR=/data/charts/index
HELM_RESOURCE_PATH=/tmp/.helm
#############
# Functions #
#############
function github_release() {
echo "Name: $1"
echo "File Path: $2"
URL=${GIT_API_URL}/repos/${GIT_OWNER}/${GIT_REPO}/releases
echo "Release URL: $URL"
OUTPUT=`curl -fs -H "Authorization: token $HELM_REPO_TOKEN" -X POST $URL \
-d "
{
\"tag_name\": \"$1\",
\"target_commitish\": \"$GIT_COMMIT_ID\",
\"name\": \"$1\",
\"body\": \":robot: automated release\",
\"draft\": false,
\"prerelease\": false
}"`
if [[ $? -eq 0 ]]; then
echo "Release created for $1"
else
echo "Error creating release for $1. Checking if release already exists..."
OUTPUT=`curl -fs -H "Authorization: token $HELM_REPO_TOKEN" -X GET $URL/tags/$1`
if [[ $? -ne 0 ]]; then
echo "Error: Unable to create release and no release already exists."
exit 1
fi
fi
UPLOAD_URL=`echo $OUTPUT | jq .upload_url`
echo "Upload URL: $UPLOAD_URL"
UPLOAD_URL_REPLACER="?name=$1.tgz"
UPLOAD_URL_REPLACED=`echo ${UPLOAD_URL/\{?name,label\}/$UPLOAD_URL_REPLACER} | tr -d '"'`
echo "Updated Upload URL: $UPLOAD_URL_REPLACED"
OUTPUT2=`curl -fs -H "Authorization: token $HELM_REPO_TOKEN" -X POST -H "Content-Type: application/octet-stream" "$UPLOAD_URL_REPLACED" --upload-file "$2"`
if [[ $? -eq 0 ]]; then
echo "Chart ($1) uploaded to release"
else
echo "Error uploading chart to release ($1)"
echo $OUTPUT2
return
fi
}
function github_upload_index() {
URL=${GIT_API_URL}/repos/${GIT_OWNER}/${GIT_REPO}/contents/index.yaml
echo "Index URL: $URL"
OUTPUT=`curl -fs -H "Authorization: token $HELM_REPO_TOKEN" -X GET $URL?ref=${HELM_INDEX_BRANCH}`
if [[ $? -eq 0 ]]; then
echo "Retrieved current index.yaml"
else
echo "Error getting current index file or does not exist"
fi
SHA=`echo $OUTPUT | jq .sha | tr -d '"'`
echo "Index SHA: $SHA"
echo "Index Branch: $HELM_INDEX_BRANCH"
# this must use the openssl base64 to ensure its all on one consistent line
# Otherwise you will get a 400 bad request fro GitHub
curl -fs -H "Authorization: token $HELM_REPO_TOKEN" -X PUT $URL \
-d "
{
\"sha\": \"$SHA\",
\"message\": \":robot: automated helm repo index update\",
\"content\": \"$(openssl base64 -A -in index.yaml)\",
\"branch\": \"$HELM_INDEX_BRANCH\"
}"
if [[ $? -eq 0 ]]; then
echo "Updated index.yaml"
else
echo "Error uploading chart repo index"
exit 1
fi
}
#############
# Main #
#############
mkdir -p $CHART_CURRENT_DIR
mkdir -p $CHART_INDEX_DIR
helm repo add charts $HELM_REPO_URL --home $HELM_RESOURCE_PATH
# Validate charts have correct version
for CHART_PACKAGE in `ls -1 $CHART_STABLE_DIR/*tgz | rev | cut -f1 -d/ | rev`
do
echo "Found: $CHART_PACKAGE"
# Attempt to pull down chart package from Artifactory
CHART_NAME=`echo $CHART_PACKAGE | sed 's/\(.*\)-.*/\1/'`
CHART_VERSION=`echo $CHART_PACKAGE | rev | sed '/\..*\./s/^[^.]*\.//' | cut -d '-' -f 1 | rev`
helm fetch --home $HELM_RESOURCE_PATH --version $CHART_VERSION --destination $CHART_CURRENT_DIR charts/$CHART_NAME
if [ -f $CHART_CURRENT_DIR/$CHART_PACKAGE ]; then
# If there is an existing file, a check will be made to see if the content of the old tar and new tar are the exact same.
# The digest and sha of the tar are not trustworthy when containing tgz files.
# The code below will sort the list of files in the tgz, then decompress each file to stdout, passing the content thru sha1sum.
# This will produce an order sha sum of the tgz content.
# Note: on mac replace sha1sum with shasum
ls -al $CHART_STABLE_DIR/$CHART_PACKAGE
ls -al $CHART_CURRENT_DIR/$CHART_PACKAGE
if [[ `tar tvf $CHART_STABLE_DIR/$CHART_PACKAGE | rev | cut -f1 -d' ' | rev | sort -k1 | xargs -i tar -xOf $CHART_STABLE_DIR/$CHART_PACKAGE {} | sha1sum | cut -f1 -d' '` = \
`tar tvf $CHART_CURRENT_DIR/$CHART_PACKAGE | rev | cut -f1 -d' ' | rev | sort -k1 | xargs -i tar -xOf $CHART_CURRENT_DIR/$CHART_PACKAGE {} | sha1sum | cut -f1 -d' '` ]] ; then
# These files are the same, and can be ignored
echo " ⌁ Warning: Previously shipped file."
rm -f $CHART_CURRENT_DIR/$CHART_PACKAGE
elif [[ `tar tvf $CHART_STABLE_DIR/$CHART_PACKAGE | rev | cut -f1 -d' ' | rev | sort -k1 | grep -Ev '/charts/|requirements.lock' | xargs -i tar -xOf $CHART_STABLE_DIR/$CHART_PACKAGE {} | sha1sum | cut -f1 -d' '` = \
`tar tvf $CHART_CURRENT_DIR/$CHART_PACKAGE | rev | cut -f1 -d' ' | rev | sort -k1 | grep -Ev '/charts/|requirements.lock' | xargs -i tar -xOf $CHART_CURRENT_DIR/$CHART_PACKAGE {} | sha1sum | cut -f1 -d' '` ]] ; then
echo " ⌁ Warning: Previously shipped version, with acceptable source change due to subchart version difference."
rm -f $CHART_CURRENT_DIR/$CHART_PACKAGE
else
# These files differ, but do not have a version number update
echo " ✗ Error: Same version but different content"
exit 1
fi
else
echo " ↣ New chart version validated."
cp $CHART_STABLE_DIR/$CHART_PACKAGE $CHART_CURRENT_DIR
fi
done
# Release / Upload the packages
for filename in `ls -1 $CHART_CURRENT_DIR/*tgz | rev | cut -f1 -d/ | rev`
do
if [ -f $CHART_CURRENT_DIR/$filename ]; then
echo " ✓ Pushing chart package: $filename"
RELEASE_NAME=`echo $filename | sed -r 's@^(.*)(\.tgz)$@\1@g'`
github_release $RELEASE_NAME $CHART_CURRENT_DIR/$filename
cp $CHART_CURRENT_DIR/$filename $CHART_INDEX_DIR/$filename
helm repo index --home $HELM_RESOURCE_PATH --merge index.yaml --url https://github.com/${GIT_OWNER}/${GIT_REPO}/releases/download/${RELEASE_NAME} $CHART_INDEX_DIR
mv $CHART_INDEX_DIR/index.yaml index.yaml
rm $CHART_INDEX_DIR/$filename
fi
done
# Index Charts
github_upload_index
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment