From 5575c65dd46f6c8eb0115b85c8f0ad9c57b608d9 Mon Sep 17 00:00:00 2001 From: Antonio Aversa Date: Wed, 11 Dec 2024 11:47:55 +0100 Subject: [PATCH] SQCPPGHA-9 Extend action to support C, C++, and Objective-C projects --- .github/workflows/qa-deprecated-c-cpp.yml | 87 +++++ .../workflows/qa-install-build-wrapper.yml | 69 ++++ .github/workflows/{qa.yml => qa-main.yml} | 2 +- .github/workflows/qa-scripts.yml | 351 ++++++++++++++++++ .github/workflows/version_update.yml | 50 +++ README.md | 123 +++++- deprecated-c-cpp-action/action.yml | 127 +++++++ install-build-wrapper/action.yml | 55 +++ scripts/cert.sh | 8 + scripts/configure_paths.sh | 71 ++++ scripts/create_install_path.sh | 26 ++ scripts/download.sh | 58 +++ scripts/fetch_latest_version.sh | 25 ++ scripts/utils.sh | 25 ++ sonar-scanner-version | 11 + 15 files changed, 1082 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/qa-deprecated-c-cpp.yml create mode 100644 .github/workflows/qa-install-build-wrapper.yml rename .github/workflows/{qa.yml => qa-main.yml} (99%) create mode 100644 .github/workflows/qa-scripts.yml create mode 100644 .github/workflows/version_update.yml create mode 100644 deprecated-c-cpp-action/action.yml create mode 100644 install-build-wrapper/action.yml create mode 100755 scripts/cert.sh create mode 100755 scripts/configure_paths.sh create mode 100755 scripts/create_install_path.sh create mode 100755 scripts/download.sh create mode 100755 scripts/fetch_latest_version.sh create mode 100755 scripts/utils.sh create mode 100644 sonar-scanner-version diff --git a/.github/workflows/qa-deprecated-c-cpp.yml b/.github/workflows/qa-deprecated-c-cpp.yml new file mode 100644 index 0000000..8ab16d5 --- /dev/null +++ b/.github/workflows/qa-deprecated-c-cpp.yml @@ -0,0 +1,87 @@ +name: QA Deprecated C and C++ action + +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] + +jobs: + output-test: + name: Action outputs + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, macos-13] + cache: [true, false] + include: + - arch: X64 + - os: macos-latest + arch: ARM64 + runs-on: ${{ matrix.os }} + steps: + # Specifying a specific architecture of the runner is not possible for Github hosted runners + # We can only check if the runner architecture matches the expected one + - name: check_runner_arch + shell: bash + run: | + echo "Runner architecture: ${{ runner.arch }}" + if [[ "${{ runner.arch }}" != "${{ matrix.arch }}" ]]; then + echo "##[error]Runner architecture does not match the expected one" + exit 1 + fi + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Run SonarQube C/C++ action + id: run-action + uses: ./deprecated-c-cpp + env: + SONAR_HOST_URL: 'https://next.sonarqube.com/sonarqube/' + with: + cache-binaries: ${{ matrix.cache }} + + - name: SONAR_HOST_URL is set + shell: bash + run: | + [[ $SONAR_HOST_URL == "https://next.sonarqube.com/sonarqube/" ]] + + - name: sonar-scanner is installed and in PATH + run: | + sonar-scanner --help | grep "usage: sonar-scanner " + + - name: sonar-scanner-binary output is correct + shell: bash + env: + BINARY: ${{ steps.run-action.outputs.sonar-scanner-binary }} + run: | + "$BINARY" --help | grep "usage: sonar-scanner " + + # build-wrapper does not have --help or equivalent option. + # Pass to few arguments and ignore error code + - name: build-wrapper is installed and in PATH on Windows + if: runner.os == 'Windows' + shell: bash + run: | + (build-wrapper-win-x86-64.exe || true) | grep "build-wrapper, version " + + - name: build-wrapper is installed and in PATH on Linux + if: runner.os == 'Linux' + shell: bash + run: | + (build-wrapper-linux-x86-64 || true) | grep "build-wrapper, version " + + - name: build-wrapper is installed and in PATH on macOS + if: runner.os == 'macOs' + shell: bash + run: | + (build-wrapper-macosx-x86 || true) | grep "build-wrapper, version " + + - name: build-wrapper-binary output is correct + shell: bash + env: + BINARY: ${{ steps.run-action.outputs.build-wrapper-binary }} + run: | + ("$BINARY" || true) | grep "build-wrapper, version " diff --git a/.github/workflows/qa-install-build-wrapper.yml b/.github/workflows/qa-install-build-wrapper.yml new file mode 100644 index 0000000..793ae05 --- /dev/null +++ b/.github/workflows/qa-install-build-wrapper.yml @@ -0,0 +1,69 @@ +name: QA Install Build Wrapper action + +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] + +jobs: + output-test: + name: Action outputs + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, macos-13] + cache: [true, false] + include: + - arch: X64 + - os: macos-latest + arch: ARM64 + runs-on: ${{ matrix.os }} + steps: + # Specifying a specific architecture of the runner is not possible for Github hosted runners + # We can only check if the runner architecture matches the expected one + - name: check_runner_arch + shell: bash + run: | + echo "Runner architecture: ${{ runner.arch }}" + if [[ "${{ runner.arch }}" != "${{ matrix.arch }}" ]]; then + echo "##[error]Runner architecture does not match the expected one" + exit 1 + fi + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Run SonarQube C/C++ action + id: run-action + uses: ./install-build-wrapper + env: + SONAR_HOST_URL: 'https://next.sonarqube.com/sonarqube/' + + # build-wrapper does not have --help or equivalent option. + # Pass to few arguments and ignore error code + - name: build-wrapper is installed and in PATH on Windows + if: runner.os == 'Windows' + shell: bash + run: | + (build-wrapper-win-x86-64.exe || true) | grep "build-wrapper, version " + + - name: build-wrapper is installed and in PATH on Linux + if: runner.os == 'Linux' + shell: bash + run: | + (build-wrapper-linux-x86-64 || true) | grep "build-wrapper, version " + + - name: build-wrapper is installed and in PATH on macOS + if: runner.os == 'macOs' + shell: bash + run: | + (build-wrapper-macosx-x86 || true) | grep "build-wrapper, version " + + - name: build-wrapper-binary output is correct + shell: bash + env: + BINARY: ${{ steps.run-action.outputs.build-wrapper-binary }} + run: | + ("$BINARY" || true) | grep "build-wrapper, version " diff --git a/.github/workflows/qa.yml b/.github/workflows/qa-main.yml similarity index 99% rename from .github/workflows/qa.yml rename to .github/workflows/qa-main.yml index bd375c1..44d432f 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa-main.yml @@ -1,4 +1,4 @@ -name: QA +name: QA Main action on: push: diff --git a/.github/workflows/qa-scripts.yml b/.github/workflows/qa-scripts.yml new file mode 100644 index 0000000..74d8691 --- /dev/null +++ b/.github/workflows/qa-scripts.yml @@ -0,0 +1,351 @@ +name: QA Scripts + +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] + +jobs: + create-install-dir-test: + name: create_install_path.sh + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Existing + shell: bash + env: + INSTALL_PATH: '.sonar' + run: | + echo "- Create dir" + mkdir -p "${INSTALL_PATH}" + + echo "- Test script behavior" + ./scripts/create_install_path.sh > output + grep -v "::error::" output + + - name: Non-existing nested in current dir + shell: bash + env: + INSTALL_PATH: '.sonar' + run: | + ./scripts/create_install_path.sh > output + grep -v "::error::" output + test -d "${INSTALL_PATH}" + + - name: Nonexisting nested in home + shell: bash + env: + INSTALL_PATH: '~/third_party/.sonar' + run: | + ./scripts/create_install_path.sh > output + grep -v "::error::" output + test -d "${INSTALL_PATH}" + + - name: Empty install dir specified + shell: bash + env: + INSTALL_PATH: '' + run: | + (./scripts/create_install_path.sh || echo "=== Script failed ===") > output + grep "::error::Empty installation path specified" output + grep "=== Script failed ===" output + + - name: No permission to create directory + shell: bash + env: + INSTALL_PATH: '/non_creatable' + run: | + (./scripts/create_install_path.sh || echo "=== Script failed ===") > output + grep "::error::Failed to create non-existing installation path '/non_creatable'" output + grep "=== Script failed ===" output + + - name: Existing but not directory + shell: bash + env: + INSTALL_PATH: 'not_directory' + run: | + echo "- Create normal file" + echo "content" > "${INSTALL_PATH}" + + echo "- Test script behavior" + (./scripts/create_install_path.sh || echo "=== Script failed ===") > output + grep "::error::Installation path 'not_directory' is not a directory" output + grep "=== Script failed ===" output + + + - name: Existing but not readable + shell: bash + env: + INSTALL_PATH: 'not_readable' + run: | + echo "- Create dir and make it not readable" + mkdir -p "${INSTALL_PATH}" + chmod -r "${INSTALL_PATH}" + + echo "- Test script behavior" + (./scripts/create_install_path.sh || echo "=== Script failed ===") > output + grep "::error::Installation path 'not_readable' is not readable" output + grep "=== Script failed ===" output + + - name: Existing but not writeable + shell: bash + env: + INSTALL_PATH: 'not_writeable' + run: | + echo "- Create dir and make it not writeable" + mkdir -p "${INSTALL_PATH}" + chmod -w "${INSTALL_PATH}" + + echo "- Test script behavior" + (./scripts/create_install_path.sh || echo "=== Script failed ===") > output + grep "::error::Installation path 'not_writeable' is not writeable" output + grep "=== Script failed ===" output + setup-script-test: + name: configure_paths.sh + runs-on: ubuntu-latest + env: + INSTALL_PATH: 'install-directory' + SONAR_HOST_URL: 'http://sonar-host.com' + SONAR_SCANNER_VERSION: 'vX.Y.Z.MMMM' + SONAR_SCANNER_URL_WINDOWS_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-windows-x64.zip' + SONAR_SCANNER_SHA_WINDOWS_X64: 'DOWNLOAD-SHA-WINDOWS-X64' + SONAR_SCANNER_URL_LINUX_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-x64.zip' + SONAR_SCANNER_SHA_LINUX_X64: 'DOWNLOAD-SHA-LINUX-X64' + SONAR_SCANNER_URL_LINUX_AARCH64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-aarch64.zip' + SONAR_SCANNER_SHA_LINUX_AARCH64: 'DOWNLOAD-SHA-LINUX-AARCH64' + SONAR_SCANNER_URL_MACOSX_X64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-x64.zip' + SONAR_SCANNER_SHA_MACOSX_X64: 'DOWNLOAD-SHA-MACOSX-X64' + SONAR_SCANNER_URL_MACOSX_AARCH64: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-aarch64.zip' + SONAR_SCANNER_SHA_MACOSX_AARCH64: 'DOWNLOAD-SHA-MACOSX-AARCH64' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Windows + shell: bash + env: + OS: 'Windows' + ARCH: 'X64' + run: | + ./scripts/configure_paths.sh > output + grep -v "::error::" output + + echo "- Check sonar-scanner:" + grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-windows-x64.zip" output + grep "sonar-scanner-sha=DOWNLOAD-SHA-WINDOWS-X64" output + grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-windows-x64" output + grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-windows-x64/bin/sonar-scanner.bat" output + + echo "- Check build-wrapper:" + grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-win-x86.zip" output + grep "build-wrapper-dir=install-directory/build-wrapper-win-x86" output + grep "build-wrapper-bin=install-directory/build-wrapper-win-x86/build-wrapper-win-x86-64.exe" output + + - name: Linux X64 + shell: bash + env: + OS: 'Linux' + ARCH: 'X64' + run: | + ./scripts/configure_paths.sh > output + grep -v "::error::" output + + echo "- Check sonar-scanner:" + grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-x64.zip" output + grep "sonar-scanner-sha=DOWNLOAD-SHA-LINUX-X64" output + grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-x64" output + grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-x64/bin/sonar-scanner" output + + echo "- Check build-wrapper:" + grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-linux-x86.zip" output + grep "build-wrapper-dir=install-directory/build-wrapper-linux-x86" output + grep "build-wrapper-bin=install-directory/build-wrapper-linux-x86/build-wrapper-linux-x86-64" output + + - name: Linux ARM64 + shell: bash + env: + OS: 'Linux' + ARCH: 'ARM64' + run: | + ./scripts/configure_paths.sh > output + grep -v "::error::" output + echo "- Check sonar-scanner:" + grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-linux-aarch64.zip" output + grep "sonar-scanner-sha=DOWNLOAD-SHA-LINUX-AARCH64" output + grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-aarch64" output + grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-linux-aarch64/bin/sonar-scanner" output + echo "- Check build-wrapper:" + grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-linux-aarch64.zip" output + grep "build-wrapper-dir=install-directory/build-wrapper-linux-aarch64" output + grep "build-wrapper-bin=install-directory/build-wrapper-linux-aarch64/build-wrapper-linux-aarch64" output + + - name: macOSX_X64 + shell: bash + env: + OS: 'macOS' + ARCH: 'X64' + run: | + ./scripts/configure_paths.sh > output + grep -v "::error::" output + + echo "- Check sonar-scanner:" + grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-x64.zip" output + grep "sonar-scanner-sha=DOWNLOAD-SHA-MACOSX-X64" output + grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-x64" output + grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-x64/bin/sonar-scanner" output + + echo "- Check build-wrapper:" + grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-macosx-x86.zip" output + grep "build-wrapper-dir=install-directory/build-wrapper-macosx-x86" output + grep "build-wrapper-bin=install-directory/build-wrapper-macosx-x86/build-wrapper-macosx-x86" output + + - name: macOSX_ARM64 + shell: bash + env: + OS: 'macOS' + ARCH: 'ARM64' + run: | + ./scripts/configure_paths.sh > output + grep -v "::error::" output + + echo "- Check sonar-scanner:" + grep "sonar-scanner-url=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-vX.Y.Z.MMMM-macosx-aarch64.zip" output + grep "sonar-scanner-sha=DOWNLOAD-SHA-MACOSX-AARCH64" output + grep "sonar-scanner-dir=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-aarch64" output + grep "sonar-scanner-bin=install-directory/sonar-scanner-vX.Y.Z.MMMM-macosx-aarch64/bin/sonar-scanner" output + + echo "- Check build-wrapper:" + grep "build-wrapper-url=http://sonar-host.com/static/cpp/build-wrapper-macosx-x86.zip" output + grep "build-wrapper-dir=install-directory/build-wrapper-macosx-x86" output + grep "build-wrapper-bin=install-directory/build-wrapper-macosx-x86/build-wrapper-macosx-x86" output + + - name: Unsupported OS + shell: bash + env: + OS: 'unsupportedOS' + ARCH: 'X64' + run: | + (./scripts/configure_paths.sh || echo "=== Script failed ===") > output + + echo "- Check errors:" + grep "::error::Unsupported runner OS 'unsupportedOS'" output + grep "=== Script failed ===" output + + - name: Unsupported architecture + shell: bash + env: + OS: 'Linux' + ARCH: 'X86' + run: | + (./scripts/configure_paths.sh || echo "=== Script failed ===") > output + + echo "- Check errors:" + grep "::error::Architecture 'X86' is unsupported by build-wrapper" output + grep "=== Script failed ===" output + download-script-test: + name: download.sh + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Download test without validation + shell: bash + env: + INSTALL_PATH: 'install-directory-no-sha-validation' + DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip' + EXPECTED_SHA: 'incorrect-sha-not-validated' + TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip + run: | + ./scripts/download.sh > output + test -f "$TMP_ZIP_PATH" + grep -v "::error::" output + - name: Download test with validation + shell: bash + env: + INSTALL_PATH: 'install-directory-sha-validation' + DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip' + EXPECTED_SHA: '9411331814c1d002bd65d37758b872918b7602e7cf3ca5b83a3e19a729b2be05' + TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip + run: | + ./scripts/download.sh -v > output + test -f "$TMP_ZIP_PATH" + grep -v "::error::" output + - name: Incorrect install dir + shell: bash + env: + INSTALL_PATH: '' + run: | + (./scripts/download.sh || echo "=== Script failed ===") > output + grep "::error::Failed to create" output + grep "=== Script failed ===" output + - name: Incorrect download url + shell: bash + env: + INSTALL_PATH: 'install-directory-incorrect-url' + DOWNLOAD_URL: 'incorrect-url' + run: | + (./scripts/download.sh || echo "=== Script failed ===") > output + grep "::error::Failed to download 'incorrect-url'" output + grep "=== Script failed ===" output + - name: Incorrect SHA256 + shell: bash + env: + INSTALL_PATH: 'install-directory-incorrect-sha' + DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip' + EXPECTED_SHA: 'incorrect-sha256' + TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip + run: | + (./scripts/download.sh -v || echo "=== Script failed ===") > output + grep "::error::Checking sha256 failed" output + grep "=== Script failed ===" output + - name: Mismatching SHA256 + shell: bash + env: + INSTALL_PATH: 'install-directory-mismtaching-sha' + DOWNLOAD_URL: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip' + EXPECTED_SHA: '3e121d85a4adb1f30b917d5f3eb897966b59e02c3d6d313a78dcd964193dc963' + TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip + run: | + (./scripts/download.sh -v || echo "=== Script failed ===") > output + grep "::error::Checking sha256 failed" output + grep "=== Script failed ===" output + fetch-latest-version-test: + name: fetch_latest_version.sh + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Test script + shell: bash + run: | + ./scripts/fetch_latest_version.sh > output + + echo "- Check sonar-scanner version:" + grep "sonar-scanner-version=" output + SONAR_SCANNER_VERSION=$(cat output | cut -d= -f 2) + test ! -z "${SONAR_SCANNER_VERSION}" + + echo "- Check windows sonar-scanner URLs:" + grep "sonar-scanner-url-windows-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-windows-x64.zip" output + grep -e "^sonar-scanner-sha-windows-x64=[0-9A-Fa-f]\+$" output + + echo "- Check linux sonar-scanner URLs:" + grep "sonar-scanner-url-linux-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip" output + grep -e "^sonar-scanner-sha-linux-x64=[0-9A-Fa-f]\+$" output + grep "sonar-scanner-url-linux-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-aarch64.zip" output + grep -e "^sonar-scanner-sha-linux-aarch64=[0-9A-Fa-f]\+$" output + + echo "- Check macosx sonar-scanner URLs:" + grep "sonar-scanner-url-linux-x64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip" output + grep -e "^sonar-scanner-sha-linux-x64=[0-9A-Fa-f]\+$" output + grep "sonar-scanner-url-linux-aarch64=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-aarch64.zip" output + grep -e "^sonar-scanner-sha-linux-aarch64=[0-9A-Fa-f]\+$" output diff --git a/.github/workflows/version_update.yml b/.github/workflows/version_update.yml new file mode 100644 index 0000000..aeec0bd --- /dev/null +++ b/.github/workflows/version_update.yml @@ -0,0 +1,50 @@ +name: sonar-scanner version check +on: + workflow_dispatch: + schedule: + - cron: '15 10 * * *' + +jobs: + update-version: + name: Prepare pull request for sonar-scanner version update + runs-on: ubuntu-latest + steps: + - run: sudo apt install -y jq + + - uses: actions/checkout@v4 + with: + ref: master + persist-credentials: true + fetch-depth: 0 + + - name: "Fetch currently used sonar-scanner version" + id: tagged-version + shell: bash + run: cat sonar-scanner-version >> $GITHUB_OUTPUT + + - name: "Fetch lastest sonar-scanner version" + id: latest-version + shell: bash + run: | + ./scripts/fetch_latest_version.sh > sonar-scanner-version + cat sonar-scanner-version >> $GITHUB_OUTPUT + + - name: "Create Pull Request for version update" + if: steps.tagged-version.outputs.sonar-scanner-version != steps.latest-version.outputs.sonar-scanner-version + shell: bash + env: + UPDATE_BRANCH: update-to-sonar-scanner-${{ steps.latest-version.outputs.sonar-scanner-version }} + TITLE: "Update sonar-scanner-version to ${{ steps.latest-version.outputs.sonar-scanner-version }}" + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config --global user.name "SonarTech" + git config --global user.email "sonartech@sonarsource.com" + git checkout -b ${UPDATE_BRANCH} + git add sonar-scanner-version + git commit -m "${TITLE}" + git push --force-with-lease origin ${UPDATE_BRANCH} + gh pr list + + if [[ $(gh pr list -H "${UPDATE_BRANCH}" | grep "${UPDATE_BRANCH}" | wc -l) -eq 0 ]]; then + gh pr create -B master -H ${UPDATE_BRANCH} --title "${TITLE}" --body "Automatic updated of sonar-scanner version value. Needs to be tagged for release." + fi diff --git a/README.md b/README.md index dc75636..69f7f69 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Scan your code with SonarQube [![QA](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa.yml/badge.svg)](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa.yml) +# Scan your code with SonarQube [![QA Main](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-main.yml/badge.svg)](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-main.yml) [![QA Install Build Wrapper](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-install-build-wrapper.yml/badge.svg)](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-install-build-wrapper.yml) [![QA Scripts](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-scripts.yml/badge.svg)](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-scripts.yml) [![QA Deprecated C and C++ Action](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-deprecated-c-cpp.yml/badge.svg)](https://github.com/SonarSource/sonarqube-scan-action/actions/workflows/qa-deprecated-c-cpp.yml) This SonarSource project, available as a GitHub Action, scans your projects with SonarQube [Server](https://www.sonarsource.com/products/sonarqube/) or [Cloud](https://www.sonarsource.com/products/sonarcloud/). @@ -11,6 +11,9 @@ It helps developers detect coding issues in 30+ languages, frameworks, and IaC p The solution also provides fix recommendations leveraging AI with Sonar's AI CodeFix capability. +> [!NOTE] +> This action now supports and is the official entrypoint for scanning C, C++, Objective-C and Dart projects via GitHub actions. + ## Requirements ### Server @@ -38,7 +41,9 @@ sonar.projectKey= + env: + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + - name: Run Build Wrapper + run: | + # here goes your compilation wrapped with build-wrapper; See https://docs.sonarsource.com/sonarqube/latest/ analyzing-source-code/languages/c-family/#using-build-wrapper for more information + # build-preparation steps + # build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command + - name: SonarQube Scan + uses: sonarsource/sonarqube-scan-action@ + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + args: | + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" + #Consult https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options +``` + +If you are using SonarQube Server 10.5 or earlier, use `sonar.cfamily.build-wrapper-output` instead of `sonar.cfamily.compile-commands` in the `run` property of the last step, as Build Wrapper does not generate a compile_commands.json file before SonarQube Server 10.6, like this: +```yaml +with: + args: | + --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" +``` + +See also [example configurations of C++ projects for SonarQube Server](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sq&type=repositories). + ### Cloud ```properties @@ -108,6 +168,54 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} ``` +For C, C++ and Objective-C projects not using AutoConfig, the workflow requires additional steps to download the Build Wrapper and invoking it: + +```yaml +# Trigger analysis when pushing to your main branches, and when creating a pull request. + push: + branches: + - main + - master + - develop + - 'releases/**' + pull_request: + types: [opened, synchronize, reopened] + +name: Main Workflow +jobs: + sonarqube: + runs-on: ubuntu-latest + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + steps: + - uses: actions/checkout@v4 + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + - name: Install Build Wrapper + uses: sonarsource/sonarqube-scan-action/install-build-wrapper@ + env: + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + - name: Run Build Wrapper + run: | + # here goes your compilation wrapped with build-wrapper; See https://docs.sonarsource.com/sonarqube/latest/ analyzing-source-code/languages/c-family/#using-build-wrapper for more information + # build-preparation steps + # build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command + - name: SonarQube Scan + uses: sonarsource/sonarqube-scan-action@ + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + args: | + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" + #Consult https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options +``` + +See also [example configurations of C++ projects for SonarQube Cloud](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sc&type=repositories). + ## Action parameters You can change the analysis base directory by using the optional input `projectBaseDir` like this: @@ -190,9 +298,14 @@ This GitHub Action will not work for all technologies. If you are in one of the * Your code is built with Maven. Read the documentation about our SonarScanner for Maven in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner-for-maven/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-maven/). * Your code is built with Gradle. Read the documentation about our SonarScanner for Gradle in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner-for-gradle/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-gradle/). * You want to analyze a .NET solution. Read the documentation about our SonarScanner for .NET in SonarQube [Server](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/dotnet/introduction/) and [Cloud](https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/ci-based-analysis/sonarscanner-for-dotnet/introduction/). -* You want to analyze C or C++ code. Starting from SonarQube 10.6, this GitHub Action will scan C and C++ out of the box. If you want to have better control over the scan configuration/setup, you can switch to: - * the [SonarQube Server Scan for C and C++](https://github.com/marketplace/actions/sonarqube-scan-for-c-and-c) GitHub Action, for projects on SonarQube Server - * the [SonarQube Cloud Scan for C and C++](https://github.com/marketplace/actions/sonarcloud-scan-for-c-and-c) GitHub Action, for projects on SonarQube Cloud - look at [our sample C and C++ project](https://github.com/sonarsource-cfamily-examples?q=gh-actions-sc&type=all&language=&sort=). + +## Do not use this GitHub action if you are in the following situations + +* You want to run the action on C, C++, or Objective-C projects on a 32-bits system - build wrappers support only 64-bits OS. + +## Additional information + +The `sonarqube-scan-action/install-build-wrapper` action installs `coreutils` if run on macOS. ## Have questions or feedback? diff --git a/deprecated-c-cpp-action/action.yml b/deprecated-c-cpp-action/action.yml new file mode 100644 index 0000000..4f967d6 --- /dev/null +++ b/deprecated-c-cpp-action/action.yml @@ -0,0 +1,127 @@ +name: 'SonarQube Scan for C and C++' +description: 'Scan your C and C++ code with SonarQube to detect bugs, vulnerabilities and code smells.' +branding: + icon: check + color: green +inputs: + installation-path: + description: 'Directory where the sonar-scanner and build wrapper will be installed. Created if does not exists.' + required: false + default: '.sonar' + cache-binaries: + description: 'Controls if installed binaries are cached using GitHub cache.' + required: false + default: 'true' + +outputs: + sonar-scanner-binary: + description: "Absolute path to sonar-scanner binary." + value: ${{ steps.setup-outputs.outputs.sonar-scanner-binary }} + build-wrapper-binary: + description: "Absolute path to build-wrapper binary." + value: ${{ steps.setup-outputs.outputs.build-wrapper-binary }} + +runs: + using: "composite" + steps: + # install packaged required for greadlink and sha256sum command on macOS + - name: Install required packages for macOS + if: runner.os == 'macOS' + shell: bash + run: brew install coreutils + + - name: Verify and create installation path + shell: bash + env: + INSTALL_PATH: ${{ inputs.installation-path }} + run: ${GITHUB_ACTION_PATH}/../scripts/create_install_path.sh + + - name: Set version of sonar-scanner + id: sonar-scanner-version + shell: bash + run: cat ${GITHUB_ACTION_PATH}/../sonar-scanner-version >> $GITHUB_OUTPUT + + - name: Configure paths + id: configure_paths + shell: bash + env: + OS: ${{ runner.os }} + ARCH: ${{ runner.arch }} + INSTALL_PATH: ${{ inputs.installation-path }} + SONAR_SCANNER_VERSION: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-version }} + SONAR_SCANNER_URL_WINDOWS_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-windows-x64 }} + SONAR_SCANNER_SHA_WINDOWS_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-windows-x64 }} + SONAR_SCANNER_URL_LINUX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-linux-x64 }} + SONAR_SCANNER_SHA_LINUX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-linux-x64 }} + SONAR_SCANNER_URL_LINUX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-linux-aarch64 }} + SONAR_SCANNER_SHA_LINUX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-linux-aarch64 }} + SONAR_SCANNER_URL_MACOSX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-macosx-x64 }} + SONAR_SCANNER_SHA_MACOSX_X64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-macosx-x64 }} + SONAR_SCANNER_URL_MACOSX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-url-macosx-aarch64 }} + SONAR_SCANNER_SHA_MACOSX_AARCH64: ${{ steps.sonar-scanner-version.outputs.sonar-scanner-sha-macosx-aarch64 }} + run: ${GITHUB_ACTION_PATH}/../scripts/configure_paths.sh >> $GITHUB_OUTPUT + + - name: Cache sonar-scanner installation + id: cache-sonar-tools + if: inputs.cache-binaries == 'true' + uses: actions/cache@v4 + env: + # The default value is 60mins. Reaching timeout is treated the same as a cache miss. + SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 + with: + key: sonar-scanner-${{ runner.os }}-${{ runner.arch }}-${{ steps.sonar-scanner-version.outputs.sonar-scanner-version }} + path: ${{ steps.configure_paths.outputs.sonar-scanner-dir }} + + - name: Download and install sonar-scanner + if: steps.cache-sonar-tools.outputs.cache-hit != 'true' + shell: bash + env: + DOWNLOAD_URL: ${{ steps.configure_paths.outputs.sonar-scanner-url }} + EXPECTED_SHA: ${{ steps.configure_paths.outputs.sonar-scanner-sha }} + INSTALL_PATH: ${{ inputs.installation-path }} + TMP_ZIP_PATH: ${{ runner.temp }}/sonar-scanner.zip + run: ${GITHUB_ACTION_PATH}/../scripts/download.sh -v + + - name: Add the custom root certificate to java certificate store + shell: bash + run: ${GITHUB_ACTION_PATH}/../scripts/cert.sh + + - name: Download and install build-wrapper + shell: bash + env: + DOWNLOAD_URL: ${{ steps.configure_paths.outputs.build-wrapper-url }} + INSTALL_PATH: ${{ inputs.installation-path }} + TMP_ZIP_PATH: ${{ runner.temp }}/build-wrapper.zip + run: ${GITHUB_ACTION_PATH}/../scripts/download.sh + + - name: Setup action outputs + id: setup-outputs + shell: bash + env: + SONAR_SCANNER_DIR: ${{ steps.configure_paths.outputs.sonar-scanner-dir }} + SONAR_SCANNER_BIN: ${{ steps.configure_paths.outputs.sonar-scanner-bin }} + BUILD_WRAPPER_DIR: ${{ steps.configure_paths.outputs.build-wrapper-dir }} + BUILD_WRAPPER_BIN: ${{ steps.configure_paths.outputs.build-wrapper-bin }} + run: | + source ${GITHUB_ACTION_PATH}/../scripts/utils.sh + + echo "::group::Action outputs" + echo "SONAR_HOST_URL=${SONAR_HOST_URL}" >> $GITHUB_ENV + echo "'SONAR_HOST_URL' environment variable set to '${SONAR_HOST_URL}'" + + SONAR_SCANNER_BIN_DIR=$(realpath "${SONAR_SCANNER_DIR}/bin") + echo "${SONAR_SCANNER_BIN_DIR}" >> $GITHUB_PATH + echo "'${SONAR_SCANNER_BIN_DIR}' added to the path" + + SONAR_SCANNER_BIN=$(realpath "${SONAR_SCANNER_BIN}") + echo "sonar-scanner-binary=${SONAR_SCANNER_BIN}" >> $GITHUB_OUTPUT + echo "'sonar-scanner-binary' output set to '${SONAR_SCANNER_BIN}'" + + BUILD_WRAPPER_BIN_DIR=$(realpath "${BUILD_WRAPPER_DIR}") + echo "${BUILD_WRAPPER_BIN_DIR}" >> $GITHUB_PATH + echo "'${BUILD_WRAPPER_BIN_DIR}' added to the path" + + BUILD_WRAPPER_BIN=$(realpath "${BUILD_WRAPPER_BIN}") + echo "build-wrapper-binary=${BUILD_WRAPPER_BIN}" >> $GITHUB_OUTPUT + echo "'build-wrapper-binary' output set to '${BUILD_WRAPPER_BIN}'" + echo "::endgroup::" diff --git a/install-build-wrapper/action.yml b/install-build-wrapper/action.yml new file mode 100644 index 0000000..568feb9 --- /dev/null +++ b/install-build-wrapper/action.yml @@ -0,0 +1,55 @@ +name: 'Install Build Wrapper for C and C++' +description: > + Download and install the Build Wrapper for C, C++, and Objective-C + projects analyzed with manual config. +branding: + icon: check + color: green +outputs: + build-wrapper-binary: + description: "Absolute path to Build Wrapper binary." + value: ${{ steps.setup-outputs.outputs.build-wrapper-binary }} +runs: + using: "composite" + + steps: + # install packaged required for greadlink and sha256sum command on macOS + - name: Install required packages for macOS + if: runner.os == 'macOS' + shell: bash + run: brew install coreutils + + - name: Configure paths + id: configure_paths + shell: bash + env: + OS: ${{ runner.os }} + ARCH: ${{ runner.arch }} + INSTALL_PATH: ${{ runner.temp }} # TODO: or .sonar, if RUNNER_TEMP creates problem with caching and self-hosted runners + run: ${GITHUB_ACTION_PATH}/../scripts/configure_paths.sh >> $GITHUB_OUTPUT + + - name: Download and install Build Wrapper + shell: bash + env: + DOWNLOAD_URL: ${{ steps.configure_paths.outputs.build-wrapper-url }} + TMP_ZIP_PATH: ${{ runner.temp }}/build-wrapper-${{ inputs.configure_paths.sonar-scanner-version }}-${{ runner.os }}-${{ runner.arch }}.zip + INSTALL_PATH: ${{ runner.temp }} # TODO: or .sonar, if RUNNER_TEMP creates problem with caching and self-hosted runners + run: ${GITHUB_ACTION_PATH}/../scripts/download.sh + + - name: Setup action outputs + id: setup-outputs + shell: bash + env: + BUILD_WRAPPER_DIR: ${{ steps.configure_paths.outputs.build-wrapper-dir }} + BUILD_WRAPPER_BIN: ${{ steps.configure_paths.outputs.build-wrapper-bin }} + run: | + source ${GITHUB_ACTION_PATH}/../scripts/utils.sh + + BUILD_WRAPPER_BIN_DIR=$(realpath "${BUILD_WRAPPER_DIR}") + echo "${BUILD_WRAPPER_BIN_DIR}" >> $GITHUB_PATH + echo "'${BUILD_WRAPPER_BIN_DIR}' added to the path" + + BUILD_WRAPPER_BIN=$(realpath "${BUILD_WRAPPER_BIN}") + echo "build-wrapper-binary=${BUILD_WRAPPER_BIN}" >> $GITHUB_OUTPUT + echo "'build-wrapper-binary' output set to '${BUILD_WRAPPER_BIN}'" + echo "::endgroup::" diff --git a/scripts/cert.sh b/scripts/cert.sh new file mode 100755 index 0000000..2c2a2a5 --- /dev/null +++ b/scripts/cert.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ -n "${SONAR_ROOT_CERT}" ]]; then + echo "Adding custom root certificate to java certificate store" + rm -f /tmp/tmpcert.pem + echo "${SONAR_ROOT_CERT}" > /tmp/tmpcert.pem + keytool -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias sonarqube -file /tmp/tmpcert.pem +fi diff --git a/scripts/configure_paths.sh b/scripts/configure_paths.sh new file mode 100755 index 0000000..d1bbfe1 --- /dev/null +++ b/scripts/configure_paths.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +if [[ ${ARCH} != "X64" && ! (${ARCH} == "ARM64" && (${OS} == "macOS" || ${OS} == "Linux")) ]]; then + echo "::error::Architecture '${ARCH}' is unsupported by build-wrapper" + exit 1 +fi + +case ${OS} in + Windows) + SONAR_SCANNER_SUFFIX="windows-x64" + BUILD_WRAPPER_SUFFIX="win-x86" + SONAR_SCANNER_NAME="sonar-scanner.bat" + BUILD_WRAPPER_NAME="build-wrapper-win-x86-64.exe" + SONAR_SCANNER_URL="${SONAR_SCANNER_URL_WINDOWS_X64}" + SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_WINDOWS_X64}" + ;; + Linux) + case ${ARCH} in + X64) + SONAR_SCANNER_SUFFIX="linux-x64" + BUILD_WRAPPER_SUFFIX="linux-x86" + BUILD_WRAPPER_NAME="build-wrapper-linux-x86-64" + SONAR_SCANNER_URL="${SONAR_SCANNER_URL_LINUX_X64}" + SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_LINUX_X64}" + ;; + ARM64) + SONAR_SCANNER_SUFFIX="linux-aarch64" + BUILD_WRAPPER_SUFFIX="linux-aarch64" + BUILD_WRAPPER_NAME="build-wrapper-linux-aarch64" + SONAR_SCANNER_URL="${SONAR_SCANNER_URL_LINUX_AARCH64}" + SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_LINUX_AARCH64}" + ;; + esac + SONAR_SCANNER_NAME="sonar-scanner" + ;; + macOS) + case ${ARCH} in + X64) + SONAR_SCANNER_SUFFIX="macosx-x64" + SONAR_SCANNER_URL="${SONAR_SCANNER_URL_MACOSX_X64}" + SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_MACOSX_X64}" + ;; + ARM64) + SONAR_SCANNER_SUFFIX="macosx-aarch64" + SONAR_SCANNER_URL="${SONAR_SCANNER_URL_MACOSX_AARCH64}" + SONAR_SCANNER_SHA="${SONAR_SCANNER_SHA_MACOSX_AARCH64}" + ;; + esac + BUILD_WRAPPER_SUFFIX="macosx-x86" + SONAR_SCANNER_NAME="sonar-scanner" + BUILD_WRAPPER_NAME="build-wrapper-macosx-x86" + ;; + *) + echo "::error::Unsupported runner OS '${OS}'" + exit 1 + ;; +esac + + +echo "sonar-scanner-url=${SONAR_SCANNER_URL}" +echo "sonar-scanner-sha=${SONAR_SCANNER_SHA}" + +SONAR_SCANNER_DIR="${INSTALL_PATH}/sonar-scanner-${SONAR_SCANNER_VERSION}-${SONAR_SCANNER_SUFFIX}" +echo "sonar-scanner-dir=${SONAR_SCANNER_DIR}" +echo "sonar-scanner-bin=${SONAR_SCANNER_DIR}/bin/${SONAR_SCANNER_NAME}" + +BUILD_WRAPPER_DIR="${INSTALL_PATH}/build-wrapper-${BUILD_WRAPPER_SUFFIX}" +echo "build-wrapper-url=${SONAR_HOST_URL%/}/static/cpp/build-wrapper-${BUILD_WRAPPER_SUFFIX}.zip" +echo "build-wrapper-dir=${BUILD_WRAPPER_DIR}" +echo "build-wrapper-bin=${BUILD_WRAPPER_DIR}/${BUILD_WRAPPER_NAME}" + diff --git a/scripts/create_install_path.sh b/scripts/create_install_path.sh new file mode 100755 index 0000000..7e35571 --- /dev/null +++ b/scripts/create_install_path.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +source "$(dirname -- "$0")/utils.sh" + +echo "Installation path is '${INSTALL_PATH}'" + +test ! -z "${INSTALL_PATH}" +check_status "Empty installation path specified" + +if [[ ! -e "${INSTALL_PATH}" ]]; then + mkdir -p "${INSTALL_PATH}" + check_status "Failed to create non-existing installation path '${INSTALL_PATH}'" +fi + +ABSOLUTE_INSTALL_PATH=$(realpath "${INSTALL_PATH}") +echo "Absolute installation path is '${ABSOLUTE_INSTALL_PATH}'" + +test -d "${INSTALL_PATH}" +check_status "Installation path '${INSTALL_PATH}' is not a directory (absolute path is '${ABSOLUTE_INSTALL_PATH}')" + +test -r "${INSTALL_PATH}" +check_status "Installation path '${INSTALL_PATH}' is not readable (absolute path is '${ABSOLUTE_INSTALL_PATH}')" + +test -w "${INSTALL_PATH}" +check_status "Installation path '${INSTALL_PATH}' is not writeable (absolute path is '${ABSOLUTE_INSTALL_PATH}')" + diff --git a/scripts/download.sh b/scripts/download.sh new file mode 100755 index 0000000..9e1aefa --- /dev/null +++ b/scripts/download.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +source "$(dirname -- "$0")/utils.sh" + +VERIFY_CORRECTNESS=false + +help() { + cat <