Created
November 6, 2018 16:53
-
-
Save MarcosBernal/d4b7f423ce7ecd18a6597ea658edd737 to your computer and use it in GitHub Desktop.
Git Hook to check the .gitlab-ci.yml file before creating a commit (pre-commit). It sends the file to gitlab ci lint to check it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
########################### | |
# Validate .gitlab-ci.yml # | |
# by Peter Weinert # | |
########################### | |
# Modified version extracted from https://gitlab.lrz.de/snippets/234 | |
GITLAB_URL="https://gitlab.com" | |
GITLAB_API_LINT="${GITLAB_URL}/api/v4/ci/lint" | |
GITLAB_WEB_LINT="${GITLAB_URL}/ci/lint" | |
ANSI_RED="\e[31m" | |
ANSI_YELLOW="\e[33m" | |
ANSI_LIGHT="\e[1m" | |
ANSI_OFF="\e[0m" | |
# Check if .gitlab-ci.yml is added or modified in index | |
CI_CHANGED=`git diff-index --name-only HEAD | grep '.gitlab-ci.yml$'` | |
if [ ! -z "$CI_CHANGED" ] | |
then | |
# checkout from index to a temporary file named $temp_file | |
temp_file_assoc=$(git checkout-index --temp -- .gitlab-ci.yml) | |
set -f # Disable file name generation (globbing) | |
temp_file=($temp_file_assoc) | |
set +f | |
temp_file=${temp_file[0]} | |
trap "rm -f $temp_file" EXIT INT TERM # Remove file if the program exit receiva a kill or term signal | |
# Sanitize: read the whole file in a loop (:a;N;$!ba), see https://stackoverflow.com/questions/1251999/how-can-i-replace-a-newline-n-using-sed | |
# and escape special json characters (\ \f \n \r \t / ") with a backslash. | |
SANE_CONTENT="$( cat "$temp_file" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\\/\\\\/g' -e 's/\f/\\f/g' -e 's/\n/\\n/g' -e 's/\r/\\r/g' -e 's/\t/\\t/g' -e 's/\//\\\//g' -e 's/"/\\"/g' )" | |
# Pack YAML in JSON | |
JSON="{\"content\": \"${SANE_CONTENT}\"}" | |
# Use Lint - if timeout is reached the validation will succeed nevertheless | |
ANSWER=`curl -s --connect-timeout 2 --max-time 4 --header "Content-Type: application/json" ${GITLAB_API_LINT} --data "$JSON"` | |
ERROR_CODE=$? | |
if [[ "$ERROR_CODE" != "0" ]]; then | |
echo -e "${ANSI_LIGHT}${ANSI_YELLOW}WARNING: .gitlab-ci.yml not validated!${ANSI_OFF} Curl failed with error code ${ANSI_LIGHT}${ANSI_RED}${ERROR_CODE}${ANSI_OFF}" >&2 | |
else | |
if [[ $ANSWER =~ "invalid" ]]; then | |
echo -e "${ANSI_LIGHT}${ANSI_RED}ERROR: Invalid .gitlab-ci.yml.${ANSI_OFF} Lint reports ${ANSWER}." >&2 | |
echo -e "Use your Gitlab Lint (${GITLAB_WEB_LINT}) for more information." >&2 | |
echo -e "Aborting commit." >&2 | |
exit 1 | |
elif [[ ! $ANSWER =~ "valid" ]]; then | |
echo -e "${ANSI_LIGHT}${ANSI_YELLOW}WARNING: No regular answer received.${ANSI_OFF} Lint reports '${ANSWER}'." >&2 | |
echo -e "This is most likely a bug in the JSON to YAML converter section of this script." >&2 | |
echo -e "Please report includung the exact .gitlab-ci.yml." >&2 | |
echo -e "Data send was (backslashes escaped) $( echo "$JSON" | sed -e 's/\\/\\\\/g' )" >&2 | |
# else | |
# echo -e "File .gitlab-ci.yml is valid." | |
fi | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It will only generate an output in case of an error arises. Uncomment lines 55 and 56 to get feedback when it passes the validation.