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},
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
70 let mut push_opts = PushOptions::new();
71 let mut callbacks = RemoteCallbacks::new();
72 callbacks.credentials(config.credentials());
74 callbacks.sideband_progress(|data| {
75 if let Ok(text) = std::str::from_utf8(data) {
77 for line in text.lines() {
78 if line.contains(&build_next_app()) {
79 println!("Building the app {}", succeed_symbol());
80 }
81 if line.contains(&start_server(&config.project.repository)) {
82 println!("App restart {}", succeed_symbol());
83 }
84 }
85 }
86 true });
88 callbacks.push_update_reference(|_x, status_message| match status_message {
89 Some(e) => {
90 println!("Deployment fail: {}", e);
91 Ok(())
92 }
93 None => Ok(()),
94 });
95 push_opts.remote_callbacks(callbacks);
96
97 let spinner = Spinner::new(
98 spinners::Spinners::Hamburger,
99 succeed_message("Deploying > "),
100 );
101
102 match origin.push(&["refs/heads/main:refs/heads/main"], Some(&mut push_opts)) {
103 Ok(_) => Ok(CommandResult {
104 spinner,
105 symbol: succeed_symbol(),
106 msg: succeed_message("Deployment complete."),
107 }),
108 Err(e) => Err(anyhow!(fail_message(&e.to_string()))),
109 }
110}