feat: pull handler
- test simple pull ok Signed-off-by: Pakin <pakin.t@forth.co.th>
This commit is contained in:
parent
bb3e55eecb
commit
d19dab7561
1 changed files with 80 additions and 1 deletions
81
src/app.rs
81
src/app.rs
|
|
@ -661,7 +661,7 @@ async fn push_handler(State(state): State<AppState>) -> impl IntoResponse {
|
|||
.map(|x| x.to_string())
|
||||
.unwrap_or("master".to_string());
|
||||
|
||||
if let Err(e) = push(config, repo, remote_name, branch) {
|
||||
if let Err(e) = push(config, repo, "origin", branch) {
|
||||
return (
|
||||
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": e.to_string()})),
|
||||
|
|
@ -700,6 +700,84 @@ fn push(
|
|||
Err("cannot lock repo".into())
|
||||
}
|
||||
|
||||
async fn pull_handler(State(state): State<AppState>) -> impl IntoResponse {
|
||||
let config = state.clone().get_all_configures();
|
||||
let repo = state.repo.clone();
|
||||
let remote_name = match state.get_config("GIT_REPO_REMOTE") {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return (
|
||||
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": "repo remote not existed"})),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let branch = &config
|
||||
.get("GIT_REPO_BRANCH_NAME")
|
||||
.map(|x| x.to_string())
|
||||
.unwrap_or("master".to_string());
|
||||
|
||||
if let Err(e) = pull(config, repo, "origin", branch) {
|
||||
return (
|
||||
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"error": e.to_string()})),
|
||||
);
|
||||
}
|
||||
|
||||
(
|
||||
axum::http::StatusCode::OK,
|
||||
Json(json!({"result": "pull completed"})),
|
||||
)
|
||||
}
|
||||
|
||||
// Pull is fetch + merge
|
||||
fn pull(
|
||||
config: gcm::Configure,
|
||||
repo: Arc<Mutex<Repository>>,
|
||||
remote_name: &str,
|
||||
branch: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Ok(rlock) = repo.try_lock() {
|
||||
let mut rem = rlock.find_remote(remote_name)?;
|
||||
let mut callback = RemoteCallbacks::new();
|
||||
callback.credentials(|_url, _user, _allowed| {
|
||||
Cred::userpass_plaintext(
|
||||
config.get("GIT_REPO_USERNAME").unwrap_or(&"".to_string()),
|
||||
config.get("GIT_REPO_PASSWORD").unwrap_or(&"".to_string()),
|
||||
)
|
||||
});
|
||||
let mut fetch_options = FetchOptions::new();
|
||||
fetch_options.remote_callbacks(callback);
|
||||
fetch_options.download_tags(git2::AutotagOption::All);
|
||||
|
||||
info!("fetching from {}...", remote_name);
|
||||
rem.fetch(&[branch], Some(&mut fetch_options), None)?;
|
||||
|
||||
// resolve fetch vs merge
|
||||
let fetch_head = rlock.find_reference("FETCH_HEAD")?;
|
||||
let fetch_commit = rlock.reference_to_annotated_commit(&fetch_head)?;
|
||||
|
||||
let analysis = rlock.merge_analysis(&[&fetch_commit])?;
|
||||
if analysis.0.is_fast_forward() {
|
||||
let refname = format!("refs/heads/{branch}");
|
||||
let mut reference = rlock.find_reference(&refname)?;
|
||||
reference.set_target(fetch_commit.id(), "Fast-Forward")?;
|
||||
rlock.set_head(&refname)?;
|
||||
rlock.checkout_head(Some(git2::build::CheckoutBuilder::default().force()))?;
|
||||
info!("Fast-forwared to {}", fetch_commit.id());
|
||||
} else if analysis.0.is_normal() {
|
||||
warn!("need manual merge");
|
||||
} else {
|
||||
info!("already up to date");
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err("cannot lock repo".into())
|
||||
}
|
||||
|
||||
/// Return git state & server state
|
||||
async fn health_handler(State(_): State<AppState>) -> impl IntoResponse {
|
||||
(
|
||||
|
|
@ -748,6 +826,7 @@ pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
|||
.route("/fetch", get(fetch_handler))
|
||||
.route("/commit", post(commit_handler))
|
||||
.route("/push", get(push_handler))
|
||||
.route("/pull", get(pull_handler))
|
||||
.route("/health", get(health_handler))
|
||||
// .route("/healthz", get(reg::health))
|
||||
.with_state(state);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue