diff --git a/.github/workflows/brew.sh b/.github/workflows/brew.sh index a4289ed..5e03be3 100644 --- a/.github/workflows/brew.sh +++ b/.github/workflows/brew.sh @@ -1,2 +1,15 @@ -brew install postgresql -brew install pkg-config \ No newline at end of file +#!/bin/bash + +# Check if a package is already installed via Homebrew, then skip +check_and_install() { + if ! brew list $1 &>/dev/null; then + echo "Installing $1..." + brew install $1 + else + echo "$1 is already installed" + fi +} + +# Install packages if they don't exist +check_and_install postgresql +check_and_install pkg-config \ No newline at end of file diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index e16ec9a..b84ab97 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,36 +1,55 @@ +# Backtesting C++ Workflow +# To build, test and perform SonarCloud analysis +name: Build + on: - # Trigger analysis when pushing in master or pull requests, and when creating - # a pull request. push: branches: - - main + - main # Trigger on pushes to main branch pull_request: - types: [opened, synchronize, reopened] -name: Build + types: + - opened # When PR is first created + - synchronize # When new commits are pushed to the PR + - reopened # When PR is reopened after being closed +# Environment variables used across jobs env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + BUILD_TYPE: Release # Set CMake build configuration + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Output directory for build wrapper jobs: - build: name: Build & Test - runs-on: macos-14 + runs-on: macos-14 # Use macOS 14 (Sonoma) runner + steps: - - uses: actions/checkout@v4 + # Step 1: Check out the repository code + - name: Checkout repository + uses: actions/checkout@v4 + + # Step 2: Set up Homebrew package manager - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master - - name: Install packages - run: > - bash ./.github/workflows/brew.sh - - name: Build libraries - run: > - bash ./.github/workflows/build.sh - - name: Select Xcode - run: sudo xcode-select -switch /Applications/Xcode_15.2.app && /usr/bin/xcodebuild -version + + # Step 3: Install required dependencies using Homebrew + - name: Install dependencies + run: bash ./.github/workflows/brew.sh + + # Step 4: Build project external libraries + - name: Build C++ Libraries + run: bash ./.github/workflows/build.sh + + # Step 5: Configure Xcode version + - name: Select Xcode version + run: | + sudo xcode-select -switch /Applications/Xcode_15.2.app + /usr/bin/xcodebuild -version + # Run XCode tests with specific configurations: + # - Builds and runs the test suite + # - Generates code coverage reports + # - Uses PostgreSQL and libpqxx external dependencies + # - Outputs results in JUnit format - name: Run tests run: > CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO @@ -48,13 +67,16 @@ jobs: - name: Convert coverage report to sonarqube format run: > bash ./.github/workflows/xccov-to-sonarqube-generic.sh *.xcresult/ > sonarqube-generic-coverage.xml + # Artifact will be available only for 1 day, this is because + # it's only used to pass test data to SonarCloud only - name: Upload coverage report uses: actions/upload-artifact@v4 with: path: sonarqube-generic-coverage.xml - retention-days: 1 # Artifact will be available only for 5 days. + retention-days: 1 + sonar-scan: - name: Sonar scan + name: SonarCloud Scan runs-on: ubuntu-latest needs: build steps: @@ -63,39 +85,42 @@ jobs: with: ref: ${{ github.HEAD_REF }} fetch-depth: 0 - - name: Check compiler version + - name: Check compiler version, for debugging run: | g++ --version cmake --version - - name: Build libraries + - name: Build C++ Libraries run: > bash ./.github/workflows/build.sh - - name: Set up Python 3.8 for gcovr + - name: Install Python 3.12 for gcovr uses: actions/setup-python@v5 with: - python-version: 3.8 - - name: install gcovr 5.0 + python-version: 3.12 + # Gcovr provides a utility for managing the use of the GNU gcov utility and generating + # summarized code coverage results. This command is inspired by the Python coverage.py + # package, which provides a similar utility for Python. + # https://pypi.org/project/gcovr/ + - name: Install gcovr run: | - pip install gcovr==5.0 # 5.1 is not supported by sonarcloud - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v3 + pip install gcovr==8.3 + # SonarQube Server and Cloud (formerly SonarQube and SonarCloud) is a widely used static + # analysis solution for continuous code quality and security inspection. + # This action now supports and is the official entrypoint for scanning C++ projects via GitHub actions. + # https://github.com/SonarSource/sonarqube-scan-action + - name: Install Build Wrapper + uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v4.2.1 - name: Download all workflow run artifacts uses: actions/download-artifact@v4 - - name: Unpack Artifact - run: > - ls -l ./ - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type run: cmake -S ${{github.workspace}} -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - name: Run build-wrapper run: | build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - name: Run sonar-scanner + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v4.2.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Put the name of your token here - run: | - sonar-scanner \ - --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" \ - -Dsonar.coverageReportPaths=artifact/sonarqube-generic-coverage.xml \ No newline at end of file + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" \ \ No newline at end of file