quality / commitlint (push) Skipped
quality / changes (push) Successful in 7s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 21s
quality / web (push) Successful in 1m12s
quality / go (push) Successful in 1m3s
quality / bird2 (push) Successful in 16s
CD / quality (push) Successful in 3m7s
CD / publish (push) Successful in 3m58s
- Introduced `docker_hub_token` and `docker_hub_username` secrets for Docker Hub login in CI/CD workflows. - Updated `.gitea/workflows/ci.yaml`, `.gitea/workflows/cd.yaml`, and `.gitea/workflows/quality.yaml` to utilize these secrets for Docker Hub authentication. - Enhanced README and releasing documentation to clarify the use of Docker Hub credentials for image mirroring and builds.
103 lines
7.2 KiB
Markdown
103 lines
7.2 KiB
Markdown
# Релизы и версионирование EvoBGP
|
||
|
||
EvoBGP использует [Conventional Commits](https://www.conventionalcommits.org/) и [semantic-release](https://semantic-release.gitbook.io/) для полностью автоматических релизов на Gitea (`git.shx.one`). Ручное повышение версии в коде не требуется.
|
||
|
||
## Как определяется версия
|
||
|
||
| Тип коммита | Bump |
|
||
|-------------|------|
|
||
| `feat` | minor (1.0.0 → 1.1.0) |
|
||
| `fix`, `perf`, `ci`, `refactor` | patch (1.5.1 → 1.5.2) |
|
||
| `feat!`, `fix!` или `BREAKING CHANGE:` в теле | major (1.0.0 → 2.0.0) |
|
||
| `docs`, `chore`, `test` | без релиза |
|
||
|
||
**Scope:** один идентификатор **без запятых** (`web`, `httpapi`, `api`). Заголовок `refactor(a, b): …` **не парсится** semantic-release → релиз не создаётся (commitlint на PR это тоже отклонит). Подробнее — раздел «Scope и semantic-release» ниже.
|
||
|
||
`refactor` — patch без новых функций: перестройка кода/UI при том же поведении для пользователя. По semver на одном уровне с `fix`, но семантически «мельче» `feat` (не minor).
|
||
|
||
Отдельного суффикса `1.x.y.fix` в semver нет: «fix» в Conventional Commits означает **patch** (третья цифра). Для починки пайплайна без смены продукта — `fix(ci):` или `ci:` (оба дают patch после настройки `.releaserc.json`).
|
||
|
||
Первый релиз при отсутствии git-тегов — **1.0.0**, если есть releasable-коммиты.
|
||
|
||
**Как не перепутать `feat` и `fix`:** см. раздел «Выбор type: semver, а не «красивые слова»» в [.cursor/rules/conventional-commits.mdc](../.cursor/rules/conventional-commits.mdc). Кратко: `feat` — новая возможность (minor); `fix` — починка ожидаемого поведения (patch); follow-up баги после недавнего `feat` — всегда `fix`, даже если diff большой.
|
||
|
||
Подробные правила сообщений коммитов: [.cursor/rules/conventional-commits.mdc](../.cursor/rules/conventional-commits.mdc).
|
||
|
||
## CI-пайплайн (push в main)
|
||
|
||
```text
|
||
push/merge в main
|
||
→ workflow CD: quality (openapi, web, go, bird2)
|
||
→ job publish:
|
||
→ semantic-release: git tag vX.Y.Z на текущий commit (без доп. commit)
|
||
→ Gitea Release + CHANGELOG.md как attachment
|
||
→ зеркало base-образов в evobgp-buildcache:base-*
|
||
→ docker buildx bake с VERSION=X.Y.Z (pull=false, named builder evobgp)
|
||
→ образы: latest, vX.Y.Z, X.Y.Z, sha-*, короткий SHA
|
||
```
|
||
|
||
Pull request: workflow **CI** — quality gates + commitlint; релиз и образы **не** публикуются.
|
||
|
||
Workflows: [.gitea/workflows/ci.yaml](../.gitea/workflows/ci.yaml), [.gitea/workflows/cd.yaml](../.gitea/workflows/cd.yaml), reusable [.gitea/workflows/quality.yaml](../.gitea/workflows/quality.yaml).
|
||
|
||
Конфиг semantic-release: [.releaserc.json](../.releaserc.json) — без `@semantic-release/git` (CHANGELOG не коммитится в репозиторий).
|
||
|
||
## Секреты Gitea
|
||
|
||
PAT репозитория — **`ACTIONS_PAT`** (Settings → Actions → Secrets).
|
||
|
||
| Секрет | Зачем |
|
||
|--------|--------|
|
||
| `ACTIONS_PAT` | git tag `vX.Y.Z`, Gitea Release, push в Container Registry |
|
||
| `docker_hub_token` | логин на Docker Hub при зеркале base-образов и bake (лимиты anonymous pull) |
|
||
| `docker_hub_username` | имя пользователя Docker Hub; если пусто — `gitea.actor` |
|
||
|
||
Fallback для **git tag**: `github.token`, если PAT недоступен. Push образов в Container Registry — **только `ACTIONS_PAT`** (у job token Gitea нет права packages).
|
||
|
||
## Источник правды для версии в runtime
|
||
|
||
Semver из git-тега пробрасывается в Go-бинарники через `-ldflags` при сборке Docker (`deploy/docker/gobinary/Dockerfile`). Пакет [`internal/version`](../internal/version/version.go):
|
||
|
||
- локально (`go run`) — `version: "dev"`
|
||
- в образе после релиза — совпадает с тегом (например `1.2.3`)
|
||
|
||
API: `GET /version`, `GET /v1/version` — поля `version`, `git_sha`, `build_time`.
|
||
|
||
Web UI показывает версию из API (footer sidebar, страница «Мониторинг»).
|
||
|
||
## Scope и semantic-release
|
||
|
||
Парсер [conventional-commits-parser](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-commits-parser) (его использует semantic-release) **не понимает запятые в scope**:
|
||
|
||
| Заголовок | Парсится | Релиз |
|
||
|-----------|----------|-------|
|
||
| `refactor(web): fix layout` | да, `refactor` | patch |
|
||
| `refactor(NetworkOverviewTab, NetworkSpeakersCard): fix layout` | **нет**, `type: null` | **нет** |
|
||
|
||
Правило: **один scope** из таблицы в [.cursor/rules/conventional-commits.mdc](../.cursor/rules/conventional-commits.mdc) (`web`, `httpapi`, `api`, …).
|
||
|
||
На push в `main` job **publish** запускает `scripts/commit/verify-release-commits.mjs` — в логе будут предупреждения о непарсящихся коммитах.
|
||
|
||
Если релиз «не создался», а CI зелёный: смотрите лог release — часто `No releasable commits`. Исправление: новый коммит с корректным заголовком (например `refactor(web): …`).
|
||
|
||
## Перезапуск упавшего job publish
|
||
|
||
semantic-release пишет `.release-version` только в `successCmd` при **новом** релизе. Если тег `vX.Y.Z` уже создан, а `docker buildx bake` упал, повторный run того же SHA делает semantic-release no-op (файла нет). Job **publish** тогда берёт версию из git-тега на `HEAD` и публикует образы.
|
||
|
||
Перезапускать нужно **весь job publish**, не отдельный шаг bake: checkout + semantic-release + detect + bake идут подряд.
|
||
|
||
## CHANGELOG
|
||
|
||
Release notes — в Gitea Release; файл `CHANGELOG.md` генерируется в CI и прикрепляется как asset, **не** попадает в git history.
|
||
|
||
## Проверка после релиза
|
||
|
||
1. Один run workflow **CD** на push в main: job **publish** зелёный.
|
||
2. Gitea: тег `vX.Y.Z` на том же commit, что и merge; Release с notes.
|
||
3. Container Registry: `evobgp-api:vX.Y.Z`, `evobgp-api:X.Y.Z`, `evobgp-api:latest`.
|
||
4. `curl http://localhost:8080/version` → `"version":"X.Y.Z"`.
|
||
|
||
## Первый релиз (bootstrap)
|
||
|
||
Merge в `main` с `feat(release): ...` → **v1.0.0** в том же CI run.
|