package main import ( "log" "os" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport/http" ) func main() { // Load GitHub env vars token := os.Getenv("GITHUB_TOKEN") repo_name := os.Getenv("GITHUB_REPOSITORY") // e.g. "user/repo" ref := os.Getenv("GITHUB_REF") // e.g. "refs/heads/main" refName := os.Getenv("GITHUB_REF_NAME") // e.g. "main" server := os.Getenv("GITHUB_SERVER_URL") // e.g. "https://github.com" if repo_name == "" || ref == "" || refName == "" || server == "" { log.Fatal("Missing one or more required GitHub environment variables") } fetch_options := git.FetchOptions{ RemoteName: "origin", RefSpecs: []config.RefSpec{config.RefSpec(ref + ":" + ref)}, Depth: 1, } if token != "" { fetch_options.Auth = &http.BasicAuth{ Username: "x-access-token", // GitHub requires this literal username Password: token, } } // Clone the repository (shallow fetch of the ref) repoURL := server + "/" + repo_name log.Println("Cloning", repoURL, "with ref", ref) repo, err := git.PlainInit(".", false) if err != nil { log.Fatal(err) } _, err = repo.CreateRemote(&config.RemoteConfig{ Name: "origin", URLs: []string{repoURL}, }) if err != nil { log.Fatal(err) } err = repo.Fetch(&fetch_options) if err != nil && err != git.NoErrAlreadyUpToDate { log.Fatal(err) } w, err := repo.Worktree() if err != nil { log.Fatal(err) } err = w.Checkout(&git.CheckoutOptions{ Branch: plumbing.ReferenceName("refs/heads/" + refName), }) if err != nil { log.Fatal(err) } log.Println("Checked out", refName) }