AimRT/.github/workflows/cppcheck.yml

246 lines
10 KiB
YAML
Raw Normal View History

name: check Workflow
on:
workflow_call:
inputs:
image_name:
required: true
type: string
default: ubuntu
image_tag:
required: false
type: string
default: latest
jobs:
check:
runs-on: amd64
container:
image: ${{ inputs.image_name }}:${{ inputs.image_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
env:
https_proxy: ${{ secrets.https_proxy }}
http_proxy: ${{ secrets.http_proxy }}
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Get short sha
id: slug
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
- name: generate cppcheck.sh
run: |
echo "generate /tmp/cppcheck.sh ..."
cat << EOF >/tmp/cppcheck.sh
#!/bin/bash
echo "Running check.sh"
default_ignore=(
"build/"
".*_test.cc"
\${CPPCHECK_IGNORE[@]}
)
echo "default_ignore is : \${default_ignore[@]}"
# 构造忽略参数
ignore_args=""
for ignore in \${default_ignore[@]}; do
# 判断是否为目录
if [ -d "\$ignore" ]; then
ignore_args="-i\$ignore \$ignore_args"
else
files=\$(find . ! -path '*/build/*' -regex "\$ignore" -type f)
for file in \$files; do
ignore_args="-i\$file \$ignore_args"
done
fi
done
# 如果当前目录下没有cc或者cpp或者cxx或者c文件则直接退出不需要进行cppcheck检查
if [ -z "\$(find . -name "*.cc" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.c")" ]; then
echo "no cc or cpp or cxx files, not need to cppcheck"
exit 0
fi
echo "check cmd is :"
echo "cppcheck . --enable=warning,style,performance,portability,missingInclude --xml \$ignore_args"
cppcheck . --enable=warning,style,performance,portability,missingInclude --xml \$ignore_args 2>/tmp/cppcheck.xml
# 如果cppcheck检查出错直接退出
if [ \$? -ne 0 ]; then
echo "cppcheck failed"
exit -1
fi
echo "github.sha is : ${{ github.sha }}"
echo "short_sha is : ${{ steps.slug.outputs.sha8 }}"
# 生成报告并提交到指定http文件服务器上
if [ -n "${{secrets.CPPCHECK_REPORT_POST_URL}}" ]; then
check_report_dir=${{ github.repository }}/${{ github.ref_name }}/${{ steps.slug.outputs.sha8 }}
mkdir -p \$check_report_dir
echo "github.repository_owner is : ${{ github.repository_owner }}"
echo "github.repository.name is : ${{ github.repository }}"
echo "github.ref_name is : ${{ github.ref_name }}"
echo "steps.slug.outputs.sha8 is : ${{ steps.slug.outputs.sha8 }}"
echo "check_report_dir is : \$check_report_dir"
cppcheck-htmlreport --file=/tmp/cppcheck.xml --title=CSA --report-dir=\$check_report_dir --source-dir=./
echo "check_report_dir is : \$check_report_dir"
# zip 压缩 \$check_report_dir
zip -r \${{ steps.slug.outputs.sha8 }}.zip \$check_report_dir
curl -F file=@${{ steps.slug.outputs.sha8 }}.zip -F unzip=true \${{secrets.CPPCHECK_REPORT_POST_URL}}
# 判断推送是否成功
if [ \$? -ne 0 ]; then
echo "cppcheck report push failed"
exit -1
fi
# 删除临时文件
rm -rf \$check_report_dir
rm -rf \${{ steps.slug.outputs.sha8 }}.zip
# 打印报告地址
# echo "cppcheck report url: ${{secrets.CPPCHECK_REPORT_POST_URL}}/\$check_report_dir/index.html"
echo -e "\\033[1;35m cppcheck report url: ${{secrets.CPPCHECK_REPORT_URL}}/\$check_report_dir/index.html \\033[0m"
fi
EOF
- name: generate cppcheck_analyze.py
run: |
echo "generate /tmp/cppcheck_analyze.py ..."
cat << EOF >/tmp/cppcheck_analyze.py
#!/usr/bin/env python3
import os
import sys
import xml.dom.minidom as minidom
#cppcheck 所有的错误类型的严重性
severityList=['information', 'performance', 'style', 'portability', 'warning', 'error']
informationSeverityCount = 0
performanceSeverityCount = 0
styleSeverityCount = 0
portabilitySeverityCount = 0
warningSeverityCount = 0
errorSeverityCount = 0
# 如果 /tmp/cppcheck.xml 文件不存在,则直接退出
if not os.path.exists('/tmp/cppcheck.xml'):
print("/tmp/cppcheck.xml not exists")
sys.exit(0)
# 打开cppcheck输出文件
with open('/tmp/cppcheck.xml', 'r') as file:
# 解析XML文件
dom = minidom.parse(file)
# 获取所有的error元素
errors = dom.getElementsByTagName('error')
for error in errors:
# 分别统计每种严重性的错误数
for i in range(len(severityList)):
if error.getAttribute('severity') == severityList[i]:
if i == 0:
informationSeverityCount += 1
elif i == 1:
performanceSeverityCount += 1
elif i == 2:
styleSeverityCount += 1
elif i == 3:
portabilitySeverityCount += 1
elif i == 4:
warningSeverityCount += 1
elif i == 5:
# 如果是syntaxError则不计入errorSeverityCount
if error.getAttribute('id') == 'syntaxError':
continue
# 如果是internalAstError则不计入errorSeverityCount
if error.getAttribute('id') == 'internalAstError':
continue
# 如果是internalAstError则不计入errorSeverityCount
if error.getAttribute('id') == 'unknownMacro':
continue
# 如 果msg中包含"Syntax"则不计入errorSeverityCount
if error.getAttribute('msg').find("Syntax") != -1:
continue
errorSeverityCount += 1
print(error.getAttribute('msg'))
# 打印结果
# print(severityList)
print("informationSeverityCount: ", informationSeverityCount)
print("performanceSeverityCount: ", performanceSeverityCount)
print("styleSeverityCount: ", styleSeverityCount)
print("portabilitySeverityCount: ", portabilitySeverityCount)
print("warningSeverityCount: ", warningSeverityCount)
print("errorSeverityCount: ", errorSeverityCount)
# 获取环境变量,如果超过阈值则返回-1否则返回0
# 获取环境变量
informationSeverityMax = os.environ.get('INFORMATION_SEVERITY_MAX')
performanceSeverityMax = os.environ.get('PERFORMANCE_SEVERITY_MAX')
styleSeverityMax = os.environ.get('STYLE_SEVERITY_MAX')
portabilitySeverityMax = os.environ.get('PORTABILITY_SEVERITY_MAX')
warningSeverityMax = os.environ.get('WARNING_SEVERITY_MAX')
errorSeverityMax = os.environ.get('ERROR_SEVERITY_MAX')
# 如果环境变量不存在则不做处理
if informationSeverityMax != None:
if informationSeverityCount >= int(informationSeverityMax):
print("informationSeverityCount[{}] >= informationSeverityMax[{}]".format(informationSeverityCount, informationSeverityMax))
sys.exit(-1)
if performanceSeverityMax != None:
if performanceSeverityCount >= int(performanceSeverityMax):
print("performanceSeverityCount[{}] >= performanceSeverityMax[{}]".format(performanceSeverityCount, performanceSeverityMax))
sys.exit(-1)
if styleSeverityMax != None:
if styleSeverityCount >= int(styleSeverityMax):
print("styleSeverityCount[{}] >= styleSeverityMax[{}]".format(styleSeverityCount, styleSeverityMax))
sys.exit(-1)
if portabilitySeverityMax != None:
if portabilitySeverityCount >= int(portabilitySeverityMax):
print("portabilitySeverityCount[{}] >= portabilitySeverityMax[{}]".format(portabilitySeverityCount, portabilitySeverityMax))
sys.exit(-1)
if warningSeverityMax != None:
if warningSeverityCount >= int(warningSeverityMax):
print("warningSeverityCount[{}] >= warningSeverityMax[{}]".format(warningSeverityCount, warningSeverityMax))
sys.exit(-1)
if errorSeverityMax != None:
if errorSeverityCount >= int(errorSeverityMax):
print("errorSeverityCount[{}] >= errorSeverityMax[{}]".format(errorSeverityCount, errorSeverityMax))
sys.exit(-1)
EOF
- name: run cppcheck
run: |
chmod +x /tmp/cppcheck.sh
chmod +x /tmp/cppcheck_analyze.py
/tmp/cppcheck.sh
/tmp/cppcheck_analyze.py
- name: run format
run: |
./format.sh
git config --global --add safe.directory '*'
git status
if [ -n "$(git status --porcelain)" ]; then
echo "check ${{ github.ref_name }} failed"
exit 1
fi