From bf20180485cdf01dbbd70b6b0297d302af65ffd4 Mon Sep 17 00:00:00 2001 From: Antonio Aversa Date: Wed, 11 Dec 2024 12:09:25 +0100 Subject: [PATCH 1/4] SQCPPGHA-9 Rebranding and forwarding to sonarqube-scan-action/deprecated-c-cpp-action --- .github/workflows/tests.yml | 346 --------------------- .github/workflows/version_update.yml | 51 --- README.md | 106 ++++--- action.yml | 103 +----- images/SQ_Logo_Cloud_Dark_Backgrounds.png | Bin 0 -> 21928 bytes images/SQ_Logo_Cloud_Light_Backgrounds.png | Bin 0 -> 23073 bytes images/SonarQube-72px.png | Bin 2619 -> 0 bytes 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 - 14 files changed, 67 insertions(+), 763 deletions(-) delete mode 100644 .github/workflows/version_update.yml create mode 100644 images/SQ_Logo_Cloud_Dark_Backgrounds.png create mode 100644 images/SQ_Logo_Cloud_Light_Backgrounds.png delete mode 100644 images/SonarQube-72px.png delete mode 100755 scripts/cert.sh delete mode 100755 scripts/configure_paths.sh delete mode 100755 scripts/create_install_path.sh delete mode 100755 scripts/download.sh delete mode 100755 scripts/fetch_latest_version.sh delete mode 100755 scripts/utils.sh delete mode 100644 sonar-scanner-version diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 05ac0f6..ca090c9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,352 +7,6 @@ on: types: [opened, synchronize, reopened] jobs: - create-install-dir-test: - name: create_install_path.sh script test - 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 script test - 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: Unssuported 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: Unssuported 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 script test - 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 script test - 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 - output-test: name: Test action outputs strategy: diff --git a/.github/workflows/version_update.yml b/.github/workflows/version_update.yml deleted file mode 100644 index f028f3c..0000000 --- a/.github/workflows/version_update.yml +++ /dev/null @@ -1,51 +0,0 @@ -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 e14742e..aabf77b 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,46 @@ -# Configure & Run C, C++ and Objective-C Scan with SonarQube [![Tests](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml/badge.svg)](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml) +# Scan your C, C++, and Objective-C code with SonarQube [![Tests](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml/badge.svg)](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml) -This SonarSource project, available as a GitHub Action, sets up the tools needed to configure and run scans of C, C++, and Objective-C projects with SonarQube. +This SonarSource project, available as a GitHub Action, scans your C, C++, and Objective-C projects with [SonarQube Server](https://www.sonarsource.com/products/sonarqube/). -The SonarQube logo +![Logo](./images/SQ_Logo_Cloud_Dark_Backgrounds.png#gh-dark-mode-only) +![Logo](./images/SQ_Logo_Cloud_Light_Backgrounds.png#gh-light-mode-only) -[SonarQube](https://www.sonarsource.com/products/sonarqube/) is a widely used static analysis solution for continuous code quality and security inspection. -It helps developers identify and fix issues in their code that could lead to bugs, vulnerabilities, or decreased development velocity. -SonarQube supports the most popular programming languages, including Java, JavaScript, TypeScript, C#, Python, C, C++, and [many more](https://www.sonarsource.com/knowledge/languages/). +[SonarQube Server](https://www.sonarsource.com/products/sonarqube/) is a widely used static analysis solution for continuous code quality and security inspection. -## Requirements +It helps developers detect coding issues in 30+ languages, frameworks, and IaC platforms, including Java, JavaScript, TypeScript, C#, Python, C, C++, and [many more](https://www.sonarsource.com/knowledge/languages/). -To run an analysis on your code, you first need to set up your project on SonarQube. -Your SonarQube instance must be accessible from GitHub, and you will need a Project analysis token or a Global analysis token to run the analysis (more information below under **Environment variables**). +The solution also provides fix recommendations leveraging AI with Sonar's AI CodeFix capability. -Read more information on how to analyze your code [here](https://docs.sonarqube.org/latest/analysis/github-integration/). +## Requirements +To run an analysis on your code, you first need to set up your project on SonarQube Server. Your SonarQube Server instance must be accessible from GitHub, and you will need an access token to run the analysis (more information below under **Environment variables**). -## Usage +Read more information on how to analyze your code [here](https://docs.sonarsource.com/sonarqube-server/latest/devops-platform-integration/github-integration/introduction/). - -Project metadata, including the location to the sources to be analyzed, must be declared in the file `sonar-project.properties` in the base directory: +## Usage ```properties -sonar.projectKey= +sonar.projectKey= # relative paths to source directories. More details and properties are described -# in https://docs.sonarsource.com/sonarqube/latest/project-administration/analysis-scope/ +# at https://docs.sonarsource.com/sonarqube-server/latest/project-administration/analysis-scope/ sonar.sources=. ``` -The workflow, usually declared in `.github/workflows/build.yml`, looks like: +The workflow, usually declared under `.github/workflows`, looks like the following: ```yaml on: - # Trigger analysis when pushing in master or pull requests, and when creating - # a pull request. + # 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: @@ -52,79 +53,84 @@ jobs: # Disabling shallow clone is recommended for improving relevancy of reporting fetch-depth: 0 - name: Install sonar-scanner and build-wrapper - uses: sonarsource/sonarqube-github-c-cpp@v2 - env: - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + uses: sonarsource/sonarqube-github-c-cpp@ # Ex: v4.0.0, See the latest version at https://github.com/marketplace/actions/sonarqube-scan-for-c-and-c - 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 + # here goes your compilation wrapped with build-wrapper; See https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/languages/c-family/overview/#analysis-steps-using-build-wrapper for more information + # build-preparation steps + # build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command - name: Run sonar-scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} run: sonar-scanner --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 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 10.6, like this: +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 - run: sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" +run: sonar-scanner --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" ``` +See also [example configurations of C++ projects for SonarQube Server](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sq&type=repositories). + +## Action parameters You can change the `build-wrapper` and `sonar-scanner` installation path by using the optional input `installation-path` like this: ```yaml -uses: sonarsource/sonarqube-github-c-cpp@v2 +uses: sonarsource/sonarqube-github-c-cpp@ with: installation-path: my/custom/directory/path ``` + Also, the absolute paths to the installed build-wrapper and sonar-scanner binaries are returned as outputs from the action. Moreover, by default the action will cache sonar-scanner installation. However, you can disable caching by using the optional input: `cache-binaries` like this: ```yaml -uses: sonarsource/sonarqube-github-c-cpp@v2 +uses: sonarsource/sonarqube-github-c-cpp@ with: cache-binaries: false ``` -If your SonarQube server uses a self-signed certificate, you can pass a root certificate (in PEM format) to the java certificate store: +See also [example configurations](https://github.com/sonarsource-cfamily-examples?q=gh-actions-sq&type=all&language=&sort=) -```yaml -uses: sonarsource/sonarqube-github-c-cpp@v2 -env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} -``` +### Environment variables -See also [example configurations](https://github.com/search?q=org%3Asonarsource-cfamily-examples+gh-actions-sq&type=repositories) +- `SONAR_TOKEN` – **Required** this is the token used to authenticate access to SonarQube. You can read more about security tokens in the [documentation](https://docs.sonarsource.com/sonarqube-server/latest/user-guide/managing-tokens/). You can set the `SONAR_TOKEN` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). +- *`GITHUB_TOKEN` – Provided by Github (see [Authenticating with the GITHUB_TOKEN](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token)).* +- `SONAR_HOST_URL` – this tells the scanner where SonarQube Server is hosted. You can set the `SONAR_HOST_URL` environment variable in the "Variables" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). +- `SONAR_ROOT_CERT` – Holds an additional certificate (in PEM format) that is used to validate the certificate of SonarQube Server or of a secured proxy to it. You can set the `SONAR_ROOT_CERT` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). -### Secrets and environment variables +Here is an example of how you can pass a certificate (in PEM format) to the Scanner truststore: -Following secrets are required for successful invocation of sonar-scanner: -- `SONAR_TOKEN` – **Required** this is the token used to authenticate access to SonarQube. You can read more about security tokens [here](https://docs.sonarqube.org/latest/user-guide/user-token/). You can set the `SONAR_TOKEN` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). -- *`GITHUB_TOKEN` – Provided by Github (see [Authenticating with the GITHUB_TOKEN](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token)).* +```yaml +- uses: sonarsource/sonarqube-github-c-cpp@ + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} +``` + +If your source code file names contain special characters that are not covered by the locale range of `en_US.UTF-8`, you can configure your desired locale like this: -Environment variables: -- `SONAR_HOST_URL` – **Required** this tells the scanner where SonarQube is hosted. You can set the `SONAR_HOST_URL` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). -- `SONAR_ROOT_CERT` – Holds an additional root certificate (in PEM format) that is used to validate the SonarQube server certificate. You can set the `SONAR_ROOT_CERT` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). +```yaml +- uses: sonarsource/sonarqube-github-c-cpp@ + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + LC_ALL: "ru_RU.UTF-8" +``` ## Do not use this GitHub action if you are in the following situations -* You want to analyze code that doesn't have C, C++, or Objective-C? Use the [SonarQube Scan GitHub Action](https://github.com/SonarSource/sonarqube-scan-action) instead -* You want to run the action on a 32-bits system - build wrappers support only 64-bits OS +* You want to analyze code written in a language other than C or C++. Use the [SonarQube GitHub Action for SonarQube Server and Cloud](https://github.com/SonarSource/sonarqube-scan-action/) instead. +* You want to run the action on a 32-bits system - build wrappers support only 64-bits OS. ## Additional information -This action installs `coreutils` if run on macOS +This action installs `coreutils` if run on macOS. ## Have question or feedback? -To provide feedback (requesting a feature or reporting a bug) please post on the [SonarSource Community Forum](https://community.sonarsource.com/) with the tag `sonarqube`. +To provide feedback (requesting a feature or reporting a bug) please post on the [SonarSource Community Forum](https://community.sonarsource.com/tags/c/help/sq/github-actions). ## License diff --git a/action.yml b/action.yml index e24d545..7fcd601 100644 --- a/action.yml +++ b/action.yml @@ -24,104 +24,23 @@ outputs: 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 + - name: SonarQube Scan + id: scan + uses: sonarsource/sonarqube-scan-action/deprecated-c-cpp@antonio/SQCPPGHA-9-rebranding-and-forward 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 - + installation-path: ${{ inputs.installation-path }} + cache-binaries: ${{ inputs.cache-binaries }} - 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 }} + SONAR_SCANNER_BINARY: ${{ steps.scan.outputs.sonar-scanner-binary }} + BUILD_WRAPPER_BINARY: ${{ steps.scan.outputs.build-wrapper-binary }} 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" + echo "sonar-scanner-binary=${SONAR_SCANNER_BINARY}" >> $GITHUB_OUTPUT + echo "'sonar-scanner-binary' output set to '${SONAR_SCANNER_BINARY}'" - 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 "build-wrapper-binary=${BUILD_WRAPPER_BINARY}" >> $GITHUB_OUTPUT + echo "'build-wrapper-binary' output set to '${BUILD_WRAPPER_BINARY}'" echo "::endgroup::" diff --git a/images/SQ_Logo_Cloud_Dark_Backgrounds.png b/images/SQ_Logo_Cloud_Dark_Backgrounds.png new file mode 100644 index 0000000000000000000000000000000000000000..9e9a1f41fbee273783b6a7d7ab70eca31d1cb103 GIT binary patch literal 21928 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 R@|EL?cl1njOKv)Z{|~^DYvup| literal 0 HcmV?d00001 diff --git a/images/SQ_Logo_Cloud_Light_Backgrounds.png b/images/SQ_Logo_Cloud_Light_Backgrounds.png new file mode 100644 index 0000000000000000000000000000000000000000..4a7f25ef944058ce6f86ee030af45739b8a8314f GIT binary patch literal 23073 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 HIK28Fw3+~m literal 0 HcmV?d00001 diff --git a/images/SonarQube-72px.png b/images/SonarQube-72px.png deleted file mode 100644 index 400830be4f315781b907b99994f430c39f345038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2619 zcmV-B3dHq^P)3C{k>cv^ z;qdp}!*G4~-xkX|I$jN~?tXk5gZ&o;{MFZo+Zs`r9G>ft>`y3>FD_Fprws6`-gy~ zS)Ix$6SR=#)0cK^cQ|q5cl_BCf>V zr4yv%#ef2xG6My#5U&I`ilM8vBY6(4|a*S;W$vi9}hZ6Qtu5LCYgC(=S3nZ7hrA2^GsO z)1gc=FX?`K!}5-flYvPRCGZJp@aqJaY))CGc4yMj@!}EgJ8-#WY`~EqbOMGtd`Lj$ zegDz%I>5Kz%L$cn`jinw*@G+_`8>OHbR^hpHkTKhi(M4@JL_UJHiisT@`SGX!cqz;zHJCc5K)nVdP$w9bEzu{6h=~v5XSGK(B=qTcp z$w81ytnisS5P(clgG9lYe$3ZJC;RIAKb=$9s}`q6ffkKp0D-yV?k}L zkt6#3Dcbf_b`bof@3Q}Z<<(KyBMjD=`!+h}Ae{uVA0=UM%?z2^7`Hw8#q zXLGR&WfXK{eJp3$m+VsDyD1Q<4_H^qK<~2#PSKy+#{o9TGN>Lv`mW$3mP4@}qc5B! z)krARLAaENx3bJ4NAR0IrU!c7I-!(eqZSiuK|ifs2$E)qBzuf{vP{K?vk%u=qYW9b zejwK5c+@S4*9M-Rqi!I?G|QrmT$CVbuA9n00hrl>;3o;eZoEU*WrEhoiK4bc3FaN@ zAYAHOFUu5rTdPkX2hHaau01yD!P)>Kfc!!i?=S>;4)S>ho`JBDwv6nT^_duJ2RzCi z3E~uTxOU=B0>QMpkBbbA?W4h0+ZgLHF*F_W-7RMmvZML(fPGSec_+&?xE18!Sw3yU zRA1|ZIw=uUJL5BIueJ(k=|>Cr{vs}~yeyL^SH=4c?r`2&OTY@4LJ(!G}?E-B^DEY(HTjBlZ}>5 z(ay0bW{=wMI=ErzjL=c(5T1EyRvTo)c{zr4qwJ|%=%F(g5rlJk@JSh1hyIIYv)~|z z^)AiQ$!0KobZ3)1NxiP#zC@@_OOR;5SyvJOgZY`rk!AJ>b;Tf76*ZNCI_)k0+(iw5NJv; z?Vwr)YNOR&w5JhW1I7Wh1IL-3k^PdOo!0l)z(=>!(rVmiV0jU){g`bpmlrVTQU+l@ zgQ6cK4z4qT&l>zzea>2HmZ^!f(cJ}m)0;=Wx63})p%M^QCS#Ck8 z7lqtqKK#xJ`ll3Z?AgviB9N87fQA}OVSkgQfIf{ED zdFD<7YHaXZ$YBMOHtVm2W&;Dz@{a_x-ODn?-d2`dK>w=bSbW?pPj#G2c#euvvGlS$BS-5|F8IuN zK8PxR1XuEF+}7WVJNi7}{NkQwBpftnFP%J<VdU2GW?7gNRv*Y-i=?&p-}w za#U;Iqsg(!4g~h-YlL=CfAdW z#ZzD=$BG|0X|q`_XXRggiS%6~N%FRQ> /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 deleted file mode 100755 index d1bbfe1..0000000 --- a/scripts/configure_paths.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/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 deleted file mode 100755 index 7e35571..0000000 --- a/scripts/create_install_path.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/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 deleted file mode 100755 index 9e1aefa..0000000 --- a/scripts/download.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -source "$(dirname -- "$0")/utils.sh" - -VERIFY_CORRECTNESS=false - -help() { - cat < Date: Thu, 12 Dec 2024 12:22:46 +0100 Subject: [PATCH 2/4] Code review: remove GITHUB_TOKEN from example and env vars section in README --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index aabf77b..4cfbbb5 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,6 @@ jobs: # build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} build-command - name: Run sonar-scanner env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: sonar-scanner --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 ``` @@ -97,7 +96,7 @@ See also [example configurations](https://github.com/sonarsource-cfamily-example ### Environment variables - `SONAR_TOKEN` – **Required** this is the token used to authenticate access to SonarQube. You can read more about security tokens in the [documentation](https://docs.sonarsource.com/sonarqube-server/latest/user-guide/managing-tokens/). You can set the `SONAR_TOKEN` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). -- *`GITHUB_TOKEN` – Provided by Github (see [Authenticating with the GITHUB_TOKEN](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token)).* +automating-your-workflow-with-github-actions/authenticating-with-the-github_token)).* - `SONAR_HOST_URL` – this tells the scanner where SonarQube Server is hosted. You can set the `SONAR_HOST_URL` environment variable in the "Variables" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). - `SONAR_ROOT_CERT` – Holds an additional certificate (in PEM format) that is used to validate the certificate of SonarQube Server or of a secured proxy to it. You can set the `SONAR_ROOT_CERT` environment variable in the "Secrets" settings page of your repository, or you can add them at the level of your GitHub organization (recommended). From e1e60566af6f9276f73e6db47b5eb20ea51ab03b Mon Sep 17 00:00:00 2001 From: Antonio Aversa Date: Thu, 12 Dec 2024 13:41:44 +0100 Subject: [PATCH 3/4] Code review: change title to SonarQube Server Co-authored-by: Michael Jabbour <117195239+michael-jabbour-sonarsource@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cfbbb5..c1e1fa6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Scan your C, C++, and Objective-C code with SonarQube [![Tests](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml/badge.svg)](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml) +# Scan your C, C++, and Objective-C code with SonarQube Server [![Tests](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml/badge.svg)](https://github.com/SonarSource/sonarqube-github-c-cpp/actions/workflows/tests.yml) This SonarSource project, available as a GitHub Action, scans your C, C++, and Objective-C projects with [SonarQube Server](https://www.sonarsource.com/products/sonarqube/). From e91b8e5fab6b7703dccdf199597a9238eaeb0a3d Mon Sep 17 00:00:00 2001 From: Antonio Aversa Date: Tue, 17 Dec 2024 11:58:44 +0100 Subject: [PATCH 4/4] Set forwarding to newly released v4.2.1 --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 7fcd601..df6aae0 100644 --- a/action.yml +++ b/action.yml @@ -26,7 +26,7 @@ runs: steps: - name: SonarQube Scan id: scan - uses: sonarsource/sonarqube-scan-action/deprecated-c-cpp@antonio/SQCPPGHA-9-rebranding-and-forward + uses: sonarsource/sonarqube-scan-action/deprecated-c-cpp@v4.2.1 with: installation-path: ${{ inputs.installation-path }} cache-binaries: ${{ inputs.cache-binaries }}