From 1f659fabd34caab2421fa2769cb5d94fa3bbf6f4 Mon Sep 17 00:00:00 2001
From: Antonio Aversa <antonio.aversa@sonarsource.com>
Date: Thu, 28 Nov 2024 10:32:04 +0100
Subject: [PATCH] SQSCANGHA-55 Support GitHub self-hosted runners without wget

---
 .github/workflows/qa.yml     | 85 ++++++++++++++++++++++++++++++++++++
 install-sonar-scanner-cli.sh | 44 ++++++++++++++-----
 2 files changed, 118 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml
index d0610f2..8b4240a 100644
--- a/.github/workflows/qa.yml
+++ b/.github/workflows/qa.yml
@@ -269,6 +269,91 @@ jobs:
       - name: Assert
         run: |
           ./test/assertFileExists ./test/example-project/.scannerwork/report-task.txt        
+  dontFailWhenMissingWgetButCurlAvailable:
+    name: Don't fail when missing wget but curl available
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+      - name: Remove wget
+        run: sudo apt-get remove -y wget
+      - name: Assert wget is not available
+        run: |
+          if command -v wget 2>&1 >/dev/null
+          then
+            exit 1
+          fi
+      - name: Run action
+        uses: ./
+        env:
+          NO_CACHE: true
+          SONAR_HOST_URL: http://not_actually_used
+          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
+        with:
+          args: -Dsonar.scanner.internal.dumpToFile=./output.properties
+      - name: Assert
+        run: |
+          ./test/assertFileExists ./output.properties
+  dontFailWhenMissingCurlButWgetAvailable:
+    name: Don't fail when missing curl but wget available
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+      - name: Remove curl
+        run: sudo apt-get remove -y curl
+      - name: Assert curl is not available
+        run: |
+          if command -v curl 2>&1 >/dev/null
+          then
+            exit 1
+          fi
+      - name: Run action
+        id: runTest
+        uses: ./
+        env:
+          NO_CACHE: true
+          SONAR_HOST_URL: http://not_actually_used
+          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
+        with:
+          args: -Dsonar.scanner.internal.dumpToFile=./output.properties
+      - name: Assert
+        run: |
+          ./test/assertFileExists ./output.properties
+  failWhenBothWgetAndCurlMissing:
+    name: Fail when both wget and curl are missing
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+      - name: Remove wget and curl
+        run: sudo apt-get remove -y wget curl
+      - name: Assert wget and curl are not available
+        run: |
+          if command -v wget 2>&1 >/dev/null
+          then
+            exit 1
+          fi
+          if command -v curl 2>&1 >/dev/null
+          then
+            exit 1
+          fi
+      - name: Run action
+        id: runTest
+        uses: ./
+        continue-on-error: true
+        env:
+          NO_CACHE: true
+          SONAR_HOST_URL: http://not_actually_used
+          SONAR_SCANNER_JSON_PARAMS: '{"sonar.scanner.internal.dumpToFile": "./output.properties"}'
+        with:
+          args: -Dsonar.scanner.internal.dumpToFile=./output.properties
+      - name: Assert failure of previous step
+        if: steps.runTest.outcome == 'success'
+        run: exit 1
   useSslCertificate:
     name: >
       'SONAR_ROOT_CERT' is converted to truststore
diff --git a/install-sonar-scanner-cli.sh b/install-sonar-scanner-cli.sh
index 5cdbedb..d87c8e4 100755
--- a/install-sonar-scanner-cli.sh
+++ b/install-sonar-scanner-cli.sh
@@ -2,33 +2,55 @@
 
 set -eou pipefail
 
-#See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
+# See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
+#
+# Script-specific variables required:
+# - INPUT_SCANNERVERSION: e.g. 6.2.1.4610
+# - INPUT_SCANNERBINARIESURL: e.g. https://github.com/me/my-repo/raw/refs/heads/main/binaries
 
-WGET=wget
-if [[ "$RUNNER_OS" == "Linux" &&  "$RUNNER_ARCH" == "X64" ]]; then
+if [[ "$RUNNER_OS" == "Linux" && "$RUNNER_ARCH" == "X64" ]]; then
      FLAVOR="linux-x64"
-elif [[ "$RUNNER_OS" == "Linux" &&  "$RUNNER_ARCH" == "ARM64" ]]; then
+elif [[ "$RUNNER_OS" == "Linux" && "$RUNNER_ARCH" == "ARM64" ]]; then
      FLAVOR="linux-aarch64"
-elif [[ "$RUNNER_OS" == "Windows" &&  "$RUNNER_ARCH" == "X64" ]]; then
+elif [[ "$RUNNER_OS" == "Windows" && "$RUNNER_ARCH" == "X64" ]]; then
      FLAVOR="windows-x64"
-     WGET="C:\\msys64\\usr\\bin\\wget.exe"
-elif [[ "$RUNNER_OS" == "macOS" &&  "$RUNNER_ARCH" == "X64" ]]; then
+elif [[ "$RUNNER_OS" == "macOS" && "$RUNNER_ARCH" == "X64" ]]; then
      FLAVOR="macosx-x64"
-elif [[ "$RUNNER_OS" == "macOS" &&  "$RUNNER_ARCH" == "ARM64" ]]; then
+elif [[ "$RUNNER_OS" == "macOS" && "$RUNNER_ARCH" == "ARM64" ]]; then
      FLAVOR="macosx-aarch64"
 else
-     echo "$RUNNER_OS $RUNNER_ARCH not supported"
+     echo "::error title=SonarScanner::$RUNNER_OS $RUNNER_ARCH not supported"
      exit 1
 fi
 
+SCANNER_FILE_NAME="sonar-scanner-cli-$INPUT_SCANNERVERSION-$FLAVOR.zip"
+SCANNER_URI="${INPUT_SCANNERBINARIESURL%/}/$SCANNER_FILE_NAME"
+
+if command -v wget &> /dev/null; then
+    DOWNLOAD_COMMAND="wget"
+    DOWNLOAD_ARGS="--no-verbose --user-agent=sonarqube-scan-action $SCANNER_URI"
+elif command -v curl &> /dev/null; then
+    DOWNLOAD_COMMAND="curl"
+    DOWNLOAD_ARGS="--silent --show-error --user-agent sonarqube-scan-action --output $SCANNER_FILE_NAME $SCANNER_URI"
+elif [ "$RUNNER_OS" == "Windows" ] && [ -t "C:\\msys64\\usr\\bin\\wget.exe" ]; then
+    DOWNLOAD_COMMAND="C:\\msys64\\usr\\bin\\wget.exe"
+    DOWNLOAD_ARGS="--no-verbose --user-agent=sonarqube-scan-action $SCANNER_URI"
+elif [ "$RUNNER_OS" == "Windows" ] && [ -t "C:\\msys64\\usr\\bin\\curl.exe" ]; then
+    DOWNLOAD_COMMAND="C:\\msys64\\usr\\bin\\curl.exe"
+    DOWNLOAD_ARGS="--silent --show-error --user-agent sonarqube-scan-action --output $SCANNER_FILE_NAME $SCANNER_URI"
+else
+    echo "::error title=SonarScanner::Neither wget nor curl found on the machine"
+    exit 1
+fi
+
 set -x
 
 mkdir -p $RUNNER_TEMP/sonarscanner
 cd $RUNNER_TEMP/sonarscanner
 
-$WGET --no-verbose --user-agent="sonarqube-scan-action" "${INPUT_SCANNERBINARIESURL%/}/sonar-scanner-cli-$INPUT_SCANNERVERSION-$FLAVOR.zip"
+$DOWNLOAD_COMMAND $DOWNLOAD_ARGS
 
-unzip -q sonar-scanner-cli-$INPUT_SCANNERVERSION-$FLAVOR.zip
+unzip -q $SCANNER_FILE_NAME
 
 # Folder name should correspond to the directory cached by the actions/cache
 mv sonar-scanner-$INPUT_SCANNERVERSION-$FLAVOR $RUNNER_TEMP/sonar-scanner-cli-$INPUT_SCANNERVERSION-$RUNNER_OS-$RUNNER_ARCH