@@ -19,6 +19,9 @@ import (
1919 u "github.com/actionforge/actrun-cli/utils"
2020
2121 "github.com/Masterminds/semver/v3"
22+ "github.com/go-git/go-git/v5"
23+ "github.com/go-git/go-git/v5/plumbing"
24+ "github.com/go-git/go-git/v5/plumbing/transport/http"
2225 "github.com/google/uuid"
2326 "go.yaml.in/yaml/v4"
2427)
@@ -398,34 +401,78 @@ func init() {
398401 return nil , []error {core .CreateErr (nil , nil , "INPUT_TOKEN not set" )}
399402 }
400403
401- cloneUrl := fmt .Sprintf ("https://%s@ github.com/%s/%s" , ghToken , owner , repo )
404+ cloneUrl := fmt .Sprintf ("https://github.com/%s/%s" , owner , repo )
402405
403406 if err := os .MkdirAll (filepath .Dir (repoRoot ), 0755 ); err != nil {
404407 return nil , []error {core .CreateErr (nil , err , "unable to create action directory" )}
405408 }
406409
407- c := exec .Command ("git" , "clone" , "--quiet" , "--no-checkout" , cloneUrl , repoRoot )
408- c .Stderr = os .Stderr
409- err = c .Run ()
410+ cloneOpts := & git.CloneOptions {
411+ URL : cloneUrl ,
412+ NoCheckout : true ,
413+ }
414+
415+ // TODO: (Seb) Find alternative for running in
416+ // debug mode if user has SSH keys set up instead of a token.
417+ cloneOpts .Auth = & http.BasicAuth {
418+ Username : "x-access-token" ,
419+ Password : ghToken ,
420+ }
421+
422+ clonedRepo , err := git .PlainClone (repoRoot , false , cloneOpts )
410423 if err != nil {
411- return nil , []error {err }
424+ return nil , []error {core .CreateErr (nil , err , "failed to clone repository" )}
425+ }
426+
427+ // checkout the specified ref (or HEAD if empty)
428+ worktree , err := clonedRepo .Worktree ()
429+ if err != nil {
430+ return nil , []error {core .CreateErr (nil , err , "failed to get worktree" )}
431+ }
432+
433+ checkoutOpts := & git.CheckoutOptions {}
434+ if ref != "" {
435+ // resolve as a revision (commit hash, tag, or branch)
436+ hash , err := clonedRepo .ResolveRevision (plumbing .Revision (ref ))
437+ if err != nil {
438+ // if not a hash, try as a branch name
439+ checkoutOpts .Branch = plumbing .NewBranchReferenceName (ref )
440+ } else {
441+ checkoutOpts .Hash = * hash
442+ }
412443 }
413444
414- c = exec .Command ("git" , "checkout" , u .If (ref == "" , "HEAD" , ref ))
415- c .Stderr = os .Stderr
416- c .Dir = repoRoot
417- err = c .Run ()
445+ err = worktree .Checkout (checkoutOpts )
418446 if err != nil {
419- return nil , []error {err }
447+ return nil , []error {core . CreateErr ( nil , err , "failed to checkout ref '%s'" , ref ) }
420448 }
421449 } else {
422- // reset in case something or someone tampered with the cached gh actions
423- c := exec .Command ("git" , "reset" , "--quiet" , "--hard" , u .If (ref == "" , "HEAD" , ref ))
424- c .Stderr = os .Stderr
425- c .Dir = repoRoot
426- err = c .Run ()
450+ // reset in just case something tampered with the cached gh actions
451+ existingRepo , err := git .PlainOpen (repoRoot )
452+ if err != nil {
453+ return nil , []error {core .CreateErr (nil , err , "failed to open cached repository" )}
454+ }
455+
456+ worktree , err := existingRepo .Worktree ()
457+ if err != nil {
458+ return nil , []error {core .CreateErr (nil , err , "failed to get worktree" )}
459+ }
460+
461+ checkoutOpts := & git.CheckoutOptions {
462+ Force : true ,
463+ }
464+ if ref != "" {
465+ hash , err := existingRepo .ResolveRevision (plumbing .Revision (ref ))
466+ if err != nil {
467+ checkoutOpts .Branch = plumbing .NewBranchReferenceName (ref )
468+ } else {
469+ checkoutOpts .Hash = * hash
470+ }
471+ }
472+
473+ err = worktree .Checkout (checkoutOpts )
427474 if err != nil {
428- return nil , []error {err }
475+ return nil , []error {core . CreateErr ( nil , err , "failed to reset to ref '%s'" , ref ) }
429476 }
430477 }
431478
0 commit comments