Skip to content

Commit 80d53e7

Browse files
Add coverage tests to github workflow for PRs to main (RooCodeInc#2500)
* add coverage to github workflows * add changeset * continue to run on errors * address comments from ellipsis-dev * add unit tests, confirm passing * remove pyproject.toml approach to deps instalL * use github_output env var * add verbose mode for debugging * verbose was not being captured * std out, not print * remove 1000 line dump... * print every line separately to prevent clipping * build extension before testing * clean up debugging prints * break coverage.py into smaller files * break coverage.py into smaller files * Relative module names not supported * rename coverage to coverage_check to avoid naming collision * rename coverage to coverage_check to avoid naming collision * debugging missing coverage files * output error on coverage report * handling ellipsis-dev comments * see if we need vscode test deps * experimenting to try to get it running * use absolute paths * put everything in root directory * address more comments from ellipsis-dev * import run_command in extraction.py * fix verbose flag * use parent parser * ensure safe command test will allow our commands * make sure we install before coverage * update tests to ensure run --------- Co-authored-by: Dennis Bartlett <[email protected]>
1 parent 16f5d3c commit 80d53e7

File tree

10 files changed

+1710
-4
lines changed

10 files changed

+1710
-4
lines changed

.changeset/warm-pets-worry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": minor
3+
---
4+
5+
add coverage tests to github workflows
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Coverage utility package for GitHub Actions workflows.
3+
This package handles extracting coverage percentages, comparing them, and generating PR comments.
4+
"""
5+
6+
# Import external dependencies
7+
import requests
8+
9+
# Import main function for CLI usage
10+
from .__main__ import main
11+
12+
# Import functions from extraction module
13+
from .extraction import extract_coverage, compare_coverage, run_coverage, set_verbose
14+
15+
# Import functions from github_api module
16+
from .github_api import generate_comment, post_comment, set_github_output
17+
18+
# Import functions from workflow module
19+
from .workflow import process_coverage_workflow
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
"""
2+
Main module.
3+
This module provides the CLI interface for the coverage utility script.
4+
"""
5+
6+
import sys
7+
import argparse
8+
9+
from .extraction import extract_coverage, compare_coverage, run_coverage, set_verbose
10+
from .github_api import generate_comment, post_comment, set_github_output
11+
from .workflow import process_coverage_workflow
12+
from .util import log
13+
14+
def setup_verbose_mode(args):
15+
"""
16+
Set up verbose mode based on command line arguments.
17+
18+
Args:
19+
args: Parsed command line arguments
20+
"""
21+
if getattr(args, 'verbose', False):
22+
set_verbose(True)
23+
log("Verbose mode enabled")
24+
25+
def main():
26+
# Create parent parser with common arguments
27+
parent_parser = argparse.ArgumentParser(add_help=False)
28+
parent_parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output')
29+
30+
# Create main parser that inherits common arguments
31+
parser = argparse.ArgumentParser(description='Coverage utility script for GitHub Actions workflows', parents=[parent_parser])
32+
subparsers = parser.add_subparsers(dest='command', help='Command to run')
33+
34+
# extract-coverage command - used directly in workflow
35+
extract_parser = subparsers.add_parser('extract-coverage', help='Extract coverage percentage from a file', parents=[parent_parser])
36+
extract_parser.add_argument('file_path', help='Path to the coverage report file')
37+
extract_parser.add_argument('--type', choices=['extension', 'webview'], default='extension',
38+
help='Type of coverage report')
39+
extract_parser.add_argument('--github-output', action='store_true', help='Output in GitHub Actions format')
40+
41+
# compare-coverage command - used by process-workflow
42+
compare_parser = subparsers.add_parser('compare-coverage', help='Compare coverage percentages', parents=[parent_parser])
43+
compare_parser.add_argument('base_cov', help='Base branch coverage percentage')
44+
compare_parser.add_argument('pr_cov', help='PR branch coverage percentage')
45+
compare_parser.add_argument('--output-prefix', default='', help='Prefix for GitHub Actions output variables')
46+
compare_parser.add_argument('--github-output', action='store_true', help='Output in GitHub Actions format')
47+
48+
# generate-comment command - used by process-workflow
49+
comment_parser = subparsers.add_parser('generate-comment', help='Generate PR comment with coverage comparison', parents=[parent_parser])
50+
comment_parser.add_argument('base_ext_cov', help='Base branch extension coverage')
51+
comment_parser.add_argument('pr_ext_cov', help='PR branch extension coverage')
52+
comment_parser.add_argument('ext_decreased', help='Whether extension coverage decreased (true/false)')
53+
comment_parser.add_argument('ext_diff', help='Extension coverage difference')
54+
comment_parser.add_argument('base_web_cov', help='Base branch webview coverage')
55+
comment_parser.add_argument('pr_web_cov', help='PR branch webview coverage')
56+
comment_parser.add_argument('web_decreased', help='Whether webview coverage decreased (true/false)')
57+
comment_parser.add_argument('web_diff', help='Webview coverage difference')
58+
59+
# post-comment command - used by process-workflow
60+
post_parser = subparsers.add_parser('post-comment', help='Post a comment to a GitHub PR', parents=[parent_parser])
61+
post_parser.add_argument('comment_path', help='Path to the file containing the comment text')
62+
post_parser.add_argument('pr_number', help='PR number')
63+
post_parser.add_argument('repo', help='Repository in the format "owner/repo"')
64+
post_parser.add_argument('--token', help='GitHub token')
65+
66+
# run-coverage command - used by process-workflow
67+
run_parser = subparsers.add_parser('run-coverage', help='Run a coverage command and extract the coverage percentage', parents=[parent_parser])
68+
run_parser.add_argument('coverage_cmd', help='Command to run')
69+
run_parser.add_argument('output_file', help='File to save the output to')
70+
run_parser.add_argument('--type', choices=['extension', 'webview'], default='extension',
71+
help='Type of coverage report')
72+
run_parser.add_argument('--github-output', action='store_true', help='Output in GitHub Actions format')
73+
74+
# process-workflow command - used directly in workflow
75+
workflow_parser = subparsers.add_parser('process-workflow', help='Process the entire coverage workflow', parents=[parent_parser])
76+
workflow_parser.add_argument('--base-branch', required=True, help='Base branch name')
77+
workflow_parser.add_argument('--pr-number', help='PR number')
78+
workflow_parser.add_argument('--repo', help='Repository in the format "owner/repo"')
79+
workflow_parser.add_argument('--token', help='GitHub token')
80+
81+
# set-github-output command - used by process-workflow
82+
output_parser = subparsers.add_parser('set-github-output', help='Set GitHub Actions output variable', parents=[parent_parser])
83+
output_parser.add_argument('name', help='Output variable name')
84+
output_parser.add_argument('value', help='Output variable value')
85+
86+
args = parser.parse_args()
87+
88+
# Set up verbose mode
89+
setup_verbose_mode(args)
90+
91+
if args.command == 'extract-coverage':
92+
log(f"Extracting coverage from file: {args.file_path} (type: {args.type})")
93+
coverage_pct = extract_coverage(args.file_path, args.type)
94+
if args.github_output:
95+
set_github_output(f"{args.type}_coverage", coverage_pct)
96+
else:
97+
log(f"Coverage: {coverage_pct}%")
98+
99+
elif args.command == 'compare-coverage':
100+
log(f"Comparing coverage: base={args.base_cov}%, PR={args.pr_cov}%")
101+
decreased, diff = compare_coverage(args.base_cov, args.pr_cov)
102+
if args.github_output:
103+
prefix = args.output_prefix
104+
set_github_output(f"{prefix}decreased", str(decreased).lower())
105+
set_github_output(f"{prefix}diff", diff)
106+
log(f"Coverage difference: {diff}%")
107+
log(f"Coverage decreased: {decreased}")
108+
else:
109+
log(f"decreased={str(decreased).lower()}")
110+
log(f"diff={diff}")
111+
112+
elif args.command == 'generate-comment':
113+
log("Generating coverage comparison comment")
114+
comment = generate_comment(
115+
args.base_ext_cov, args.pr_ext_cov, args.ext_decreased, args.ext_diff,
116+
args.base_web_cov, args.pr_web_cov, args.web_decreased, args.web_diff
117+
)
118+
# Output the comment to stdout
119+
log(comment)
120+
121+
elif args.command == 'post-comment':
122+
log(f"Posting comment from {args.comment_path} to PR #{args.pr_number} in {args.repo}")
123+
post_comment(args.comment_path, args.pr_number, args.repo, args.token)
124+
125+
elif args.command == 'run-coverage':
126+
log(f"Running coverage command: {args.coverage_cmd}")
127+
log(f"Output file: {args.output_file}")
128+
log(f"Coverage type: {args.type}")
129+
coverage_pct = run_coverage(args.coverage_cmd, args.output_file, args.type)
130+
if args.github_output:
131+
set_github_output(f"{args.type}_coverage", coverage_pct)
132+
else:
133+
log(f"Coverage: {coverage_pct}%")
134+
135+
elif args.command == 'process-workflow':
136+
log("Processing coverage workflow")
137+
log(f"Base branch: {args.base_branch}")
138+
if args.pr_number:
139+
log(f"PR number: {args.pr_number}")
140+
if args.repo:
141+
log(f"Repository: {args.repo}")
142+
process_coverage_workflow(args)
143+
144+
elif args.command == 'set-github-output':
145+
log(f"Setting GitHub output: {args.name}={args.value}")
146+
set_github_output(args.name, args.value)
147+
148+
else:
149+
log("No command specified")
150+
parser.print_help()
151+
sys.exit(1)
152+
153+
if __name__ == "__main__":
154+
main()

0 commit comments

Comments
 (0)