smbcloud_cli/deploy/
mod.rs

1mod config;
2mod git;
3mod remote_messages;
4
5use crate::{
6    account::lib::protected_request,
7    cli::CommandResult,
8    ui::{fail_message, succeed_message, succeed_symbol},
9};
10use anyhow::{anyhow, Result};
11use config::check_config;
12use git::remote_deployment_setup;
13use git2::{PushOptions, RemoteCallbacks, Repository};
14use remote_messages::{build_next_app, start_server};
15use smbcloud_networking::environment::Environment;
16use spinners::Spinner;
17
18pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
19    // Check credentials.
20    protected_request(env).await?;
21
22    // Check config.
23    let config = check_config().await?;
24
25    // Check remote repository setup.
26    let repo = match Repository::open(".") {
27        Ok(repo) => repo,
28        Err(_) => {
29            return Err(anyhow!(fail_message(
30                "No git repository found. Init with `git init` command."
31            )))
32        }
33    };
34
35    let _main_branch = match repo.head() {
36        Ok(branch) => branch,
37        Err(_) => {
38            return Err(anyhow!(fail_message(
39                "No main branch found. Create with `git checkout -b <branch>` command."
40            )))
41        }
42    };
43
44    let mut origin = remote_deployment_setup(&repo, &config.name).await?;
45
46    let mut push_opts = PushOptions::new();
47    let mut callbacks = RemoteCallbacks::new();
48    // Set the credentials
49    callbacks.credentials(config.credentials());
50    callbacks.sideband_progress(|data| {
51        // Convert bytes to string, print line by line
52        if let Ok(text) = std::str::from_utf8(data) {
53            for line in text.lines() {
54                if line.contains(&build_next_app()) {
55                    println!("Building the app {}", succeed_symbol());
56                }
57                if line.contains(&start_server(&config.name)) {
58                    println!("Restarting the server {}", succeed_symbol());
59                }
60            }
61        }
62        true // continue receiving.
63    });
64    callbacks.push_update_reference(|_x, status_message| match status_message {
65        Some(e) => {
66            println!("Deployment fail: {}", e);
67            Ok(())
68        }
69        None => Ok(()),
70    });
71    push_opts.remote_callbacks(callbacks);
72
73    let spinner = Spinner::new(
74        spinners::Spinners::Hamburger,
75        succeed_message("Deploying: "),
76    );
77    match origin.push(&["refs/heads/main:refs/heads/main"], Some(&mut push_opts)) {
78        Ok(_) => Ok(CommandResult {
79            spinner,
80            symbol: succeed_symbol(),
81            msg: succeed_message("Deployment complete."),
82        }),
83        Err(e) => Err(anyhow!(fail_message(&e.to_string()))),
84    }
85}