diff --git a/.github/actions/clang-tidy/action.sh b/.github/actions/clang-tidy/action.sh new file mode 100755 index 0000000..8bdc62b --- /dev/null +++ b/.github/actions/clang-tidy/action.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -e + +trap 'rm -rf ${TEMP_DIR}' EXIT + +function log() { + local level ts + level="$1" + ts="$(date --utc -Iseconds)" + shift + printf "[%s] - [%s] - \"%s\"\n" "${level^^}" "${ts}" "$*" +} + +function run_tidy() { + local output file_warnings file_errors + output=$(clang-tidy --header-filter=".*${PROJECT_NAME}.*" -p "$BUILD_DIR" "$1" 2>&1 || true) + file_warnings=$(echo "$output" | grep -c "${FILENAMES_BASE}/.*warning:" || true) + file_errors=$(echo "$output" | grep -c "${FILENAMES_BASE}/.*error:" || true) + echo "$file|$file_warnings|$file_errors" >"${TEMP_DIR}/${1}.count" + if [ "$file_errors" -gt 0 ]; then + echo "$output" | grep "${FILENAMES_BASE}/.*error:" >"${TEMP_DIR}/${1}.output" + elif [ "$file_warnings" -gt 0 ]; then + echo "$output" | grep "${FILENAMES_BASE}/.*warning:" >"${TEMP_DIR}/${1}.output" + fi +} + +SOURCE_DIR="$(realpath "$1")" +BUILD_DIR="$(realpath "$2")" +PROJECT_NAME="${SOURCE_DIR##*/}" +TEMP_DIR="$(mktemp -d)" + +log info "source directory: ${SOURCE_DIR}" +log info "build directory: ${BUILD_DIR}" + +if [ ! -f "${BUILD_DIR}/compile_commands.json" ]; then + log error "${BUILD_DIR}/compile_commands.json not found , please build the project first to generate compile_commands.json" + exit 1 +fi + +cd "${SOURCE_DIR}" +if ! (clang-tidy --version); then + log error "clang-tidy not installed" + exit 1 +fi + +log info "running clang-tidy, build=${BUILD_DIR} source=${SOURCE_DIR}" + +WORKER_COUNT="$(nproc)" +for file in *.cpp; do + run_tidy "${file}" & + while [ "$(jobs | wc -l)" -ge "${WORKER_COUNT}" ]; do + sleep 0.1 + done +done +wait + +log info "processing results" + +WARNINGS=0 +ERRORS=0 + +for file in *.cpp; do + if [ -f "${TEMP_DIR}/${file}.count" ]; then + IFS='|' read -r _ FILE_WARNINGS FILE_ERRORS <"${TEMP_DIR}/${file}.count" + if [ "$FILE_ERRORS" -gt 0 ]; then + log error "$file - has $FILE_ERRORS errors" + cat "${TEMP_DIR}/${file}.output" + ERRORS=$((ERRORS + FILE_ERRORS)) + elif [ "$FILE_WARNINGS" -gt 0 ]; then + log warn "$file - has $FILE_WARNINGS warnings" + cat "${TEMP_DIR}/${file}.output" + WARNINGS=$((WARNINGS + FILE_WARNINGS)) + else + log info "$file - no issues" + fi + fi +done + +log info "clang-tidy summary: warnings=$WARNINGS errors=$ERRORS" + +if [ $ERRORS -gt 0 ]; then + log error "clang-tidy found $ERRORS errors" + exit 1 +elif [ $WARNINGS -gt 0 ]; then + log warn "clang-tidy found $WARNINGS warnings (non-blocking)" + exit 0 +else + log info "no issues found" + exit 0 +fi diff --git a/.github/actions/clang-tidy/action.yaml b/.github/actions/clang-tidy/action.yaml new file mode 100644 index 0000000..839a2b0 --- /dev/null +++ b/.github/actions/clang-tidy/action.yaml @@ -0,0 +1,30 @@ +name: clang-tidy +description: run clang-tidy +inputs: + source_directory: + description: directory of the project source files + required: true + build_directory: + description: project build directory + required: true + +runs: + using: composite + steps: + - name: check + shell: bash + run: | + if ! (clang-tidy --version); then + log error "clang-tidy not installed" + exit 1 + fi + - name: clang-tidy + shell: bash + env: + SOURCE_DIR: ${{ inputs.source_directory }} + BUILD_DIR: ${{ inputs.build_directory }} + run: ${{ github.action_path }}/action.sh "${SOURCE_DIR}" "${BUILD_DIR}" + +branding: + icon: "terminal" + color: "black" diff --git a/.github/workflows/full_test.yml b/.github/workflows/full_test.yaml similarity index 93% rename from .github/workflows/full_test.yml rename to .github/workflows/full_test.yaml index 2dee04c..5ef6adb 100644 --- a/.github/workflows/full_test.yml +++ b/.github/workflows/full_test.yaml @@ -49,14 +49,14 @@ jobs: file.write("matrix_storage_filename=%s" % "${{ matrix.storage }}".replace(" ","").replace("--", "_")[1:]) - name: checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v6.0.2 with: repository: ${{ inputs.repo }} ref: ${{ inputs.ref }} fetch-depth: 0 - name: set up python ${{ matrix.python-version }} - uses: actions/setup-python@v6.0.0 + uses: actions/setup-python@v6.2.0 with: python-version: ${{ matrix.python-version }} cache: pip @@ -86,7 +86,7 @@ jobs: ### Setup authentication/credentials - name: authenticate (aws) if: contains(matrix.storage, 's3') || contains(matrix.storage, 's3path') - uses: aws-actions/configure-aws-credentials@v5.0.0 + uses: aws-actions/configure-aws-credentials@v6.1.1 with: role-to-assume: ${{ secrets.aws_role_arn }} aws-region: us-east-1 @@ -103,7 +103,7 @@ jobs: - name: authenticate (gcp) if: contains(matrix.storage, 'azure') - uses: Azure/login@v2.3.0 + uses: Azure/login@v3.0.0 with: creds: ${{ secrets.azure_creds_json }} @@ -148,7 +148,7 @@ jobs: LABELBOX_TOKEN: ${{ secrets.labelbox_token }} - name: save test results - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7.0.1 if: always() with: name: test-results-py${{ matrix.python-version }}-${{ matrix.os }}-${{ env.matrix_storage_filename }}_${{ github.run_number }}-${{ github.run_attempt }} @@ -166,12 +166,12 @@ jobs: steps: - name: checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v6.0.2 with: fetch-depth: 0 - name: set up python - uses: actions/setup-python@v6.0.0 + uses: actions/setup-python@v6.2.0 with: python-version: "3.10" cache: pip @@ -189,7 +189,7 @@ jobs: - name: run flaky tests id: flaky-tests - uses: nick-fields/retry@v3.0.2 + uses: nick-fields/retry@v4.0.0 with: timeout_minutes: 20 max_attempts: 3 @@ -208,7 +208,7 @@ jobs: LABELBOX_TOKEN: ${{ secrets.labelbox_token }} - name: save test results - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7.0.1 if: always() with: name: test-results-flaky_${{ github.run_number }}-${{ github.run_attempt }} @@ -225,12 +225,12 @@ jobs: steps: - name: checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v6.0.2 with: fetch-depth: 0 - name: checkout the buH source code - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v6.0.2 with: path: buH repository: activeloopai/buH @@ -238,13 +238,13 @@ jobs: # This will slowly get behind as new versions are released that are not in the cache. The cache can be dropped through the github UI when creation takes too long - name: cache datasets_clean - uses: actions/cache@v4.2.4 + uses: actions/cache@v5.0.5 with: path: datasets_clean/* key: buH-datasets-clean - name: set up python - uses: actions/setup-python@v6.0.0 + uses: actions/setup-python@v6.2.0 with: python-version: "3.10" cache: pip @@ -281,7 +281,7 @@ jobs: run: rm -rf datasets - name: save test results - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v7.0.1 if: always() with: name: test-results-backwards-compat_${{ github.run_attempt }} @@ -297,12 +297,12 @@ jobs: BUGGER_OFF: "true" steps: - name: checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v6.0.2 with: fetch-depth: 0 - name: download test results - uses: actions/download-artifact@v5.0.0 + uses: actions/download-artifact@v8.0.1 with: path: results @@ -312,13 +312,13 @@ jobs: # files: results/test-results-*/*.results.xml - name: publish test report - uses: mikepenz/action-junit-report@v5.6.2 + uses: mikepenz/action-junit-report@v6.4.1 if: always() with: report_paths: results/test-results-*/*.results.xml # - name: set up python - # uses: actions/setup-python@v6.0.0 + # uses: actions/setup-python@v6.2.0 # with: # python-version: "3.10" # cache: pip @@ -332,7 +332,7 @@ jobs: sed -i 's/coverage.xml/total.coverage.xml/' sonar-project.properties - name: upload coverage to codecov - uses: codecov/codecov-action@v5.5.1 + uses: codecov/codecov-action@v6.0.1 with: files: ./total.coverage.xml flags: unittests