Pular para o conteúdo principal

Automação de lançamentos

Os lançamentos do Libre WebUI são criados na raiz do repositório com o script de lançamento. O script lê o histórico real do git desde a tag da versão anterior, atualiza as versões dos pacotes, grava o registro de alterações, executa as verificações de lançamento, cria o commit de lançamento e cria a tag da versão. O GitHub é a fonte da compilação e da publicação dos binários; os metadados da versão e os links nomeados dos artifacts são espelhados no repositório Forgejo do projeto.

Configuração local inicial

Instale as dependências e ative os hooks do repositório:

npm install
npm run setup-hooks

A configuração dos hooks define:

  • .githooks/commit-msg para validação de Conventional Commits
  • .githooks/pre-commit para verificações de formatação
  • .gitmessage como template local de mensagem de commit

Crie um lançamento

Execute o script de lançamento em uma árvore de trabalho limpa, na branch em que pretende criar a tag:

# Patch release
npm run release

# Minor release
npm run release:minor

# Major release
npm run release:major

O script, automaticamente:

  1. Verifica se a árvore de trabalho está limpa e se a próxima tag local está disponível.
  2. Coleta evidências de commits, arquivos, dependências, locales e do registro de alterações ainda não lançado.
  3. Gera as notas de lançamento a partir dessas evidências.
  4. Atualiza package.json, os arquivos de pacotes do workspace, package-lock.json, as versões do chart Helm e do aplicativo e o CHANGELOG.md.
  5. Executa npm run release:check, incluindo formatação, lint, compilações, testes, auditoria de segurança e simulação de publicação no npm.
  6. Somente depois que todas as verificações passam, cria o commit de lançamento e a tag anotada da versão.

Geração do registro de alterações

Visualize a próxima seção do registro de alterações sem modificar arquivos:

npm run changelog

Atualize manualmente o CHANGELOG.md com a seção gerada:

npm run changelog -- update

Por padrão, a geração do registro de alterações pode solicitar a um modelo local compatível com Ollama um rascunho refinado e, depois, validar o resultado com as evidências coletadas do git. Se a IA não estiver disponível ou o resultado parecer inseguro, o script recorre a um gerador determinístico.

Substituições úteis:

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

Envie um lançamento

Depois de criar o commit de lançamento e a tag anotada, publique somente o commit exato da branch e a tag indicados pelo script. A branch de produção é enviada primeiro ao Forgejo e depois ao GitHub, com o envio das tags seguidas explicitamente desativado:

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

Os SHAs de branch retornados pelos dois serviços devem ser iguais ao commit local pretendido para o lançamento. Aguarde a aprovação dos workflows obrigatórios do GitHub para esse commit exato antes de publicar a tag.

Confirme que a tag da versão ainda não existe em nenhum dos serviços e, então, envie essa única tag primeiro ao Forgejo e depois ao 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^{}'

Substitua vX.Y.Z pela tag do lançamento. Em uma tag anotada, verifique tanto o SHA do objeto da tag quanto o SHA de seu commit desreferenciado. Nunca use git push --tags, pois isso pode publicar tags locais não relacionadas.

Caminho de lançamento na CI

Enviar uma tag v* executa o workflow de lançamento do GitHub. O workflow:

  • Executa npm run release:check
  • Compila artifacts do Electron para macOS, Windows e Linux
  • Cria o lançamento no GitHub a partir da seção correspondente do CHANGELOG.md
  • Espelha no Forgejo o registro de lançamento e os links nomeados dos artifacts
  • Compila imagens Docker
  • Publica o chart Helm com a mesma versão da tag do lançamento
  • Publica o pacote npm usando NPM_TOKEN

A mesma verificação pode ser executada localmente antes de criar a tag:

npm run release:check

Espelho de lançamentos no Forgejo

O espelho usa um token de acesso pessoal do Forgejo armazenado como o segredo criptografado FORGEJO_TOKEN do GitHub Actions. Conceda ao token apenas o escopo write:repository, confirme que seu proprietário pode gravar em libre-webui/libre-webui e nunca faça commit nem exiba o token.

O espelho é deliberadamente idempotente. Ele procura lançamentos por tag, cria somente registros de lançamento ausentes, reconcilia os metadados do lançamento do GitHub e ignora links de artifacts que já existem. Portanto, uma nova tentativa após uma falha de rede ou de workflow conclui o trabalho ausente sem duplicar lançamentos ou assets.

Os assets de lançamento no Forgejo são links externos nomeados que apontam para o browser_download_url público correspondente no GitHub. O GitHub continua sendo o host dos binários, enquanto o Forgejo mostra os mesmos nomes de arquivos para download sem duplicar dezenas de gigabytes de artifacts do aplicativo desktop. Os arquivos do código-fonte continuam sendo gerados de forma independente a partir da tag exata em cada serviço.

Visualize ou preencha um lançamento

Examine o que seria alterado sem gravar no Forgejo:

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

Depois de carregar FORGEJO_TOKEN e GITHUB_TOKEN no ambiente do processo a partir do gerenciador de segredos do mantenedor, espelhe esse lançamento:

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

A tag exata já deve existir no GitHub e no Forgejo e resolver para o mesmo objeto da tag e commit desreferenciado antes que um lançamento seja espelhado.

Visualize ou preencha todos os lançamentos

Audite todos os GitHub Releases comparando-os com o Forgejo:

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

Preencha todos os Forgejo Releases ausentes ou incompletos:

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

GITHUB_TOKEN é obrigatório para --all, inclusive nas simulações, porque a paridade exata das tags e a descoberta de assets exigem mais solicitações do que o limite da API anônima do GitHub permite. FORGEJO_TOKEN também é obrigatório quando --dry-run não é usado.

O caminho --all pagina as duas APIs e considera objetos GitHub Release, e não todas as tags Git. Uma tag que intencionalmente não possui GitHub Release continua apenas como tag no Forgejo. Execute a simulação novamente após o preenchimento; ela não deve informar alterações pendentes.

Política de tags imutáveis

As tags de versão publicadas são imutáveis. Depois que uma tag existe em qualquer serviço remoto:

  • Não a exclua.
  • Não use force-push nela.
  • Não a mova para um commit corrigido.
  • Não reutilize sua versão semântica para outro conteúdo.

Se o conteúdo publicado do lançamento estiver incorreto, corrija o código-fonte e o registro de alterações e publique a próxima versão patch. Se apenas uma página de lançamento ou um link externo de asset estiver ausente, execute novamente o espelho idempotente sem alterar a tag.

A tag v0.8.6 do Forgejo passou por um realinhamento único e explicitamente aprovado durante a introdução do espelhamento duplo de lançamentos. Ele corrigiu dois objetos de tag históricos que descreviam árvores de código-fonte idênticas, mas seguiam linhagens de commits diferentes. Essa migração auditada não abre precedente para mover tags publicadas.

Política de versões do Helm

A version do chart Helm, o appVersion do chart, a versão do pacote raiz e a tag de lançamento usam intencionalmente a mesma versão semântica. O script de lançamento avança todas juntas, e a CI rejeita divergências.

O chart é publicado somente a partir de uma tag imutável de lançamento v*. Não publique conteúdo modificado do chart com uma versão já existente. Uma alteração no chart deve passar pelo próximo lançamento do aplicativo para receber uma nova versão.

A versão 0.14.1 do chart contém uma substituição única por digest, pois esse lançamento antecede as tags semânticas de Docker. O digest identifica a imagem multi-arquitetura 0.14.1 verificada. O script de lançamento remove essa substituição ao criar o próximo lançamento; depois disso, a imagem padrão será resolvida para o appVersion do chart.

O workflow do Docker publica essa tag de versão semântica no GHCR e no Docker Hub a partir da mesma tag de lançamento v*. A publicação no Helm aguarda até 20 minutos pela imagem pública correspondente no Docker Hub e falha em vez de publicar um chart cuja imagem padrão esteja ausente. A imagem do Ollama incluída permanece configurável de forma independente e usa por padrão a tag upstream latest.

Conventional Commits

As mensagens de commit devem usar o formato Conventional Commits:

<type>[optional scope]: <description>

Tipos comuns:

  • feat: recurso voltado ao usuário
  • fix: correção de bug
  • docs: atualização da documentação
  • refactor: reestruturação interna do código
  • perf: melhoria de desempenho
  • test: cobertura de testes
  • chore: manutenção, lançamento ou trabalho de compilação

Alterações incompatíveis usam !:

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

Solução de problemas

O diretório de trabalho não está limpo

Faça commit ou stash das alterações locais antes do lançamento:

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

Não há alterações para lançar

Verifique os commits desde a tag anterior:

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

O registro de alterações precisa de edição manual

Edite CHANGELOG.md e faça commit da correção antes de publicar a tag:

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

Reverta um commit de lançamento local

Se nem o commit nem a tag de lançamento foram enviados:

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

Se qualquer um dos remotos já tiver a tag, não a exclua nem substitua. Corrija o problema em main, crie o próximo lançamento patch e publique essa nova tag imutável por todo o processo obrigatório.

O espelho do Forgejo está incompleto

Primeiro, verifique se os SHAs do objeto da tag remota e do commit desreferenciado correspondem nos dois serviços. Em seguida, visualize e tente novamente o lançamento afetado:

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

Uma falha de autorização significa que FORGEJO_TOKEN está ausente, expirou, pertence a um usuário sem acesso ao repositório ou não tem write:repository. Uma tag remota ausente ou diferente deve ser investigada separadamente; o espelho de lançamentos nunca cria nem move tags Git.

Arquivos do mantenedor

  • .gitmessage - template de mensagem de commit
  • .githooks/commit-msg - validação de Conventional Commits
  • .githooks/pre-commit - verificação prévia de formatação
  • scripts/release.js - orquestração de lançamentos
  • scripts/mirror-forgejo-releases.mjs - espelho e preenchimento idempotente de lançamentos no Forgejo
  • scripts/generate-changelog.js - comando de visualização/atualização do registro de alterações
  • scripts/lib/releaseNotes.js - coleta de evidências e geração do registro de alterações
  • .github/workflows/release.yml - workflow de lançamento na CI acionado por tags
  • .github/workflows/helm-publish.yml - validação do Helm e publicação de tags

Para obter mais informações sobre Conventional Commits, acesse https://www.conventionalcommits.org/.