Skip to content

Commit

Permalink
Add a polling timeout (#50)
Browse files Browse the repository at this point in the history
The property timeout-minutes in a GitHub step is not supported in composed actions. So the workaround to stop the waiting for finishing the sonar scan is not working in such cases.
To fix this issue, a polling timeout variable was introduced, which stops the waiting if the timeout is reached.
  • Loading branch information
MueChr authored Aug 30, 2024
1 parent 72f24eb commit dc2f7b0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ runs:
using: "composite"
steps:
- id: quality-gate-check
run: $GITHUB_ACTION_PATH/script/check-quality-gate.sh ${{ inputs.scanMetadataReportFile }}
run: $GITHUB_ACTION_PATH/script/check-quality-gate.sh "${{ inputs.scanMetadataReportFile }}" "${{ inputs.pollingTimeoutSec }}"
shell: bash
inputs:
scanMetadataReportFile:
description: Location of the scanner metadata report file
required: false
default: .scannerwork/report-task.txt
pollingTimeoutSec:
description: "The maximum time (in seconds) to poll for SonarQube's Quality Gate status. Default: 300."
required: false
default: "300"
outputs:
quality-gate-status:
description: >
Expand Down
16 changes: 15 additions & 1 deletion script/check-quality-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ if [[ -z "${SONAR_TOKEN}" ]]; then
fi

metadataFile="$1"
pollingTimeoutSec="$2"


if [[ ! -f "$metadataFile" ]]; then
echo "$metadataFile does not exist."
exit 1
fi

if [[ ! $pollingTimeoutSec =~ ^[0-9]+$ || $pollingTimeoutSec -le 0 ]]; then
echo "'$pollingTimeoutSec' is an invalid value for the polling timeout. Please use a positive, non-zero number."
exit 1
fi

if [[ ! -z "${SONAR_HOST_URL}" ]]; then
serverUrl="${SONAR_HOST_URL%/}"
ceTaskUrl="${SONAR_HOST_URL%/}/api$(sed -n 's/^ceTaskUrl=.*api//p' "${metadataFile}")"
Expand All @@ -37,14 +44,21 @@ fi
task="$(curl --location --location-trusted --max-redirs 10 --silent --fail --show-error --user "${SONAR_TOKEN}": "${ceTaskUrl}")"
status="$(jq -r '.task.status' <<< "$task")"

until [[ ${status} != "PENDING" && ${status} != "IN_PROGRESS" ]]; do
endTime=$(( ${SECONDS} + ${pollingTimeoutSec} ))

until [[ ${status} != "PENDING" && ${status} != "IN_PROGRESS" || ${SECONDS} -ge ${endTime} ]]; do
printf '.'
sleep 5
task="$(curl --location --location-trusted --max-redirs 10 --silent --fail --show-error --user "${SONAR_TOKEN}": "${ceTaskUrl}")"
status="$(jq -r '.task.status' <<< "$task")"
done
printf '\n'

if [[ ${status} == "PENDING" || ${status} == "IN_PROGRESS" ]] && [[ ${SECONDS} -ge ${endTime} ]]; then
echo "Polling timeout reached for waiting for finishing of the Sonar scan! Aborting the check for SonarQube's Quality Gate."
exit 1
fi

analysisId="$(jq -r '.task.analysisId' <<< "${task}")"
qualityGateUrl="${serverUrl}/api/qualitygates/project_status?analysisId=${analysisId}"
qualityGateStatus="$(curl --location --location-trusted --max-redirs 10 --silent --fail --show-error --user "${SONAR_TOKEN}": "${qualityGateUrl}" | jq -r '.projectStatus.status')"
Expand Down
63 changes: 54 additions & 9 deletions test/check-quality-gate-test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300
[ "$status" -eq 0 ]
}

Expand All @@ -52,11 +52,39 @@ teardown() {

@test "fail when empty metadata file" {
export SONAR_TOKEN="test"
run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300
[ "$status" -eq 1 ]
[ "$output" = "Invalid report metadata file." ]
}

@test "fail when no polling timeout is provided" {
export SONAR_TOKEN="test"
run script/check-quality-gate.sh metadata_tmp
[ "$status" -eq 1 ]
[ "$output" = "'' is an invalid value for the polling timeout. Please use a positive, non-zero number." ]
}

@test "fail when polling timeout is not a number" {
export SONAR_TOKEN="test"
run script/check-quality-gate.sh metadata_tmp metadata_tmp
[ "$status" -eq 1 ]
[ "$output" = "'metadata_tmp' is an invalid value for the polling timeout. Please use a positive, non-zero number." ]
}

@test "fail when polling timeout is zero" {
export SONAR_TOKEN="test"
run script/check-quality-gate.sh metadata_tmp 0
[ "$status" -eq 1 ]
[ "$output" = "'0' is an invalid value for the polling timeout. Please use a positive, non-zero number." ]
}

@test "fail when polling timeout is negative" {
export SONAR_TOKEN="test"
run script/check-quality-gate.sh metadata_tmp -1
[ "$status" -eq 1 ]
[ "$output" = "'-1' is an invalid value for the polling timeout. Please use a positive, non-zero number." ]
}

@test "fail when no Quality Gate status" {
export SONAR_TOKEN="test"
echo "serverUrl=http://localhost:9000" >> metadata_tmp
Expand All @@ -68,7 +96,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < ${GITHUB_OUTPUT}

Expand All @@ -77,6 +105,23 @@ teardown() {
[[ "$output" = *"Quality Gate not set for the project. Please configure the Quality Gate in SonarQube or remove sonarqube-quality-gate action from the workflow."* ]]
}

@test "fail when polling timeout is reached" {
export SONAR_TOKEN="test"
echo "serverUrl=http://localhost:9000" >> metadata_tmp
echo "ceTaskUrl=http://localhost:9000/api/ce/task?id=AXlCe3jz9LkwR9Gs0pBY" >> metadata_tmp

#mock curl
function curl() {
echo '{"task":{"analysisId":"AXlCe3jz9LkwR9Gs0pBY","status":"PENDING"}}'
}
export -f curl

run script/check-quality-gate.sh metadata_tmp 5

[ "$status" -eq 1 ]
[[ "$output" = *"Polling timeout reached for waiting for finishing of the Sonar scan! Aborting the check for SonarQube's Quality Gate."* ]]
}

@test "fail when Quality Gate status WARN" {
export SONAR_TOKEN="test"
echo "serverUrl=http://localhost:9000" >> metadata_tmp
Expand All @@ -94,7 +139,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < ${GITHUB_OUTPUT}

Expand All @@ -121,7 +166,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < ${GITHUB_OUTPUT}

Expand All @@ -147,7 +192,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < ${GITHUB_OUTPUT}

Expand Down Expand Up @@ -187,7 +232,7 @@ teardown() {
}
export -f sleep

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < ${GITHUB_OUTPUT}

Expand Down Expand Up @@ -220,7 +265,7 @@ teardown() {
export GITHUB_OUTPUT="${github_output_dir}/github_output"
touch "${GITHUB_OUTPUT}"

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

read -r github_out_actual < "${GITHUB_OUTPUT}"

Expand All @@ -246,7 +291,7 @@ teardown() {
}
export -f curl

run script/check-quality-gate.sh metadata_tmp
run script/check-quality-gate.sh metadata_tmp 300

[ "$status" -eq 0 ]
[[ "$output" = *"::set-output name=quality-gate-status::PASSED"* ]]
Expand Down

0 comments on commit dc2f7b0

Please sign in to comment.