Skip to content

Commit

Permalink
chore: drop codecov
Browse files Browse the repository at this point in the history
  • Loading branch information
percevalw committed May 15, 2024
1 parent 7e7831e commit 7ddb8b0
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 18 deletions.
141 changes: 141 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Coverage

on:
workflow_call:
inputs:
base-branch:
required: true
type: string
badge-template:
required: false
type: string
coverage-branch:
required: false
type: string
default: coverage
coverage-report:
required: false
type: string
default: coverage.txt
coverage-badge:
required: false
type: string
default: coverage.svg
coverage-data-pattern:
required: true
type: string

jobs:
pull-request-coverage:
name: Check Pull Request Coverage
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
env:
GITHUB_PR_NUMBER: ${{github.event.pull_request.number}}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# Use latest Python, so it understands all syntax.
python-version: "3.7"

- uses: actions/download-artifact@v4
with:
pattern: coverage-data-*
merge-multiple: true

- name: Combine coverage
run: |
python -Im pip install --upgrade "git+https://github.com/percevalw/coveragepy.git#egg=coverage[toml]"
python -Im coverage combine
- name: Compare coverage
if: github.event_name == 'pull_request'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Get the main branch, so that we can run `git diff main`
git fetch origin ${{ inputs.base-branch }}:${{ inputs.base-branch }} --depth=1
# We share store main coverage data in a separate branch, so we fetch it too
git fetch origin ${{ inputs.coverage-branch }}:${{ inputs.coverage-branch }} --depth=1 || true
# Report and write to summary.
echo '## Coverage Report' > /tmp/report.md
if git show ${{ inputs.coverage-branch }}:${{ inputs.coverage-report }} > /tmp/main-coverage.txt; then
coverage report --skip-covered --skip-empty --show-missing --format=diff --base-coverage-report=/tmp/main-coverage.txt --base-revision=${{ inputs.base-branch }} --fail-under=base >> /tmp/report.md || status=$?
else
coverage report --skip-covered --skip-empty --show-missing --format=diff --base-revision=main >> /tmp/report.md || status=$?
fi
cat /tmp/report.md >> $GITHUB_STEP_SUMMARY
COMMENT_BODY_JSON=$(jq -Rs . <<< $(cat /tmp/report.md))
HEADER="Authorization: token $GITHUB_TOKEN"
PR_COMMENTS_URL="https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments"
# Fetch existing comments to find if one from this workflow already exists
COMMENTS=$(curl -s -H "$HEADER" "$PR_COMMENTS_URL")
COMMENT_ID=$(echo "$COMMENTS" | jq -r '.[] | select(.user.login == "github-actions[bot]" and (.body | startswith("## Coverage Report"))) | .id')
# Check if we have a comment ID, if so, update it, otherwise create a new one
if [[ "$COMMENT_ID" ]]; then
# Update existing comment
curl -s -X PATCH -H "$HEADER" -H "Content-Type: application/json" -d "{\"body\": $COMMENT_BODY_JSON}" "https://api.github.com/repos/${{ github.repository }}/issues/comments/$COMMENT_ID"
else
# Post new comment
curl -s -X POST -H "$HEADER" -H "Content-Type: application/json" -d "{\"body\": $COMMENT_BODY_JSON}" "$PR_COMMENTS_URL"
fi
if [ $status -ne 0 ]; then
exit $status
fi
main-coverage:
name: Update Base Coverage
if: github.ref_name == inputs.base-branch
runs-on: ubuntu-latest
env:
GITHUB_PR_NUMBER: ${{github.event.pull_request.number}}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# Use the earliest possible version of Python due to a bug in coveragepy.
# See https://github.com/nedbat/coveragepy/issues/1572
python-version: "3.7"

- uses: actions/download-artifact@v4
with:
pattern: ${{ inputs.coverage-data-pattern }}
merge-multiple: true

- name: Set up Git
run: |
git config user.name ${{ github.actor }}
git config user.email ${{ github.actor }}@users.noreply.github.com
- uses: actions/checkout@v4
with:
repository: aphp/foldedtensor
sparse-checkout: |
.github/workflows/generate_badge.py
- name: Combine coverage and generate the report and the badge
run: |
python -Im pip install --upgrade "git+https://github.com/percevalw/coveragepy.git[toml]"
python -Im coverage combine
coverage report --show-missing > /tmp/main-coverage.txt
# Generate the coverage badge
python .github/workflows/generate_badge.py -r /tmp/main-coverage.txt -t ${{ inputs.badge-template.svg }} > /tmp/coverage.svg
git fetch origin ${{ inputs.coverage-branch }}:${{ inputs.coverage-branch }} --depth=1 || true
git checkout ${{ inputs.coverage-branch }} || git checkout --orphan ${{ inputs.coverage-branch }}
git reset --hard
cp /tmp/main-coverage.txt ${{ inputs.coverage-report }}
cp /tmp/coverage.svg ${{ inputs.coverage-badge }}
git add ${{ inputs.coverage-report }} ${{ inputs.coverage-badge }}
git commit -m "Update main coverage"
git push origin ${{ inputs.coverage-branch }}
106 changes: 106 additions & 0 deletions .github/workflows/generate_badge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# ruff: noqa: E471
import argparse
import colorsys
import re
from pathlib import Path
from typing import Optional, Tuple

DEFAULT_TEMPLATE = """\
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="108" height="20" role="img" aria-label="coverage: 97.1%">
<title>coverage: {COVERAGE}</title>
<g shape-rendering="crispEdges">
<rect width="61" height="20" fill="#555"/>
<rect x="61" width="47" height="20" fill="{COLOR}"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
<text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text>
<text x="835" y="140" transform="scale(.1)" fill="#fff" textLength="{WIDTH}">{COVERAGE}</text>
</g>
</svg>""" # noqa: E501


def parse_any_color_as_hsl(color: str) -> Tuple[float, float, float]:
if color.startswith("hsl"):
h, s, l = tuple(map(float, re.findall(r"\d+(?:\.\d+)?", color)))[:3]
return (h / 360, s / 100, l / 100)
elif color.startswith("#"):
rgb = tuple(int(color[i : i + 2], 16) / 255 for i in (1, 3, 5))
h, l, s = colorsys.rgb_to_hls(*rgb)
elif color.startswith("rgb"):
h, l, s = colorsys.rgb_to_hls(*map(int, re.findall(r"\d+", color)))
else:
raise ValueError(f"Unknown color format: {color}")
return h, s, l


def make_badge(
bad_color_hsl: Tuple[float, float, float],
good_color_hsl: Tuple[float, float, float],
min_coverage: int = 70,
report_path: str = "coverage.txt",
badge_template_path: Optional[str] = None,
):
with open(report_path) as f:
coverage_str = float(f.read().splitlines(False)[-1].split()[-1].strip(" %"))
coverage = float(coverage_str)
ratio = (max(coverage, min_coverage) - min_coverage) / (100 - min_coverage)
hue = bad_color_hsl[0] + ratio * (good_color_hsl[0] - bad_color_hsl[0])
saturation = bad_color_hsl[1] + ratio * (good_color_hsl[1] - bad_color_hsl[1])
lightness = bad_color_hsl[2] + ratio * (good_color_hsl[2] - bad_color_hsl[2])
rgb = colorsys.hls_to_rgb(hue, lightness, saturation)

badge_template = (
Path(badge_template_path).read_text()
if badge_template_path
else DEFAULT_TEMPLATE
)
badge = badge_template.format(
COVERAGE=f"{int(coverage)}%",
COLOR=f"#{''.join(f'{int(c * 255):02x}' for c in rgb)}",
WIDTH="250" if coverage < 100 else "330",
)
return badge


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"-b",
"--bad-color",
type=str,
default="hsl(9.62deg 71.56% 57.25%)",
)
parser.add_argument(
"-g",
"--good-color",
type=str,
default="hsl(103.64deg 84.62% 43.33%)",
)
parser.add_argument(
"-m",
"--min-coverage",
type=int,
default=70,
)
parser.add_argument(
"-r",
"--report-path",
type=str,
default="coverage.txt",
)
parser.add_argument(
"-t",
"--badge-template-path",
type=str,
default=None,
nargs="?",
)
args = parser.parse_args()
badge = make_badge(
bad_color_hsl=parse_any_color_as_hsl(args.bad_color),
good_color_hsl=parse_any_color_as_hsl(args.good_color),
min_coverage=args.min_coverage,
report_path=args.report_path,
badge_template_path=args.badge_template_path,
)
print(badge)
37 changes: 20 additions & 17 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Tests and Linting
on:
pull_request:
push:
branches: [main]
branches: [ main ]

jobs:
Linting:
Expand All @@ -29,19 +29,14 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ]
steps:
- uses: actions/checkout@v2
- name: Cache downloaded resources
uses: actions/cache@v3
with:
path: ~/.data/
key: resources
- name: Set up Java
uses: actions/setup-java@v2
with:
distribution: "temurin" # See 'Supported distributions' for available options
java-version: "8"
- name: Set up Python
uses: actions/setup-python@v2
with:
Expand All @@ -53,27 +48,35 @@ jobs:
pip install -e '.[dev]'
- name: Test with Pytest on Python ${{ matrix.python-version }}
env:
UMLS_API_KEY: ${{ secrets.UMLS_API_KEY }}
run: python -m pytest --cov foldedtensor --cov-report xml --ignore tests/test_docs.py
if: matrix.python-version != '3.9'

- name: Test with Pytest on Python ${{ matrix.python-version }}
env:
UMLS_API_KEY: ${{ secrets.UMLS_API_KEY }}
run: python -m pytest --cov foldedtensor --cov-report xml
if: matrix.python-version == '3.9'
run: coverage run -m pytest

- name: Upload coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-data-${{ matrix.python-version }}
path: .coverage.*
if-no-files-found: ignore

- name: Upload coverage
uses: codecov/codecov-action@v2
if: matrix.python-version == '3.9'
Coverage:
needs: Pytest
uses: ./.github/workflows/coverage.yml
with:
base-branch: main
coverage-data-pattern: coverage-data-*.xml
coverage-report: coverage.txt
coverage-badge: coverage.svg
coverage-branch: coverage

Installation:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

![Tests](https://img.shields.io/github/actions/workflow/status/aphp/foldedtensor/tests.yml?branch=main&label=tests&style=flat-square)
[![PyPI](https://img.shields.io/pypi/v/foldedtensor?color=blue&style=flat-square)](https://pypi.org/project/foldedtensor/)
[![Codecov](https://img.shields.io/codecov/c/github/aphp/foldedtensor?logo=codecov&style=flat-square)](https://codecov.io/gh/aphp/foldedtensor)
[![Coverage](https://raw.githubusercontent.com/aphp/foldedtensor/coverage/coverage.svg)](https://raw.githubusercontent.com/aphp/foldedtensor/coverage/coverage.txt)
[![License](https://img.shields.io/github/license/aphp/foldedtensor?color=x&style=flat-square)](https://github.com/aphp/foldedtensor/blob/main/LICENSE)

# FoldedTensor: PyTorch extension for handling deeply nested sequences of variable length
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ testpaths = [
"tests",
]

[tool.coverage.run]
concurrency = ["multiprocessing"]
parallel = true
include = ['foldedtensor/*']

[tool.coverage.report]
include = ['foldedtensor/*']
precision = 1

[build-system]
requires = [
Expand Down

0 comments on commit 7ddb8b0

Please sign in to comment.