Skip to content

Commit

Permalink
migrate, optimize & other things
Browse files Browse the repository at this point in the history
  • Loading branch information
m1guelpf committed Jul 23, 2024
1 parent 47d41aa commit ad803a2
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 10 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ async fn run_deploy(slug: String, r#ref: Option<String>, client: &Client) -> Res
Log::Error(message) => eprintln!("{message}"),
},
Ok(Progress::Stage(stage)) => match stage {
Stage::Deployed => log::info!("Deployed site"),
Stage::Migrated => log::info!("Migrated database"),
Stage::Starting => log::info!("Starting deployment"),
Stage::Optimized => log::info!("Optimized deployment"),
Stage::Downloaded => log::info!("Downloaded repository"),
Stage::DepsInstalled => log::info!("Installed dependencies"),
Stage::Deployed => log::info!("Deployed site"),
},
Err(error) => return Err(error.into()),
}
Expand Down
1 change: 1 addition & 0 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ slug = "0.1.5"
toml = "0.8.15"
shlex = "1.3.0"
anyhow = "1.0.71"
symlink = "0.1.0"
serde = "1.0.165"
flate2 = "1.0.30"
indexmap = "2.2.6"
Expand Down
120 changes: 111 additions & 9 deletions crates/server/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,27 @@ use crate::{

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Failed to bootstrap the project.")]
Bootstrap(std::io::Error),

#[error("Failed to clone the repository.")]
Download(#[from] reqwest::Error),

#[error("Failed to extract the repository contents.")]
Extraction(#[from] std::io::Error),
Extraction(std::io::Error),

#[error("Failed to configure the deployment.")]
Configure(std::io::Error),

#[error("Failed to install dependencies.")]
InstallDeps(std::io::Error),

#[error("Failed to run defined commands.")]
RunCommands(std::io::Error),

#[error("Failed to optimize the deployment.")]
Optimize(std::io::Error),

#[error("Failed to cleanup old deployments.")]
Cleanup(std::io::Error),

Expand All @@ -40,6 +49,9 @@ impl From<Error> for orbit_types::Error {
Error::Cleanup(_) => Self::Cleanup,
Error::Publish(_) => Self::Publish,
Error::Download(_) => Self::Download,
Error::Optimize(_) => Self::Optimize,
Error::Bootstrap(_) => Self::Bootstrap,
Error::Configure(_) => Self::Configure,
Error::Extraction(_) => Self::Extraction,
Error::InstallDeps(_) => Self::InstallDeps,
Error::RunCommands(_) => Self::RunCommands,
Expand Down Expand Up @@ -82,37 +94,79 @@ impl Deployer {
try_fn_stream(|stream| async move {
stream.emit(Stage::Starting.into()).await;

self.bootstrap_site()?;
self.download_repo().await?;

stream.emit(Stage::Downloaded.into()).await;

self.install_deps()
self.configure_deployment()?;

if self.should_install_deps() {
self.install_deps()
.try_for_each(|log| async {
stream.emit(Progress::Log(log)).await;
Ok(())
})
.await?;

stream.emit(Stage::DepsInstalled.into()).await;
}

self.run_commands()
.try_for_each(|log| async {
stream.emit(Progress::Log(log)).await;
Ok(())
})
.await?;

stream.emit(Stage::DepsInstalled.into()).await;
self.optimize_deployment()
.try_for_each(|log| async {
stream.emit(Progress::Log(log)).await;
Ok(())
})
.await?;

self.run_commands()
stream.emit(Stage::Optimized.into()).await;

self.migrate()
.try_for_each(|log| async {
stream.emit(Progress::Log(log)).await;
Ok(())
})
.await?;

// migrate, optimize, etc. here
stream.emit(Stage::Migrated.into()).await;

self.set_live()?;
self.clear_old_deployments()?;

stream.emit(Stage::Deployed.into()).await;

self.clear_old_deployments()?;

Ok(())
})
}

fn bootstrap_site(&self) -> Result<(), Error> {
fs::create_dir_all(self.get_path()).map_err(Error::Bootstrap)?;

let current_path = self.site.path.join("current");
if current_path.exists() && !current_path.is_symlink() {
fs::remove_dir_all(current_path).map_err(Error::Bootstrap)?;
}

let storage_path = self.site.path.join("storage");
if !storage_path.exists() {
fs::create_dir_all(storage_path.join("logs")).map_err(Error::Bootstrap)?;
fs::create_dir_all(storage_path.join("app/public")).map_err(Error::Bootstrap)?;
fs::create_dir_all(storage_path.join("framework/cache")).map_err(Error::Bootstrap)?;
fs::create_dir_all(storage_path.join("framework/views")).map_err(Error::Bootstrap)?;
fs::create_dir_all(storage_path.join("framework/sessions"))
.map_err(Error::Bootstrap)?;
}

Ok(())
}

async fn download_repo(&self) -> Result<(), Error> {
// we unwrap here since Config::validate errors ealier if `github_repo` does not cointain a `/`
let (owner, repo) = self.site.github_repo.split_once('/').unwrap();
Expand All @@ -138,7 +192,25 @@ impl Deployer {
untar_to(
tar::Archive::new(GzDecoder::new(tarball.as_ref())),
&self.get_path(),
)?;
)
.map_err(Error::Extraction)?;

Ok(())
}

fn configure_deployment(&self) -> Result<(), Error> {
let env_path = self.site.path.join(".env");
if env_path.exists() {
symlink::symlink_dir(env_path, self.get_path().join(".env"))
.map_err(Error::Configure)?;
}

let storage_path = self.get_path().join("storage");
if storage_path.exists() {
fs::remove_dir_all(&storage_path).map_err(Error::Configure)?;
}
symlink::symlink_dir(self.site.path.join("storage"), storage_path)
.map_err(Error::Configure)?;

Ok(())
}
Expand All @@ -147,6 +219,9 @@ impl Deployer {
spawn_with_logs(
Command::new("composer")
.arg("install")
.arg("--prefer-dist")
.arg("--no-interaction")
.arg("--optimize-autoloader")
.current_dir(self.get_path()),
)
.map_err(Error::InstallDeps)
Expand All @@ -170,13 +245,34 @@ impl Deployer {
.map_err(Error::RunCommands)
}

fn migrate(&self) -> impl Stream<Item = Result<Log, Error>> {
spawn_with_logs(
Command::new("php")
.arg("artisan")
.arg("migrate")
.arg("--force")
.current_dir(self.get_path()),
)
.map_err(Error::InstallDeps)
}

fn optimize_deployment(&self) -> impl Stream<Item = Result<Log, Error>> {
spawn_with_logs(
Command::new("php")
.arg("artisan")
.arg("optimize")
.current_dir(self.get_path()),
)
.map_err(Error::Optimize)
}

fn set_live(&self) -> Result<(), Error> {
let current_deployment = self.site.path.join("current");
if current_deployment.exists() {
fs::remove_file(&current_deployment).map_err(Error::Publish)?;
}

std::os::unix::fs::symlink(
symlink::symlink_dir(
format!("deployments/{}", self.deployment_id),
current_deployment,
)
Expand Down Expand Up @@ -217,4 +313,10 @@ impl Deployer {
.path
.join(format!("deployments/{}", self.deployment_id))
}

fn should_install_deps(&self) -> bool {
let path = self.get_path();

path.join("composer.json").exists() && !path.join("vendor").exists()
}
}
15 changes: 15 additions & 0 deletions crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,21 @@ pub enum Stage {
Downloaded,
/// Dependencies for the current deployment have been installed.
DepsInstalled,
/// The current deployment has been migrated.
Migrated,
/// The current deployment has been optimized.
Optimized,
/// The deployment is now live.
Deployed,
}

#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Error {
/// Failed to boorstrap the project.
#[error("Failed to bootstrap the project.")]
Bootstrap,

/// Failed to clone the repository.
#[error("Failed to clone the repository.")]
Download,
Expand All @@ -41,6 +49,10 @@ pub enum Error {
#[error("Failed to extract the repository contents.")]
Extraction,

/// Failed to configure the deployment.
#[error("Failed to configure the deployment.")]
Configure,

/// Failed to install dependencies.
#[error("Failed to install dependencies.")]
InstallDeps,
Expand All @@ -49,6 +61,9 @@ pub enum Error {
#[error("Failed to run defined commands.")]
RunCommands,

#[error("Failed to optimize the deployment.")]
Optimize,

/// Failed to build the deployment.
#[error("Failed to cleanup old deployments.")]
Cleanup,
Expand Down

0 comments on commit ad803a2

Please sign in to comment.