fix: avoid duplicated content in summary (#5939)

- Remove the previous summary file is present to avoid showing stale
  contents from old summaries.
- Extract the logic to write summary heading and lines to dedicated
  functions in output.sh to make it easier adding new formats in the
  future.
This commit is contained in:
Marco Ferrari 2024-07-30 08:35:14 +02:00 committed by GitHub
parent 78ed3ef5fc
commit ef57e132e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 193 additions and 19 deletions

View file

@ -238,6 +238,7 @@ lint-codebase: ## Lint the entire codebase
-e FILTER_REGEX_EXCLUDE=".*(/test/linters/|CHANGELOG.md).*" \ -e FILTER_REGEX_EXCLUDE=".*(/test/linters/|CHANGELOG.md).*" \
-e GITLEAKS_CONFIG_FILE=".gitleaks-ignore-tests.toml" \ -e GITLEAKS_CONFIG_FILE=".gitleaks-ignore-tests.toml" \
-e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" \ -e RENOVATE_SHAREABLE_CONFIG_PRESET_FILE_NAMES="default.json,hoge.json" \
-e SAVE_SUPER_LINTER_SUMMARY=true \
-e VALIDATE_ALL_CODEBASE=true \ -e VALIDATE_ALL_CODEBASE=true \
-v "$(CURDIR):/tmp/lint" \ -v "$(CURDIR):/tmp/lint" \
$(SUPER_LINTER_TEST_CONTAINER_URL) $(SUPER_LINTER_TEST_CONTAINER_URL)
@ -280,7 +281,7 @@ lint-subset-files-enable-expensive-io-checks: ## Lint a small subset of files in
$(SUPER_LINTER_TEST_CONTAINER_URL) $(SUPER_LINTER_TEST_CONTAINER_URL)
.PHONY: test-lib .PHONY: test-lib
test-lib: test-build-file-list test-detect-files test-github-event test-setup-ssh test-validation ## Test super-linter test-lib: test-build-file-list test-detect-files test-github-event test-setup-ssh test-validation test-output ## Test super-linter
.PHONY: test-build-file-list .PHONY: test-build-file-list
test-build-file-list: ## Test buildFileList test-build-file-list: ## Test buildFileList
@ -323,6 +324,14 @@ test-validation: ## Test validation
--entrypoint /tmp/lint/test/lib/validationTest.sh \ --entrypoint /tmp/lint/test/lib/validationTest.sh \
$(SUPER_LINTER_TEST_CONTAINER_URL) $(SUPER_LINTER_TEST_CONTAINER_URL)
.PHONY: test-output
test-output: ## Test output
docker run \
-v "$(CURDIR):/tmp/lint" \
-w /tmp/lint \
--entrypoint /tmp/lint/test/lib/outputTest.sh \
$(SUPER_LINTER_TEST_CONTAINER_URL)
# Run this test against a small directory because we're only interested in # Run this test against a small directory because we're only interested in
# loading default configuration files. The directory that we run super-linter # loading default configuration files. The directory that we run super-linter
# against should not be .github because that includes default linter rules. # against should not be .github because that includes default linter rules.

View file

@ -476,6 +476,8 @@ The summary is in Markdown format. Super-linter supports the following formats:
- Table (default) - Table (default)
The summary output of previous Super-linter runs is not preserved.
### Super-linter outputs ### Super-linter outputs
If you set `SAVE_SUPER_LINTER_OUTPUT` to `true`, Super-linter saves its output If you set `SAVE_SUPER_LINTER_OUTPUT` to `true`, Super-linter saves its output

40
lib/functions/output.sh Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env bash
WriteSummaryHeader() {
local SUPER_LINTER_SUMMARY_OUTPUT_PATH="${1}"
{
echo "# Super-linter summary"
echo ""
echo "| Language | Validation result |"
echo "| -----------------------|-------------------|"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
}
WriteSummaryLineSuccess() {
local SUPER_LINTER_SUMMARY_OUTPUT_PATH="${1}"
local LANGUAGE_NAME="${2}"
echo "| ${LANGUAGE_NAME} | Pass ✅ |" >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
}
WriteSummaryLineFailure() {
local SUPER_LINTER_SUMMARY_OUTPUT_PATH="${1}"
local LANGUAGE_NAME="${2}"
echo "| ${LANGUAGE_NAME} | Fail ❌ |" >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
}
WriteSummaryFooterSuccess() {
local SUPER_LINTER_SUMMARY_OUTPUT_PATH="${1}"
{
echo ""
echo "All files and directories linted successfully"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
}
WriteSummaryFooterFailure() {
local SUPER_LINTER_SUMMARY_OUTPUT_PATH="${1}"
{
echo ""
echo "Super-linter detected linting errors"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
}

View file

@ -31,6 +31,8 @@ source /action/lib/functions/setupSSH.sh # Source the function script(s)
source /action/lib/functions/githubEvent.sh source /action/lib/functions/githubEvent.sh
# shellcheck source=/dev/null # shellcheck source=/dev/null
source /action/lib/functions/githubDomain.sh source /action/lib/functions/githubDomain.sh
# shellcheck source=/dev/null
source /action/lib/functions/output.sh
if ! ValidateGitHubUrls; then if ! ValidateGitHubUrls; then
fatal "GitHub URLs failed validation" fatal "GitHub URLs failed validation"
@ -565,12 +567,7 @@ Footer() {
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
debug "Saving Super-linter summary to ${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" debug "Saving Super-linter summary to ${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
{ WriteSummaryHeader "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
echo "# Super-linter summary"
echo ""
echo "| Language | Validation result |"
echo "| -----------------------|-------------------|"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
fi fi
for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do
@ -591,7 +588,7 @@ Footer() {
error "Errors found in ${LANGUAGE}" error "Errors found in ${LANGUAGE}"
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
echo "| ${LANGUAGE} | Fail ❌ |" >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" WriteSummaryLineFailure "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" "${LANGUAGE}"
fi fi
# Print output as error in case users disabled the INFO level so they # Print output as error in case users disabled the INFO level so they
@ -619,7 +616,7 @@ Footer() {
elif [[ ${ERROR_COUNTER} -eq 0 ]]; then elif [[ ${ERROR_COUNTER} -eq 0 ]]; then
notice "Successfully linted ${LANGUAGE}" notice "Successfully linted ${LANGUAGE}"
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
echo "| ${LANGUAGE} | Pass ✅ |" >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" WriteSummaryLineSuccess "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" "${LANGUAGE}"
fi fi
CallStatusAPI "${LANGUAGE}" "success" CallStatusAPI "${LANGUAGE}" "success"
ANY_LINTER_SUCCESS="true" ANY_LINTER_SUCCESS="true"
@ -641,18 +638,12 @@ Footer() {
if [[ ${SUPER_LINTER_EXIT_CODE} -eq 0 ]]; then if [[ ${SUPER_LINTER_EXIT_CODE} -eq 0 ]]; then
notice "All files and directories linted successfully" notice "All files and directories linted successfully"
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
{ WriteSummaryFooterSuccess "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
echo ""
echo "All files and directories linted successfully"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
fi fi
else else
error "Super-linter detected linting errors" error "Super-linter detected linting errors"
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
{ WriteSummaryFooterFailure "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
echo ""
echo "Super-linter detected linting errors"
} >>"${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
fi fi
fi fi
@ -820,6 +811,9 @@ if [[ "${SAVE_SUPER_LINTER_OUTPUT}" = "true" ]] ||
fi fi
if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then if [[ "${SAVE_SUPER_LINTER_SUMMARY}" == "true" ]]; then
debug "Remove eventual ${SUPER_LINTER_SUMMARY_OUTPUT_PATH} leftover"
rm -f "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"
debug "Ensuring that ${SUPER_LINTER_SUMMARY_OUTPUT_PATH} exists." debug "Ensuring that ${SUPER_LINTER_SUMMARY_OUTPUT_PATH} exists."
if ! touch "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"; then if ! touch "${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"; then
fatal "Cannot create Super-linter summary file: ${SUPER_LINTER_SUMMARY_OUTPUT_PATH}" fatal "Cannot create Super-linter summary file: ${SUPER_LINTER_SUMMARY_OUTPUT_PATH}"

View file

@ -0,0 +1,3 @@
<!-- markdownlint-disable -->
Super-linter detected linting errors

View file

@ -0,0 +1,3 @@
<!-- markdownlint-disable -->
All files and directories linted successfully

View file

@ -0,0 +1,4 @@
# Super-linter summary
| Language | Validation result |
| -----------------------|-------------------|

View file

@ -0,0 +1,2 @@
<!-- markdownlint-disable -->
| Test Language | Fail ❌ |

View file

@ -0,0 +1,2 @@
<!-- markdownlint-disable -->
| Test Language | Pass ✅ |

View file

@ -466,6 +466,7 @@ control "super-linter-validate-files" do
"/action/lib/functions/linterRules.sh", "/action/lib/functions/linterRules.sh",
version_file_path, version_file_path,
"/action/lib/functions/log.sh", "/action/lib/functions/log.sh",
"/action/lib/functions/output.sh",
"/action/lib/functions/possum.sh", "/action/lib/functions/possum.sh",
"/action/lib/functions/updateSSL.sh", "/action/lib/functions/updateSSL.sh",
"/action/lib/functions/validation.sh", "/action/lib/functions/validation.sh",

114
test/lib/outputTest.sh Executable file
View file

@ -0,0 +1,114 @@
#!/usr/bin/env bash
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 source=/dev/null
source "lib/functions/log.sh"
# shellcheck source=/dev/null
source "lib/functions/output.sh"
TEMP_WORKSPACE="$(pwd)/super-linter-output"
function InitWorkspace() {
CleanupWorkspace
mkdir -p "${TEMP_WORKSPACE}"
}
function CleanupWorkspace() {
rm -rf "${TEMP_WORKSPACE}"
}
function CheckIfFileDiff() {
local INPUT_FILE="${1}"
local EXPECTED_FILE="${2}"
# Remove eventual HTML comments from the expected file because we use them to disable certain linter rules
if ! diff "${INPUT_FILE}" <(grep -vE '^\s*<!--' "${EXPECTED_FILE}"); then
fatal "${INPUT_FILE} contents don't match with the expected contents (${EXPECTED_FILE})"
else
echo "${INPUT_FILE} contents match with the expected contents (${EXPECTED_FILE})"
fi
}
function WriteSummaryMarkdownTableHeaderTest() {
local FUNCTION_NAME
FUNCTION_NAME="${FUNCNAME[0]}"
info "${FUNCTION_NAME} start"
local RESULTS_FILE="${TEMP_WORKSPACE}/${FUNCTION_NAME}-output.md"
InitWorkspace
WriteSummaryHeader "${RESULTS_FILE}"
CheckIfFileDiff "${RESULTS_FILE}" "test/data/super-linter-summary/markdown/table/expected-summary-heading.md"
CleanupWorkspace
notice "${FUNCTION_NAME} PASS"
}
function WriteSummaryMarkdownTableLineSuccessTest() {
local FUNCTION_NAME
FUNCTION_NAME="${FUNCNAME[0]}"
info "${FUNCTION_NAME} start"
local RESULTS_FILE="${TEMP_WORKSPACE}/${FUNCTION_NAME}-output-${FUNCTION_NAME}.md"
InitWorkspace
WriteSummaryLineSuccess "${RESULTS_FILE}" "Test Language"
CheckIfFileDiff "${RESULTS_FILE}" "test/data/super-linter-summary/markdown/table/expected-summary-line-success.md"
CleanupWorkspace
notice "${FUNCTION_NAME} PASS"
}
function WriteSummaryMarkdownTableLineFailureTest() {
local FUNCTION_NAME
FUNCTION_NAME="${FUNCNAME[0]}"
info "${FUNCTION_NAME} start"
local RESULTS_FILE="${TEMP_WORKSPACE}/${FUNCTION_NAME}-output-${FUNCTION_NAME}.md"
InitWorkspace
WriteSummaryLineFailure "${RESULTS_FILE}" "Test Language"
CheckIfFileDiff "${RESULTS_FILE}" "test/data/super-linter-summary/markdown/table/expected-summary-line-failure.md"
CleanupWorkspace
notice "${FUNCTION_NAME} PASS"
}
function WriteSummaryMarkdownTableFooterSuccessTest() {
local FUNCTION_NAME
FUNCTION_NAME="${FUNCNAME[0]}"
info "${FUNCTION_NAME} start"
local RESULTS_FILE="${TEMP_WORKSPACE}/${FUNCTION_NAME}-output-${FUNCTION_NAME}.md"
InitWorkspace
WriteSummaryFooterSuccess "${RESULTS_FILE}"
CheckIfFileDiff "${RESULTS_FILE}" "test/data/super-linter-summary/markdown/table/expected-summary-footer-success.md"
CleanupWorkspace
notice "${FUNCTION_NAME} PASS"
}
function WriteSummaryMarkdownTableFooterFailureTest() {
local FUNCTION_NAME
FUNCTION_NAME="${FUNCNAME[0]}"
info "${FUNCTION_NAME} start"
local RESULTS_FILE="${TEMP_WORKSPACE}/${FUNCTION_NAME}-output-${FUNCTION_NAME}.md"
InitWorkspace
WriteSummaryFooterFailure "${RESULTS_FILE}"
CheckIfFileDiff "${RESULTS_FILE}" "test/data/super-linter-summary/markdown/table/expected-summary-footer-failure.md"
CleanupWorkspace
notice "${FUNCTION_NAME} PASS"
}
WriteSummaryMarkdownTableHeaderTest
WriteSummaryMarkdownTableLineSuccessTest
WriteSummaryMarkdownTableLineFailureTest
WriteSummaryMarkdownTableFooterSuccessTest
WriteSummaryMarkdownTableFooterFailureTest

View file

@ -27,13 +27,13 @@ run_test_cases_expect_failure() {
configure_linters_for_test_cases configure_linters_for_test_cases
COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/bad" -e CHECKOV_FILE_NAME=".checkov-test-linters-failure.yaml" -e FILTER_REGEX_INCLUDE=".*bad.*") COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/bad" -e CHECKOV_FILE_NAME=".checkov-test-linters-failure.yaml" -e FILTER_REGEX_INCLUDE=".*bad.*")
EXPECTED_EXIT_CODE=1 EXPECTED_EXIT_CODE=1
EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH="test/data/github-actions-step-summary/expected-step-summary-test-linters-expect-failure-${SUPER_LINTER_CONTAINER_IMAGE_TYPE}.md" EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH="test/data/super-linter-summary/markdown/table/expected-summary-test-linters-expect-failure-${SUPER_LINTER_CONTAINER_IMAGE_TYPE}.md"
} }
run_test_cases_expect_success() { run_test_cases_expect_success() {
configure_linters_for_test_cases configure_linters_for_test_cases
COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/good" -e CHECKOV_FILE_NAME=".checkov-test-linters-success.yaml" -e FILTER_REGEX_INCLUDE=".*good.*") COMMAND_TO_RUN+=(-e ANSIBLE_DIRECTORY="/test/linters/ansible/good" -e CHECKOV_FILE_NAME=".checkov-test-linters-success.yaml" -e FILTER_REGEX_INCLUDE=".*good.*")
EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH="test/data/github-actions-step-summary/expected-step-summary-test-linters-expect-success-${SUPER_LINTER_CONTAINER_IMAGE_TYPE}.md" EXPECTED_SUPER_LINTER_SUMMARY_FILE_PATH="test/data/super-linter-summary/markdown/table/expected-summary-test-linters-expect-success-${SUPER_LINTER_CONTAINER_IMAGE_TYPE}.md"
} }
run_test_cases_log_level() { run_test_cases_log_level() {