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: Set SONAR_HOST_URL to 'https://sonarcloud.io'
      if: env.SONAR_HOST_URL == ''
      shell: bash
      run: |
        echo "Setting SONAR_HOST_URL to 'https://sonarcloud.io'"
        echo "SONAR_HOST_URL=https://sonarcloud.io" >> $GITHUB_ENV

    - 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@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
      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::"
