|
22 | 22 | from rich.table import Table |
23 | 23 | from rich.text import Text |
24 | 24 |
|
25 | | -from codeflash.api.cfapi import is_github_app_installed_on_repo |
| 25 | +from codeflash.api.cfapi import is_github_app_installed_on_repo, setup_github_actions |
26 | 26 | from codeflash.cli_cmds.cli_common import apologize_and_exit |
27 | 27 | from codeflash.cli_cmds.console import console, logger |
28 | 28 | from codeflash.cli_cmds.extension import install_vscode_extension |
29 | 29 | from codeflash.code_utils.compat import LF |
30 | 30 | from codeflash.code_utils.config_parser import parse_config_file |
31 | 31 | from codeflash.code_utils.env_utils import check_formatter_installed, get_codeflash_api_key |
32 | | -from codeflash.code_utils.git_utils import get_git_remotes, get_repo_owner_and_name |
| 32 | +from codeflash.code_utils.git_utils import get_current_branch, get_git_remotes, get_repo_owner_and_name |
33 | 33 | from codeflash.code_utils.github_utils import get_github_secrets_page_url |
34 | 34 | from codeflash.code_utils.shell_utils import get_shell_rc_path, save_api_key_to_rc |
35 | 35 | from codeflash.either import is_successful |
@@ -807,21 +807,110 @@ def install_github_actions(override_formatter_check: bool = False) -> None: # n |
807 | 807 | materialized_optimize_yml_content = customize_codeflash_yaml_content( |
808 | 808 | optimize_yml_content, config, git_root, benchmark_mode |
809 | 809 | ) |
810 | | - with optimize_yaml_path.open("w", encoding="utf8") as optimize_yml_file: |
811 | | - optimize_yml_file.write(materialized_optimize_yml_content) |
812 | | - # Success panel for workflow creation |
813 | | - workflow_success_panel = Panel( |
814 | | - Text( |
815 | | - f"✅ Created GitHub action workflow at {optimize_yaml_path}\n\n" |
816 | | - "Your repository is now configured for continuous optimization!", |
817 | | - style="green", |
818 | | - justify="center", |
819 | | - ), |
820 | | - title="🎉 Workflow Created!", |
821 | | - border_style="bright_green", |
822 | | - ) |
823 | | - console.print(workflow_success_panel) |
824 | | - console.print() |
| 810 | + |
| 811 | + # Get repository information for API call |
| 812 | + git_remote = config.get("git_remote", "origin") |
| 813 | + pr_created_via_api = False |
| 814 | + pr_url = None |
| 815 | + |
| 816 | + try: |
| 817 | + owner, repo_name = get_repo_owner_and_name(repo, git_remote) |
| 818 | + except Exception as e: |
| 819 | + logger.error(f"[cmd_init.py:install_github_actions] Failed to get repository owner and name: {e}") |
| 820 | + # Fall back to local file creation |
| 821 | + workflows_path.mkdir(parents=True, exist_ok=True) |
| 822 | + with optimize_yaml_path.open("w", encoding="utf8") as optimize_yml_file: |
| 823 | + optimize_yml_file.write(materialized_optimize_yml_content) |
| 824 | + workflow_success_panel = Panel( |
| 825 | + Text( |
| 826 | + f"✅ Created GitHub action workflow at {optimize_yaml_path}\n\n" |
| 827 | + "Your repository is now configured for continuous optimization!", |
| 828 | + style="green", |
| 829 | + justify="center", |
| 830 | + ), |
| 831 | + title="🎉 Workflow Created!", |
| 832 | + border_style="bright_green", |
| 833 | + ) |
| 834 | + console.print(workflow_success_panel) |
| 835 | + console.print() |
| 836 | + else: |
| 837 | + # Try to create PR via API |
| 838 | + try: |
| 839 | + base_branch = get_current_branch(repo) if repo.active_branch else "main" |
| 840 | + console.print("Creating PR with GitHub Actions workflow...") |
| 841 | + logger.info( |
| 842 | + f"[cmd_init.py:install_github_actions] Calling setup_github_actions API for {owner}/{repo_name} on branch {base_branch}" |
| 843 | + ) |
| 844 | + |
| 845 | + response = setup_github_actions( |
| 846 | + owner=owner, |
| 847 | + repo=repo_name, |
| 848 | + base_branch=base_branch, |
| 849 | + workflow_content=materialized_optimize_yml_content, |
| 850 | + ) |
| 851 | + |
| 852 | + if response.status_code == 200: |
| 853 | + response_data = response.json() |
| 854 | + if response_data.get("success"): |
| 855 | + pr_url = response_data.get("pr_url") |
| 856 | + if pr_url: |
| 857 | + pr_created_via_api = True |
| 858 | + workflow_success_panel = Panel( |
| 859 | + Text( |
| 860 | + f"✅ PR created: {pr_url}\n\n" |
| 861 | + "Your repository is now configured for continuous optimization!", |
| 862 | + style="green", |
| 863 | + justify="center", |
| 864 | + ), |
| 865 | + title="🎉 Workflow PR Created!", |
| 866 | + border_style="bright_green", |
| 867 | + ) |
| 868 | + console.print(workflow_success_panel) |
| 869 | + console.print() |
| 870 | + logger.info( |
| 871 | + f"[cmd_init.py:install_github_actions] Successfully created PR #{response_data.get('pr_number')} for {owner}/{repo_name}" |
| 872 | + ) |
| 873 | + else: |
| 874 | + # File already exists with same content |
| 875 | + pr_created_via_api = True # Mark as handled (no PR needed) |
| 876 | + already_exists_panel = Panel( |
| 877 | + Text( |
| 878 | + "✅ Workflow file already exists with the same content.\n\n" |
| 879 | + "No changes needed - your repository is already configured!", |
| 880 | + style="green", |
| 881 | + justify="center", |
| 882 | + ), |
| 883 | + title="✅ Already Configured", |
| 884 | + border_style="bright_green", |
| 885 | + ) |
| 886 | + console.print(already_exists_panel) |
| 887 | + console.print() |
| 888 | + else: |
| 889 | + raise Exception(response_data.get("error", "Unknown error")) |
| 890 | + else: |
| 891 | + # API call failed, fall back to local file creation |
| 892 | + raise Exception(f"API returned status {response.status_code}") |
| 893 | + |
| 894 | + except Exception as api_error: |
| 895 | + # Fall back to local file creation if API call fails |
| 896 | + logger.warning( |
| 897 | + f"[cmd_init.py:install_github_actions] API call failed, falling back to local file creation: {api_error}" |
| 898 | + ) |
| 899 | + workflows_path.mkdir(parents=True, exist_ok=True) |
| 900 | + with optimize_yaml_path.open("w", encoding="utf8") as optimize_yml_file: |
| 901 | + optimize_yml_file.write(materialized_optimize_yml_content) |
| 902 | + workflow_success_panel = Panel( |
| 903 | + Text( |
| 904 | + f"✅ Created GitHub action workflow at {optimize_yaml_path}\n\n" |
| 905 | + "Your repository is now configured for continuous optimization!", |
| 906 | + style="green", |
| 907 | + justify="center", |
| 908 | + ), |
| 909 | + title="🎉 Workflow Created!", |
| 910 | + border_style="bright_green", |
| 911 | + ) |
| 912 | + console.print(workflow_success_panel) |
| 913 | + console.print() |
825 | 914 |
|
826 | 915 | try: |
827 | 916 | existing_api_key = get_codeflash_api_key() |
@@ -866,10 +955,25 @@ def install_github_actions(override_formatter_check: bool = False) -> None: # n |
866 | 955 | console.print(launch_panel) |
867 | 956 | click.pause() |
868 | 957 | click.echo() |
869 | | - click.echo( |
870 | | - f"Please edit, commit and push this GitHub actions file to your repo, and you're all set!{LF}" |
871 | | - f"🚀 Codeflash is now configured to automatically optimize new Github PRs!{LF}" |
872 | | - ) |
| 958 | + # Show appropriate message based on whether PR was created via API |
| 959 | + if pr_created_via_api: |
| 960 | + if pr_url: |
| 961 | + click.echo( |
| 962 | + f"🚀 Codeflash is now configured to automatically optimize new Github PRs!{LF}" |
| 963 | + f"Once you merge the PR and add the secret, the workflow will be active.{LF}" |
| 964 | + ) |
| 965 | + else: |
| 966 | + # File already exists |
| 967 | + click.echo( |
| 968 | + f"🚀 Codeflash is now configured to automatically optimize new Github PRs!{LF}" |
| 969 | + f"Just add the secret and the workflow will be active.{LF}" |
| 970 | + ) |
| 971 | + else: |
| 972 | + # Fell back to local file creation |
| 973 | + click.echo( |
| 974 | + f"Please edit, commit and push this GitHub actions file to your repo, and you're all set!{LF}" |
| 975 | + f"🚀 Codeflash is now configured to automatically optimize new Github PRs!{LF}" |
| 976 | + ) |
873 | 977 | ph("cli-github-workflow-created") |
874 | 978 | except KeyboardInterrupt: |
875 | 979 | apologize_and_exit() |
|
0 commit comments