mirror of
https://github.com/jlengrand/engine.git
synced 2026-03-10 08:11:21 +00:00
Add support for mono-repo with multiple build context
This commit is contained in:
committed by
Erèbe - Romain Gerard
parent
0eaa7dcb0c
commit
cea0a3d80d
@@ -299,77 +299,55 @@ impl BuildPlatform for LocalDocker {
|
||||
}
|
||||
|
||||
// git clone
|
||||
let into_dir = workspace_directory(
|
||||
let repository_root_path = workspace_directory(
|
||||
self.context.workspace_root_dir(),
|
||||
self.context.execution_id(),
|
||||
format!("build/{}", build.image.name.as_str()),
|
||||
);
|
||||
|
||||
info!("cloning repository: {}", build.git_repository.url);
|
||||
info!(
|
||||
"cloning repository: {} to {}",
|
||||
build.git_repository.url, repository_root_path
|
||||
);
|
||||
let git_clone = git::clone(
|
||||
build.git_repository.url.as_str(),
|
||||
&into_dir,
|
||||
&repository_root_path,
|
||||
&build.git_repository.credentials,
|
||||
);
|
||||
|
||||
match git_clone {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
let message = format!(
|
||||
"Error while cloning repository {}. Error: {:?}",
|
||||
&build.git_repository.url, err
|
||||
);
|
||||
|
||||
error!("{}", message);
|
||||
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
if let Err(err) = git_clone {
|
||||
let message = format!(
|
||||
"Error while cloning repository {}. Error: {:?}",
|
||||
&build.git_repository.url, err
|
||||
);
|
||||
error!("{}", message);
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
|
||||
// git checkout to given commit
|
||||
let repo = &git_clone.unwrap();
|
||||
let repo = git_clone.unwrap();
|
||||
let commit_id = &build.git_repository.commit_id;
|
||||
match git::checkout(&repo, &commit_id, build.git_repository.url.as_str()) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
let message = format!(
|
||||
"Error while git checkout repository {} with commit id {}. Error: {:?}",
|
||||
&build.git_repository.url, commit_id, err
|
||||
);
|
||||
|
||||
error!("{}", message);
|
||||
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
if let Err(err) = git::checkout(&repo, commit_id, build.git_repository.url.as_str()) {
|
||||
let message = format!(
|
||||
"Error while git checkout repository {} with commit id {}. Error: {:?}",
|
||||
&build.git_repository.url, commit_id, err
|
||||
);
|
||||
error!("{}", message);
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
|
||||
// git checkout submodules
|
||||
match checkout_submodules(repo) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
let message = format!(
|
||||
"Error while checkout submodules from repository {}. Error: {:?}",
|
||||
&build.git_repository.url, err
|
||||
);
|
||||
if let Err(err) = checkout_submodules(&repo) {
|
||||
let message = format!(
|
||||
"Error while checkout submodules from repository {}. Error: {:?}",
|
||||
&build.git_repository.url, err
|
||||
);
|
||||
error!("{}", message);
|
||||
|
||||
error!("{}", message);
|
||||
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
return Err(self.engine_error(EngineErrorCause::Internal, message));
|
||||
}
|
||||
|
||||
let into_dir_docker_style = format!("{}/.", into_dir.as_str());
|
||||
|
||||
let dockerfile_relative_path = match &build.git_repository.dockerfile_path {
|
||||
Some(dockerfile_relative_path) => match dockerfile_relative_path.trim() {
|
||||
"" | "." | "/" | "/." | "./" | "Dockerfile" => Some("Dockerfile"),
|
||||
dockerfile_root_path => Some(dockerfile_root_path),
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut disable_build_cache = false;
|
||||
|
||||
let mut env_var_args: Vec<String> = Vec::with_capacity(build.options.environment_variables.len());
|
||||
|
||||
for ev in &build.options.environment_variables {
|
||||
@@ -407,48 +385,67 @@ impl BuildPlatform for LocalDocker {
|
||||
}
|
||||
}
|
||||
|
||||
let application_id = build.image.application_id.clone();
|
||||
let app_id = build.image.application_id.clone();
|
||||
let build_context_path = format!("{}/{}/.", repository_root_path.as_str(), build.git_repository.root_path);
|
||||
// If no Dockerfile specified, we should use BuildPacks
|
||||
let result = if build.git_repository.dockerfile_path.is_some() {
|
||||
// build container from the provided Dockerfile
|
||||
|
||||
let dockerfile_exists = match dockerfile_relative_path {
|
||||
Some(path) => {
|
||||
let dockerfile_complete_path = format!("{}/{}", into_dir.as_str(), path);
|
||||
let exists = Path::new(dockerfile_complete_path.as_str()).exists();
|
||||
if !exists {
|
||||
warn!("Dockerfile not found under given {}", dockerfile_complete_path)
|
||||
}
|
||||
exists
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
let dockerfile_relative_path = build.git_repository.dockerfile_path.as_ref().unwrap();
|
||||
let dockerfile_normalized_path = match dockerfile_relative_path.trim() {
|
||||
"" | "." | "/" | "/." | "./" | "Dockerfile" => "Dockerfile",
|
||||
dockerfile_root_path => dockerfile_root_path,
|
||||
};
|
||||
|
||||
let result = match dockerfile_exists {
|
||||
true => {
|
||||
// build container from the provided Dockerfile
|
||||
let dockerfile_complete_path = format!("{}/{}", into_dir.as_str(), dockerfile_relative_path.unwrap());
|
||||
let dockerfile_relative_path = format!("{}/{}", build.git_repository.root_path, dockerfile_normalized_path);
|
||||
let dockerfile_absolute_path = format!("{}/{}", repository_root_path.as_str(), dockerfile_relative_path);
|
||||
|
||||
self.build_image_with_docker(
|
||||
build,
|
||||
dockerfile_complete_path.as_str(),
|
||||
into_dir_docker_style.as_str(),
|
||||
env_var_args,
|
||||
!disable_build_cache,
|
||||
&listeners_helper,
|
||||
)
|
||||
}
|
||||
false => {
|
||||
// build container with Buildpacks
|
||||
self.build_image_with_buildpacks(
|
||||
build,
|
||||
into_dir_docker_style.as_str(),
|
||||
env_var_args,
|
||||
!disable_build_cache,
|
||||
&listeners_helper,
|
||||
)
|
||||
// If the dockerfile does not exist, abort
|
||||
if !Path::new(dockerfile_absolute_path.as_str()).exists() {
|
||||
warn!("Dockerfile not found under {}", dockerfile_absolute_path);
|
||||
listeners_helper.error(ProgressInfo::new(
|
||||
ProgressScope::Application {
|
||||
id: build.image.application_id.clone(),
|
||||
},
|
||||
ProgressLevel::Error,
|
||||
Some(format!(
|
||||
"Dockerfile is not present at location {}",
|
||||
dockerfile_relative_path
|
||||
)),
|
||||
self.context.execution_id(),
|
||||
));
|
||||
|
||||
return Err(self.engine_error(
|
||||
EngineErrorCause::User("Dockerfile not found at location"),
|
||||
format!(
|
||||
"Your Dockerfile is not present at the specified location {}/{}",
|
||||
build.git_repository.root_path.as_str(),
|
||||
build.git_repository.dockerfile_path.unwrap_or_default().as_str()
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
self.build_image_with_docker(
|
||||
build,
|
||||
dockerfile_absolute_path.as_str(),
|
||||
build_context_path.as_str(),
|
||||
env_var_args,
|
||||
!disable_build_cache,
|
||||
&listeners_helper,
|
||||
)
|
||||
} else {
|
||||
// build container with Buildpacks
|
||||
self.build_image_with_buildpacks(
|
||||
build,
|
||||
build_context_path.as_str(),
|
||||
env_var_args,
|
||||
!disable_build_cache,
|
||||
&listeners_helper,
|
||||
)
|
||||
};
|
||||
|
||||
listeners_helper.deployment_in_progress(ProgressInfo::new(
|
||||
ProgressScope::Application { id: application_id },
|
||||
ProgressScope::Application { id: app_id },
|
||||
ProgressLevel::Info,
|
||||
Some(format!("container {} is built ✔", self.name_with_id())),
|
||||
self.context.execution_id(),
|
||||
|
||||
@@ -50,6 +50,7 @@ pub struct GitRepository {
|
||||
pub credentials: Option<Credentials>,
|
||||
pub commit_id: String,
|
||||
pub dockerfile_path: Option<String>,
|
||||
pub root_path: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||
|
||||
@@ -142,6 +142,10 @@ impl Action {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_root_path_value() -> String {
|
||||
"/".to_string()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Application {
|
||||
pub id: String,
|
||||
@@ -152,6 +156,8 @@ pub struct Application {
|
||||
pub branch: String,
|
||||
pub commit_id: String,
|
||||
pub dockerfile_path: Option<String>,
|
||||
#[serde(default = "default_root_path_value")]
|
||||
pub root_path: String,
|
||||
pub private_port: Option<u16>,
|
||||
pub total_cpus: String,
|
||||
pub cpu_burst: String,
|
||||
@@ -285,15 +291,13 @@ impl Application {
|
||||
Build {
|
||||
git_repository: GitRepository {
|
||||
url: self.git_url.clone(),
|
||||
credentials: match &self.git_credentials {
|
||||
Some(credentials) => Some(Credentials {
|
||||
login: credentials.login.clone(),
|
||||
password: credentials.access_token.clone(),
|
||||
}),
|
||||
_ => None,
|
||||
},
|
||||
credentials: self.git_credentials.as_ref().map(|credentials| Credentials {
|
||||
login: credentials.login.clone(),
|
||||
password: credentials.access_token.clone(),
|
||||
}),
|
||||
commit_id: self.commit_id.clone(),
|
||||
dockerfile_path: self.dockerfile_path.clone(),
|
||||
root_path: self.root_path.clone(),
|
||||
},
|
||||
image: self.to_image(),
|
||||
options: BuildOptions {
|
||||
@@ -377,9 +381,7 @@ impl Storage {
|
||||
crate::cloud_provider::models::Storage {
|
||||
id: self.id.clone(),
|
||||
name: self.name.clone(),
|
||||
storage_type: match self.storage_type {
|
||||
_ => crate::cloud_provider::digitalocean::application::StorageType::Standard,
|
||||
},
|
||||
storage_type: crate::cloud_provider::digitalocean::application::StorageType::Standard,
|
||||
size_in_gib: self.size_in_gib,
|
||||
mount_point: self.mount_point.clone(),
|
||||
snapshot_retention_in_days: self.snapshot_retention_in_days,
|
||||
@@ -771,13 +773,10 @@ impl ExternalService {
|
||||
Build {
|
||||
git_repository: GitRepository {
|
||||
url: self.git_url.clone(),
|
||||
credentials: match &self.git_credentials {
|
||||
Some(credentials) => Some(Credentials {
|
||||
login: credentials.login.clone(),
|
||||
password: credentials.access_token.clone(),
|
||||
}),
|
||||
_ => None,
|
||||
},
|
||||
credentials: self.git_credentials.as_ref().map(|credentials| Credentials {
|
||||
login: credentials.login.clone(),
|
||||
password: credentials.access_token.clone(),
|
||||
}),
|
||||
commit_id: self.commit_id.clone(),
|
||||
dockerfile_path: Some(match self.action {
|
||||
Action::Create => self.on_create_dockerfile_path.clone(),
|
||||
@@ -785,6 +784,7 @@ impl ExternalService {
|
||||
Action::Delete => self.on_delete_dockerfile_path.clone(),
|
||||
Action::Nothing => self.on_create_dockerfile_path.clone(),
|
||||
}),
|
||||
root_path: default_root_path_value(),
|
||||
},
|
||||
image: self.to_image(),
|
||||
options: BuildOptions {
|
||||
@@ -826,10 +826,7 @@ impl ProgressInfo {
|
||||
created_at: Utc::now(),
|
||||
scope,
|
||||
level,
|
||||
message: match message {
|
||||
Some(msg) => Some(msg.into()),
|
||||
_ => None,
|
||||
},
|
||||
message: message.map(|msg| msg.into()),
|
||||
execution_id: execution_id.into(),
|
||||
}
|
||||
}
|
||||
@@ -1015,20 +1012,14 @@ impl Context {
|
||||
|
||||
pub fn is_dry_run_deploy(&self) -> bool {
|
||||
match &self.metadata {
|
||||
Some(meta) => match meta.dry_run_deploy {
|
||||
Some(true) => true,
|
||||
_ => false,
|
||||
},
|
||||
Some(meta) => matches!(meta.dry_run_deploy, Some(true)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn requires_forced_upgrade(&self) -> bool {
|
||||
match &self.metadata {
|
||||
Some(meta) => match meta.forced_upgrade {
|
||||
Some(true) => true,
|
||||
_ => false,
|
||||
},
|
||||
Some(meta) => matches!(meta.forced_upgrade, Some(true)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -1039,20 +1030,17 @@ impl Context {
|
||||
|
||||
pub fn resource_expiration_in_seconds(&self) -> Option<u32> {
|
||||
match &self.metadata {
|
||||
Some(meta) => match meta.resource_expiration_in_seconds {
|
||||
Some(ttl) => Some(ttl),
|
||||
_ => None,
|
||||
},
|
||||
Some(meta) => meta.resource_expiration_in_seconds.map(|ttl| ttl),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn docker_build_options(&self) -> Option<Vec<String>> {
|
||||
match &self.metadata {
|
||||
Some(meta) => match meta.docker_build_options.clone() {
|
||||
Some(b) => Some(b.split(" ").map(|x| x.to_string()).collect()),
|
||||
_ => None,
|
||||
},
|
||||
Some(meta) => meta
|
||||
.docker_build_options
|
||||
.clone()
|
||||
.map(|b| b.split(' ').map(|x| x.to_string()).collect()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,6 +324,7 @@ pub fn environment_3_apps_3_routers_3_databases(context: &Context, secrets: Func
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "5990752647af11ef21c3d46a51abbde3da1ab351".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: "/".to_string(),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -374,6 +375,7 @@ pub fn environment_3_apps_3_routers_3_databases(context: &Context, secrets: Func
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "5990752647af11ef21c3d46a51abbde3da1ab351".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -425,6 +427,7 @@ pub fn environment_3_apps_3_routers_3_databases(context: &Context, secrets: Func
|
||||
commit_id: "158ea8ebc9897c50a7c56b910db33ce837ac1e61".to_string(),
|
||||
dockerfile_path: Some(format!("Dockerfile-{}", version_mongo)),
|
||||
action: Action::Create,
|
||||
root_path: String::from("/"),
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
access_token: "xxx".to_string(),
|
||||
@@ -590,6 +593,7 @@ pub fn working_minimal_environment(context: &Context, secrets: FuncTestsSecrets)
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "fc575a2f3be0b9100492c8a463bf18134a8698a5".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -670,6 +674,7 @@ pub fn environnement_2_app_2_routers_1_psql(context: &Context, secrets: FuncTest
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "680550d1937b3f90551849c0da8f77c39916913b".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -720,6 +725,7 @@ pub fn environnement_2_app_2_routers_1_psql(context: &Context, secrets: FuncTest
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "680550d1937b3f90551849c0da8f77c39916913b".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -833,6 +839,7 @@ pub fn echo_app_environment(context: &Context, secrets: FuncTestsSecrets) -> Env
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "2205adea1db295547b99f7b17229afd7e879b6ff".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -887,6 +894,7 @@ pub fn environment_only_http_server(context: &Context) -> Environment {
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "a873edd459c97beb51453db056c40bca85f36ef9".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
@@ -927,6 +935,7 @@ pub fn environment_only_http_server_router(context: &Context, secrets: FuncTests
|
||||
git_url: "https://github.com/Qovery/engine-testing.git".to_string(),
|
||||
commit_id: "a873edd459c97beb51453db056c40bca85f36ef9".to_string(),
|
||||
dockerfile_path: Some("Dockerfile".to_string()),
|
||||
root_path: String::from("/"),
|
||||
action: Action::Create,
|
||||
git_credentials: Some(GitCredentials {
|
||||
login: "x-access-token".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user