GrantForge

    Разработчикам

    Разработка, тестирование и CI

    Локальные сборки, тесты, стандарты кодирования и проверки CI.

    Окружение

    • JDK 21 (артефакты — байт-код Java 17; движок политик — Java 8)
    • Node.js 22 и pnpm 8.10.2
    • Docker (интеграционные тесты баз данных, нагрузочные бенчмарки и образы)
    • Python 3.12 (скрипты CI)

    Основные команды

    ./mvnw verify                          # 构建并测试全部 Java 模块(含控制台)
    ./mvnw verify -DskipFrontend           # 跳过控制台构建
    bash script/ci/web.sh test             # 控制台单元测试
    bash script/ci/web.sh e2e              # 控制台浏览器测试(模拟后端)
    bash script/ci/e2e_fullstack.sh        # 打包、启动真实服务并运行全栈测试
    bash script/ci/db_integration.sh postgres:17   # 在指定数据库上运行集成测试
    bash script/ci/perf_benchmark.sh smoke # 小规模性能基准

    Для разработки консоли запускайте pnpm dev в core/grantforge-web; Vite проксирует /api и другие запросы на сервер localhost:9999.

    Запуск из IDE

    Запускайте org.devlive.grantforge.server.GrantForge (модуль grantforge-server) напрямую; по умолчанию он использует базу данных H2. Сервер автоматически загружает модули плагинов, собранные в каталоге plugins/ репозитория (см. Плагины и типы сервисов); перед первым использованием модуля плагина выполните один раз ./mvnw -pl plugins/grantforge-plugin-hdfs -am install -DskipTests, чтобы скопировать его зависимости.

    Стандарты кодирования

    • Бэкенд: Error Prone + NullAway (по умолчанию non-null, там, где значение может отсутствовать, — JSpecify @Nullable), Checkstyle, PMD, SpotBugs; ArchUnit охраняет общие соглашения (никаких инъекций в поля, нативного SQL, сущностей в API, вызовов Optional.get() и т. д.).
    • Фронтенд: строгий режим TypeScript, ESLint без предупреждений; все тексты проходят через i18n, ключи должны быть литералами, а наборы ключей для китайского и английского языков совпадают.
    • Каждый исходный файл содержит заголовок лицензии MIT; каждому классу из основного исходного кода должен соответствовать тестовый класс (исключения перечислены в script/ci/test_mapping_exclusions.txt).
    • Пороги покрытия задаются для каждого модуля (script/ci/coverage_thresholds.txt).
    • Миграции баз данных — это YAML Liquibase: один файл на изменение, только добавление (существующие файлы никогда не изменяются); типы задаются перекрёстными для всех СУБД свойствами, такими как ${text}.
    • Сообщения коммитов следуют Conventional Commits, тема не длиннее 72 символов.

    CI

    Задача Что делает
    Чистота репозитория Заголовки лицензий, запрещённые пути, сопоставление тестов, i18n, манифест разрешений, форматирование файлов, проверка скриптов и workflow
    Сообщения коммитов Формат сообщений коммитов
    Юнит-тесты CI-скриптов Тесты самих скриптов CI
    Java 21 (тесты и статический анализ) Шлюз: сборка и юнит-тесты всех Java-модулей, покрытие, NullAway, Checkstyle, SpotBugs, PMD, проверка версий байт-кода
    Java 17 / 25 / latest Те же юнит-тесты на остальных поддерживаемых JDK
    Фронтенд Соответствие типов API контракту, проверка типов и сборка, ESLint, юнит-тесты, браузерные тесты
    JavaScript SDK Проверка типов, сборка, ESLint, юнит-тесты
    Базы данных Миграции и интеграционные тесты на H2, PostgreSQL 14/17, MySQL 8.0/8.4, MariaDB 10.11/11.4, Oracle 23 и SQL Server 2022
    Совместимость API плагинов Сравнение контракта плагинов с предыдущим релизом
    Сквозная приёмка Упаковка, запуск сервера и браузерные сквозные тесты на PostgreSQL
    Документация Проверки, тесты и сборка сайта документации

    Каждая задача запускается, только если изменение затрагивает её область (script/ci/changed_areas.py): изменение документации не собирает Java, изменение консоли не запускает тесты баз данных. Задачи баз данных, API плагинов и full-stack ждут шлюза Java 21 и не повторяют то, что он уже проверил: без юнит-тестов, JaCoCo, enforcer и Error Prone (GRANTFORGE_CHECKED=1, script/ci/maven.sh). Для защиты ветки достаточно одной проверки CI result. Ночной процесс запускает наборы Testcontainers, smoke-тест образа и тест производительности для того, что изменилось за последние сутки, а по воскресеньям — всё; тег релиза получает собственный полный прогон CI, который релиз ждёт вместо повторного тестирования, а релиз, прерванный на полпути, завершается повторным запуском. Процессы безопасности сканируют зависимости и секреты.

    Релизы

    Версии имеют вид year.minor.patch (например 2026.0.0), кандидаты в релиз получают суффикс -rc.N. Версии во всех pom-файлах, npm-пакетах, appVersion Helm-чарта, боковой панели консоли и README должны совпадать; CI проверяет их скриптом check_versions.py.

    Релиз из ветки dev выполняется одной командой:

    bash script/release/tag.sh 2026.1.0 --dry-run          # 只检查并预览发布说明,不做任何修改
    bash script/release/tag.sh 2026.1.0 --next 2026.2.0    # 设置版本、打标签 v2026.1.0 并推送,再把 dev 切到下一个版本

    Скрипт требует чистое рабочее дерево, локальную ветку, не отстающую от удалённой, и несуществующий тег; после подтверждения он создаёт коммит chore(release): prepare <version>, навешивает аннотированный тег и отправляет его. Тег запускает release.yml:

    • script/ci/release.sh собирает дистрибутив, SBOM CycloneDX, содержащий только зависимости релиза, и SHA256SUMS;
    • мультиархитектурные образы отправляются в ghcr.io/devlive-community/grantforge;
    • артефакты Maven (включая исходный код и Javadoc) публикуются в GitHub Packages; если репозиторий настроен через CENTRAL_USERNAME, CENTRAL_PASSWORD (токен Central Portal), GPG_PRIVATE_KEY и GPG_PASSPHRASE, они подписываются и публикуются в Maven Central;
    • создаётся GitHub Release, в описании которого перечислены все коммиты с предыдущего релиза (v* или числовый тег, например 1.0.6), сгруппированные по возможностям, исправлениям, производительности и т. д., со ссылками на коммиты.

    Кандидаты в релиз помечаются как pre-release и не обновляют тег latest образов. Локально профиль central по умолчанию ничего не публикует (central.skip=true); только релизный workflow явно передаёт -Dcentral.skip=false.

    Перед созданием тега напишите журнал выпуска docs/content/<язык>/changelog/<версия>.md на каждом языке и добавьте его в docs/lib/navigation.ts; без него tag.sh отказывается выпускать релиз (кроме кандидатов). npm-пакет публикуется через trusted publishing: npm сверяет OIDC-токен уровня задания с издателем, настроенным для пакета, секрет NPM_TOKEN не нужен. Релиз сначала публикует заменяемое (GitHub Packages, образ), затем Maven Central и npm, и последним — релиз на GitHub; прерванный на полпути релиз завершается повторным запуском процесса, который пропускает уже опубликованное.

    Манифест разрешений

    Страницы, кнопки консоли и используемые ими API объявлены в core/grantforge-web/src/permissions/. check_permission_manifest.py гарантирует, что каждый объявленный API существует, а каждый эндпоинт, требующий разрешений, покрыт какой-либо кнопкой или страницей (исключения для прямых вызовов перечислены в script/ci/permission_direct_apis.txt).

    Документация

    Этот сайт расположен в docs/ и использует статический экспорт Next.js с Tailwind CSS:

    cd docs
    pnpm install
    pnpm dev        # http://localhost:3100
    pnpm check      # 页面、链接与图片检查
    pnpm build      # 输出到 docs/out

    Страницы — это Markdown в docs/content/, а навигация определена в docs/lib/navigation.ts. Справочник API и коды ошибок генерируются при сборке из контракта и исходного кода. Скриншоты создаёт script/docs/screenshots.sh, который запускает реальный сервер, наполняет его тестовыми данными и управляет Playwright.

    Редактировать эту страницу на GitHub