--- /dev/null
+#!/usr/bin/env python
+
+##
+# Copyright (C) 2020 Samsung Electronics
+# License: Apache-2.0
+#
+# @file gen_badge.py
+# @brief A tool for generating a github badge image in svg format
+# @author Wook Song <wook16.song@samsung.com>
+# Dongju Chae <dongju.chae@samsung.com>
+# Gichan Jang <gichan2.jang@samsung.com>
+
+import os
+import sys
+import requests
+from bs4 import BeautifulSoup
+import xml.etree.ElementTree as elemTree
+
+# shields local server (https://github.com/badges/shields)
+shields_url = "http://localhost:8080"
+
+##
+# @brief Generate a github badge svg file representing daily build result
+def gen_badge(label, message, color, path):
+ print("gen badge")
+ url_str = shields_url + '/badge/' + label+'-' + message + '-' + color
+ print('Target url : ' + url_str)
+ res = requests.get(url_str)
+ with open(path, "w") as file:
+ file.write(str(res.text))
+
+##
+# @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
+# @param[in] path A file path to save the svg file
+# @param[in] tool The name of analyzer
+def gen_coverage_badge(html, path, tool = "lcov"):
+ print("code coverage")
+ soup = BeautifulSoup(html, 'html.parser')
+
+ if tool == "gcovr":
+ parsed = soup.find('table').find_all('td', {'class' : 'headerTableEntry'})
+ else:
+ parsed = soup.find('table').find_all('td', {'class' : 'headerCovTableEntry'})
+
+ line_hits = float(parsed[0].text)
+ lines = float(parsed[1].text)
+
+ line_coverage = line_hits / lines
+ print line_coverage
+
+ if line_coverage > 0.8:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), '00b000', path)
+ elif line_coverage > 0.7:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), 'green', path)
+ elif line_coverage > 0.6:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), 'yellogreen', path)
+ elif line_coverage > 0.5:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), 'yello', path)
+ elif line_coverage > 0.4:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), 'orange', path)
+ else:
+ gen_badge ('Coverage', format(line_coverage, "2.1%"), 'red', path)
+
+def gen_unittest_badge(dir_xml, path):
+ num_total = 0
+ num_pos = 0
+ num_neg = 0
+
+ for f in os.listdir(dir_xml):
+ if f.endswith(".xml"):
+ tree = elemTree.parse(dir_xml + '/' + f)
+
+ testsuite = tree.find('./testsuite')
+ for testcase in testsuite.iter("testcase"):
+ name = testcase.attrib["name"]
+ if name.endswith ('_n'):
+ num_neg = num_neg + 1
+ else:
+ num_pos = num_pos + 1
+
+ num_total = num_pos + num_neg
+ str_unittest = str(num_total) + ' (' + str(num_pos) + ' + ' + str(num_neg) + ')'
+
+ neg_rate = (float(num_neg)/float(num_total)) * 100.0
+ print neg_rate
+
+ if neg_rate > 70.0:
+ gen_badge ('Unittest', str_unittest, '00b000', path)
+ elif neg_rate > 60.0:
+ gen_badge ('Unittest', str_unittest, 'green', path)
+ elif neg_rate > 50.0:
+ gen_badge ('Unittest', str_unittest, 'yellogreen', path)
+ elif neg_rate > 40.0:
+ gen_badge ('Unittest', str_unittest, 'yello', path)
+ elif neg_rate > 30.0:
+ gen_badge ('Unittest', str_unittest, 'orange', path)
+ else:
+ gen_badge ('Unittest', str_unittest, 'red', path)
+
+def gen_samscore_badge(score, path):
+ score = float(score)
+ print score
+
+ if score == 5.0:
+ gen_badge ('SAM Score', format(score, "1.2f"), '00b000', path)
+ elif score > 4.0:
+ gen_badge ('SAM Score', format(score, "1.2f"), 'green', path)
+ elif score > 3.0:
+ gen_badge ('SAM Score', format(score, "1.2f"), 'yello', path)
+ else:
+ gen_badge ('SAM Score', format(score, "1.2f"), 'red', path)
+
+def gen_version_badge(version, path):
+ print version
+
+ gen_badge ('Version', 'v' + version, 'blue', path)
+
+def gen_issues_badge(issues, path):
+ print issues
+
+ gen_badge ('Issues', issues + ' open', 'yellow', path)
+
+def gen_pulls_badge(pulls, path):
+ print pulls
+
+ gen_badge ('Pull Requests', pulls + ' open', 'yellow', path)
+
+if __name__ == '__main__':
+ # argv[1]: [badgetype] a string indicating the type of badge, 'codecoverage'
+ # argv[2]: [url/file] a path or url of LCOV html to get information for badge generation
+ # argv[3]: [file] a file path to save the generated svg file
+ if len(sys.argv) < 4:
+ exit(1)
+
+ badgetype = 'unknown'
+ for each_badge_type in ['codecoverage','unittest','samscore','version','issues','pulls']:
+ if sys.argv[1].lower() == each_badge_type:
+ badgetype = sys.argv[1].lower()
+ print(badgetype)
+ if badgetype == 'unknown':
+ exit(1)
+
+ path_out_svg=''
+ if not os.access(os.path.dirname(sys.argv[3]) or os.getcwd(), os.W_OK):
+ exit(1)
+ else:
+ path_out_svg = os.path.abspath(sys.argv[3])
+ if os.path.isdir(path_out_svg) or os.path.islink(path_out_svg):
+ exit(1)
+ print(path_out_svg)
+ if badgetype == 'codecoverage':
+ str_html = ''
+ print(sys.argv[2])
+ if os.path.isfile(sys.argv[2]):
+ with open(sys.argv[2], 'r') as f:
+ str_html = f.read()
+ if not BeautifulSoup(str_html, "html.parser").find():
+ exit(1)
+ elif sys.argv[2].startswith('http'):
+ str_html = get_html(sys.argv[2])
+ if str_html == '':
+ exit(2)
+ else:
+ exit(3)
+
+ gen_coverage_badge(str_html, path_out_svg)
+ elif badgetype == 'unittest':
+ gen_unittest_badge(sys.argv[2], path_out_svg)
+ elif badgetype == 'samscore':
+ gen_samscore_badge(sys.argv[2], path_out_svg)
+ elif badgetype == 'version':
+ gen_version_badge(sys.argv[2], path_out_svg)
+ elif badgetype == 'issues':
+ gen_issues_badge(sys.argv[2], path_out_svg)
+ elif badgetype == 'pulls':
+ gen_pulls_badge(sys.argv[2], path_out_svg)
--- /dev/null
+name: check coverage and update badges daily
+
+on:
+ schedule:
+ # scheduled workflow run on the latest commit on the default or base
+ # branch.
+ - cron: '00 01 * * 0-5'
+
+env:
+ BART_ID: ${{ secrets.BART_ID }}
+ BART_PW: ${{ secrets.BART_PW }}
+
+jobs:
+ daily-check:
+ runs-on: [ code-large ]
+ container:
+ image: aip-docker-local.bart.sec.samsung.net/n2s2_docker/bionic:latest
+ # for chroot-based build system
+ options: --privileged
+ credentials:
+ username: ${{ secrets.BART_ID }}
+ password : ${{ secrets.BART_PW }}
+
+ timeout-minutes: 60
+
+ steps:
+ - name: Clone your repository
+ uses: CODE-Actions/checkout@v2
+
+ - name: Create badges folder
+ run:
+ mkdir ~/badges
+ shell: bash
+
+ - name: Setup shields local server to create badges
+ run: |
+ git clone https://github.com/badges/shields.git
+ cd shields
+ git checkout $(git tag | grep server | tail -n 1) # checkout the latest tag
+ export NODE_TLS_REJECT_UNAUTHORIZED=0
+ npm i --legacy-peer-deps
+ npm run start &
+ sleep 30 # waif for server ready
+ shell: bash
+
+ - name: Coverage check
+ run: |
+ bash utils/coverage/coverage.sh lcov
+ cp -r utils/coverage/coverage_result coverage_result
+
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py codecoverage coverage_result/index.html ~/badges/codecoverage.svg
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py unittest build/tests/unittests/ ~/badges/unittest.svg
+ shell : bash
+
+ - name: Upload coverage result
+ uses: CODE-Actions/upload-artifact@v2
+ with:
+ name: coverage_result
+ path: coverage_result
+
+ - name: Get SAM Score
+ run: |
+ export SAM_HOME=/root/sam/SAM_v7.1.7-linux/
+ export PATH=$PATH:/$SAM_HOME/bin
+ rm -rf build
+
+ sam init
+ sam scan --language AUTO_C_CPP $GITHUB_WORKSPACE/.ahub/sam/build.sh \
+ -exclude $GITHUB_WORKSPACE/.ahub/sam/exclude.txt
+ sam analyze --language auto_c_cpp
+ sam calculate --language auto_c_cpp >> log.out
+
+ SAM_SCORE=`cat log.out | grep "Score -" | awk '{print $9}'`
+ echo $SAM_SCORE
+
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py samscore $SAM_SCORE ~/badges/samscore.svg
+
+ - name: Create badges
+ run: |
+ VERSION=`cat packaging/npu-engine.spec | grep Version | awk '{print $2}'`
+ echo $VERSION
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py version $VERSION ~/badges/version.svg
+
+ NUM_PULLS=`curl -u "${{ secrets.GIT_ID }}:${{ secrets.GIT_PW }}" https://github.sec.samsung.net/api/v3/repos/AIP/NPU_SystemService/pulls?state=open 2>/dev/null | jq length`
+ NUM_ISSUES=`curl -u "${{ secrets.GIT_ID }}:${{ secrets.GIT_PW }}" https://github.sec.samsung.net/api/v3/repos/AIP/NPU_SystemService/issues?state=open 2>/dev/null | jq length`
+ NUM_ISSUES=$(($NUM_ISSUES-$NUM_PULLS))
+
+ echo $NUM_PULLS
+ echo $NUM_ISSUES
+
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py pulls $NUM_PULLS ~/badges/pulls.svg
+ python2 $GITHUB_WORKSPACE/.github/actions/create-badge/gen_badge.py issues $NUM_ISSUES ~/badges/issues.svg
+ shell: bash
+
+ - name: Upload badges
+ run: |
+ git config --global user.name "${{ secrets.GIT_ID }}"
+ git config --global user.email "${{ secrets.GIT_EMAIL }}"
+
+ git clone https://${{ secrets.GIT_ID }}:${{ secrets.GIT_PW }}@github.sec.samsung.net/nnsuite/n2s2.git
+ cd n2s2
+
+ git remote set-url origin https://${{ secrets.GIT_ID }}:${{ secrets.GIT_PW }}@github.sec.samsung.net/nnsuite/n2s2.git
+ mv ~/badges/* AIP_NPU_SystemService/badges
+ git add .
+ git commit -s -m "Update the badges for NPU_SystemService"
+ git push --set-upstream origin master