Skip to content

Add function to checkout the jobs repository #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ColinKinloch
Copy link
Contributor

@ColinKinloch ColinKinloch commented Jan 24, 2025

This branch adds crate::clone_git_repository to clone git repos generally and Job::clone_git_repository to clone specifically defined by the gitlab job.

clone_git_repository is heavily based on PrepareFetch::fetch_only

Since the gitoxide PrepareFetch and PrepareCheckout structs delete the target path when they are dropped I opted to checkout the repository to a temporary directory, then move it's contents to the path provided to the target directory.

This adds a rather unwieldy GitCheckoutError enum. gitoxides Error types triggers the result_large_err clippy warning.

This requires rust version 1.73.0 or later.

Fixes #21

* `clone_git_repository` to clone arbitrary repo
* `Job::clone_git_repository` to clone the jobs repo
@ColinKinloch ColinKinloch marked this pull request as ready for review February 10, 2025 18:03
Copy link

@andrewshadura andrewshadura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks okay, but I haven’t gone deeply into details. I trust you tested this code well? (It would be great if it also included some automated tests.)

@@ -454,3 +457,148 @@ impl Runner {
}
}
}

// TODO: Should clone_git_repository be async
// gitoxide doesn't currently have async implemented for http backend
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is viable without either async or cloning in a separate thread (which would make cancellation really tricky, though you seem to have some interrupt-related stuff wired up already); blocking an entire I/O thread for what might be a very long clone process is not workable. Should this maybe just be using libgit2 or something else instead?

.ok_or(GitCheckoutError::MissingCommit)?
} else if let Some(reference) = head_ref {
repo
// TODO: This should be refs/heads/{reference} but it doesn't exist
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine, aiui refs/heads/ would only exist if you had a local tracking branch, which really isn't needed here anyway.

Comment on lines +535 to +536
if let Some(depth) = depth {
if depth > 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let Some(depth) = depth {
if depth > 0 {
if let Some(depth) = depth.and_then(NonZeroU32::new) {

also lets you avoid the .unwrap.

refspec::parse::Operation::Fetch,
) {
refspecs.push(refspec.to_owned());
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this just silently fail on errors? depending on whether or not it's an internal fail, this should at least surface a warning or similar. (ditto for the branch that follows.)

* * Clones to BuildDir
* * Checks out git_info.sha and fetches all in git_info.refspecs
* * Hardcoded username "gitlab-ci-token"
* * credHelperCommand?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit tricky to understand out-of-context, might want to add a few more details for some of these points

}

let checkout_progress = progress.add_child("checkout".to_string());
let (checkout, _outcome) = fetch.fetch_then_checkout(checkout_progress, &should_interrupt)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: if the goal is just to be able to read files from the repo, do we need to do an entire checkout to begin with? couldn't it clone a bare repo and then load files as-needed from there? though the apis might be harder to make for that...but it would likely also be a lot faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Should support checking out the git repository
3 participants