Main execution function for GitHub Action.
()
| 519 | |
| 520 | |
| 521 | def main(): |
| 522 | """Main execution function for GitHub Action.""" |
| 523 | try: |
| 524 | # Get environment configuration |
| 525 | try: |
| 526 | repo_name, pr_number = get_environment_config() |
| 527 | except ConfigurationError as e: |
| 528 | print(json.dumps({'error': str(e)})) |
| 529 | sys.exit(EXIT_CONFIGURATION_ERROR) |
| 530 | |
| 531 | # Load custom filtering instructions if provided |
| 532 | custom_filtering_instructions = None |
| 533 | filtering_file = os.environ.get('FALSE_POSITIVE_FILTERING_INSTRUCTIONS', '') |
| 534 | if filtering_file and Path(filtering_file).exists(): |
| 535 | try: |
| 536 | with open(filtering_file, 'r', encoding='utf-8') as f: |
| 537 | custom_filtering_instructions = f.read() |
| 538 | logger.info(f"Loaded custom filtering instructions from {filtering_file}") |
| 539 | except Exception as e: |
| 540 | logger.warning(f"Failed to read filtering instructions file {filtering_file}: {e}") |
| 541 | |
| 542 | # Load custom security scan instructions if provided |
| 543 | custom_scan_instructions = None |
| 544 | scan_file = os.environ.get('CUSTOM_SECURITY_SCAN_INSTRUCTIONS', '') |
| 545 | if scan_file and Path(scan_file).exists(): |
| 546 | try: |
| 547 | with open(scan_file, 'r', encoding='utf-8') as f: |
| 548 | custom_scan_instructions = f.read() |
| 549 | logger.info(f"Loaded custom security scan instructions from {scan_file}") |
| 550 | except Exception as e: |
| 551 | logger.warning(f"Failed to read security scan instructions file {scan_file}: {e}") |
| 552 | |
| 553 | # Initialize components |
| 554 | try: |
| 555 | github_client, claude_runner = initialize_clients() |
| 556 | except ConfigurationError as e: |
| 557 | print(json.dumps({'error': str(e)})) |
| 558 | sys.exit(EXIT_CONFIGURATION_ERROR) |
| 559 | |
| 560 | # Initialize findings filter |
| 561 | try: |
| 562 | findings_filter = initialize_findings_filter(custom_filtering_instructions) |
| 563 | except ConfigurationError as e: |
| 564 | print(json.dumps({'error': str(e)})) |
| 565 | sys.exit(EXIT_CONFIGURATION_ERROR) |
| 566 | |
| 567 | # Validate Claude Code is available |
| 568 | claude_ok, claude_error = claude_runner.validate_claude_available() |
| 569 | if not claude_ok: |
| 570 | print(json.dumps({'error': f'Claude Code not available: {claude_error}'})) |
| 571 | sys.exit(EXIT_GENERAL_ERROR) |
| 572 | |
| 573 | # Get PR data |
| 574 | try: |
| 575 | pr_data = github_client.get_pr_data(repo_name, pr_number) |
| 576 | pr_diff = github_client.get_pr_diff(repo_name, pr_number) |
| 577 | except Exception as e: |
| 578 | print(json.dumps({'error': f'Failed to fetch PR data: {str(e)}'})) |