Введение: когда простой go get превращается в головоломку
Вы когда-нибудь пытались выполнить go get github.com/ваш-аккаунт/приватный-репозиторий и получали в ответ холодное, недружелюбное сообщение?
go get github.com/ваш-аккаунт/приватный-репозиторий:
module github.com/ваш-аккаунт/приватный-репозиторий:
git ls-remote -q origin in /tmp/...: exit status 128:
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/ваш-аккаунт/приватный-репозиторий.git'
Или, что ещё более загадочно:
go get github.com/ваш-аккаунт/приватный-репозиторий:
terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repo, see https://golang.org/doc/faq#git_https
Знакомая ситуация? Если да — вы попали по адресу. Эта ошибка — классический «камень преткновения» для Go-разработчиков, работающих с приватными репозиториями на GitHub. На Stack Overflow этот вопрос собрал тысячи просмотров, и сегодня мы разберём его раз и навсегда.
В этой статье мы не просто решим проблему — мы поймём, почему она возникает, и научимся настраивать окружение так, чтобы go get работал с приватными репозиториями как по маслу. Поехали!
Почему Go отказывается работать с приватными репозиториями?
Чтобы понять причину, нужно заглянуть «под капот» Go. Когда вы выполняете go get, Go-тулза делает несколько вещей:
- Она пытается клонировать репозиторий по HTTPS (это протокол по умолчанию).
- Если репозиторий приватный, Git запрашивает аутентификацию (логин/пароль).
- Go, по умолчанию, отключает интерактивные запросы в терминале — это и есть то самое «terminal prompts disabled».
Почему Go так делает? Всё просто: при автоматической сборке или в CI/CD-пайплайнах интерактивный ввод пароля невозможен. Поэтому Go предпочитает «упасть» с ошибкой, чем зависнуть в ожидании ввода.
Ключевая идея: ошибка «terminal prompts disabled» — это не баг, а фича. Go говорит вам: «Я не могу спросить у тебя пароль, дай мне готовые credentials». И наша задача — предоставить их.
Способ 1: Использование SSH (самый надёжный и правильный)
Это рекомендуемый метод. SSH-ключи — это безопасно, удобно и не требует ввода пароля каждый раз.
Шаг 1. Генерируем SSH-ключ (если его нет)
Откройте терминал и выполните:
ssh-keygen -t ed25519 -C "ваш_email@example.com"
Нажмите Enter, чтобы сохранить ключ в стандартную папку (~/.ssh/id_ed25519). Можете добавить парольную фразу — это повысит безопасность.
Шаг 2. Добавляем ключ в SSH-агент
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Шаг 3. Добавляем публичный ключ на GitHub
Скопируйте содержимое ~/.ssh/id_ed25519.pub:
cat ~/.ssh/id_ed25519.pub
Перейдите на GitHub → Settings → SSH and GPG keys → New SSH key. Вставьте ключ и сохраните.
Шаг 4. Настраиваем Git на использование SSH
Теперь самое важное: нужно заставить Go использовать SSH вместо HTTPS. Для этого отредактируйте файл ~/.gitconfig:
[url "git@github.com:"]
insteadOf = https://github.com/
Эта директива говорит Git: «Когда увидишь https://github.com/ — используй git@github.com: (SSH)».
Шаг 5. Пробуем снова
go get github.com/ваш-аккаунт/приватный-репозиторий@latest
Если всё настроено правильно — ошибка исчезнет. Go будет использовать SSH для аутентификации, а SSH-агент предоставит ключ.
Способ 2: Использование Personal Access Token (PAT) — для CI/CD и скриптов
SSH отлично подходит для локальной разработки, но в CI/CD-системах (GitHub Actions, GitLab CI) часто удобнее использовать токены.
Шаг 1. Создаём токен на GitHub
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic). Нажмите «Generate new token (classic)». Выберите scope repo (для доступа к приватным репозиториям). Скопируйте токен — он показывается только один раз!
Шаг 2. Настраиваем Git на использование токена
Самый простой способ — использовать git config с указанием логина и токена в URL:
git config --global url."https://ваш_логин:ваш_токен@github.com/".insteadOf "https://github.com/"
Пример:
git config --global url."https://ivanivanov:ghp_xxxxxxxxxxxxxxxxxxxx@github.com/".insteadOf "https://github.com/"
Шаг 3. Проверяем
Теперь при выполнении go get Git будет автоматически подставлять токен в URL, и аутентификация пройдёт без вопросов.
Важно: Никогда не коммитьте токен в публичный репозиторий! Используйте переменные окружения.
Способ 3: Использование переменной GOPRIVATE (для модулей)
Иногда проблема не в аутентификации, а в том, что Go пытается найти модуль в публичном proxy (по умолчанию proxy.golang.org), который не имеет доступа к вашему приватному репозиторию. Решение — сказать Go: «Этот модуль приватный, не ищи его в proxy».
go env -w GOPRIVATE=github.com/ваш-аккаунт/*
Или для всех приватных репозиториев вашей организации:
go env -w GOPRIVATE=github.com/ваша-организация/*
После этого Go будет напрямую обращаться к GitHub, минуя публичный кэш. Комбинируйте этот способ с SSH или PAT — и вы получите идеальное решение.
Дополнительный совет: работа с go mod tidy
После настройки аутентификации не забудьте обновить зависимости:
go mod tidy
go mod download
Это гарантирует, что все модули, включая приватные, будут корректно загружены и закешированы.