From ef78e66241007690e45719237099c357be3933b2 Mon Sep 17 00:00:00 2001 From: Arthur Meyre Date: Fri, 16 Jul 2021 10:05:19 +0200 Subject: [PATCH] build(coverage): add comment to PR with diff-cover output - add script to help format the coverage comment - manage steps logic refs #15 --- .github/workflows/continuous-integration.yaml | 15 +++++-- script/actions_utils/coverage.sh | 19 ++++++++ .../actions_utils/coverage_report_format.py | 45 +++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 script/actions_utils/coverage.sh create mode 100755 script/actions_utils/coverage_report_format.py diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index fb72d470e..fb9f5b77d 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -46,19 +46,28 @@ jobs: run: | make pcc - name: PyTest + id: pytest if: ${{ steps.conformance.outcome == 'success' && !cancelled() }} run: | make pytest - name: Test coverage - if: ${{ success() && !cancelled() }} + id: coverage + if: ${{ steps.pytest.outcome != 'skipped' && !cancelled() }} run: | - poetry run diff-cover coverage.xml --fail-under 100 --html-report coverage.html --compare-branch origin/${{ github.base_ref }} + bash --noprofile --norc -o pipefail \ + script/actions_utils/coverage.sh ${{ github.base_ref }} - name: Archive test coverage uses: actions/upload-artifact@v2 - if: ${{ success() && !cancelled() }} + if: ${{ steps.coverage.outcome != 'skipped' && !cancelled() }} with: name: coverage path: coverage.html + - name: Comment with coverage + uses: marocchino/sticky-pull-request-comment@v2 + if: ${{ steps.coverage.outcome != 'skipped' && !cancelled() }} + with: + path: diff-coverage.txt + recreate: true - name: Build docs id: docs if: ${{ steps.conformance.outcome == 'success' && !cancelled() }} diff --git a/script/actions_utils/coverage.sh b/script/actions_utils/coverage.sh new file mode 100644 index 000000000..1882ea005 --- /dev/null +++ b/script/actions_utils/coverage.sh @@ -0,0 +1,19 @@ +CURR_DIR=`dirname $0` + +# Run diff-coverage +poetry run diff-cover coverage.xml --fail-under 100 \ +--html-report coverage.html \ +--compare-branch origin/"$1" | tee diff-coverage.txt + +# Get exit code without closing the script +TEST_EXIT_CODE="$?" + +# Format diff-coverage.txt for PR comment +poetry run python script/actions_utils/coverage_report_format.py \ +--diff-cover-exit-code "$TEST_EXIT_CODE" \ +--diff-cover-output diff-coverage.txt + +# Set exit code if test failed +if [[ "$TEST_EXIT_CODE" != "0" ]]; then + exit "$TEST_EXIT_CODE" +fi diff --git a/script/actions_utils/coverage_report_format.py b/script/actions_utils/coverage_report_format.py new file mode 100755 index 000000000..0d8340529 --- /dev/null +++ b/script/actions_utils/coverage_report_format.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +"""Helper script for github actions""" +import argparse +import traceback +from pathlib import Path + + +def main(args): + """Entry point""" + diff_cover_file_path = Path(args.diff_cover_output).resolve().absolute() + + diff_cover_content = None + + with open(diff_cover_file_path, "r") as f: + diff_cover_content = f.readlines() + + with open(diff_cover_file_path, "w", encoding="utf-8") as f: + if args.diff_cover_exit_code == 0: + f.write("## Coverage passed ✅\n\n") + else: + f.write("## Coverage failed ❌\n\n") + + # Open collapsible section + f.write("
Coverage details\n

\n\n") + f.write("```\n") + + f.writelines(diff_cover_content) + + # Close collapsible section + f.write("```\n\n") + f.write("

\n
\n\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(allow_abbrev=False) + + parser.add_argument("--diff-cover-exit-code", type=int, required=True) + parser.add_argument("--diff-cover-output", type=str, required=True) + + cli_args = parser.parse_args() + try: + main(cli_args) + except Exception as e: + traceback.print_exc()