Przejdź do głównej zawartości

Automatyzacja wydań

Wydania Libre WebUI tworzy się z katalogu głównego repozytorium za pomocą skryptu wydania. Skrypt odczytuje rzeczywistą historię Git od poprzedniego tagu wersji, aktualizuje wersje pakietów, zapisuje dziennik zmian, uruchamia kontrole wydania, tworzy commit wydania i tag wersji. GitHub jest źródłem kompilacji i publikacji plików binarnych; metadane wydania i nazwane łącza do artefaktów są replikowane do repozytorium Forgejo projektu.

Jednorazowa konfiguracja lokalna

Zainstaluj zależności i włącz hooki repozytorium:

npm install
npm run setup-hooks

Konfiguracja hooków ustawia:

  • .githooks/commit-msg do walidacji Conventional Commits
  • .githooks/pre-commit do kontroli formatowania
  • .gitmessage jako lokalny szablon wiadomości commita

Tworzenie wydania

Uruchom skrypt wydania w czystym drzewie roboczym na gałęzi, którą zamierzasz oznaczyć tagiem:

# Patch release
npm run release

# Minor release
npm run release:minor

# Major release
npm run release:major

Skrypt automatycznie:

  1. Sprawdza, czy drzewo robocze jest czyste i czy następny lokalny tag jest dostępny.
  2. Zbiera dowody z commitów, plików, zależności, wersji językowych i niewydanych wpisów dziennika zmian.
  3. Generuje informacje o wydaniu na podstawie tych dowodów.
  4. Aktualizuje package.json, pliki pakietów obszaru roboczego, package-lock.json, wersje chartu Helm i aplikacji oraz CHANGELOG.md.
  5. Uruchamia npm run release:check, w tym formatowanie, lint, kompilacje, testy, audyt bezpieczeństwa i próbną publikację npm.
  6. Dopiero po przejściu wszystkich kontroli tworzy commit wydania i opisany tag wersji.

Generowanie dziennika zmian

Wyświetl podgląd następnej sekcji dziennika zmian bez modyfikowania plików:

npm run changelog

Ręcznie zaktualizuj CHANGELOG.md na podstawie wygenerowanej sekcji:

npm run changelog -- update

Domyślnie generator dziennika zmian może poprosić lokalny model zgodny z Ollama o dopracowany szkic, a następnie zweryfikować wynik względem zebranych dowodów Git. Jeśli AI jest niedostępna lub wynik wygląda niebezpiecznie, skrypt używa generatora deterministycznego.

Przydatne nadpisania:

CHANGELOG_AI=0 npm run release:minor
CHANGELOG_AI_MODEL=glm-5.2:cloud npm run changelog
OLLAMA_BASE_URL=http://127.0.0.1:11434 npm run release

Wypychanie wydania

Po utworzeniu commita wydania i opisanego tagu opublikuj wyłącznie dokładny commit gałęzi i tag wskazane przez skrypt. Gałąź produkcyjna jest najpierw wypychana do Forgejo, a potem do GitHub, z jawnym wyłączeniem podążania za tagami:

git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/heads/main

git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
refs/heads/main

Oba zwrócone SHA gałęzi muszą odpowiadać zamierzonemu lokalnemu commitowi wydania. Przed opublikowaniem tagu poczekaj, aż wymagane przepływy GitHub dla dokładnie tego commita zakończą się powodzeniem.

Potwierdź, że tag wersji nie istnieje jeszcze w żadnej usłudze, a następnie wypchnij ten jeden tag najpierw do Forgejo, a potem do GitHub:

git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'

git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z
git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z

git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'

Zastąp vX.Y.Z tagiem wydania. Dla opisanego tagu zweryfikuj zarówno SHA obiektu tagu, jak i SHA wskazywanego commita. Nigdy nie używaj git push --tags, ponieważ może to opublikować niepowiązane lokalne tagi.

Ścieżka wydania CI

Wypchnięcie tagu v* uruchamia przepływ wydania GitHub. Przepływ:

  • Uruchamia npm run release:check
  • Buduje artefakty Electron dla macOS, Windows i Linux
  • Tworzy wydanie GitHub z odpowiedniej sekcji CHANGELOG.md
  • Replikuje rekord wydania i nazwane łącza artefaktów do Forgejo
  • Buduje obrazy Docker
  • Publikuje chart Helm z tą samą wersją co tag wydania
  • Publikuje pakiet npm z NPM_TOKEN

Tę samą kontrolę można uruchomić lokalnie przed oznaczeniem tagiem:

npm run release:check

Replika wydania Forgejo

Replika używa osobistego tokenu dostępu Forgejo przechowywanego jako zaszyfrowany sekret GitHub Actions FORGEJO_TOKEN. Nadaj tokenowi wyłącznie zakres write:repository, upewnij się, że jego właściciel może zapisywać do libre-webui/libre-webui, i nigdy go nie commituj ani nie wypisuj.

Replika jest celowo idempotentna. Wyszukuje wydania według tagu, tworzy tylko brakujące rekordy, uzgadnia ich metadane z wydaniem GitHub i pomija istniejące łącza artefaktów. Ponowienie po awarii sieci lub przepływu uzupełnia więc brakującą pracę bez duplikowania wydań ani zasobów.

Zasoby wydania Forgejo są nazwanymi zewnętrznymi łączami do odpowiedniego publicznego GitHub browser_download_url. GitHub pozostaje hostem plików binarnych, a Forgejo pokazuje te same nazwy plików do pobrania bez kopiowania dziesiątek gigabajtów artefaktów desktopowych. Archiwa źródłowe są generowane niezależnie z dokładnego tagu w każdej usłudze.

Podgląd lub uzupełnienie jednego wydania

Sprawdź, co uległoby zmianie, bez zapisywania do Forgejo:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run

Po załadowaniu FORGEJO_TOKEN i GITHUB_TOKEN do środowiska procesu z menedżera sekretów opiekuna zreplikuj wydanie:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z

Dokładny tag musi już istnieć w GitHub i Forgejo oraz rozwiązywać się do tego samego obiektu tagu i wskazywanego commita, zanim wydanie zostanie zreplikowane.

Podgląd lub uzupełnienie wszystkich wydań

Porównaj każde GitHub Release z Forgejo:

node scripts/mirror-forgejo-releases.mjs --all --dry-run

Uzupełnij każde brakujące lub niepełne Forgejo Release:

node scripts/mirror-forgejo-releases.mjs --all

GITHUB_TOKEN jest wymagany dla --all, także w próbach, ponieważ dokładna zgodność tagów i wykrywanie zasobów wymagają więcej żądań, niż pozwala anonimowy limit API GitHub. FORGEJO_TOKEN jest dodatkowo wymagany, gdy nie używasz --dry-run.

Ścieżka --all stronicuje oba API i bierze pod uwagę obiekty GitHub Release, a nie każdy tag Git. Tag celowo pozbawiony GitHub Release pozostaje w Forgejo samym tagiem. Po uzupełnieniu ponownie uruchom próbę; nie powinna zgłaszać oczekujących zmian.

Zasady niezmiennych tagów

Opublikowane tagi wersji są niezmienne. Gdy tag istnieje na dowolnym zdalnym serwerze:

  • Nie usuwaj go.
  • Nie wypychaj go z wymuszeniem.
  • Nie przenoś go do poprawionego commita.
  • Nie używaj ponownie jego wersji semantycznej dla innej treści.

Jeśli treść opublikowanego wydania jest błędna, popraw źródło i dziennik zmian, a następnie opublikuj kolejną wersję poprawkową. Jeśli brakuje tylko strony wydania lub zewnętrznego łącza zasobu, ponownie uruchom idempotentną replikację bez zmiany tagu.

Tag Forgejo v0.8.6 został jednorazowo, za jawną zgodą, ponownie wyrównany podczas wprowadzania podwójnej replikacji wydań. Naprawiono dwa historyczne obiekty tagów opisujące identyczne drzewa źródłowe, ale należące do różnych linii commitów. Ta skontrolowana migracja nie stanowi precedensu dla przenoszenia opublikowanych tagów.

Zasady wersji Helm

version chartu Helm, jego appVersion, wersja pakietu głównego i tag wydania celowo używają tej samej wersji semantycznej. Skrypt wydania aktualizuje je razem, a CI odrzuca rozbieżność.

Chart jest publikowany wyłącznie z niezmiennego tagu wydania v*. Nie publikuj zmienionej treści chartu pod istniejącą wersją. Zmiana chartu musi przejść przez następne wydanie aplikacji, aby otrzymać nową wersję.

Chart w wersji 0.14.1 zawiera jednorazowe nadpisanie skrótu, ponieważ to wydanie poprzedza semantyczne tagi Docker. Skrót identyfikuje zweryfikowany wieloarchitekturny obraz 0.14.1. Skrypt wydania usuwa nadpisanie podczas tworzenia kolejnego wydania; potem obraz domyślny rozwiązuje się do appVersion chartu.

Przepływ Docker publikuje ten tag wersji semantycznej w GHCR i Docker Hub z tego samego tagu wydania v*. Publikacja Helm czeka do 20 minut na odpowiedni publiczny obraz Docker Hub i kończy się błędem zamiast publikować chart bez obrazu domyślnego. Dołączony obraz Ollama pozostaje konfigurowany niezależnie i domyślnie używa nadrzędnego tagu latest.

Conventional Commits

Wiadomości commitów powinny używać formatu Conventional Commit:

<type>[optional scope]: <description>

Popularne typy:

  • feat: funkcja widoczna dla użytkownika
  • fix: poprawka błędu
  • docs: aktualizacja dokumentacji
  • refactor: wewnętrzna restrukturyzacja kodu
  • perf: poprawa wydajności
  • test: pokrycie testami
  • chore: utrzymanie, wydanie lub prace kompilacyjne

Zmiany niezgodne wstecznie używają !:

git commit -m "feat!: remove deprecated endpoint"
git commit -m "fix(auth)!: change token validation"

Rozwiązywanie problemów

Katalog roboczy nie jest czysty

Przed wydaniem zatwierdź lub schowaj lokalne zmiany:

git status --short
git add .
git commit -m "fix: resolve pending changes"

Brak zmian do wydania

Sprawdź commity od poprzedniego tagu:

git log $(git describe --tags --abbrev=0)..HEAD --oneline

Dziennik zmian wymaga ręcznej edycji

Edytuj CHANGELOG.md, a następnie zatwierdź poprawkę przed opublikowaniem tagu:

git add CHANGELOG.md
git commit -m "docs: refine changelog"

Wycofywanie lokalnego commita wydania

Jeśli ani commit wydania, ani tag nie zostały wypchnięte:

git tag -d v0.12.0
git reset --soft HEAD~1

Jeśli tag znajduje się już na dowolnym zdalnym serwerze, nie usuwaj go ani nie zastępuj. Napraw problem na main, utwórz następne wydanie poprawkowe i opublikuj nowy niezmienny tag przez pełną bramkę.

Niepełna replika Forgejo

Najpierw sprawdź, czy SHA obiektu tagu i wskazywanego commita są zgodne na obu serwerach zdalnych. Następnie wyświetl podgląd i ponów dane wydanie:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z

Błąd autoryzacji oznacza, że FORGEJO_TOKEN nie istnieje, wygasł, należy do użytkownika bez dostępu do repozytorium lub nie ma zakresu write:repository. Brakujący lub odmienny tag zdalny trzeba zbadać oddzielnie; replika wydań nigdy nie tworzy ani nie przenosi tagów Git.

Pliki opiekuna

  • .gitmessage - szablon wiadomości commita
  • .githooks/commit-msg - walidacja Conventional Commits
  • .githooks/pre-commit - wstępna kontrola formatowania
  • scripts/release.js - orkiestracja wydania
  • scripts/mirror-forgejo-releases.mjs - idempotentna replika wydań Forgejo i uzupełnianie
  • scripts/generate-changelog.js - polecenie podglądu/aktualizacji dziennika zmian
  • scripts/lib/releaseNotes.js - zbieranie dowodów i generowanie dziennika zmian
  • .github/workflows/release.yml - przepływ wydania CI sterowany tagiem
  • .github/workflows/helm-publish.yml - walidacja Helm i publikacja tagu

Więcej informacji o Conventional Commits znajdziesz na https://www.conventionalcommits.org/.