0.4.11
16 · Техническая документация

16. CI/CD и релизы

AstraCode использует GitLab CI/CD для автоматизации сборок и публикации релизов. Архитектура — двухпроектная: сборка в основном репо, бандлы загружаются в downstream-проект «astra-code-build» (project ID 286).

1. Версионирование

SemVer: MAJOR.MINOR.PATCH. Версия хранится в двух местах и должна быть синхронизирована: - astracode-rs/Cargo.toml (workspace version) - astracode-cli/package.json (метаданные внутренней CLI-обёртки)

Джоба check:version-sync в CI падает, если версии разъехались (а также проверяет совпадение тега с Cargo.toml при релизе по тегу).

2. Триггеры pipeline

В .gitlab-ci.yml (в корне репо) определены workflow rules:

yaml
workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      changes:
        - astracode-rs/Cargo.toml
    - if: '$CI_COMMIT_BRANCH =~ /.*_devops_.*/'
    - if: '$CI_PIPELINE_SOURCE == "web"'      # ручной запуск через UI
    - if: '$CI_COMMIT_TAG =~ /^\d+\.\d+\.\d+$/'  # тег SemVer

Pipeline срабатывает: - При пуше тега X.Y.Z (или любого SemVer-тега). - При изменении astracode-rs/Cargo.toml в main (для проверки version-sync). - Вручную из Web UI. - В ветках вида *_devops_*.

3. Стадии pipeline

text
check     → check:version-sync
build     → build:linux-gnu / build:macos-aarch64 / build:windows-x86_64
            (каждая с *-nolicense вариантом)
publish   → publish:package-registry{,-macos,-windows}{,-nolicense}
trigger   → trigger:astra-code-build{,-macos,-windows}{,-nolicense}

check:version-sync

Inline-скрипт в .gitlab-ci.yml сравнивает версию из [workspace.package].version (Cargo.toml) и "version" (package.json); при релизе по тегу — ещё и совпадение тега с Cargo-версией. Прокидывает ASTRACODE_VERSION через dotenv-артефакт.

build-джобы

Все сборки — cargo build --release --bin astracode (Rust toolchain фиксируется в astracode-rs/rust-toolchain.toml1.93.0).

  • build:linux-gnu — нативный Linux-бинарник; релизный бинарь не должен тащить libssl/libcrypto (проверяется ldd), т.к. системный GOST-провайдер несовместим с bundled OpenSSL 1.1.
  • build:macos-aarch64 — кросс-сборка через OSXCross (scripts/cross-build-macos.sh --target aarch64-apple-darwin), target aarch64-apple-darwin, MACOSX_DEPLOYMENT_TARGET=14.2.
  • build:windows-x86_64 — target x86_64-pc-windows-msvc, артефакт astracode.exe.

Каждая платформа имеет пару *-nolicense — тот же билд без принудительной лицензии (для канала без активации). Compile-time gate, storage лицензии и невозможность runtime-переключения канала описаны в 24-license.

publish-джобы

Загружают бинарник в Generic Package Registry основного проекта через curl --upload-file c JOB-TOKEN. Имена пакетов: - Linux: astracode (файл astracode). - macOS: astracode-macos-bin (файл astracode). - Windows: astracode-windows-bin (файл astracode.exe).

Если версия уже есть в Registry — джоба пропускает загрузку (idempotent).

Пример (Linux):

bash
curl --fail --header "JOB-TOKEN: $CI_JOB_TOKEN" \
     --upload-file astracode-rs/target/release/astracode \
     "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/astracode/${ASTRACODE_VERSION}/astracode"

trigger-джобы

Upstream определяет downstream-триггеры для каждой платформы/канала в проект astracode/astra-code-build (ID 286), передавая ASTRACODE_VERSION, ASTRACODE_SOURCE_PROJECT_ID, TARGET_PLATFORM и опционально CHANNEL=nolicense. Текущий downstream корректно обрабатывает только TARGET_PLATFORM=linux и TARGET_PLATFORM=macos: 1. Скачивает свежий бинарник из Package Registry основного проекта. 2. Упаковывает его в platform-specific bundle. 3. Загружает финальный бандл в свой Package Registry.

Windows raw binary собирается и публикуется upstream, но downstream pipeline не имеет отдельной Windows packaging job. Наличие upstream trigger с TARGET_PLATFORM=windows не следует трактовать как готовый пользовательский ZIP.

4. Downstream проект «astra-code-build»

text
https://gitlab.prosto.aib.pro/astracode/astra-code-build (project ID 286)

Это публичная точка распространения. У него есть свой Package Registry:

text
https://gitlab.prosto.aib.pro/astracode/astra-code-build/-/packages

Структура пакетов

Все готовые архивы публикуются как Generic Package distributiv версии X.Y.Z; канал отражается в имени файла:

Платформа/канал Файл
Linux licensed astracode-linux-x86_64-gnu-X.Y.Z.tar.gz
Linux nolicense astracode-linux-x86_64-gnu-nolicense-X.Y.Z.tar.gz
macOS Apple Silicon licensed astracode-macos-X.Y.Z.zip
macOS Apple Silicon nolicense astracode-macos-nolicense-X.Y.Z.zip

Точные имена формируются переменными APP_NAME_BASE_*, APP_NAME и PUBLISH_PACKAGE_NAME в downstream .gitlab-ci.yml.

5. Ручная загрузка в Package Registry

Если CI не отрабатывает (например, нужен бинарь под нестандартный target), загрузка делается вручную:

bash
# Получить персональный access token в Settings → Access Tokens (scope: api)
TOKEN="glpat-..."

# Загрузить файл
curl -k \
  --header "PRIVATE-TOKEN: $TOKEN" \
  --upload-file ./astracode-macos-X.Y.Z.zip \
  "https://gitlab.prosto.aib.pro/api/v4/projects/286/packages/generic/distributiv/X.Y.Z/astracode-macos-X.Y.Z.zip"

Флаг -k — для self-signed certificate GitLab'а.

⚠️ Токены никогда не пушить в репо и сразу отзывать через UI после использования (Settings → Access Tokens → Revoke).

6. Процесс релиза

text
1. Все правки в main, тесты зелёные
2. Bump версии:
   - обновить `[workspace.package].version` в `astracode-rs/Cargo.toml` до `X.Y.Z`
   - обновить `version` в `astracode-cli/package.json` до `X.Y.Z`
   - Обновить status snapshot'ы:
     find astracode-rs/tui/src/status/snapshots -name '*.snap' \
       | xargs sed -i 's/AstraCode (vOLD)/AstraCode (vX.Y.Z)/g'
3. git commit -m "Bump version to X.Y.Z"
4. git tag X.Y.Z
5. git push origin main
6. git push origin X.Y.Z
7. Pipeline собирает Linux/macOS/Windows, публикует в Package Registry
8. Триггерит downstream по каждой платформе → собирает финальные бандлы
9. Пишем release notes в CHANGELOG.md
10. (опционально) gh release create / GitLab Release

7. Release notes

История версий ведётся в CHANGELOG.md в корне репозитория. Актуальные release notes определяются содержимым файла на момент релиза.

Раздел заполняется мейнтейнером при релизе (см. п.6, шаг 9).

8. CHANGELOG генерация

В корне репо есть cliff.toml — конфиг для git-cliff. Генерация:

bash
git-cliff --tag X.Y.Z > CHANGELOG.md

git-cliff читает commit messages и группирует по типам (feat, fix, chore, …).

Conventional commits style:

text
feat(tui): add /help command with pager overlay
fix(locale): allow /locale after /new and /clear
chore(release): bump to X.Y.Z

9. Voting / approval релиза

Сейчас нет автоматических voting'ов — релиз тегируется мейнтейнером. Для критичных релизов: 1. Создаётся ветка release/X.Y.Z. 2. PR в main. 3. Минимум 1 reviewer approval. 4. После merge — тегируется.

10. Откат релиза

Если в X.Y.Z нашли блокирующий баг:

bash
# Удалить тег
git tag -d X.Y.Z
git push origin :refs/tags/X.Y.Z

# Удалить пакеты в Registry (через UI или API)
curl -k --header "PRIVATE-TOKEN: $TOKEN" \
  --request DELETE \
  "https://gitlab.prosto.aib.pro/api/v4/projects/286/packages/<package_id>"

Затем выпустить новую patch-версию с фиксом и yank-уведомлением в CHANGELOG.

11. Внутренняя CLI-обёртка

В репозитории сохраняется JS-обёртка и метаданные astracode-cli/package.json. Они используются для совместимости исходного дерева, проверки синхронности версии и внутренних staging-сценариев. Текущий GitLab pipeline не публикует эту обёртку как поддерживаемый канал установки AstraCode.

Ключевые поля:

json
{
  "name": "@astracode/astracode-cli",
  "version": "X.Y.Z",
  "bin": { "astracode": "bin/astracode.js" },
  "type": "module",
  "engines": { "node": ">=16" }
}

Точка входа bin/astracode.js определяет target triple по process.platform/process.arch и умеет разрешать optional platform package. Скрипты astracode-cli/scripts/build_npm_package.py и scripts/stage_npm_packages.py подготавливают такую структуру локально, но это не означает, что соответствующие пакеты публикуются текущим CI.

12. Безопасность CI

  • CI_JOB_TOKEN — короткоживущий, скоупится на текущий проект.
  • Личные токены (glpat-...) не должны попадать в pipeline (только локально).
  • Подпись бинарников — TODO (планируется minisign или GPG).
  • SBOM (Software Bill of Materials) — TODO (генерировать через cargo cyclonedx).

13. Файлы CI

  • .gitlab-ci.yml (в корне репо) — основной pipeline (workflow rules, stages, джобы, inline-скрипты).
  • astracode-rs/rust-toolchain.toml — фиксация Rust toolchain.
  • scripts/cross-build-macos.sh — кросс-сборка macOS через OSXCross.
  • cliff.toml — конфиг CHANGELOG.
  • astracode-cli/scripts/build_npm_package.py — сборка npm-модуля.