Skip to content

Commit c905677

Browse files
committed
Testing a idea
1 parent 4f16b18 commit c905677

File tree

5 files changed

+255
-132
lines changed

5 files changed

+255
-132
lines changed

.github/scripts/detect_changes.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to detect changed Python files in a git repository.
4+
Used by GitHub Actions workflow to determine which files to lint/test.
5+
"""
6+
import os
7+
import subprocess
8+
import sys
9+
10+
11+
def get_changed_files(event_name, base_ref=None, before_sha=None, after_sha=None):
12+
"""
13+
Get list of changed Python files based on git diff.
14+
15+
Args:
16+
event_name: GitHub event name ('pull_request' or 'push')
17+
base_ref: Base branch for PR comparisons
18+
before_sha: Before SHA for push comparisons
19+
after_sha: After SHA for push comparisons
20+
21+
Returns:
22+
tuple: (has_python_changes, changed_files)
23+
"""
24+
# Determine the correct git diff command based on event type
25+
if event_name == 'pull_request':
26+
# For PRs, compare against base branch
27+
cmd = ['git', 'diff', '--name-only', '--diff-filter=ACMRT', f'origin/{base_ref}', 'HEAD']
28+
else:
29+
# For pushes, use the before/after SHAs
30+
cmd = ['git', 'diff', '--name-only', '--diff-filter=ACMRT', before_sha, after_sha]
31+
32+
# Execute git command and get output
33+
result = subprocess.run(cmd, capture_output=True, text=True)
34+
all_changed_files = [f for f in result.stdout.strip().split('\n') if f]
35+
36+
# Filter for Python files, excluding setup.py initially
37+
changed_files = [f for f in all_changed_files if f.endswith('.py') and f != 'setup.py']
38+
39+
# Add setup.py only if it was actually changed
40+
if 'setup.py' in all_changed_files:
41+
changed_files.append('setup.py')
42+
43+
# Check if we have any Python changes
44+
has_python_changes = len(changed_files) > 0
45+
46+
return has_python_changes, changed_files
47+
48+
49+
if __name__ == "__main__":
50+
# Get parameters from environment variables or command line
51+
event_name = os.environ.get('GITHUB_EVENT_NAME', sys.argv[1] if len(sys.argv) > 1 else None)
52+
base_ref = os.environ.get('GITHUB_BASE_REF', sys.argv[2] if len(sys.argv) > 2 else None)
53+
before_sha = os.environ.get('GITHUB_BEFORE', sys.argv[3] if len(sys.argv) > 3 else None)
54+
after_sha = os.environ.get('GITHUB_AFTER', sys.argv[4] if len(sys.argv) > 4 else None)
55+
56+
# Get changed files
57+
has_changes, files = get_changed_files(event_name, base_ref, before_sha, after_sha)
58+
59+
# Output for GitHub Actions
60+
if has_changes:
61+
print(f"::set-output name=has_python_changes::true")
62+
print(f"::set-output name=files::{' '.join(files)}")
63+
print("Changed Python files:", ' '.join(files))
64+
else:
65+
print("::set-output name=has_python_changes::false")
66+
print("::set-output name=files::")
67+
print("No Python files changed")

.github/scripts/generate_summary.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate a summary for GitHub Actions workflow.
4+
Used to create a consistent summary at the end of the workflow.
5+
"""
6+
import os
7+
import sys
8+
9+
10+
def generate_summary(has_python_changes):
11+
"""
12+
Generate a summary for GitHub Actions step summary.
13+
14+
Args:
15+
has_python_changes: Boolean indicating if any Python files were changed
16+
"""
17+
# Get the path to the GitHub step summary file
18+
summary_file = os.environ.get('GITHUB_STEP_SUMMARY')
19+
if not summary_file:
20+
print("GITHUB_STEP_SUMMARY environment variable not found.")
21+
return
22+
23+
with open(summary_file, 'a') as f:
24+
f.write('## Pull Request Lint Results\n')
25+
if has_python_changes:
26+
f.write('Linting has completed for all Python files changed in this PR.\n')
27+
f.write('See individual job logs for detailed results.\n')
28+
else:
29+
f.write('No Python files were changed in this PR. Linting was skipped.\n')
30+
f.write('\n')
31+
f.write('⚠️ **Note:** This PR still requires manual approval regardless of linting results.\n')
32+
33+
34+
if __name__ == "__main__":
35+
# Get whether there were Python changes from arguments
36+
has_python_changes = sys.argv[1].lower() == 'true' if len(sys.argv) > 1 else False
37+
38+
# Generate the summary
39+
generate_summary(has_python_changes)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate a custom tox configuration for testing changed files.
4+
Used by GitHub Actions workflow for PR testing.
5+
"""
6+
import os
7+
import sys
8+
9+
10+
def generate_tox_config(changed_files, output_file='tox_pr.ini'):
11+
"""
12+
Generate a customized tox configuration for testing changed files.
13+
14+
Args:
15+
changed_files: List of changed Python files
16+
output_file: Path to write the tox configuration to
17+
"""
18+
with open(output_file, 'w') as tox_file:
19+
# Write tox section
20+
tox_file.write('[tox]\n')
21+
tox_file.write('envlist = py312\n')
22+
tox_file.write('skip_missing_interpreters = true\n\n')
23+
24+
# Write testenv section
25+
tox_file.write('[testenv]\n')
26+
tox_file.write('setenv =\n')
27+
tox_file.write(' COVERAGE_FILE = .coverage.{envname}\n')
28+
tox_file.write('deps =\n')
29+
tox_file.write(' -r requirements-dev.txt\n')
30+
tox_file.write('allowlist_externals =\n')
31+
tox_file.write(' pytest\n')
32+
tox_file.write(' coverage\n')
33+
tox_file.write('commands =\n')
34+
35+
# Always run a baseline test with coverage
36+
tox_file.write(' pytest -xvs --cov=patterns tests/ --cov-report=term-missing\n')
37+
38+
# Add test commands for changed files
39+
tox_file.write(' # Run specific tests for changed files\n')
40+
41+
for file in changed_files:
42+
if file.endswith('.py'):
43+
# Handle implementation files
44+
if file.startswith('patterns/'):
45+
module_name = os.path.basename(file)[:-3] # Remove .py extension
46+
pattern_dir = os.path.dirname(file).split('/', 1)[1] if '/' in os.path.dirname(file) else ''
47+
48+
tox_file.write(f' # Testing {file}\n')
49+
50+
# Check for specific test file and add it conditionally
51+
test_file = f'tests/{pattern_dir}/test_{module_name}.py'
52+
# Use conditional for test file
53+
tox_file.write(f' python -c "import os.path; test_path=\'{test_file}\'; print(f\'Test file {{test_path}} exists: {{os.path.exists(test_path)}}\')" \n')
54+
tox_file.write(f' pytest -xvs --cov=patterns --cov-append tests/{pattern_dir}/ -k "{module_name}"\n')
55+
56+
# Run test files directly if modified
57+
if file.startswith('tests/'):
58+
tox_file.write(f' pytest -xvs --cov=patterns --cov-append {file}\n')
59+
60+
# Run doctests on pattern files
61+
tox_file.write(' # Run doctests\n')
62+
for file in changed_files:
63+
if file.startswith('patterns/') and file.endswith('.py'):
64+
tox_file.write(f' pytest --doctest-modules -v --cov=patterns --cov-append {file}\n')
65+
66+
# Add coverage report commands
67+
tox_file.write(' coverage combine\n')
68+
tox_file.write(' coverage report\n')
69+
70+
71+
if __name__ == "__main__":
72+
# Get list of changed files from arguments
73+
changed_files = sys.argv[1].split() if len(sys.argv) > 1 else []
74+
75+
# Generate the tox configuration
76+
generate_tox_config(changed_files)
77+
78+
# Print the configuration to stdout
79+
with open('tox_pr.ini', 'r') as f:
80+
print(f.read())

.github/scripts/run_tests.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to run pytest on specific files based on changes.
4+
Used by GitHub Actions workflow for PR testing.
5+
"""
6+
import os
7+
import subprocess
8+
import sys
9+
10+
11+
def run_tests_for_changed_files(changed_files):
12+
"""
13+
Run appropriate tests for the changed files.
14+
15+
Args:
16+
changed_files: List of changed Python files
17+
"""
18+
# Run test discovery first
19+
print("Running pytest discovery...")
20+
subprocess.run(['python', '-m', 'pytest', '--collect-only', '-v'])
21+
22+
# Extract module paths from changed files
23+
print("Running tests for changed files...")
24+
modules = []
25+
for file in changed_files:
26+
if file.startswith('patterns/'):
27+
# Convert file path to module path (remove .py and replace / with .)
28+
module_path = file.replace('.py', '').replace('/', '.')
29+
modules.append(module_path)
30+
31+
# Run tests for each module
32+
for module in modules:
33+
module_name = module.split('.')[-1]
34+
print(f"Testing module: {module}")
35+
subprocess.run(['python', '-m', 'pytest', '-xvs', 'tests/', '-k', module_name],
36+
check=False)
37+
38+
# Then run doctests on the changed files
39+
print("Running doctests for changed files...")
40+
for file in changed_files:
41+
if file.endswith('.py'):
42+
print(f"Running doctest for {file}")
43+
subprocess.run(['python', '-m', 'pytest', '--doctest-modules', '-v', file],
44+
check=False)
45+
46+
47+
if __name__ == "__main__":
48+
# Get list of changed files from arguments
49+
changed_files = sys.argv[1].split() if len(sys.argv) > 1 else []
50+
51+
# Run the tests
52+
run_tests_for_changed_files(changed_files)

0 commit comments

Comments
 (0)