diff --git a/.github/workflows/clang-static-analysis.yml b/.github/workflows/clang-static-analysis.yml new file mode 100644 index 00000000000..abf813ed1d8 --- /dev/null +++ b/.github/workflows/clang-static-analysis.yml @@ -0,0 +1,71 @@ +name: "Clang Static Analysis" + +on: + push: + branches: + - 'master' + - '202[0-9][0-9][0-9]' + pull_request: + branches: + - 'master' + - '202[0-9][0-9][0-9]' + +jobs: + clang-sa: + if: github.repository_owner == 'sonic-net' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Setup build environment + run: | + sudo apt-get update + sudo apt-get install -y clang clang-analyzer build-essential + + - name: Configure build + run: | + make SONIC_BUILD_JOBS=$(nproc) ENABLE_CLANG_SA=y configure PLATFORM=generic + + - name: Run Clang Static Analyzer + run: | + make clang-sa + + - name: Upload analysis results + uses: actions/upload-artifact@v3 + if: always() + with: + name: clang-sa-reports + path: target/clang-sa-reports/ + + - name: Summarize findings + if: github.event_name == 'pull_request' + run: | + if [ -d "target/clang-sa-reports" ]; then + echo "## Clang Static Analysis Results" > pr_comment.md + echo "" >> pr_comment.md + for report in target/clang-sa-reports/*/index.html; do + if [ -f "$report" ]; then + echo "### Analysis Report" >> pr_comment.md + echo "Report available in workflow artifacts" >> pr_comment.md + fi + done + fi + + - name: Comment on PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + if (fs.existsSync('pr_comment.md')) { + const comment = fs.readFileSync('pr_comment.md', 'utf8'); + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + } diff --git a/rules/clang-sa.mk b/rules/clang-sa.mk new file mode 100644 index 00000000000..f19e486b56d --- /dev/null +++ b/rules/clang-sa.mk @@ -0,0 +1,23 @@ +# Clang Static Analyzer targets +.PHONY: clang-sa clang-sa-clean + +clang-sa: + @if [ "$(ENABLE_CLANG_SA)" = "y" ]; then \ + echo "Running Clang Static Analyzer..."; \ + mkdir -p $(CLANG_SA_OUTPUT_DIR); \ + cd src/sonic-swss && \ + scan-build --use-cc=clang --use-c++=clang++ \ + -o $(CLANG_SA_OUTPUT_DIR) \ + -enable-checker $(CLANG_SA_CHECKERS) \ + make -j$(SONIC_CONFIG_MAKE_JOBS) || true; \ + cd src/sonic-utilities && \ + scan-build --use-cc=clang --use-c++=clang++ \ + -o $(CLANG_SA_OUTPUT_DIR) \ + -enable-checker $(CLANG_SA_CHECKERS) \ + make -j$(SONIC_CONFIG_MAKE_JOBS) || true; \ + else \ + echo "ClangSA disabled, skipping..."; \ + fi + +clang-sa-clean: + rm -rf $(CLANG_SA_OUTPUT_DIR) diff --git a/rules/config b/rules/config index 07d60161876..430403f82a8 100644 --- a/rules/config +++ b/rules/config @@ -326,3 +326,8 @@ SONIC_PTF_ENV_PY_VER = py3 # Add timeout on some process which may hangs BUILD_PROCESS_TIMEOUT ?= 0 + +# Clang Static Analyzer configuration +ENABLE_CLANG_SA ?= n +CLANG_SA_CHECKERS ?= core,deadcode.DeadStores,security.insecureAPI.UncheckedReturn +CLANG_SA_OUTPUT_DIR ?= $(TARGET_PATH)/clang-sa-reports