Среда сборки проекта#
Для сборки проекта требуется доступ к ряду репозиториев с дополнительными зависимостями (к примеру, общие библиотеки java). Есть несколько вариантов организации работы с репозиториями.
1. Сборка с использованием публичных репозиториев#
Все зависимости скачиваются из публичных репозиториев (например, Maven Central), расположенных непосредственно в интернете.
2. Сборка с использованием внутреннего прокси-репозитория#
Используется промежуточный репозиторий-прокси.
Все зависимости запрашиваются у прокси-репозитория.
Если зависимость не найдена — прокси делает запрос к внешним репозиториям, скачивает нужное и кэширует у себя.
Подробнее можно посмотреть в официальной документации sbt
3. Сборка в закрытой среде (изолированной)#
Среда полностью изолирована от интернета.
Используется локальный репозиторий.
Все зависимости предварительно вручную загружены во внутренний репозиторий.
Настройка сборки в закрытой среде#
Шаг 1. Создать файл с конфигурацией репозитория#
Для Linux:
mkdir -p ~/.sbt
nano ~/.sbt/repositories
Для Windows:
New-Item -ItemType Directory -Force "$env:USERPROFILE\.sbt"
notepad "$env:USERPROFILE\.sbt\repositories"
Содержимое файла:
[repositories]
local
repository-1: https://repository.example.org/path/to/repository-1/
repository-2: https://repository.example.org/path/to/repository-2/
repository-n: https://repository.example.org/path/to/repository-n/, allowInsecureProtocol
repositories— секция со списком репозиториевsbt.local— локальный Ivy-репозиторий~/.ivy2/local.repository-1иrepository-2— произвольные уникальные имена репозиториев.
Добавьте строку для каждого используемого репозитория. Количество, имена и URL определяются конфигурацией конкретного менеджера репозиториев. Можно указать один URL, если на стороне менеджера настроен групповой репозиторий, содержащий все необходимые источники.
allowInsecureProtocol добавляется только для репозитория, доступного по HTTP. Этот параметр не отключает проверку
HTTPS-сертификата. Самоподписанный сертификат необходимо добавить в Java truststore на шаге 3.
Подробнее: Proxy Repositories.
Файл ~/.sbt/repositories используется launcher-ом до загрузки build.sbt и проектных плагинов. На этом этапе launcher
скачивает сам sbt, Scala и плагины.
В закрытой среде включите -Dsbt.override.build.repos=true, чтобы sbt использовал только репозитории из указанного
файла repositories. Настройка переменных приведена на шаге 2.
Шаг 2. Добавить файл с учётными данными (если нужен доступ по логину/паролю)#
Для Linux:
mkdir -p "$HOME/.sbt" "$HOME/.ivy2"
nano "$HOME/.sbt/.credentials"
install -m 600 "$HOME/.sbt/.credentials" "$HOME/.ivy2/.credentials"
Для Windows:
New-Item -ItemType Directory -Force `
"$env:USERPROFILE\.sbt", `
"$env:USERPROFILE\.ivy2"
notepad "$env:USERPROFILE\.sbt\.credentials"
Copy-Item -Force `
"$env:USERPROFILE\.sbt\.credentials" `
"$env:USERPROFILE\.ivy2\.credentials"
Содержимое:
realm=repository-realm
host=repository.example.org
user=build-user
password=very-secret-password
realm и host должны совпадать с ответом сервера.
Основным файлом является ~/.sbt/.credentials. Идентичная копия в ~/.ivy2/.credentials требуется для компонентов
текущей цепочки сборки, использующих стандартный путь Ivy. После смены логина или токена обновите оба файла.
Для Linux:
chmod 600 "$HOME/.sbt/.credentials" "$HOME/.ivy2/.credentials"
export SBT_CREDENTIALS="$HOME/.sbt/.credentials"
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS:+$JAVA_TOOL_OPTIONS }\
-Dsbt.boot.credentials=$SBT_CREDENTIALS \
-Dsbt.repository.config=$HOME/.sbt/repositories \
-Dsbt.override.build.repos=true"
Для Windows:
$env:SBT_CREDENTIALS = "$env:USERPROFILE\.sbt\.credentials"
$sbtOptions = @(
"-Dsbt.boot.credentials=$env:SBT_CREDENTIALS"
"-Dsbt.repository.config=$env:USERPROFILE\.sbt\repositories"
"-Dsbt.override.build.repos=true"
) -join " "
$env:JAVA_TOOL_OPTIONS = (($env:JAVA_TOOL_OPTIONS, $sbtOptions) -join " ").Trim()
Обе переменные обязательны для работы с закрытыми репозиториями. Выполняйте весь приведенный блок после каждой
перезагрузки и в каждой новой консоли до первого запуска GSF CLI или sbt либо добавьте его в профиль пользователя.
Одного наличия файлов .credentials и repositories недостаточно: JVM должна получить sbt.boot.credentials,
sbt.repository.config и sbt.override.build.repos через JAVA_TOOL_OPTIONS.
Скрипты GSF CLI автоматически задают только SBT_CREDENTIALS по основному пути $HOME/.sbt/.credentials или
%USERPROFILE%\.sbt\.credentials, если переменная отсутствует и файл доступен. Они не заменяют обязательную настройку
JAVA_TOOL_OPTIONS.
Настройки должны принадлежать пользователю, который запускает сборку. При запуске через sudo launcher использует
домашний каталог root. В GitLab CI файлы должны создаваться для пользователя gitlab-runner.
credential_manager.sh и Git credential helper не передают пароль sbt launcher-у. Для launcher обязательно нужны
SBT_CREDENTIALS и явно заданное системное свойство sbt.boot.credentials.
Настройка секретов GitLab CI описана в главе о сборке в CI.
Настройка доступа к Git#
Перед первым добавлением проекта сохраните учетные данные для базового адреса Git-сервера.
Для Linux, из каталога gsf-cli:
read -rsp "Git token: " GSF_GIT_TOKEN
echo
printf '%s' "$GSF_GIT_TOKEN" | ./credential_manager.sh set \
--url "<Базовый адрес Git-сервера>" \
--login "build-user" \
--password-stdin
unset GSF_GIT_TOKEN
Указывайте адрес без пути к конкретному репозиторию. Одна запись для https://git.system.ru используется при
загрузке всех модулей с адресами https://git.system.ru/.... Для другого Git-сервера создайте отдельную запись.
Протокол, хост и порт должны совпадать; похожий адрес другого хоста не получит сохраненный токен.
GSF CLI автоматически подключает сохраненные данные к Git в интерактивном и headless-режимах. Файлы
bin/credential_manager_git.sh и bin/credential_manager_git.cmd являются служебными скриптами, добавлять в них логин
и пароль не нужно. Глобальную настройку credential.helper изменять не требуется. После смены токена повторите команду
set с тем же URL.
Команду необходимо выполнять от пользователя, который запускает add_project и обновление проекта. При корректной
записи Git не запрашивает пароль отдельно для каждого модуля на этом хосте.
В headless-режиме Git не запрашивает данные через терминал. Если запись отсутствует или токен не принят сервером, операция завершается с ошибкой. В интерактивном режиме без сохраненной записи стандартный запрос Git остается доступен.
Команда credential_manager.sh show выводит пароли как ********. Для явного просмотра существует параметр
--reveal; не используйте его в CI и логах.
Шаг 3. Добавление сертификатов. В большинстве случаев в закрытой среде потребуется настроить Java-сертификаты#
Получите корневой сертификат
Выполните команду:
sudo keytool -import -trustcacerts \
-keystore $JAVA_HOME/lib/security/cacerts \
-storepass changeit \
-alias company-ca \
-file /путь/к/company-ca.crt
$JAVA_HOME— путь к установленной JDK (например,/usr/lib/jvm/bellsoft-java21-amd64)-alias— уникальное имя сертификата в хранилище (например,company-ca)-storepass changeit— пароль по умолчанию дляcacerts(если не меняли)-trustcacerts— указывает, что вы добавляете доверенный CA-сертификат
Проверка добавления:
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit | grep company-ca
GSF CLI загружает часть артефактов через Python-библиотеку requests, которая не использует Java
truststore cacerts. Если CA-сертификаты хранятся в нестандартном месте и отсутствуют в наборе CA,
доступном requests, перед ручным запуском GSF CLI укажите путь к PEM-bundle в переменной
REQUESTS_CA_BUNDLE:
export REQUESTS_CA_BUNDLE="/path/to/company-ca-bundle.pem"
test -r "$REQUESTS_CA_BUNDLE"
Переменная должна быть задана в той же консоли и для того же пользователя, который запускает
сборку. Указанный bundle заменяет стандартный набор доверенных CA для requests, поэтому должен
содержать все корневые и промежуточные CA, необходимые для используемых HTTPS-сервисов. Если вместо
bundle-файла указан каталог с сертификатами, он должен быть подготовлен командой
openssl rehash <path-to-ca-directory>.
Если восстановить корректную TLS-цепочку нельзя, для временного аварийного запуска можно явно отключить проверку сертификатов. На Windows задайте переменную для пользователя:
setx GSF_CLI_INSECURE_TLS true
После setx завершите текущий сеанс Windows и войдите снова, чтобы все links получили новую
переменную. При первом HTTPS-запросе к хранилищу артефактов GSF CLI выводит
предупреждение о небезопасном режиме. После
устранения проблемы обязательно верните проверку TLS:
setx GSF_CLI_INSECURE_TLS false
На Debian для одного запуска передайте переменную в той же команде:
GSF_CLI_INSECURE_TLS=true ./manage.sh -p <имя_проекта> build
Чтобы режим действовал для всех команд GSF CLI в текущей консоли, выполните:
export GSF_CLI_INSECURE_TLS=true
После устранения проблемы удалите переменную из текущей консоли:
unset GSF_CLI_INSECURE_TLS
Любое значение, кроме явного true без учёта регистра, оставляет проверку TLS включённой.
Небезопасный режим отключает проверку подлинности HTTPS-сервера и делает соединение уязвимым для
MITM-атак.
Шаг 4. Проверить загрузку sbt#
Примените переменные из шага 2 и запустите из каталога application:
sbt -batch sbtVersion
sbt -batch "show externalResolvers"
В externalResolvers должны присутствовать все репозитории из ~/.sbt/repositories. Публичные репозитории при включенном sbt.override.build.repos отображаться не должны.
unauthorized— сервер не принял учетные данные или launcher не прочиталSBT_CREDENTIALS.not found— артефакт отсутствует в Nexus и недоступен через upstream.ошибка сертификата — корпоративный сертификат не добавлен в truststore используемой JDK.
На чистой машине репозиторий должен предоставить org.scala-sbt:sbt и все его транзитивные зависимости. В полностью изолированном контуре эти артефакты необходимо загрузить во внутренний репозиторий заранее.
Проверка с пустым кешем#
manage.sh clean очищает служебный кеш GSF CLI, а sbt clean — результаты компиляции. Для проверки загрузки зависимостей с чистой машины дополнительно удалите кеши SBT, Ivy и Coursier, не удаляя файлы .credentials и repositories:
cd /opt/global/gsf-cli
./manage.sh -p <project_name> clean
cd /opt/global/gsf-cli/workspace/sources/<project_name>/application
sbt -batch clean
rm -rf \
"$HOME/.sbt/boot" \
"$HOME/.ivy2/cache" \
"$HOME/.ivy2/local" \
"$HOME/.cache/coursier" \
"$HOME/.coursier/cache"
После полной очистки первый refresh может завершиться ошибкой после частичной загрузки зависимостей. Повторите refresh один раз и продолжайте сборку только при успешном завершении повторного запуска:
cd /opt/global/gsf-cli
./manage.sh -p <project_name> refresh || ./manage.sh -p <project_name> refresh
./manage.sh -p <project_name> build --build-appsrc --skip-publication
cd /opt/global/gsf-cli/workspace/sources/<project_name>/application
sbt -batch "publishDevDependencies"
Флаг --build-appsrc доступен для SBT-проектов и формирует каталоги build/publish/applib и
build/publish/appsrc в рамках одной сборки. Для другого корневого каталога добавьте --publish-path <root>.
Поэтому повторно вызывать publishLibFolder и publishSrcFolder в SBT-команде не нужно.
Параметр isPublishSrcFolder в project.yaml не должен иметь значение false; по умолчанию публикация исходных артефактов
включена.