From 0524d46ca741983e1ec4a9cf7e4975bcc7dc6238 Mon Sep 17 00:00:00 2001 From: Gichan Jang Date: Thu, 14 Nov 2024 11:07:04 +0900 Subject: [PATCH] [Action] Measure test coverage from action - Measure test coverage from action - Release daily build result Signed-off-by: Gichan Jang --- .github/workflows/daily-build-gbs.yml | 81 +++++++++++++++++++++++++ .github/workflows/gen_coverage_badge.py | 79 ++++++++++++++++++++++++ .github/workflows/update_gbs_cache.yml | 45 -------------- 3 files changed, 160 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/daily-build-gbs.yml create mode 100644 .github/workflows/gen_coverage_badge.py delete mode 100644 .github/workflows/update_gbs_cache.yml diff --git a/.github/workflows/daily-build-gbs.yml b/.github/workflows/daily-build-gbs.yml new file mode 100644 index 00000000..d0a20b11 --- /dev/null +++ b/.github/workflows/daily-build-gbs.yml @@ -0,0 +1,81 @@ +name: gbs daily build and test + +on: + schedule: + # 05:00 AM (KST) Mon-Fri + - cron: "00 20 * * 0-4" + + # Allow manually triggering the workflow + workflow_dispatch: + +jobs: + build: + outputs: + x86_64: ${{ steps.gbs-result.outputs.x86_64 }} + i586: ${{ steps.gbs-result.outputs.i586 }} + armv7l: ${{ steps.gbs-result.outputs.armv7l }} + aarch64: ${{ steps.gbs-result.outputs.aarch64 }} + strategy: + fail-fast: false + matrix: + include: + - gbs_build_arch: "x86_64" + gbs_build_option: "--define \"unit_test 1\" --define \"testcoverage 1\"" + - gbs_build_arch: "i586" + gbs_build_option: "--define \"unit_test 1\"" + - gbs_build_arch: "armv7l" + gbs_build_option: "--define \"unit_test 1\"" + - gbs_build_arch: "aarch64" + gbs_build_option: "--define \"unit_test 1\"" + + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v1 + + - name: prepare deb sources for GBS + run: echo "deb [trusted=yes] http://download.tizen.org/tools/latest-release/Ubuntu_22.04/ /" | sudo tee /etc/apt/sources.list.d/tizen.list + + - name: install GBS + run: sudo apt-get update && sudo apt-get install -y gbs + + - name: configure GBS + run: cp .github/workflows/tizen.gbs.conf ~/.gbs.conf + + - name: get date + id: get-date + run: | + echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + + - name: run GBS + id: gbs-build + run: gbs build ${{ matrix.gbs_build_option }} --define "_skip_debug_rpm 1" -A ${{ matrix.gbs_build_arch }} + + - name: save gbs cache + uses: actions/cache/save@v4 + if: ${{ always() && github.ref == 'refs/heads/main' }} + with: + path: ~/GBS-ROOT/local/cache + key: gbs-cache-${{ matrix.gbs_build_arch }}-${{ steps.get-date.outputs.date }} + + - if: matrix.gbs_build_arch == 'x86_64' && steps.gbs-build.outcome == 'success' + name: extract test coverage result + run: | + pip install pybadges beautifulsoup4 setuptools + mkdir -p ~/testresult/ + pushd ~/testresult/ + cp ~/GBS-ROOT/local/repos/tizen/x86_64/RPMS/*-coverage*.rpm . + rpm2cpio *-coverage*.rpm | cpio -idv + popd + python3 .github/workflows/gen_coverage_badge.py ~/testresult/usr/share/ml-api/unittest/result/index.html ~/testresult/usr/share/ml-api/unittest/result/coverage_badge.svg + + - if: matrix.gbs_build_arch == 'x86_64' && steps.gbs-build.outcome == 'success' + name: update test coverage result to github.io + uses: ./.github/actions/gitpush + with: + source: ~/testresult/usr/share/ml-api/unittest/result/* + dest: testresult/ml-api + message: "${{ steps.get-date.outputs.date }} : Update test coverage result." + taos_account: ${{ secrets.TAOS_ACCOUNT }} + taos_account_token: ${{ secrets.TAOS_ACCOUNT_TOKEN }} diff --git a/.github/workflows/gen_coverage_badge.py b/.github/workflows/gen_coverage_badge.py new file mode 100644 index 00000000..13c1eeaa --- /dev/null +++ b/.github/workflows/gen_coverage_badge.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +## +# SPDX-License-Identifier: LGPL-2.1-only +# Copyright (C) 2024 Samsung Electronics +# +# @file gen_github_badge_svg.py +# @brief A tool for generating a github badge image in svg format +# @author Wook Song +# @author Gichan Jang +# @note +# usage : python gen_badge.py {gcov-index-file} {output.svg} +# +import sys +import os +from bs4 import BeautifulSoup +from pybadges import badge + +## +# @brief Get a gradient colorcode from green to red of given value (scaled) +# @param[in] val A value to be conveted to a gradient colorcode (i.e., #FFFFFF) +# @param[in] scale A limit for the val, 0 <= val <= scale +def get_code_g_y_r(val, scale): + """get_code_g_y_r(val, scale) -> str""" + if val <= 50: + red = 255 + green = val * (255 / (float(scale) / 2)) + else: + green = 255 * val / scale + red = 255 - (val - 50) * (255 / (float(scale) / 2)) + + rgb = (int(red), int(green), int(0)) + + return '#%02x%02x%02x' % rgb + +## +# @brief Generate a github badge svg file representing code coverage +# @param[in] html A concatenated string of the whole contents in index.html that is the result of LCOV +# @param[in] path A file path to save the svg file +def gen_coverage_badge(html, path): + #parse LCOV html + soup = BeautifulSoup(html, 'html.parser') + lines, line_hits, funcs, func_hits = \ + soup.find('table').find_all('td', {'class': 'headerCovTableEntry'}) + line_hits = float(line_hits.text) + lines = float(lines.text) + line_coverage = line_hits / lines + rgb_code = get_code_g_y_r(line_coverage * 100, 100) + coverage_str = str(format(line_coverage * 100, '.2f')) + '%' + s = badge(left_text='coverage', right_text=coverage_str, right_color=rgb_code) + + file = open(path, "w") + file.write(s) + file.close() + + +if __name__ == '__main__': + # argv[1]: [url/file] a path or url of LCOV html to get information for badge generation + # argv[2]: [file] a file path to save the generated svg file + if len(sys.argv) < 3: + exit(1) + + str_html = '' + if os.path.isfile(sys.argv[1]): + with open(sys.argv[1], 'r') as f: + str_html = f.read() + if not BeautifulSoup(str_html, "html.parser").find(): + exit(1) + else: + exit(1) + + path_out_svg='' + if not os.access(os.path.dirname(sys.argv[2]) or os.getcwd(), os.W_OK): + exit(1) + else: + path_out_svg = os.path.abspath(sys.argv[2]) + if os.path.isdir(path_out_svg) or os.path.islink(path_out_svg): + exit(1) + + gen_coverage_badge(str_html, path_out_svg) diff --git a/.github/workflows/update_gbs_cache.yml b/.github/workflows/update_gbs_cache.yml deleted file mode 100644 index 1377461a..00000000 --- a/.github/workflows/update_gbs_cache.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Update GBS cache once a day - -on: - schedule: - # 05:00 AM (KST) Mon-Fri - - cron: "00 20 * * 0-4" - - # Allow manually triggering the workflow - workflow_dispatch: - -jobs: - cache_gbs_build: - strategy: - matrix: - gbs_build_arch: [x86_64, i586, armv7l, aarch64] - - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v1 - - - name: prepare deb sources for GBS - run: echo "deb [trusted=yes] http://download.tizen.org/tools/latest-release/Ubuntu_22.04/ /" | sudo tee /etc/apt/sources.list.d/tizen.list - - - name: install GBS - run: sudo apt-get update && sudo apt-get install -y gbs - - - name: configure GBS - run: cp .github/workflows/tizen.gbs.conf ~/.gbs.conf - - - name: get date - id: get-date - run: | - echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT - - - name: run GBS - run: gbs build --skip-srcrpm --define "_skip_debug_rpm 1" -A ${{ matrix.gbs_build_arch }} - - - name: save gbs cache - uses: actions/cache/save@v4 - if: always() - with: - path: ~/GBS-ROOT/local/cache - key: gbs-cache-${{ matrix.gbs_build_arch }}-${{ steps.get-date.outputs.date }}