Клонировать репозиторий из GitHub Enterprise с помощью go-git
Я пытаюсь использовать go-git
клонировать репозиторий из GitHub Enterprise. Для этого я использую протокол HTTPS с токеном доступа с соответствующими разрешениями для моих репозиториев (проверено в командной строке). go-git
не удается при создании git-upload-pack
Вызов RPC, потому что сервер отвечает 400:
$ go run main.go
unexpected client error: unexpected requesting "https://github.mycompany.net/my-org/myrepo.git/info/refs?service=git-upload-pack" status code: 400
Запрос, который он делает, эквивалентен этому:
GET /my-org/myrepo.git/info/refs?service=git-upload-pack HTTP/1.1
Host: github.mycompany.net
User-Agent: git/1.0
Accept: */*
Authorization: Bearer atokenthatisdefinitelyvalid
Без токена в заголовке запроса я получаю ожидаемое 401 (Anonymous access denied
) ответ из хранилища. С токеном он отвечает 400.
Я обнаружил, что то же самое относится к общедоступным репозиториям на не-Enterprise GitHub; с той разницей, что он (как ожидается) работает без Authorization
заголовок, так как ничего не нужно. Если я добавлю действительный токен, GitHub, как и его версия Enterprise, ответит 400.
Ниже приведен минимальный пример. Есть ли способ использовать go-git
с GitHub Enterprise, который требует аутентификацию? В идеале использовать токен аутентификации?
package main
import (
"fmt"
"io/ioutil"
git "gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
)
const (
repoURL = "https://github.mycompany.net/my-org/myrepo.git"
githubAccessToken = "atokenthatisdefinitelyvalid"
)
func main() {
dir, _ := ioutil.TempDir("", "temp_dir")
options := &git.CloneOptions{
Auth: &http.TokenAuth{Token: githubAccessToken},
URL: repoURL,
Depth: 500,
ReferenceName: plumbing.ReferenceName("refs/heads/master"),
SingleBranch: true,
Tags: git.NoTags,
}
_, err := git.PlainClone(dir, false, options)
fmt.Println(err)
}
2 ответа
Оказывается, что Github использует токен в качестве пароля для вашего пользователя, поэтому он требует базовой аутентификации, а не токена в заголовке:
options := &git.CloneOptions{
Auth: &http.BasicAuth{Username: "myusername", Token: "mytoken"},
URL: repoURL,
Depth: 500,
ReferenceName: plumbing.ReferenceName("refs/heads/master"),
SingleBranch: true,
Tags: git.NoTags,
}
У них есть возможность использовать токен:
https://github.com/src-d/go-git/blob/master/plumbing/transport/http/common.go#L204-L227
import (
git "gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
)
func main() {
...
auth := http.TokenAuth{Token: "TOKEN_HERE"}
opts := git.CloneOptions{
URL: "https://github.com/user/repo",
Auth: &auth,
}
git.PlainClone("/tmp/cloneDir", false, &opts)
..
}
Не уверен на 100%, решит ли это все ваши проблемы