feat: enable shell error checks (#5126)

Enable error checks to:

- Exit on errors
- Disallow empty variables
- Fail when a piped command errors
This commit is contained in:
Marco Ferrari 2024-02-20 20:05:39 +01:00 committed by GitHub
parent 079f676511
commit 0967cd29d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 99 additions and 164 deletions

View file

@ -199,8 +199,8 @@ You can configure super-linter using the following environment variables:
| **DOCKERFILE_HADOLINT_FILE_NAME** | `.hadolint.yaml` | Filename for [hadolint configuration](https://github.com/hadolint/hadolint) (ex: `.hadolintlintrc.yaml`) |
| **EDITORCONFIG_FILE_NAME** | `.ecrc` | Filename for [editorconfig-checker configuration](https://github.com/editorconfig-checker/editorconfig-checker) |
| **ENABLE_GITHUB_ACTIONS_GROUP_TITLE** | `false` if `RUN_LOCAL=true`, `true` otherwise | Flag to enable [GitHub Actions log grouping](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines). |
| **FILTER_REGEX_EXCLUDE** | `none` | Regular expression defining which files will be excluded from linting (ex: `.*src/test.*`) |
| **FILTER_REGEX_INCLUDE** | `all` | Regular expression defining which files will be processed by linters (ex: `.*src/.*`) |
| **FILTER_REGEX_EXCLUDE** | not set | Regular expression defining which files will be excluded from linting (ex: `.*src/test.*`). Not setting this variable means to process all files. |
| **FILTER_REGEX_INCLUDE** | not set | Regular expression defining which files will be processed by linters (ex: `.*src/.*`). Not setting this variable means to process all files. `FILTER_REGEX_INCLUDE` is evaluated before `FILTER_REGEX_EXCLUDE`. |
| **GITHUB_ACTIONS_CONFIG_FILE** | `actionlint.yml` | Filename for [Actionlint configuration](https://github.com/rhysd/actionlint/blob/main/docs/config.md) (ex: `actionlint.yml`) |
| **GITHUB_ACTIONS_COMMAND_ARGS** | `null` | Additional arguments passed to `actionlint` command. Useful to [ignore some errors](https://github.com/rhysd/actionlint/blob/main/docs/usage.md#ignore-some-errors) |
| **GITHUB_CUSTOM_API_URL** | `https://api.${GITHUB_DOMAIN}` | Specify a custom GitHub API URL in case GitHub Enterprise is used: e.g. `https://github.myenterprise.com/api/v3` |

View file

@ -10,10 +10,12 @@ function IssueHintForFullGitHistory() {
}
function GenerateFileDiff() {
local DIFF_GIT_DEFAULT_BRANCH_CMD
DIFF_GIT_DEFAULT_BRANCH_CMD="git -C \"${GITHUB_WORKSPACE}\" diff --diff-filter=d --name-only ${DEFAULT_BRANCH}...${GITHUB_SHA} | xargs -I % sh -c 'echo \"${GITHUB_WORKSPACE}/%\"' 2>&1"
DIFF_TREE_CMD="git -C \"${GITHUB_WORKSPACE}\" diff-tree --no-commit-id --name-only -r ${GITHUB_SHA} ${GITHUB_BEFORE_SHA} | xargs -I % sh -c 'echo \"${GITHUB_WORKSPACE}/%\"' 2>&1"
if [ "${GITHUB_EVENT_NAME:-}" == "push" ]; then
local DIFF_TREE_CMD
DIFF_TREE_CMD="git -C \"${GITHUB_WORKSPACE}\" diff-tree --no-commit-id --name-only -r ${GITHUB_SHA} ${GITHUB_BEFORE_SHA} | xargs -I % sh -c 'echo \"${GITHUB_WORKSPACE}/%\"' 2>&1"
RunFileDiffCommand "${DIFF_TREE_CMD}"
if [ ${#RAW_FILE_ARRAY[@]} -eq 0 ]; then
debug "Generating the file array with diff-tree produced [0] items, trying with git diff against the default branch..."

View file

@ -278,38 +278,21 @@ function RunAdditionalInstalls() {
##################################
if [ "${VALIDATE_PHP_PSALM}" == "true" ] && [ -e "${FILE_ARRAYS_DIRECTORY_PATH}/file-array-PHP_PSALM" ]; then
# found PHP files and were validating it, need to composer install
info "Found PHP files to validate, and [VALIDATE_PHP_PSALM] set to true, need to run composer install"
info "looking for composer.json in the users repository..."
mapfile -t COMPOSER_FILE_ARRAY < <(find / -name composer.json 2>&1)
debug "COMPOSER_FILE_ARRAY contents:[${COMPOSER_FILE_ARRAY[*]}]"
############################################
# Check if we found the file in the system #
############################################
info "Found PHP files to validate, and VALIDATE_PHP_PSALM is set to ${VALIDATE_PHP_PSALM}. Check if we need to run composer install"
mapfile -t COMPOSER_FILE_ARRAY < <(find "${GITHUB_WORKSPACE}" -name composer.json 2>&1)
debug "COMPOSER_FILE_ARRAY contents: ${COMPOSER_FILE_ARRAY[*]}"
if [ "${#COMPOSER_FILE_ARRAY[@]}" -ne 0 ]; then
for LINE in "${COMPOSER_FILE_ARRAY[@]}"; do
local COMPOSER_PATH
COMPOSER_PATH=$(dirname "${LINE}" 2>&1)
info "Found [composer.json] at:[${LINE}]"
COMPOSER_CMD=$(
cd "${COMPOSER_PATH}" || exit 1
composer install --no-progress -q 2>&1
)
##############
# Error code #
##############
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ "${ERROR_CODE}" -ne 0 ]; then
# Error
error "ERROR! Failed to run composer install at location:[${COMPOSER_PATH}]"
fatal "ERROR:[${COMPOSER_CMD}]"
info "Found Composer file: ${LINE}"
local COMPOSER_CMD
if ! COMPOSER_CMD=$(cd "${COMPOSER_PATH}" && composer install --no-progress -q 2>&1); then
fatal "Failed to run composer install for ${COMPOSER_PATH}. Output: ${COMPOSER_CMD}"
else
# Success
info "Successfully ran:[composer install] for PHP validation"
info "Successfully ran composer install."
fi
debug "Composer install output: ${COMPOSER_CMD}"
done
fi
fi
@ -326,50 +309,21 @@ function RunAdditionalInstalls() {
###############################
if [ "${VALIDATE_R}" == "true" ] && [ -e "${FILE_ARRAYS_DIRECTORY_PATH}/file-array-R" ]; then
info "Detected R Language files to lint."
info "Trying to install the R package inside:[${GITHUB_WORKSPACE}]"
#########################
# Run the build command #
#########################
BUILD_CMD=$(R CMD build "${GITHUB_WORKSPACE}" 2>&1)
##############
# Error code #
##############
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ "${ERROR_CODE}" -ne 0 ]; then
# Error
warn "ERROR! Failed to run:[R CMD build] at location:[${GITHUB_WORKSPACE}]"
warn "BUILD_CMD:[${BUILD_CMD}]"
info "Installing the R package in: ${GITHUB_WORKSPACE}"
local BUILD_CMD
if ! BUILD_CMD=$(R CMD build "${GITHUB_WORKSPACE}" 2>&1); then
warn "Failed to build R package in ${GITHUB_WORKSPACE}. Output: ${BUILD_CMD}"
else
# Get the build package
BUILD_PKG=$(
cd "${GITHUB_WORKSPACE}" || exit 0
echo *.tar.gz 2>&1
)
##############################
# Install the build packages #
##############################
INSTALL_CMD=$(
cd "${GITHUB_WORKSPACE}" || exit 0
R -e "remotes::install_local('.', dependencies=T)" 2>&1
)
##############
# Error code #
##############
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
debug "INSTALL_CMD:[${INSTALL_CMD}]"
if [ "${ERROR_CODE}" -ne 0 ]; then
warn "ERROR: Failed to install the build package at:[${BUILD_PKG}]"
local BUILD_PKG
if ! BUILD_PKG=$(cd "${GITHUB_WORKSPACE}" && echo *.tar.gz 2>&1); then
warn "Failed to echo R archives. Output: ${BUILD_PKG}"
fi
debug "echo R archives output: ${BUILD_PKG}"
local INSTALL_CMD
if ! INSTALL_CMD=$(cd "${GITHUB_WORKSPACE}" && R -e "remotes::install_local('.', dependencies=T)" 2>&1); then
warn "Failed to install the R package. Output: ${BUILD_PKG}]"
fi
debug "R package install output: ${INSTALL_CMD}"
fi
if [ ! -f "${R_RULES_FILE_PATH_IN_ROOT}" ]; then
@ -385,24 +339,9 @@ function RunAdditionalInstalls() {
####################################
if [ "${VALIDATE_TERRAFORM_TFLINT}" == "true" ] && [ -e "${FILE_ARRAYS_DIRECTORY_PATH}/file-array-TERRAFORM_TFLINT" ]; then
info "Detected TFLint Language files to lint."
info "Trying to install the TFLint init inside:[${GITHUB_WORKSPACE}]"
#########################
# Run the build command #
#########################
BUILD_CMD=$(
cd "${GITHUB_WORKSPACE}" || exit 0
tflint --init -c "${TERRAFORM_TFLINT_LINTER_RULES}" 2>&1
)
##############
# Error code #
##############
ERROR_CODE=$?
##############################
# Check the shell for errors #
##############################
if [ "${ERROR_CODE}" -ne 0 ]; then
info "Initializing TFLint in ${GITHUB_WORKSPACE}"
local BUILD_CMD
if ! BUILD_CMD=$(cd "${GITHUB_WORKSPACE}" && tflint --init -c "${TERRAFORM_TFLINT_LINTER_RULES}" 2>&1); then
fatal "ERROR! Failed to initialize tflint with the ${TERRAFORM_TFLINT_LINTER_RULES} config file: ${BUILD_CMD}"
else
info "Successfully initialized tflint with the ${TERRAFORM_TFLINT_LINTER_RULES} config file"

View file

@ -95,6 +95,8 @@ fatal() {
exit 1
}
debug "LOG_LEVEL is set to: ${LOG_LEVEL}"
# shellcheck disable=SC2034 # Variable is referenced in other files
SUPER_LINTER_INITIALIZATION_LOG_GROUP_TITLE="Super-Linter initialization"
export SUPER_LINTER_INITIALIZATION_LOG_GROUP_TITLE

View file

@ -2,7 +2,7 @@
function SetupSshAgent() {
# Check to see if a SSH_KEY_SECRET was passed
if [ -n "${SSH_KEY}" ]; then
if [ -n "${SSH_KEY:-}" ]; then
info "--------------------------------------------"
info "SSH key found, setting up agent..."
export SSH_AUTH_SOCK=/tmp/ssh_agent.sock
@ -30,7 +30,7 @@ function GetGitHubSshRsaKeyFingerprint() {
export -f GetGitHubSshRsaKeyFingerprint
function SetupGithubComSshKeys() {
if [[ -n "${SSH_KEY}" || "${SSH_SETUP_GITHUB}" == "true" ]]; then
if [[ -n "${SSH_KEY:-}" || "${SSH_SETUP_GITHUB}" == "true" ]]; then
info "Adding ${GITHUB_DOMAIN} SSH keys"
# Fetched out of band from
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
function CheckSSLCert() {
if [ -z "${SSL_CERT_SECRET}" ]; then
if [ -z "${SSL_CERT_SECRET:-}" ]; then
# No cert was passed
debug "User did not provide a SSL_CERT_SECRET"
else

View file

@ -51,7 +51,7 @@ function GetValidationInfo() {
local VALIDATE_LANGUAGE
VALIDATE_LANGUAGE="VALIDATE_${LANGUAGE}"
debug "Set VALIDATE_LANGUAGE while validating the configuration: ${VALIDATE_LANGUAGE}"
if [ -n "${!VALIDATE_LANGUAGE}" ]; then
if [ -n "${!VALIDATE_LANGUAGE:-}" ]; then
# Validate if user provided a string representing a valid boolean
ValidateBooleanVariable "${VALIDATE_LANGUAGE}" "${!VALIDATE_LANGUAGE}"
# It was set, need to set flag
@ -77,7 +77,7 @@ function GetValidationInfo() {
local VALIDATE_LANGUAGE
VALIDATE_LANGUAGE="VALIDATE_${LANGUAGE}"
if [[ ${ANY_SET} == "true" ]]; then
if [ -z "${!VALIDATE_LANGUAGE}" ]; then
if [ -z "${!VALIDATE_LANGUAGE:-}" ]; then
# Flag was not set, default to:
# if ANY_TRUE then set to false
# if ANY_FALSE then set to true
@ -107,7 +107,7 @@ function GetValidationInfo() {
##############################
# Validate Ansible Directory #
##############################
if [ -z "${ANSIBLE_DIRECTORY}" ]; then
if [ -z "${ANSIBLE_DIRECTORY:-}" ]; then
ANSIBLE_DIRECTORY="${GITHUB_WORKSPACE}/ansible"
debug "Set ANSIBLE_DIRECTORY to the default: ${ANSIBLE_DIRECTORY}"
else

View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
##################################################################
# Debug Vars #
# Define these early, so we can use debug logging ASAP if needed #
@ -48,8 +52,6 @@ export LOG_WARN
LOG_ERROR=$(if [[ ${LOG_LEVEL} == "ERROR" || ${LOG_LEVEL} == "WARN" || ${LOG_LEVEL} == "NOTICE" || ${LOG_LEVEL} == "INFO" || ${LOG_LEVEL} == "VERBOSE" || ${LOG_LEVEL} == "DEBUG" || ${LOG_LEVEL} == "TRACE" ]]; then echo "true"; fi)
export LOG_ERROR
unset LOG_LEVEL
#########################
# Source Function Files #
#########################
@ -170,7 +172,7 @@ TEST_CASE_FOLDER='test/linters' # Folder for test cases we should always ignore
# Set the log level
TF_LOG_LEVEL="info"
if [ "${ACTIONS_RUNNER_DEBUG}" = "true" ]; then
if [[ "${LOG_DEBUG}" == "true" ]]; then
TF_LOG_LEVEL="debug"
fi
export TF_LOG_LEVEL
@ -186,6 +188,7 @@ debug "TFLINT_LOG: ${TFLINT_LOG}"
ANSIBLE_FILE_NAME="${ANSIBLE_CONFIG_FILE:-.ansible-lint.yml}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
ARM_FILE_NAME=".arm-ttk.psd1"
BASH_SEVERITY="${BASH_SEVERITY:-""}"
CHECKOV_FILE_NAME="${CHECKOV_FILE_NAME:-".checkov.yaml"}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
CLOJURE_FILE_NAME=".clj-kondo/config.edn"
@ -229,6 +232,7 @@ KUBERNETES_KUBECONFORM_OPTIONS="${KUBERNETES_KUBECONFORM_OPTIONS:-null}"
LATEX_FILE_NAME=".chktexrc"
# shellcheck disable=SC2034 # Variable is referenced indirectly
LUA_FILE_NAME=".luacheckrc"
MARKDOWN_CUSTOM_RULE_GLOBS="${MARKDOWN_CUSTOM_RULE_GLOBS:-""}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
MARKDOWN_FILE_NAME="${MARKDOWN_CONFIG_FILE:-.markdown-lint.yml}"
# shellcheck disable=SC2034 # Variable is referenced indirectly
@ -339,31 +343,20 @@ LANGUAGE_ARRAY=('ANSIBLE' 'ARM' 'BASH' 'BASH_EXEC' 'CHECKOV' 'CLANG_FORMAT'
##########################
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
FILE_ARRAY_VARIABLE_NAME="FILE_ARRAY_${LANGUAGE}"
debug "Setting ${FILE_ARRAY_VARIABLE_NAME} variable..."
debug "Initializing ${FILE_ARRAY_VARIABLE_NAME}"
eval "${FILE_ARRAY_VARIABLE_NAME}=()"
done
################################################################################
########################## FUNCTIONS BELOW #####################################
################################################################################
################################################################################
#### Function Header ###########################################################
Header() {
###############################
# Give them the possum action #
###############################
if [[ "${SUPPRESS_POSSUM}" == "false" ]]; then
/bin/bash /action/lib/functions/possum.sh
fi
##########
# Prints #
##########
info "---------------------------------------------"
info "--- GitHub Actions Multi Language Linter ----"
info " - Image Creation Date:[${BUILD_DATE}]"
info " - Image Revision:[${BUILD_REVISION}]"
info " - Image Version:[${BUILD_VERSION}]"
info " - Image Creation Date: ${BUILD_DATE}"
info " - Image Revision: ${BUILD_REVISION}"
info " - Image Version: ${BUILD_VERSION}"
info "---------------------------------------------"
info "---------------------------------------------"
info "The Super-Linter source code can be found at:"
@ -389,12 +382,7 @@ ConfigureGitSafeDirectories() {
done
}
################################################################################
#### Function GetGitHubVars ####################################################
GetGitHubVars() {
##########
# Prints #
##########
info "--------------------------------------------"
info "Gathering GitHub information..."
@ -404,7 +392,7 @@ GetGitHubVars() {
if [[ ${RUN_LOCAL} != "false" ]]; then
info "RUN_LOCAL has been set to: ${RUN_LOCAL}. Bypassing GitHub Actions variables..."
if [ -z "${GITHUB_WORKSPACE}" ]; then
if [ -z "${GITHUB_WORKSPACE:-}" ]; then
GITHUB_WORKSPACE="${DEFAULT_WORKSPACE}"
fi
@ -560,12 +548,8 @@ GetGitHubVars() {
# We need this for parallel
export GITHUB_WORKSPACE
}
################################################################################
#### Function CallStatusAPI ####################################################
CallStatusAPI() {
####################
# Pull in the vars #
####################
LANGUAGE="${1}" # language that was validated
STATUS="${2}" # success | error
SUCCESS_MSG='No errors were found in the linting process'
@ -689,8 +673,7 @@ Footer() {
exit ${SUPER_LINTER_EXIT_CODE}
}
################################################################################
#### Function UpdateLoopsForImage ##############################################
UpdateLoopsForImage() {
######################################################################
# Need to clean the array lists of the linters removed for the image #
@ -719,12 +702,13 @@ UpdateLoopsForImage() {
cleanup() {
local -ri EXIT_CODE=$?
if [ -n "${GITHUB_WORKSPACE:-}" ]; then
debug "Removing temporary files and directories"
rm -rf \
"${GITHUB_WORKSPACE}/.mypy_cache" \
"${GITHUB_WORKSPACE}/logback.log"
if [ "${SUPER_LINTER_COPIED_R_LINTER_RULES_FILE}" == "true" ]; then
if [[ "${SUPER_LINTER_COPIED_R_LINTER_RULES_FILE:-}" == "true" ]]; then
debug "Deleting ${R_RULES_FILE_PATH_IN_ROOT} because super-linter created it."
rm -rf "${R_RULES_FILE_PATH_IN_ROOT}"
fi
@ -740,16 +724,15 @@ cleanup() {
else
debug "Skipping the moving of the log file from ${LOG_TEMP} to ${LOG_FILE_PATH}"
fi
else
debug "GITHUB_WORKSPACE is not set. Skipping filesystem cleanup steps"
fi
exit "${EXIT_CODE}"
trap - 0 1 2 3 6 14 15
}
trap 'cleanup' 0 1 2 3 6 14 15
################################################################################
############################### MAIN ###########################################
################################################################################
##########
# Header #
##########
@ -806,6 +789,11 @@ fi
ValidateDeprecatedVariables
# After checking if LOG_LEVEL is set to a deprecated value (see the ValidateDeprecatedVariables function),
# we can unset it so other programs that rely on this variable, such as Checkov and renovate-config-validator
# don't get confused.
unset LOG_LEVEL
#################################
# Get the linter rules location #
#################################

View file

@ -4,6 +4,11 @@ set -o errexit
set -o nounset
set -o pipefail
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# Default log level
# shellcheck disable=SC2034
LOG_LEVEL="DEBUG"
# shellcheck disable=SC2034
LOG_DEBUG="true"
# shellcheck disable=SC2034
@ -25,9 +30,6 @@ git config --global init.defaultBranch "${DEFAULT_BRANCH}"
git config --global user.email "super-linter@example.com"
git config --global user.name "Super-linter"
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
function InitGitRepositoryAndCommitFiles() {
local REPOSITORY_PATH="${1}" && shift
local FILES_TO_COMMIT="${1}"

View file

@ -4,6 +4,11 @@ set -o errexit
set -o nounset
set -o pipefail
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# Default log level
# shellcheck disable=SC2034
LOG_LEVEL="DEBUG"
# shellcheck disable=SC2034
LOG_DEBUG="true"
# shellcheck disable=SC2034
@ -18,9 +23,6 @@ LOG_ERROR="true"
# shellcheck source=/dev/null
source "lib/functions/log.sh"
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# shellcheck source=/dev/null
source "lib/functions/validation.sh"
# shellcheck source=/dev/null

View file

@ -4,6 +4,11 @@ set -o errexit
set -o nounset
set -o pipefail
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# Default log level
# shellcheck disable=SC2034
LOG_LEVEL="DEBUG"
# shellcheck disable=SC2034
LOG_TRACE="true"
# shellcheck disable=SC2034
@ -20,9 +25,6 @@ LOG_ERROR="true"
# shellcheck source=/dev/null
source "lib/functions/log.sh"
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
GITHUB_DOMAIN="github.com"
# shellcheck disable=SC2034
GITHUB_META_URL="https://api.${GITHUB_DOMAIN}/meta"

View file

@ -4,6 +4,11 @@ set -o errexit
set -o nounset
set -o pipefail
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# Default log level
# shellcheck disable=SC2034
LOG_LEVEL="DEBUG"
# shellcheck disable=SC2034
LOG_DEBUG="true"
# shellcheck disable=SC2034
@ -15,16 +20,9 @@ LOG_WARN="true"
# shellcheck disable=SC2034
LOG_ERROR="true"
# Default log level
# shellcheck disable=SC2034
LOG_LEVEL="DEBUG"
# shellcheck source=/dev/null
source "lib/functions/log.sh"
# shellcheck disable=SC2034
CREATE_LOG_FILE=false
# shellcheck source=/dev/null
source "lib/functions/validation.sh"