o
    d۷i1                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZmZ e eZdZed	ZG d
d deZdedefddZdededB fddZdefddZdefddZdefddZdededdfddZ dedede!eef fddZ"defd d!Z#d"ed#eddfd$d%Z$dej%dd&d'd(d)ej%d*d+d,d-d.d/ej%d*d0d1d2d.d/ej%dd3d4d5d)fd6eedB ej&d7d)f d"edB d8ed9ed:edB ddfd;d<Z'dS )=    N)Path)	Annotated)	APIClient)get_app_config)Identity)get_rich_toolkithandle_http_errorsim  z.github/workflows/deploy.ymlc                   @   s   e Zd ZdZdS )GitHubSecretErrorz2Raised when setting a GitHub Actions secret fails.N)__name__
__module____qualname____doc__ r   r   Y/home/ubuntu/vllm_env/lib/python3.10/site-packages/fastapi_cloud_cli/commands/setup_ci.pyr	      s    r	   originreturnc                 C      t d| }|r|dS dS )a2  Extract the GitHub host from a git remote URL.

    Supports both github.com and GitHub Enterprise hosts.
    Examples:
        git@github.com:owner/repo.git -> github.com
        https://github.com/owner/repo.git -> github.com
        git@enterprise.github.com:owner/repo.git -> enterprise.github.com
    z(?:git@|https://)([^:/]+)   z
github.comresearchgroupr   matchr   r   r   _get_github_host   s   
r   c                 C   r   )z.Extract 'owner/repo' from a GitHub remote URL.z[:/]([^:/]+/[^/]+?)(?:\.git)?$r   Nr   r   r   r   r   _repo_slug_from_origin)   s   r   c                   C      t dduS )z(Check if git is installed and available.gitNshutilwhichr   r   r   r   _check_git_installed2      r!   c                   C   r   )z8Check if the GitHub CLI (gh) is installed and available.ghNr   r   r   r   r   _check_gh_cli_installed7   r"   r$   c               	   C   s\   zt jg ddddd} | j W S  t jtfy-   t jg ddddd} | j  Y S w )z0Get the remote origin URL of the Git repository.)r#   repoview--jsonurl-qz.urlTcapture_outputtextcheck)r   configz--getzremote.origin.url
subprocessrunstdoutstripCalledProcessErrorFileNotFoundErrorresultr   r   r   _get_remote_origin<   s"   r8   namevaluec              
   C   sT   zt jddd| d|gddd W d	S  t jtfy) } z	td|  d|d	}~ww )
zuSet a GitHub Actions secret via the gh CLI.

    Raises:
        GitHubSecretError: If setting the secret fails.
    r#   secretsetz--bodyT)r+   r-   zFailed to set GitHub secret ''N)r0   r1   r4   r5   r	   )r9   r:   er   r   r   _set_github_secretS   s   r?   app_id
token_namec                 C   sh   t  '}|jd|  d|tdd}|  | }|d |d dW  d   S 1 s-w   Y  dS )	z`Create a new deploy token.

    Returns token_data dict with 'value' and 'expired_at' keys.
    z/apps/z/tokens)r9   expires_in_days)jsonr:   
expired_at)r:   rD   N)r   postTOKEN_EXPIRES_DAYSraise_for_statusrC   )r@   rA   clientresponsedatar   r   r   _create_tokenc   s   
$rK   c               	   C   s>   zt jg ddddd} | j W S  t jtfy   Y dS w )z-Get the default branch of the Git repository.)r#   r%   r&   r'   defaultBranchRefr)   z.defaultBranchRef.nameTr*   mainr/   r6   r   r   r   _get_default_branchr   s   	rN   branchworkflow_pathc                 C   s*   d|  d}|j jddd || d S )Nz9name: Deploy to FastAPI Cloud
on:
  push:
    branches: [a4  ]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: astral-sh/setup-uv@v7
      - run: uv run fastapi deploy
        env:
          FASTAPI_CLOUD_TOKEN: ${{ secrets.FASTAPI_CLOUD_TOKEN }}
          FASTAPI_CLOUD_APP_ID: ${{ secrets.FASTAPI_CLOUD_APP_ID }}
T)parentsexist_ok)parentmkdir
write_text)rO   rP   workflow_contentr   r   r   _write_workflow_file   s
   rW   z--branchz-bzDBranch that triggers deploys (defaults to the repo's default branch))helpFz--secrets-onlyz-szBProvisions token and sets secrets, skips writing the workflow fileT)rX   show_defaultz	--dry-runz-dzAPrints steps that would be taken without actually performing themz--filez-fz8Custom workflow filename (written to .github/workflows/)pathzEPath to the folder containing the app (defaults to current directory)secrets_onlydry_runfilec              
   C   s  t  }t <}| s|jddd td| pt }t|}|s0|jddd tdt	 s?|jddd tdzt
 }	W n tjyY   |jddd tdd	w d
|	 vrl|jddd tdt|	pq|	}
t|	}t }|s~t }|r|d |  |jddd |  |d|
 d| d |  d}d}|ptj}d| d| d}d}|r|| || |s|| 	 W d	   d	S ddlm}m} ||jd}d|
 d| d}|jdd*}t|dd t|j|}|| W d	   n	1 sw   Y  W d	   n	1 s"w   Y  |  |rn|jdd0}zt d |d!  t d"|j W n t!yW   |"d# tdd	w || W d	   n	1 shw   Y  n4d$| d%|
 d&}|jd'd(d |  |d)| d* |  |d+|d!   |d,|j  |  |s#|rtd-| }nt}d.}|s|# r|j$d/| d0d1d2d3}|s|j%d4d1d& }|rtd-| }n|d5 |  d2}|  |r#d6| d| d}|jd7d}t'|| || W d	   n	1 sw   Y  |  || |  |d8|d9 d	d:  d; W d	   d	S 1 sGw   Y  d	S )<a  Configures a GitHub Actions workflow for deploying the app on push to the specified branch.

    Examples:
        fastapi cloud setup-ci                      # Provisions token, sets secrets, and writes workflow file for the 'main' branch
        fastapi cloud setup-ci --branch develop     # Same as above but for the 'develop' branch
        fastapi cloud setup-ci --secrets-only       # Only provisions token and sets secrets, does not write workflow file
        fastapi cloud setup-ci --dry-run            # Prints the steps that would be taken without performing them
        fastapi cloud setup-ci --file ci.yml        # Writes workflow to .github/workflows/ci.yml
    z<No credentials found. Use [blue]`fastapi login`[/] to login.auth)tagr   zENo app linked to this directory. Run [blue]`fastapi deploy`[/] first.errorz=git is not installed. Please install git to use this command.zfError retrieving git remote origin URL. Make sure you're in a git repository with a remote origin set.NgithubzfRemote origin is not a GitHub repository. Please set up a GitHub repo and add it as the remote origin.u>   [yellow]This is a dry run — no changes will be made[/yellow]zConfiguring CIFastAPIzSetting up CI for [bold]z[/bold] (branch: )zCreated deploy tokenzJSet [bold]FASTAPI_CLOUD_TOKEN[/bold] and [bold]FASTAPI_CLOUD_APP_ID[/bold]zWrote [bold].github/workflows/u,   Done — commit and push to start deploying.r   )datetimetimezonez%Y-%m-%d %H:%M UTCu   GitHub Actions — z (zGenerating deploy token...)titlezError creating deploy token.)default_messagezSetting repo secrets...FASTAPI_CLOUD_TOKENr:   FASTAPI_CLOUD_APP_IDz(Failed to set GitHub secrets via gh CLI.zhttps:///z/settings/secrets/actionsz>[yellow]gh CLI not found. Set these secrets manually:[/yellow]infoz  Repository: [blue]z[/]z%  [bold]FASTAPI_CLOUD_TOKEN[/bold] = z&  [bold]FASTAPI_CLOUD_APP_ID[/bold] = z.github/workflows/TzWorkflow file [bold]z"[/bold] already exists. Overwrite?workflowF)r_   defaultzUEnter a new filename (without path) or leave blank to skip writing the workflow file:zSkipped writing workflow file.zWrote [bold]zWriting workflow file...z#Your deploy token expires on [bold]rD   
   zM[/bold]. Regenerate it from the dashboard or re-run this command before then.)(r   r   is_logged_inprinttyperExitr   cwdr   r!   r8   r0   r4   lowerr   r   r$   rN   
print_lineprint_titleDEFAULT_WORKFLOW_PATHr9   rd   re   nowutcstrftimeprogressr   rK   r@   logr?   r	   	set_errorexistsconfirminputr3   rW   )rZ   rO   r[   r\   r]   identitytoolkitapp_path
app_configr   	repo_sluggithub_hosthas_gh	msg_tokenmsg_secretsworkflow_filemsg_workflowmsg_donerd   re   	timestamprA   r{   
token_datasecrets_urlrP   write_workflow	overwritenew_namer   r   r   setup_ci   s  ,









N
 	
	



 $r   )(loggingr   r   r0   pathlibr   typingr   rq   fastapi_cloud_cli.utils.apir   fastapi_cloud_cli.utils.appsr   fastapi_cloud_cli.utils.authr   fastapi_cloud_cli.utils.clir   r   	getLoggerr
   loggerrF   rw   	Exceptionr	   strr   r   boolr!   r$   r8   r?   dictrK   rN   rW   OptionArgumentr   r   r   r   r   <module>   s    
	!