Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/scripts/coverage_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
render regenerate the human-readable COVERAGE.md from that CSV
compare render a markdown coverage diff against the last recorded entry,
for posting on a pull request
badge emit shields.io endpoint JSON for the latest recorded total

Standard library only, so it runs on any CI image without extra setup.
"""
Expand Down Expand Up @@ -563,6 +564,55 @@ def delta(current: float, module: str, field: str) -> str:
print(body)


# shields.io endpoint schema: https://shields.io/badges/endpoint-badge
BADGE_SCHEMA_VERSION = 1

# Floor percentages, highest first. Anything under the last floor is red.
BADGE_COLORS = (
(90.0, "brightgreen"),
(75.0, "green"),
(60.0, "yellowgreen"),
(40.0, "yellow"),
(20.0, "orange"),
)


def badge_color(percentage: float) -> str:
for floor, color in BADGE_COLORS:
if percentage >= floor:
return color
return "red"


def cmd_badge(args: argparse.Namespace) -> None:
"""Write shields.io endpoint JSON for one suite's latest TOTAL row.

Read by an endpoint badge in README.md. The file is published on the
coverage history branch rather than main, so refreshing the badge costs
contributors nothing (see coverage-history.yml for why that matters).

A suite with no recorded entry yet renders as "unknown" rather than
failing, so the badge degrades quietly instead of breaking the README.
"""
total = latest_entry(read_history(args.csv), args.suite).get("TOTAL")
if total is None:
payload = {"message": "unknown", "color": "lightgrey"}
else:
percentage = float(total[args.metric])
payload = {
"message": f"{percentage:.0f}%",
"color": badge_color(percentage),
}

payload = {"schemaVersion": BADGE_SCHEMA_VERSION, "label": args.label, **payload}
text = json.dumps(payload, indent=2) + "\n"
if args.out:
with open(args.out, "w", encoding="utf-8") as handle:
handle.write(text)
else:
sys.stdout.write(text)


def add_common(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"--suite",
Expand Down Expand Up @@ -630,6 +680,30 @@ def main() -> None:
)
compare.set_defaults(func=cmd_compare)

badge = subparsers.add_parser(
"badge", help="emit shields.io endpoint JSON for the latest total"
)
badge.add_argument(
"--suite",
choices=sorted(SUITES),
default="instrumentation",
help="which suite to report (default: instrumentation)",
)
badge.add_argument("--csv", default=DEFAULT_CSV)
badge.add_argument("--out", default="", help="write here instead of stdout")
badge.add_argument(
"--label",
default="coverage (instrumented)",
help="text on the left half of the badge",
)
badge.add_argument(
"--metric",
default="line_pct",
choices=("line_pct", "branch_pct", "instruction_pct"),
help="which percentage to display (default: line_pct)",
)
badge.set_defaults(func=cmd_badge)

args = parser.parse_args()
args.func(args)

Expand Down
18 changes: 14 additions & 4 deletions .github/scripts/push_coverage_history.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,25 @@ DATA_DIR="${DATA_DIR:-coverage-data}"
DATA_BRANCH="${DATA_BRANCH:-coverage-history}"
SCRIPT="${SCRIPT:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/coverage_history.py}"

# Every generated file published on the data branch. COVERAGE.md and the badge
# are both derived from history.csv, so they are regenerated, not merged.
FILES=(history.csv COVERAGE.md coverage-badge.json)

cd "$DATA_DIR"

git config user.name 'googlemaps-bot'
git config user.email 'googlemaps-bot@google.com'

if git diff --quiet -- history.csv COVERAGE.md; then
# Stage first and compare the index: a newly generated file is untracked, and
# "git diff" does not see untracked files, so checking before staging would
# skip the commit the first time a new output appears.
git add -- "${FILES[@]}"

if git diff --cached --quiet -- "${FILES[@]}"; then
echo "Coverage history unchanged; nothing to commit."
exit 0
fi

git add history.csv COVERAGE.md
git commit -m "$MESSAGE"

for attempt in 1 2 3; do
Expand All @@ -65,13 +73,15 @@ for attempt in 1 2 3; do

python3 "$SCRIPT" merge --csv history.csv --ours "$OURS"
python3 "$SCRIPT" render --csv history.csv --out COVERAGE.md
python3 "$SCRIPT" badge --csv history.csv --out coverage-badge.json

git add -- "${FILES[@]}"

if git diff --quiet -- history.csv COVERAGE.md; then
if git diff --cached --quiet -- "${FILES[@]}"; then
echo "Our rows are already on $DATA_BRANCH; nothing left to push."
exit 0
fi

git add history.csv COVERAGE.md
git commit -m "$MESSAGE"
done

Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/coverage-history.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ concurrency:
cancel-in-progress: false

env:
# Branch holding history.csv and COVERAGE.md.
# Branch holding history.csv, COVERAGE.md and coverage-badge.json.
DATA_BRANCH: coverage-history
# How long to wait for the pull request's emulator run to finish before
# giving up and recording unit coverage only. instrumentation-test.yml takes
Expand Down Expand Up @@ -111,6 +111,8 @@ jobs:
--commit "$COMMIT_SHA" --pr "$PR_NUMBER" --subject "$SUBJECT"
python3 .github/scripts/coverage_history.py render \
--csv coverage-data/history.csv --out coverage-data/COVERAGE.md
python3 .github/scripts/coverage_history.py badge \
--csv coverage-data/history.csv --out coverage-data/coverage-badge.json

- name: Push unit coverage
run: |
Expand Down Expand Up @@ -189,6 +191,8 @@ jobs:
--commit "$COMMIT_SHA" --pr "$PR_NUMBER" --subject "$SUBJECT"
python3 .github/scripts/coverage_history.py render \
--csv coverage-data/history.csv --out coverage-data/COVERAGE.md
python3 .github/scripts/coverage_history.py badge \
--csv coverage-data/history.csv --out coverage-data/coverage-badge.json

- name: Push instrumentation coverage
if: steps.emulator.outputs.run_id != ''
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
![Release](https://github.com/googlemaps/android-maps-compose/workflows/Release/badge.svg)
![Stable](https://img.shields.io/badge/stability-stable-green)
[![Tests/Build](https://github.com/googlemaps/android-maps-compose/actions/workflows/test.yml/badge.svg)](https://github.com/googlemaps/android-maps-compose/actions/workflows/test.yml)
[![Instrumented coverage](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fgooglemaps%2Fandroid-maps-compose%2Fcoverage-history%2Fcoverage-badge.json)](https://github.com/googlemaps/android-maps-compose/blob/coverage-history/COVERAGE.md)

![Contributors](https://img.shields.io/github/contributors/googlemaps/android-maps-compose?color=green)
[![License](https://img.shields.io/github/license/googlemaps/android-maps-compose?color=blue)][license]
Expand Down
Loading