smbcloud_cli/deploy/
mod.rs1pub mod config;
2mod git;
3mod remote_messages;
4mod setup;
5
6use crate::{
7 account::{lib::is_logged_in, login::process_login, me::me},
8 cli::CommandResult,
9 deploy::config::check_project,
10 ui::{fail_message, succeed_message, succeed_symbol},
11};
12use anyhow::{anyhow, Result};
13use config::check_config;
14use git::remote_deployment_setup;
15use git2::{PushOptions, RemoteCallbacks, Repository};
16use remote_messages::{build_next_app, start_server};
17use smbcloud_model::project::DeploymentPayload;
18use smbcloud_model::project::DeploymentStatus;
19use smbcloud_networking::environment::Environment;
20use smbcloud_networking_project::crud_project_deployment_create::create;
21use spinners::Spinner;
22
23pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
24 if !is_logged_in(env) {
26 let _ = process_login(env).await;
27 }
28
29 let config = check_config(env).await?;
31
32 check_project(env, config.project.id).await?;
34
35 let repo = match Repository::open(".") {
37 Ok(repo) => repo,
38 Err(_) => {
39 return Err(anyhow!(fail_message(
40 "No git repository found. Init with `git init` command."
41 )))
42 }
43 };
44
45 let main_branch = match repo.head() {
46 Ok(branch) => branch,
47 Err(_) => {
48 return Err(anyhow!(fail_message(
49 "No main branch found. Create with `git checkout -b <branch>` command."
50 )))
51 }
52 };
53
54 let mut origin = remote_deployment_setup(&repo, &config.project.repository).await?;
55
56 let commit_hash = match main_branch.resolve() {
57 Ok(result) => match result.target() {
58 Some(hash_id) => hash_id,
59 None => todo!(),
60 },
61 Err(_) => todo!(),
62 };
63 let payload = DeploymentPayload {
64 commit_hash: commit_hash.to_string(),
65 status: DeploymentStatus::Started,
66 };
67
68 let _deployment = create(env, config.project.id, payload).await?;
69 let user = me(env).await?;
70
71 let mut push_opts = PushOptions::new();
72 let mut callbacks = RemoteCallbacks::new();
73 callbacks.credentials(config.credentials(user));
75 callbacks.sideband_progress(|data| {
76 if let Ok(text) = std::str::from_utf8(data) {
78 for line in text.lines() {
79 if line.contains(&build_next_app()) {
80 println!("Building the app {}", succeed_symbol());
81 }
82 if line.contains(&start_server(&config.project.repository)) {
83 println!("App restart {}", succeed_symbol());
84 }
85 }
86 }
87 true });
89 callbacks.push_update_reference(|_x, status_message| match status_message {
90 Some(e) => {
91 println!("Deployment fail: {}", e);
92 Ok(())
93 }
94 None => Ok(()),
95 });
96 push_opts.remote_callbacks(callbacks);
97
98 let spinner = Spinner::new(
99 spinners::Spinners::Hamburger,
100 succeed_message("Deploying > "),
101 );
102
103 match origin.push(&["refs/heads/main:refs/heads/main"], Some(&mut push_opts)) {
104 Ok(_) => Ok(CommandResult {
105 spinner,
106 symbol: succeed_symbol(),
107 msg: succeed_message("Deployment complete."),
108 }),
109 Err(e) => Err(anyhow!(fail_message(&e.to_string()))),
110 }
111}