name: test Workflow on: workflow_call: inputs: image_name: required: true type: string default: ubuntu image_tag: required: false type: string default: latest run_platform: required: false type: string default: amd64 test_report: required: false type: boolean default: false secrets: TEST_CMD: required: true jobs: test: runs-on: ${{ inputs.run_platform }} 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 test_coverage.sh if: inputs.test_report == true run: | echo "generate /tmp/test_coverage.sh ..." cat << EOF >/tmp/test_coverage.sh #!/bin/bash # 生成报告并提交到指定http文件服务器上 if [ -z "${{ secrets.TEST_COVERAGE_REPORT_POST_URL }}" ]; then echo "TEST_COVERAGE_REPORT_POST_URL is empty, not generate test coverage report" exit 0 fi ret=0 # 创建一个\$workdir文件夹,用于存放所有的.gcda文件 workdir='/tmp/gtest_report' rm \$workdir -rf mkdir -p \$workdir default_ignore=( "_test.cc" "_test.c" "_test.cpp" "*/build/_deps/*" ) default_test_cov_ignore=( "*/include/*" "*/build/_deps/*" \${TEST_COVERAGE_IGNORE[@]} ) # 查找同时存在 *.gcda 和 *.gcno 文件的文件 gcda_files=\$(find ./build -type f -name "*.gcda") for gcda_file in \$gcda_files; do # 如果匹配了 \$default_ignore 中的文件,则跳过 for ignore in \${default_ignore[@]}; do # 使用正则表达式匹配 if [[ \$gcda_file =~ \$ignore ]]; then echo "ignore \$gcda_file" continue 2 fi done gcno_file="\${gcda_file%.gcda}.gcno" if [ -f "\$gcno_file" ]; then cp "\$gcda_file" "\$workdir" cp "\$gcno_file" "\$workdir" fi done cd \$workdir # 如果当前目录下没有gcda文件,则直接退出,不需要进行测试覆盖率检查 if [ -z "\$(find . -name "*.gcda")" ]; then echo "no gcda files, not need to test coverage" exit 0 fi # 使用 gcov 来生成覆盖率数据 gcov *.gcno >/dev/null 2>&1 # 生成报告 lcov -c -d . -o coverage.info >/dev/null 2>&1 # 过滤掉不需要的信息 for ignore in \${default_test_cov_ignore[@]}; do lcov --remove coverage.info "\$ignore" -o coverage.info >/dev/null 2>&1 done # 列出测试覆盖率 lcov -l coverage.info # 判断整体覆盖率是否达标 test_coverage=\$(lcov -l coverage.info | grep "Total:" | sed 's/|/| /g' | awk '{print \$2}' | awk -F '%' '{print \$1}') # if error to get test_coverage if [ -z "\$test_coverage" ]; then echo "no test coverage, skip" exit 0 fi # 生成html报告 test_coverage_dir=${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ github.ref_name }}/${{ steps.slug.outputs.sha8 }} mkdir -p \$test_coverage_dir genhtml coverage.info -o \$test_coverage_dir >/dev/null 2>&1 # zip 压缩 \$test_coverage_dir zip -r ${{ steps.slug.outputs.sha8 }}.zip \$test_coverage_dir # 生成报告并提交到指定http文件服务器上 curl -F file=@\${{ steps.slug.outputs.sha8 }}.zip -F unzip=true \${{secrets.TEST_COVERAGE_REPORT_POST_URL}} # 判断推送是否成功 if [ \$? -ne 0 ]; then echo "test report push failed ..." ret=1 fi # 如果 TEST_COVERAGE_THRESHOLD 变量为空,则默认为 0 if [ -z "\$TEST_COVERAGE_THRESHOLD" ]; then TEST_COVERAGE_THRESHOLD=0 fi echo "test coverage: \$test_coverage" # 将TEST_COVERAGE_THRESHOLD转换为数字,防止出现字符串比较的情况 test_coverage_threshold=\$(echo \$TEST_COVERAGE_THRESHOLD | tr -d '"') #比较两个数的大小,一个是小数,一个是整数 if [ \$(echo "\$test_coverage >= \$test_coverage_threshold" | bc) -eq 1 ]; then echo "test coverage is greater than \$test_coverage_threshold" else echo "test coverage is less than \$test_coverage_threshold" ret=1 fi # 删除临时文件 rm -rf \$test_coverage_dir rm -rf ${{ steps.slug.outputs.sha8 }}.zip # 打印报告地址 echo -e "\\033[1;35m test coverage report url: ${{secrets.TEST_COVERAGE_REPORT_URL}}/\$test_coverage_dir/index.html \\033[0m" exit \$ret EOF - name: Run test stage shell: bash env: https_proxy: "" http_proxy: "" no_proxy: "*" run: | echo "runnint test in workflow_call" source /opt/ros/humble/setup.bash echo "${{ secrets.TEST_CMD}}" eval "${{ secrets.TEST_CMD}}" - name: authorize test_coverage.sh if: inputs.test_report == true env: https_proxy: "" http_proxy: "" no_proxy: "*" run: | chmod +x /tmp/test_coverage.sh echo "test_coverage.sh is authorized" bash /tmp/test_coverage.sh