| 436 | } |
| 437 | |
| 438 | fn build( |
| 439 | &self, |
| 440 | build: &mut Build, |
| 441 | logger: &EnvLogger, |
| 442 | metrics_registry: Arc<dyn MetricsRegistry>, |
| 443 | abort: &dyn Abort, |
| 444 | ) -> Result<(), BuildError> { |
| 445 | // check if we should already abort the task |
| 446 | if abort.status().should_cancel() { |
| 447 | return Err(BuildError::Aborted { |
| 448 | application: build.image.service_id.clone(), |
| 449 | }); |
| 450 | } |
| 451 | |
| 452 | // LOGGING |
| 453 | let repository_root_path = self.get_repository_build_root_path(build)?; |
| 454 | logger.send_progress(format!("📥 Cloning repository {}", build.git_repository.url)); |
| 455 | |
| 456 | // Retrieve git credentials |
| 457 | let git_user_creds = match build.git_repository.credentials() { |
| 458 | None => None, |
| 459 | Some(Ok(creds)) => Some(creds), |
| 460 | Some(Err(err)) => { |
| 461 | logger.send_warning(format!("🗝️ Unable to get credentials for git repository: {err}")); |
| 462 | None |
| 463 | } |
| 464 | }; |
| 465 | |
| 466 | // Create callback that will be called by git to provide credentials per user |
| 467 | // If people use submodule, they need to provide us their ssh key |
| 468 | let get_credentials = |user: &str| { |
| 469 | let mut creds: Vec<(CredentialType, Cred)> = Vec::with_capacity(build.git_repository.ssh_keys.len() + 1); |
| 470 | for ssh_key in build.git_repository.ssh_keys.iter() { |
| 471 | let public_key = ssh_key.public_key.as_deref(); |
| 472 | let passphrase = ssh_key.passphrase.as_deref(); |
| 473 | if let Ok(cred) = Cred::ssh_key_from_memory(user, public_key, &ssh_key.private_key, passphrase) { |
| 474 | creds.push((CredentialType::SSH_MEMORY, cred)); |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | if let Some(git_creds) = &git_user_creds { |
| 479 | creds.push(( |
| 480 | CredentialType::USER_PASS_PLAINTEXT, |
| 481 | Cred::userpass_plaintext(&git_creds.login, &git_creds.password).unwrap(), |
| 482 | )); |
| 483 | } |
| 484 | |
| 485 | creds |
| 486 | }; |
| 487 | |
| 488 | // Cleanup, mono repo can require to clone multiple time the same repo |
| 489 | // FIXME: re-use the same repo and just checkout at the correct commit |
| 490 | if repository_root_path.exists() { |
| 491 | let app_id = build.image.service_id.clone(); |
| 492 | fs::remove_dir_all(&repository_root_path).map_err(|err| BuildError::IoError { |
| 493 | application: app_id, |
| 494 | action_description: "cleaning old repository".to_string(), |
| 495 | raw_error: err, |