Установка, настройка и сборка на Linux#
Инструкция проводит от установки GSF CLI до сборки applib и appsrc. Команды рассчитаны на Bash в Debian-подобной
системе x86_64. Для другой ОС семейства Linux названия системных пакетов и способ их установки нужно подобрать
отдельно.
Для CI сначала подготовьте агент по главе о раннерах. Дальше вся настройка сборки, включая pipeline, выполняется по этой главе.
Перед установкой#
Подготовьте URL конфигурационного Git-проекта, его ветку и имя проекта в GSF CLI. В примерах имя — main, каталог
установки — /opt/global/gsf-cli. Git URL должен оканчиваться на .git.
Для сборки используются JDK 21 и SBT 1.x начиная с 1.8.2; ниже показана установка SBT 1.10.7. Версию самого SBT,
загружаемую launcher, также определяет конфигурация прикладного проекта. IDEA нужна для работы разработчика со средой,
сборка через config.json обходится без неё.
Выберите, откуда будут загружаться зависимости:
Условия |
Что подготовить |
|---|---|
Публичные репозитории |
Доступ к указанным в проекте источникам в интернете |
Внутренний прокси |
Адреса прокси-репозиториев; недостающие зависимости прокси скачивает и кеширует из внешних источников |
Изолированный контур |
Все зависимости заранее загружены во внутренние репозитории; установочные файлы тоже доступны внутри контура |
На чистой машине нужны сам SBT, Scala, плагины и их транзитивные зависимости, библиотеки проекта, исходники модулей и дистрибутив GlobalServer.
Установка компонентов#
Пользователь и каталоги#
Укажите пользователя, который будет запускать сборку. Для локальной работы это ваша учётная запись, для GitLab —
gitlab-runner, для Jenkins — пользователь SSH-агента:
GSF_BUILD_USER="<build_user>"
GSF_BUILD_GROUP="$(id -gn "$GSF_BUILD_USER")"
id "$GSF_BUILD_USER"
sudo mkdir -p /opt/global/{tmp,builds}
Установочные команды с sudo выполняются администратором. После установки переключитесь на пользователя сборки. Его
$HOME определяет расположение файлов SBT и credentials.
Используйте пути без пробелов: часть скриптов окружения GSF CLI не заключает их в кавычки.
Системные пакеты и сертификаты для загрузки#
sudo apt-get update
sudo apt-get install -y ca-certificates curl git wget zip unzip nano python3-venv
Если установочные файлы или Git доступны через HTTPS с корпоративным сертификатом, до обращения к этим адресам
установите CA. Получите корневой и промежуточные сертификаты в PEM и добавьте каждый отдельным .crt-файлом:
sudo install -m 0644 /path/to/company-root-ca.crt \
/usr/local/share/ca-certificates/company-root-ca.crt
sudo update-ca-certificates
Для промежуточных CA повторите install, затем update-ca-certificates. Если доверие уже настроено при подготовке
runner, повторять установку не нужно.
JDK 21, SBT и GSF CLI#
Установите JDK 21 из принятого в вашей организации дистрибутива. В примерах используется
/usr/lib/jvm/bellsoft-java21-amd64; замените этот путь на фактический во всех командах и в config.json.
/usr/lib/jvm/bellsoft-java21-amd64/bin/java -version
/usr/lib/jvm/bellsoft-java21-amd64/bin/javac -version
Обе команды должны показывать версию 21. Нужен JDK с javac, одного JRE недостаточно.
Скачайте и распакуйте компоненты:
sudo wget -P /opt/global/tmp \
https://repo.global-system.ru/artifactory/common/ru/bitec/gsf-cli-linux/LATEST/gsf-cli-linux-LATEST.zip
sudo wget -P /opt/global/tmp \
https://github.com/sbt/sbt/releases/download/v1.10.7/sbt-1.10.7.zip
sudo unzip /opt/global/tmp/sbt-1.10.7.zip -d /opt/global
sudo unzip /opt/global/tmp/gsf-cli-linux-LATEST.zip -d /opt/global/gsf-cli
В изолированном контуре положите заранее полученные архивы в /opt/global/tmp и выполните только распаковку.
Python-окружение#
Проверьте python3 --version: для поставляемых offline wheels нужен CPython 3.9.2–3.13 на x86_64.
sudo bash /opt/global/gsf-cli/bin/installpkg.sh
sudo bash /opt/global/gsf-cli/bin/initvenv.sh
sudo chown -R "$GSF_BUILD_USER:$GSF_BUILD_GROUP" /opt/global
installpkg.sh устанавливает python3-venv через apt; если пакет уже установлен, этот вызов можно пропустить. В
изолированной сети пакет должен поступать из внутреннего источника.
initvenv.sh создаёт окружение в gsf-cli/python и устанавливает зависимости из requirements.txt. Если в
дистрибутиве есть каталог wheels, установка выполняется с --no-index. Без него потребуется доступ к настроенному
Python package index.
Linux-дистрибутив содержит wheels для CPython 3.9.2–3.13 на x86_64, включая Python 3.13 из Debian 13. Эта поставка не
означает поддержку любой архитектуры или любого Linux-дистрибутива.
Проверьте права от имени пользователя сборки:
sudo -u "$GSF_BUILD_USER" -H test -x /opt/global/gsf-cli/manage.sh
sudo -u "$GSF_BUILD_USER" -H test -x /opt/global/gsf-cli/config.sh
sudo -u "$GSF_BUILD_USER" -H test -x /opt/global/sbt/bin/sbt
sudo -u "$GSF_BUILD_USER" -H test -f /opt/global/sbt/bin/sbt-launch.jar
sudo -u "$GSF_BUILD_USER" -H test -x /usr/lib/jvm/bellsoft-java21-amd64/bin/java
sudo -u "$GSF_BUILD_USER" -H test -x /usr/lib/jvm/bellsoft-java21-amd64/bin/javac
sudo -u "$GSF_BUILD_USER" -H mkdir -p /opt/global/gsf-cli/workspace
sudo -u "$GSF_BUILD_USER" -H touch /opt/global/gsf-cli/workspace/.write-test
sudo -u "$GSF_BUILD_USER" -H rm /opt/global/gsf-cli/workspace/.write-test
Если архив распаковался без права запуска .sh, восстановите его для скриптов GSF CLI и SBT:
sudo find /opt/global/gsf-cli -type f -name '*.sh' -exec chmod u+x {} +
sudo chmod u+x /opt/global/sbt/bin/sbt
Окружение пользователя сборки#
Если работаете локально под выбранной учётной записью, оставайтесь в своей консоли. Для CI откройте Bash от имени пользователя агента:
sudo -u "$GSF_BUILD_USER" -H bash
Все дальнейшие команды до раздела pipeline выполняются в этой консоли. Проверьте пользователя и задайте пути:
whoami
printf '%s\n' "$HOME"
export JAVA_HOME="/usr/lib/jvm/bellsoft-java21-amd64"
export PATH="/opt/global/sbt/bin:$JAVA_HOME/bin:$PATH"
cd /opt/global/gsf-cli
./manage.sh version
java -version
javac -version
Пути из config.json будут применяться к командам SBT, запущенным GSF CLI. Для ручного вызова sbt из консоли
переменные JAVA_HOME и PATH также должны указывать на выбранные инструменты.
Java и Python: доверие к сертификатам#
Если репозитории используют обычную доверенную TLS-цепочку, переходите к регистрации ключа. Для корпоративного CA настройте ещё два потребителя сертификатов.
В хранилище используемой JDK 21 импортируйте CA от пользователя с правом записи в JDK. Если у пользователя агента
нет sudo, эти команды выполняет администратор в отдельной консоли с тем же путём JDK:
sudo /usr/lib/jvm/bellsoft-java21-amd64/bin/keytool -import -trustcacerts \
-keystore /usr/lib/jvm/bellsoft-java21-amd64/lib/security/cacerts \
-storepass changeit -alias company-ca -file /path/to/company-ca.crt
/usr/lib/jvm/bellsoft-java21-amd64/bin/keytool -list \
-keystore /usr/lib/jvm/bellsoft-java21-amd64/lib/security/cacerts \
-storepass changeit | grep company-ca
company-ca — уникальный alias. changeit — стандартный пароль cacerts; если он изменён, используйте действующий.
Для каждого дополнительного CA выберите отдельный alias.
Часть артефактов GSF CLI скачивает через Python Requests. Java truststore не используется этими запросами. Если корпоративных CA нет в наборе, доступном Requests, укажите читаемый пользователем сборки PEM-bundle:
export REQUESTS_CA_BUNDLE="/path/to/company-ca-bundle.pem"
test -r "$REQUESTS_CA_BUNDLE"
Bundle заменяет стандартный набор Requests и должен содержать все корневые и промежуточные CA для используемых
HTTPS-сервисов. Вместо файла можно указать каталог сертификатов, предварительно обработанный
openssl rehash <path-to-ca-directory>.
Системные сертификаты, Java cacerts и REQUESTS_CA_BUNDLE решают разные части задачи. Настройка только одного из них
не гарантирует доступ всем инструментам сборки.
Мастер-ключ и учётные данные#
Регистрация ключа#
Из /opt/global/gsf-cli, от пользователя сборки:
./config.sh register_private_key -c /opt/global
test -f /opt/global/.gsf-cli.priv
-c получает существующий каталог. Команда создаёт в нём .gsf-cli.priv или использует уже лежащий там ключ. Путь
записывается в workspace/store.json. Если GSF CLI уже загрузил зарегистрированный ключ, повторная команда не меняет
его расположение.
Мастер-ключ нужен для шифрования паролей. Не удаляйте его при обновлении CLI: сохранённые credentials без него не расшифровать.
Доступ к Git#
Перед первым добавлением или обновлением проекта сохраните учётные данные для базового URL Git-сервера:
read -rp "Git URL: " GSF_GIT_URL
read -rp "Git login: " GSF_GIT_LOGIN
read -rsp "Git token: " GSF_GIT_TOKEN
printf '\n'
printf '%s' "$GSF_GIT_TOKEN" | ./credential_manager.sh set \
--url "$GSF_GIT_URL" --login "$GSF_GIT_LOGIN" --password-stdin
unset GSF_GIT_URL GSF_GIT_LOGIN GSF_GIT_TOKEN
Для https://git.example.org/group/project.git базовый URL — https://git.example.org. Одна запись действует для всех
вложенных путей с теми же протоколом, хостом и портом. Для другого Git-хоста добавьте отдельную запись. Учётной записи
нужны права чтения конфигурационного проекта, Git-модулей и SBT-плагина, если он тоже загружается из Git.
В интерактивном режиме публичный Git без авторизации позволяет пропустить этот шаг. Без сохранённой записи стандартный запрос Git также остаётся доступен.
Внимание
В текущем headless-режиме GSF CLI требует сохранённую Git-запись даже для публичного URL. Без неё команда завершится ошибкой до обращения к серверу. Поэтому для headless добавьте действующие учётные данные всех Git-хостов. Анонимная headless-сборка публичного Git без таких записей текущим кодом не обеспечена.
Если для URL есть запись в хранилище GSF CLI, он автоматически подключает свой Git helper в обоих режимах. Для этого
вызова Git остальные helpers отключаются. Не записывайте пароль в bin/credential_manager_git.sh. После смены токена
повторите set для того же URL.
Когда нужен credential.helper store#
GSF CLI не выполняет git config --global credential.helper store. Если вы сохранили данные через
credential_manager.sh set, вручную включать store для вызовов Git из GSF CLI не нужно.
Эта настройка пригодится для обычного Git, если он каждый раз спрашивает логин и пароль. В интерактивном режиме без подходящей записи в хранилище GSF CLI также вызывает обычный Git, и тот использует свои настройки. Чтобы включить сохранение данных для текущего пользователя Linux, выполните:
git config --global credential.helper store
После этого повторите Git-операцию и введите логин и токен. Команда только включает helper; сами данные сохраняются
после успешной авторизации. store хранит их на диске открытым текстом, обычно в ~/.git-credentials.
Подробнее — документация git-credential-store.
Настройка store не создаёт запись в GSF CLI и не заменяет её в headless. Если CLI сообщает «Не заданы учетные данные»,
используйте credential_manager.sh set, как показано выше.
Доступ к артефактам#
Если GlobalServer доступны только после авторизации, добавьте запись для их хоста:
read -rp "Repository URL: " GSF_REPO_URL
read -rp "Repository login: " GSF_REPO_LOGIN
read -rsp "Repository token: " GSF_REPO_TOKEN
printf '\n'
printf '%s' "$GSF_REPO_TOKEN" | ./credential_manager.sh set \
--url "$GSF_REPO_URL" --login "$GSF_REPO_LOGIN" --password-stdin
unset GSF_REPO_URL GSF_REPO_LOGIN GSF_REPO_TOKEN
./credential_manager.sh show
stat -c '%a %U:%G %n' /opt/global/.gsf-cli.priv workspace/store.json
Для ключа и store.json ожидаются права 600 и владелец — пользователь сборки. show отображает пароли как
********. Параметр --reveal открывает их; в CI и логах не используйте его.
Повторите настройку для каждого хоста с отдельным доступом. После переноса установки сохраните пару «ключ + store.json» и исправьте пути либо заново зарегистрируйте ключ и учётные данные. Сам по себе перенос runner не переносит эти файлы.
Закрытые репозитории SBT#
Для публичных источников без авторизации и без принудительного прокси этот раздел можно пропустить. Для закрытых
репозиториев создайте оба файла .credentials, задайте SBT_CREDENTIALS и все три параметра JVM ниже. Это
требуется и при ручном запуске, и в CI.
Адреса репозиториев#
mkdir -p "$HOME/.sbt" "$HOME/.ivy2"
nano "$HOME/.sbt/repositories"
Содержимое:
[repositories]
local
repository-1: https://repository.example.org/path/to/repository-1/
repository-2: https://repository.example.org/path/to/repository-2/
local — локальный Ivy-репозиторий ~/.ivy2/local. Имена repository-1 и repository-2 произвольные и должны быть
уникальны. Добавьте строку для каждого источника. Один групповой URL подходит, если он предоставляет все необходимые
артефакты в нужном формате.
Для источника по HTTP, если он используется в вашем контуре, строка выглядит так:
repository-http: http://repository.example.org/path/to/repository/, allowInsecureProtocol
allowInsecureProtocol разрешает HTTP, но не отключает проверку HTTPS-сертификата. Для HTTPS с корпоративным CA
настройте truststore, как описано выше. Формат Ivy-репозитория при необходимости включает шаблон размещения артефактов;
его берите из конфигурации вашего менеджера репозиториев.
Подробнее — Proxy Repositories в SBT.
Launcher читает repositories до загрузки прикладного build.sbt. В изолированном контуре убедитесь, что внутренние
источники содержат org.scala-sbt:sbt и все необходимые зависимости; кеш другой машины не заменяет их подготовку.
Две копии credentials#
nano "$HOME/.sbt/.credentials"
Запишите:
realm=repository-realm
host=repository.example.org
user=build-user
password=very-secret-password
Замените пример действующими данными. realm и host должны соответствовать ответу сервера. Пример рассчитан на один
hostname, realm и учётную запись для всех перечисленных SBT-репозиториев.
chmod 600 "$HOME/.sbt/.credentials"
install -m 600 "$HOME/.sbt/.credentials" "$HOME/.ivy2/.credentials"
Основной файл — ~/.sbt/.credentials. Копия ~/.ivy2/.credentials обязательна для компонентов цепочки сборки,
использующих путь Ivy. После смены пароля или токена обновите оба файла.
Переменные запуска#
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"
sbt.boot.credentials передаёт launcher файл доступа, sbt.repository.config задаёт список источников, а
sbt.override.build.repos=true принудительно использует этот список вместо репозиториев, объявленных сборкой.
Выполняйте блок в каждой новой консоли до первого запуска GSF CLI/SBT или добавьте его в профиль пользователя сборки.
Точно так же сохраняйте нужные JAVA_HOME, PATH и REQUESTS_CA_BUNDLE. При запуске через CI переменные задаются
внутри job — примеры приведены ниже.
Скрипты GSF CLI автоматически подставляют только SBT_CREDENTIALS, если переменная не задана и основной файл
существует. Три параметра JVM нужно передать явно. Наличие файлов на диске не заменяет этот шаг.
GSF credential manager и Git helper не передают пароль launcher. При запуске от root или другого пользователя файлы в
домашнем каталоге пользователя сборки также не будут найдены автоматически.
Подготовка проекта#
Через config.json: без IDEA и для CI#
Создайте /opt/global/builds/config.json от пользователя сборки:
nano /opt/global/builds/config.json
{
"sbt_home": "/opt/global/sbt",
"concurrent_module_updates": 1,
"projects": [
{
"name": "main",
"project_source": "https://git.example.org/group/configuration-project.git",
"project_branch": "main",
"jdk_home": "/usr/lib/jvm/bellsoft-java21-amd64",
"build_system": "sbt",
"publish_type": "SNAPSHOT"
}
]
}
Замените URL и ветку реальными значениями. concurrent_module_updates: 1 включает последовательную загрузку модулей; по
умолчанию допускается до 20 одновременных обновлений.
Внимание
load_config приводит список проектов GSF CLI к списку из файла. Уже зарегистрированные проекты, которых в нём нет, удаляются вместе с исходниками, дистрибутивом, ярлыками, окружением IDEA и служебным кешем. Перед загрузкой включите в файл все проекты, которые должны остаться в этой установке.
python3 -m json.tool /opt/global/builds/config.json >/dev/null
./config.sh enable_headless
./config.sh load_config -f /opt/global/builds/config.json
load_config регистрирует настройки, но не клонирует исходники и не делает проект активным. Дальше используйте
-p main. Первое клонирование произойдёт при refresh.
Headless запрещает запросы пользователю. Если не хватает настройки или доступа, команда завершится ошибкой. Режим сохраняется для всей установки GSF CLI. Для возврата к диалогам:
./config.sh disable_headless
Для CI оставьте headless включённым. Если вам нужны диалоги, но не нужна IDEA, можно загрузить config.json, отключить
headless и выполнять те же команды refresh и build.
Через мастер: рабочее место разработчика#
В этом варианте config.json не требуется. Установите IntelliJ IDEA с плагином Scala. Закройте открытую IDEA в общем
окружении перед добавлением проекта. Для работы с IDEA используйте скрипты из gsf-cli/links готового дистрибутива.
Запускайте их из терминала с настроенными выше переменными, чтобы IDEA и SBT получили доступ к закрытым репозиториям.
cd /opt/global/gsf-cli
./config.sh disable_headless
./links/add_project.sh
Укажите путь SBT /opt/global/sbt, имя проекта, Git URL и существующую ветку, систему сборки sbt, JDK 21 и вариант
портов. Мастер предложит подготовить проект, запросит путь IDEA и недостающие данные доступа. Для закрытых источников
файлы SBT и переменные уже должны быть настроены.
Следуйте запросам импорта проекта в IDEA. После импорта дождитесь его завершения, закройте IDEA и продолжите
конфигурацию. Подтвердите активацию проекта, чтобы следующие ярлыки работали с ним. Позже выбрать активный проект можно
через ./links/activate_project.sh.
Результат мастера — исходники в workspace/sources/<project_name>/application, сервер в
workspace/dists/<project_name>/Global3se и ярлыки в workspace/links/<project_name>. Если подготовку пропустили,
позднее выполните ./manage.sh -p <project_name> prepare_project.
Для повседневной работы используйте общие ярлыки из /opt/global/gsf-cli/links:
Скрипт |
Действие |
|---|---|
|
Обновить проект и зависимости |
|
Открыть IDEA для активного проекта |
|
Открыть консоль SBT активного проекта |
|
Обновить конфигурацию IDEA |
Открывайте IDEA через ./links/active_project_start_idea.sh: скрипт задаёт окружение проекта перед запуском среды.
В общем окружении допускается одна IDEA. Если нужны несколько проектов одновременно, используйте
./links/start_sep_idea.sh и выберите проект в диалоге.
Первая сборка и результат#
Ниже имя проекта — main. Если вы выбрали другое, замените его во всех командах. Команды выполняются от того же
пользователя, с теми же переменными доступа.
При работе через мастер и IDEA обновите активный проект ярлыком из каталога GSF CLI:
cd /opt/global/gsf-cli
./links/active_project_refresh.sh
Для маршрута через config.json выполните обновление командой:
cd /opt/global/gsf-cli
./manage.sh -p main refresh
После полной очистки кешей исходная инструкция допускает один повторный refresh: первый запуск может успеть загрузить
часть зависимостей перед ошибкой. Если повтор тоже неуспешен, остановитесь и проверьте причину. Ошибки доступа или
отсутствующий артефакт повтор сам по себе не исправит.
После успешного обновления соберите JAR-файлы. Общего ярлыка для build в поставке нет, поэтому в обоих вариантах
используется команда:
./manage.sh -p main build --build-appsrc --skip-publication
В workspace/sources/main/application/build/publish появятся:
applib/
*.jar
metadata.yaml
appsrc/
*-sources.jar
JAR-файлы могут находиться и во вложенных каталогах. Посмотреть их можно так:
find workspace/sources/main/application/build/publish/applib -type f -name '*.jar'
find workspace/sources/main/application/build/publish/appsrc -type f -name '*-sources.jar'
--build-appsrc выполняет publishSrcFolder после publishLibFolder и проверяет наличие обоих видов JAR. Флаг
поддерживается только для SBT. Для заполнения результата выполняется чистая SBT-сборка.
Чтобы собрать в другой каталог, задайте общий корень:
./manage.sh -p main build --build-appsrc --skip-publication \
--publish-path /opt/global/builds/publish/main
Результат будет в <root>/applib и <root>/appsrc. Не используйте один корень для нескольких проектов: выполняйте
отдельную команду с -p и отдельным путём. Относительный --publish-path считается от каталога application.
--skip-publication оставляет результат локально. Без него build вызывает публикацию, включая sbt publish. Путь
--publish-path не меняет адрес Maven-репозитория. При включённой публикации исходников в Maven отправляются отдельные
*-sources.jar, а не каталог appsrc одним артефактом.
GSF CLI не создаёт applib.zip и appsrc.zip. Если следующему этапу нужны ZIP, упакуйте каталоги отдельно в CI/CD или
передайте их nscli.
Сборка в GitLab CI#
Этот раздел выполняется после настройки установки GSF CLI для пользователя gitlab-runner. Runner использует один
постоянный workspace; параллельные GSF-сборки от этого пользователя запрещены. Для других задач выделите другую
установку и пользователя.
Переменные проекта#
В Settings → CI/CD → Variables для закрытых SBT-репозиториев создайте:
Переменная |
Содержимое |
Настройки |
|---|---|---|
|
Файл |
|
|
Файл |
|
Для File-переменной GitLab создаёт временный файл, а в переменную окружения передаёт путь к нему. Пример предполагает один hostname, realm и одну учётную запись для SBT-репозиториев.
Защитите ветку или Git tag, из которых запускается сборка. Иначе Protected-переменные будут недоступны. Не храните
токены в .gitlab-ci.yml, не включайте CI_DEBUG_TRACE и не выводите env/printenv в job с секретами.
Подробнее — переменные GitLab CI/CD.
Pipeline#
Создайте .gitlab-ci.yml в корне проекта. Замените tag и имя GSF-проекта своими значениями; Git credentials в headless
всё равно должны быть сохранены в GSF CLI.
stages:
- build
variables:
GSF_CONFIG_FILE: "/opt/global/builds/config.json"
GSF_PROJECT_NAME: "main"
gsf_build:
stage: build
tags:
- gsf-build
timeout: 4h
before_script:
- |
set -e
: "${GSF_PROJECT_NAME:?Не задано имя проекта}"
test -r "$GSF_CONFIG_FILE"
test -x /opt/global/gsf-cli/config.sh
test -x /opt/global/gsf-cli/manage.sh
umask 077
case "$GSF_REPOSITORY_MODE" in
internal)
: "${GSF_SBT_REPOSITORIES_FILE:?Не задан файл репозиториев}"
: "${GSF_SBT_CREDENTIALS_FILE:?Не задан файл credentials}"
test -s "$GSF_SBT_REPOSITORIES_FILE"
test -s "$GSF_SBT_CREDENTIALS_FILE"
install -d -m 700 "$HOME/.sbt" "$HOME/.ivy2"
install -m 600 "$GSF_SBT_REPOSITORIES_FILE" "$HOME/.sbt/repositories"
install -m 600 "$GSF_SBT_CREDENTIALS_FILE" "$HOME/.sbt/.credentials"
install -m 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"
;;
public) ;;
*) echo "Неизвестный GSF_REPOSITORY_MODE" >&2; exit 1 ;;
esac
script:
- /opt/global/gsf-cli/config.sh enable_headless
- /opt/global/gsf-cli/config.sh load_config -f "$GSF_CONFIG_FILE"
- /opt/global/gsf-cli/manage.sh -p "$GSF_PROJECT_NAME" refresh || /opt/global/gsf-cli/manage.sh -p "$GSF_PROJECT_NAME" refresh
- /opt/global/gsf-cli/manage.sh -p "$GSF_PROJECT_NAME" build --build-appsrc --skip-publication --publish-path "$CI_PROJECT_DIR/publish"
after_script:
- rm -f "$HOME/.sbt/repositories" "$HOME/.sbt/.credentials" "$HOME/.ivy2/.credentials"
artifacts:
paths:
- publish/applib/
- publish/appsrc/
Каждый job, использующий закрытые репозитории, должен получить обе копии credentials, SBT_CREDENTIALS и три параметра
JVM до первой команды GSF CLI или SBT. Включение headless и загрузка config.json повторяются при каждой сборке,
поэтому изменения конфигурации применяются автоматически. Файл должен сохранять полный список нужных проектов.
CA для Python в pipeline#
Если требуется REQUESTS_CA_BUNDLE, добавьте в существующий блок variables путь к читаемому пользователем
gitlab-runner bundle:
variables:
REQUESTS_CA_BUNDLE: "/path/to/company-ca-bundle.pem"
Либо создайте File-переменную GSF_CA_BUNDLE_FILE и добавьте в before_script:
- export REQUESTS_CA_BUNDLE="$GSF_CA_BUNDLE_FILE"
- test -r "$REQUESTS_CA_BUNDLE"
Bundle должен содержать все необходимые CA. Java cacerts остаётся отдельной настройкой. Каталог вместо PEM-файла
допустим после openssl rehash.
Для временного аварийного запуска при неустранённой TLS-ошибке можно добавить GSF_CLI_INSECURE_TLS: "true" в
variables. Это отключает проверку HTTPS в запросах GSF CLI к артефактам; удалите переменную после восстановления
цепочки. Git и Java она не настраивает.
Перед первым pipeline#
Проверьте runner online, tag, защиту ветки и доступность Protected-переменных. У пользователя gitlab-runner должны
читаться ключ, store.json, config.json, оба исполняемых файла JDK 21 и SBT.
Убедитесь, что Git-записи покрывают конфигурационный проект, модули и плагин, а доступ к артефактам — SBT-репозитории и
GlobalServer. Проверьте URL и realm в application/project/repositories/default.yaml, источники внутри project.yaml.
На хосте проверьте ресурсы:
df -h /opt/global
free -h
Проверьте YAML через CI/CD → Editor → Validate, затем запустите pipeline. После успешной сборки в job artifacts
должны находиться publish/applib и publish/appsrc с JAR-файлами.
Если сборка не проходит#
Сначала посмотрите workspace/logs/cmd_error_log.txt и ежедневный YYYY-MM-DD.log. В Linux для manage.sh можно
временно вернуть stderr в терминал:
NO_STDERR_REDIRECT=1 ./manage.sh -p main refresh
Ошибка |
Что проверить |
|---|---|
|
Того ли пользователя запустили; есть ли ключ и запись нужного Git URL в GSF CLI |
|
Права учётной записи, realm/host, обе копии credentials и переменные JVM; для загрузок Python — запись credential manager |
|
Наличие артефакта во внутреннем репозитории, путь и доступность upstream у прокси |
Ошибка сертификата Java |
|
Ошибка сертификата Requests |
|
Диалог запрещён в headless |
Не задана настройка, которую команда пытается спросить; интерактивный мастер в CI запускать не нужно |
Нет |
Система сборки SBT, параметр |
Подробный лог SBT: publishDevDependencies#
Если ошибка возникает при подготовке dev-зависимостей, повторите SBT-задачу publishDevDependencies с параметром
-debug. Он включает подробный вывод SBT. У команды manage build такого параметра нет.
Для проекта, подготовленного через мастер, используйте его ярлык. В терминале с настроенными переменными выполните:
cd /opt/global/gsf-cli/workspace/links/main
./sbt.sh -debug "publishDevDependencies"
main замените именем своего проекта. Этот sbt.sh находится в workspace/links/<project_name> и передаёт аргументы
в SBT, предварительно задав окружение проекта. Общий ярлык links/active_project_sbt.sh используется для обычного
открытия консоли SBT.
Если проект настроен через config.json и ярлыков нет, используйте созданный при подготовке сборки set_env.sh:
cd /opt/global/gsf-cli/workspace/sources/main/application
source build/scripts/set_env.sh
sbt -debug "publishDevDependencies"
В обоих случаях запуск выполняется под пользователем сборки. Для закрытых репозиториев по-прежнему нужны обе копии
.credentials, SBT_CREDENTIALS и все три JVM-параметра. Скрипты не задают эти параметры за вас.
Смотрите первую ошибку и сообщения перед ней: по подробному выводу проще понять, на каком репозитории или зависимости
останавливается задача. Это повтор только publishDevDependencies; он не собирает applib и appsrc целиком.
После исправления ошибки вернитесь к обычным refresh и build. Возможности подробного лога описаны в
справке SBT.
Проверка источников SBT#
От пользователя сборки, с настроенными переменными, выполните:
cd /opt/global/gsf-cli/workspace/sources/main/application
source build/scripts/set_env.sh
sbt -batch sbtVersion
sbt -batch "show externalResolvers"
Проверьте, что зависимости загружаются из указанных внутренних источников. В изолированном режиме публичные источники не
должны использоваться вопреки sbt.override.build.repos=true.
[ПРОВЕРИТЬ: DOC-007 — сверить фактический вывод
externalResolvers с версией SBT/плагина. В исходной главе обещалось буквальное присутствие всех строк
repositories в этом выводе; одного отображаемого списка недостаточно для проверки сетевых обращений.]
Проверка с пустыми кешами#
Этот шаг нужен для проверки зависимостей чистой машины. Он не относится к обычному запуску сборки. Сначала убедитесь, что все нужные артефакты доступны в репозиториях и другие сборки этого пользователя остановлены.
manage.sh clean удаляет служебный cache.json GSF CLI, а sbt clean — результаты компиляции. Для проверки загрузки
зависимостей также очищаются кеши SBT, Ivy и Coursier. ~/.ivy2/local содержит локально опубликованные артефакты: после
удаления они тоже должны быть восстановлены. Файлы .credentials и repositories оставьте на месте.
cd /opt/global/gsf-cli
./manage.sh -p main clean
cd workspace/sources/main/application
source build/scripts/set_env.sh
sbt -batch clean
rm -rf \
"$HOME/.sbt/boot" \
"$HOME/.ivy2/cache" \
"$HOME/.ivy2/local" \
"$HOME/.cache/coursier" \
"$HOME/.coursier/cache"
cd /opt/global/gsf-cli
./manage.sh -p main refresh || ./manage.sh -p main refresh
Продолжайте только после успешного refresh:
./manage.sh -p main build --build-appsrc --skip-publication
cd workspace/sources/main/application
source build/scripts/set_env.sh
sbt -batch "publishDevDependencies"
Последняя команда сохранена из исходного сценария восстановления зависимостей. refresh уже вызывает эту задачу;
дополнительный запуск не заменяет проверку его результата. Повторно вызывать publishLibFolder и publishSrcFolder не
нужно — оба каталога сформированы командой build --build-appsrc.
Временное отключение проверки TLS#
Если корректную TLS-цепочку нельзя восстановить до аварийного запуска, для одной команды:
GSF_CLI_INSECURE_TLS=true ./manage.sh -p main build --build-appsrc --skip-publication
Для всех команд текущей консоли:
export GSF_CLI_INSECURE_TLS=true
После исправления сертификатов:
unset GSF_CLI_INSECURE_TLS
Только явное true без учёта регистра и окружающих пробелов отключает проверку. GSF CLI выводит предупреждение при
первом таком HTTPS-запросе к артефактам. Соединение становится уязвимым для MITM-атак. Переменная относится к запросам
Python за артефактами; ошибки Git или SBT решаются настройкой их сертификатов.