0

Trying to fetch the status of the URL for sonarqube quality gate and check if the status is "OK" the condition should pass or if the status is "ERROR" then it should fail.

quality_gatesstatus=$(curl -u $SONAR_TOKEN:https://$SONAR_SERVER/api/qualitygates/project_status?projectKey=$SONAR_PROJECT_KEY\&pullRequest=$SONAR_PR_KEY | grep -Po '"status": *\K"[^"]*"')

echo $SONAR_PR_KEY

echo "Checking the Sonar Quality gate status"
if ("$quality_gatesstatus" != "OK") && ("$quality_gatesstatus" != "NONE")
then
echo "check sonar server and fix the issues: $quality_gatesstatus"
exit 1  
else
echo "Quality gate succeeded"
fi

But its not working as per the IF statement, its going always to the else condition

Santosh Kumar
  • 53
  • 1
  • 10
  • Are you not getting an error message? It seems unlikely the the value of `$quality_gatesstatus` is an executable command, and even less likely that it expects arguments `!=` and `OK`. – William Pursell May 13 '22 at 12:54
  • [Shellcheck](https://www.shellcheck.net/) finds several problems with the code, including critical ones. – pjh May 13 '22 at 12:56
  • Yes I am getting an error for quality_gatesstatus like command not found. Where I am doing mistake? Could you please help – Santosh Kumar May 13 '22 at 12:59
  • Your mistake is that you are making up syntax based on your experience with other languages. – chepner May 13 '22 at 14:09

1 Answers1

0

The line:

if ("$quality_gatesstatus" != "OK") && ("$quality_gatesstatus" != "NONE")

is evaluated as follows (not precisely, this is a heuristic):

  1. the variable $quality_gatestatus is expanded to some string, say S
  2. S is executed as a command, with the arguments != and OK
  3. If that command succeeds, then it is executed again with the arguments != and NONE. If that command succeeds then the first block of commands is executed. Otherwise, the commands in the else block are executed.

The error you are seeing is because the string S is not an executable command. Almost certainly what you actually want is:

if [ "$quality_gatesstatus" != OK ] && [ "$quality_gatesstatus" != NONE ]; then ...

but more likely you want a case statement:

case "$quality_gatesstatus" in
OK) ... ;;
NONE) ... ;;
*) ... ;;
esac

The syntax of the shell is a bit counter-intuitive. It is not if condition; then commands; fi. It is if commands; then commands; fi. In other words, when you write if [ 5 = 5 ], the [ and ] are not part of the shell syntax. Instead, the command [ is executed with arguments 5, =, and ]. Although [ is probably the most common command executed in an if block, it can be any set of commands, and it is common to see constructs like if grep ... or if shh ... or if curl .... It is slightly less common to see if cmd1; cmd2; cmd3; then ..., but you will see it now and again.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Ok if I use case statement, I want to fail the job if the statement finds "ERROR". – Santosh Kumar May 13 '22 at 13:05
  • @SantoshKumar `ERROR) echo "error message" >&2; exit 1;;` – William Pursell May 13 '22 at 13:10
  • Can you please frame the condition properly, coz I am using it like this: `if [ "$quality_gatesstatus" != OK ] && [ "$quality_gatesstatus" != NONE ]; then echo "check sonar server and fix the issues: $quality_gatesstatus" exit 1 fi` This one is failing still as the condition holds good, like quality status contains only "OK" but still it is failing. – Santosh Kumar May 13 '22 at 13:27
  • I am using like this `echo "Checking the Sonar Quality gate status" case "$quality_gatesstatus" in OK) echo "Sonar Quality gate succeeded" ;; NONE) ... ;; ERROR) echo "error message" >&2; exit 1;; esac` But its passing irrespective of either cases so its not working if the case is ERROR. – Santosh Kumar May 13 '22 at 14:01
  • Do you mean you are seeing `check sonar server and fix the issues: OK`? Glancing at your `grep`, it seems likely that `$quality_gatesstatus` contains more than just the string OK or NONE. I don't know what you mean by "passing". – William Pursell May 13 '22 at 14:03
  • `$quality_gatesstatus` contains `"ERROR" "OK" "OK" "ERROR" "OK" "OK"`. So if it finds "ERROR" keyword in the `case` statement it should fail. But its passing. – Santosh Kumar May 13 '22 at 14:16
  • Error message: **"ERROR" "OK" "OK" "ERROR" "OK" "OK" 7006 Checking the Sonar Quality gate status ci/bin/sonar-quality-gates-checker.sh: line 19: ...: command not found ##[error]Bash exited with code '127'. Finishing: Wait for Sonar quality gates ** – Santosh Kumar May 13 '22 at 14:18
  • The string `"OK"` is not the same as the string `OK`. – William Pursell May 13 '22 at 14:19
  • My `case` looks like this: `echo "Checking the Sonar Quality gate status" case "$quality_gatesstatus" in OK) echo "Sonar Quality gate succeeded" ;; ERROR) echo "error message" >&2; exit 1;; *) ... ;; esac` – Santosh Kumar May 13 '22 at 14:20
  • In many contexts, quotes are removed. In others, they are not. If you try to compare the literal string `"OK"` with the literal string `OK`, they will not match. For your case, probably the easiest thing to do is fix your `grep` so that the double quotes are not in the string you are trying to match. – William Pursell May 13 '22 at 14:21
  • `grep -Po '"status": *\K"[^"]*"'` so here shall I remove double quotes and keep only like this `*\K[^]*` – Santosh Kumar May 13 '22 at 14:38
  • No, if you do that then the `grep` won't match. One trivial approach would be to pipe things through `tr -d '"'`, either before the match or after. Or account for the quotes when you try to match things: `if [ "$quality_gatesstatus" = '"OK"' ]`. There are many options. – William Pursell May 13 '22 at 14:47
  • I have added pipe things like `quality_gatesstatus=$(curl -u $SONAR_TOKEN: https://$SONAR_SERVER/api/qualitygates/project_status?projectKey=$SONAR_PROJECT_KEY\&pullRequest=$SONAR_PR_KEY | grep -Po '"status": *\K"[^"]*"' | tr -d '"')` but no luck, still not working as expected. Its failing even for OK. – Santosh Kumar May 15 '22 at 05:45
  • curl output looks like this with out any grep: `{"projectStatus":{"status":"ERROR","conditions":[{"status":"OK","metricKey":"new_reliability_rating","comparator":"GT","periodIndex":1,"errorThreshold":"1","actualValue":"1"},{"status":"OK","metricKey":"reliability_rating","comparator":"GT","errorThreshold":"1","actualValue":"1"},{"status":"OK","metricKey":"new_security_rating","comparator":"GT","periodIndex":1,"errorThreshold":"1","actualValue":"1"},{"status":"OK","metricKey":"security_rating","comparator":"GT","errorThreshold":"1","actualValue":"1"},` It should fetch only value status:OK/ERROR. – Santosh Kumar May 15 '22 at 11:25