Skip to content

Commit 7f3b60c

Browse files
author
RandomCrocodile
committed
chore: add opt-in PR coverage-comment posting to local-ci
Since GitHub Actions minutes are limited, local-ci now produces the same coverage markdown as CI (SummaryGithub.md) and can optionally post it to a PR as a single sticky comment via the gh CLI, gated behind POST_COVERAGE_PR=<num>. It edits a prior marked comment instead of spamming, mirroring the CI sticky comment. Posting is opt-in and never runs unless the variable is set; all posting failures are warnings that never fail the pipeline.
1 parent f77c43d commit 7f3b60c

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

scripts/local-ci.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
# ./scripts/local-ci.sh test # build + test only
1212
# ./scripts/local-ci.sh package # build + package only
1313
# ./scripts/local-ci.sh all # everything (default)
14+
#
15+
# GitHub Actions minutes are limited, so full test+coverage runs are expensive to
16+
# do on every push. This script produces the SAME coverage artifacts locally,
17+
# including SummaryGithub.md — the markdown that CI would post to the PR. To share
18+
# it without spending Actions minutes, opt in to posting it as a single sticky PR
19+
# comment (requires the 'gh' CLI, authenticated):
20+
#
21+
# POST_COVERAGE_PR=88 ./scripts/local-ci.sh test # post/update coverage on PR #88
22+
#
23+
# Posting is opt-in and never happens unless POST_COVERAGE_PR is set.
1424
# =============================================================================
1525

1626
set -euo pipefail
@@ -38,6 +48,57 @@ success() { echo -e "${GREEN}✓ $1${NC}"; }
3848
warn() { echo -e "${YELLOW}$1${NC}"; }
3949
fail() { echo -e "${RED}$1${NC}"; }
4050

51+
# ---------------------------------------------------------------------------
52+
# Post a coverage summary as a single sticky PR comment (opt-in).
53+
# Finds a prior comment by a hidden marker and edits it, so repeated runs update
54+
# one comment instead of spamming — the same behaviour as the CI sticky comment.
55+
# Failures are warnings only; posting must never fail the pipeline.
56+
# ---------------------------------------------------------------------------
57+
post_coverage_comment() {
58+
local pr="$1" file="$2"
59+
local marker="<!-- local-ci-coverage -->"
60+
61+
if ! command -v gh &>/dev/null; then
62+
warn "gh CLI not found; cannot post coverage comment. Install: https://cli.github.com"
63+
return 0
64+
fi
65+
if [ ! -f "$file" ]; then
66+
warn "No coverage summary at $file; nothing to post."
67+
return 0
68+
fi
69+
70+
local repo
71+
repo=$(gh repo view --json nameWithOwner --jq .nameWithOwner 2>/dev/null || true)
72+
if [ -z "$repo" ]; then
73+
warn "Could not resolve the GitHub repository; skipping coverage comment."
74+
return 0
75+
fi
76+
77+
local body_file
78+
body_file=$(mktemp)
79+
{ printf '%s\n\n' "$marker"; cat "$file"; } > "$body_file"
80+
81+
local existing_id
82+
existing_id=$(gh api "repos/$repo/issues/$pr/comments" --paginate \
83+
--jq "map(select(.body | contains(\"$marker\"))) | last | .id" 2>/dev/null || true)
84+
85+
if [ -n "$existing_id" ] && [ "$existing_id" != "null" ]; then
86+
if gh api -X PATCH "repos/$repo/issues/comments/$existing_id" -F body=@"$body_file" >/dev/null 2>&1; then
87+
success "Updated sticky coverage comment on PR #$pr"
88+
else
89+
warn "Failed to update coverage comment on PR #$pr."
90+
fi
91+
else
92+
if gh api -X POST "repos/$repo/issues/$pr/comments" -F body=@"$body_file" >/dev/null 2>&1; then
93+
success "Posted coverage comment on PR #$pr"
94+
else
95+
warn "Failed to post coverage comment on PR #$pr."
96+
fi
97+
fi
98+
99+
rm -f "$body_file"
100+
}
101+
41102
# ---------------------------------------------------------------------------
42103
# Find MSBuild via vswhere (CI uses microsoft/setup-msbuild@v2)
43104
# ---------------------------------------------------------------------------
@@ -278,6 +339,12 @@ do_test() {
278339
&& success "Markdown summary: $COVERAGE_DIR/report/SummaryGithub.md"
279340
[ -f "$COVERAGE_DIR/report/index.html" ] \
280341
&& success "HTML report: $COVERAGE_DIR/report/index.html"
342+
343+
# Opt-in: post the markdown summary to a PR as a single sticky comment.
344+
if [ -n "${POST_COVERAGE_PR:-}" ]; then
345+
step "COVERAGE — posting summary to PR #$POST_COVERAGE_PR"
346+
post_coverage_comment "$POST_COVERAGE_PR" "$COVERAGE_DIR/report/SummaryGithub.md"
347+
fi
281348
else
282349
warn "reportgenerator unavailable even after install attempt; skipping coverage report."
283350
warn "Install manually: dotnet tool install -g dotnet-reportgenerator-globaltool"

0 commit comments

Comments
 (0)