Avatar ·

Как правильно скачать приватный репозиторий через go get?

Всем привет. Я новичок в Go и пытаюсь разобраться с модулями. У нас в компании есть несколько внутренних библиотек, которые лежат в приватных репозиториях на GitHub (и GitLab). Я добавил SSH-ключи в аккаунт, клонировать репозитории через git clone ssh://git@github.com/company/lib.git получается. Но когда я пытаюсь использовать `go get` для добавления зависимости в проект, всё валится с ошибкой. Вот что я делаю: Создаю новый модуль: ``` go mod init myproject ``` Пытаюсь добавить зависимость: ``` go get github.com/company/private-lib@v1.0.0 ``` Получаю ошибку: ``` go: github.com/company/private-lib@v1.0.0: reading https://github.com/company/private-lib?go-get=1: 404 Not Found ``` Я пробовал разные варианты: указывал `GOPRIV=github.com/company`, `GONOSUMCHECK=*`, но ничего не помогает. В чём может быть проблема? Может быть, я не настроил `~/.netrc` или что-то с `GOPROXY`? Подскажите, пожалуйста, правильный путь. Заранее спасибо! <<>>

Краткий ответ: настройте GOPRIV и используйте SSH вместо HTTPS

Проблема в том, что go get по умолчанию пытается получить информацию о пакете через HTTPS-запрос к https://github.com/company/private-lib?go-get=1. Для публичных репозиториев это работает, но приватные репозитории возвращают 404, так как GitHub не даёт доступ без аутентификации.

Пошаговое решение

  1. Настройте переменную окружения GOPRIV

Эта переменная говорит Go, что для определённых доменов не нужно обращаться к публичным прокси (GOPROXY) и проверять контрольные суммы (GOSUMCHECK). Добавьте в ~/.bashrc или ~/.zshrc:

export GOPRIV=github.com/company,gitlab.com/company

Если у вас несколько организаций, можно указать через запятую или использовать wildcard:

export GOPRIV=*.company.com
  1. Настройте Git на использование SSH вместо HTTPS

Go использует Git под капотом. Если ваш SSH-ключ настроен, но Go всё равно ходит по HTTPS, нужно переопределить URL. Создайте или отредактируйте файл ~/.gitconfig:

[url "ssh://git@github.com/"]
    insteadOf = https://github.com/
[url "ssh://git@gitlab.com/"]
    insteadOf = https://gitlab.com/

Теперь все HTTPS-запросы к GitHub/GitLab будут автоматически заменяться на SSH.

  1. Проверьте доступность репозитория

Выполните в терминале:

GIT_SSH_COMMAND="ssh -v" git ls-remote git@github.com:company/private-lib.git

Если команда выполняется успешно — Git настроен правильно.

  1. Очистите кеш и попробуйте снова
go clean -modcache
go get github.com/company/private-lib@latest

Полный пример рабочей конфигурации

Предположим, у вас проект myproject и приватный пакет github.com/company/private-lib с тегом v1.0.0.

# 1. Инициализируем модуль
go mod init myproject

# 2. Убеждаемся, что GOPRIV установлена
echo $GOPRIV
# Должно быть: github.com/company

# 3. Добавляем зависимость
go get github.com/company/private-lib@v1.0.0

# 4. Проверяем go.mod
cat go.mod
# Должна появиться строка:
# require github.com/company/private-lib v1.0.0

Дополнительные советы

  • Для CI/CD: используйте токены доступа (personal access tokens) и настройте ~/.netrc:
machine github.com login <USERNAME> password <TOKEN>
  • Для GitLab: добавьте jobs_token в URL:
git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/".insteadOf "https://gitlab.com/"
  • Проверка версий: если репозиторий без тегов, используйте @branch-name или @commit-hash.

После этих настроек go get будет работать как с публичными, так и с приватными репозиториями.

<<>>

Альтернативный подход: использование replace directives

Если у вас нет возможности менять глобальные настройки Git или вы работаете в изолированной среде (например, на сервере сборки без SSH-доступа), можно использовать механизм replace в go.mod.

Суть метода: вы клонируете приватный репозиторий локально, а затем указываете Go использовать локальную копию вместо удалённой.

Пример

# Клонируем приватный репозиторий рядом с проектом
git clone git@github.com:company/private-lib.git ../private-lib

# В go.mod вашего проекта добавляем:
replace github.com/company/private-lib => ../private-lib

После этого go mod tidy подхватит локальную версию. Этот подход удобен для разработки, но не подходит для продакшн-сборок без дополнительной автоматизации (например, скриптов, которые клонируют все зависимости перед сборкой).

Также можно использовать GOPROXY=off в сочетании с GONOSUMCHECK=*, чтобы полностью отключить обращение к внешним прокси:

export GOPROXY=off
export GONOSUMCHECK=*
go get github.com/company/private-lib@v1.0.0

Но этот способ требует, чтобы все зависимости уже были в кеше или доступны локально.