Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/fastapi_cloud_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .commands.apps.link import link_app
from .commands.apps.unlink import unlink_app
from .commands.auth import auth_app
from .commands.ci import ci_app
from .commands.deploy import deploy
from .commands.deployments import deployments_app
from .commands.env import env_app
Expand Down Expand Up @@ -70,6 +71,7 @@ def cloud_main(
cloud_app.add_typer(env_app, name="env")
cloud_app.add_typer(auth_app, name="auth")
cloud_app.add_typer(apps_app, name="apps")
cloud_app.add_typer(ci_app, name="ci")
cloud_app.add_typer(deployments_app, name="deployments")
cloud_app.add_typer(teams_app, name="teams")
cloud_app.add_typer(tokens_app, name="tokens")
Expand Down
13 changes: 13 additions & 0 deletions src/fastapi_cloud_cli/commands/ci/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import typer

from fastapi_cloud_cli.commands.ci.print_workflow import (
print_workflow as print_workflow_command,
)

ci_app = typer.Typer(
no_args_is_help=True,
help="Manage CI integration helpers.",
)
ci_app.command("print-workflow")(print_workflow_command)

__all__ = ["ci_app"]
45 changes: 45 additions & 0 deletions src/fastapi_cloud_cli/commands/ci/print_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import Annotated, Any

import typer
from pydantic import BaseModel
from rich_toolkit import RichToolkit

from fastapi_cloud_cli.commands.setup_ci import (
DEFAULT_WORKFLOW_PATH,
_get_default_branch,
_get_workflow_content,
)
from fastapi_cloud_cli.utils.cli import get_rich_toolkit
from fastapi_cloud_cli.utils.execution import JsonOutputOption


class CIWorkflowOutput(BaseModel):
filename: str
content: str


def _render_workflow_output(data: CIWorkflowOutput, toolkit: RichToolkit) -> None:
toolkit.console.print(data.content, markup=False, end="")


def print_workflow(
branch: Annotated[
str | None,
typer.Option(
"--branch",
"-b",
help="Branch that triggers deploys (defaults to the repo's default branch).",
),
] = None,
json_output: JsonOutputOption = False,
) -> Any:
"""Prints the GitHub Actions workflow YAML without writing files or secrets."""

branch = branch or _get_default_branch()
workflow = CIWorkflowOutput(
filename=DEFAULT_WORKFLOW_PATH.name,
content=_get_workflow_content(branch),
)

with get_rich_toolkit(minimal=True, json_output=json_output) as toolkit:
toolkit.success(workflow, render_output=_render_workflow_output)
8 changes: 6 additions & 2 deletions src/fastapi_cloud_cli/commands/setup_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ def _get_default_branch() -> str:
return "main"


def _write_workflow_file(branch: str, workflow_path: Path) -> None:
workflow_content = f"""\
def _get_workflow_content(branch: str) -> str:
return f"""\
name: Deploy to FastAPI Cloud
on:
push:
Expand All @@ -149,6 +149,10 @@ def _write_workflow_file(branch: str, workflow_path: Path) -> None:
FASTAPI_CLOUD_TOKEN: ${{{{ secrets.FASTAPI_CLOUD_TOKEN }}}}
FASTAPI_CLOUD_APP_ID: ${{{{ secrets.FASTAPI_CLOUD_APP_ID }}}}
"""


def _write_workflow_file(branch: str, workflow_path: Path) -> None:
workflow_content = _get_workflow_content(branch)
workflow_path.parent.mkdir(parents=True, exist_ok=True)
workflow_path.write_text(workflow_content)

Expand Down
42 changes: 42 additions & 0 deletions tests/test_cli_ci.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import json
from unittest.mock import patch

from typer.testing import CliRunner

from fastapi_cloud_cli.cli import cloud_app as app
from fastapi_cloud_cli.commands.setup_ci import _get_workflow_content

runner = CliRunner()


def test_print_workflow_uses_default_branch() -> None:
with patch(
"fastapi_cloud_cli.commands.ci.print_workflow._get_default_branch",
return_value="develop",
):
result = runner.invoke(app, ["ci", "print-workflow"])

assert result.exit_code == 0
assert result.stdout == _get_workflow_content("develop")
assert result.stderr == ""


def test_print_workflow_uses_branch_option() -> None:
result = runner.invoke(app, ["ci", "print-workflow", "--branch", "main"])

assert result.exit_code == 0
assert result.stdout == _get_workflow_content("main")
assert result.stderr == ""


def test_print_workflow_json_outputs_envelope() -> None:
result = runner.invoke(app, ["ci", "print-workflow", "--branch", "main", "--json"])

assert result.exit_code == 0
assert json.loads(result.stdout) == {
"data": {
"filename": "deploy.yml",
"content": _get_workflow_content("main"),
}
}
assert result.stderr == ""
Loading