argws / laravel-updater
Sistema genérico de autoatualização para aplicações Laravel.
Installs: 70
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/argws/laravel-updater
Requires
- php: >=8.2
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/contracts: ^10.0|^11.0|^12.0
- illuminate/filesystem: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- monolog/monolog: ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
- dev-main
- v0.1.88
- v0.1.87
- v0.1.86
- v0.1.85
- v0.1.84
- v0.1.83
- v0.1.82
- v0.1.81
- v0.1.80
- v0.1.79
- v0.1.78
- v0.1.77
- v0.1.76
- v0.1.75
- v0.1.74
- v0.1.73
- v0.1.72
- v0.1.71
- v0.1.70
- v0.1.69
- v0.1.68
- v0.1.67
- v0.1.66
- v0.1.65
- v0.1.64
- v0.1.63
- v0.1.62
- v0.1.61
- v0.1.60
- v0.1.59
- v0.1.58
- v0.1.57
- v0.1.56
- v0.1.55
- v0.1.54
- v0.1.53
- v0.1.52
- v0.1.51
- v0.1.50
- v0.1.49
- v0.1.48
- v0.1.47
- v0.1.46
- v0.1.45
- v0.1.44
- v0.1.43
- v0.1.42
- v0.1.41
- v0.1.40
- v0.1.39
- v0.1.38
- v0.1.37
- v0.1.36
- v0.1.35
- v0.1.34
- v0.1.33
- v0.1.32
- v0.1.31
- v0.1.30
- v0.1.29
- v0.1.28
- v0.1.27
- v0.1.26
- v0.1.25
- v0.1.24
- v0.1.23
- v0.1.22
- v0.1.21
- v0.1.20
- v0.1.19
- v0.1.18
- v0.1.17
- v0.1.16
- v0.1.15
- v0.1.14
- v0.1.13
- v0.1.12
- v0.1.11
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-FIX-ERRO-BRICKED
- dev-fix-authenticate
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-9wqk2p
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-7ubm0x
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-sbx5ih
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-2ssmp2
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup
- dev-wkarts-dev/corrigir-view-settings-e-tornar-responsiva-xw5z38
- dev-wkarts-dev/corrigir-view-settings-e-tornar-responsiva
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-0bejeo
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-qzk7h7
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-aae6el
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-ie6m88
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-o9wm7y
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-ufjrk6
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-98bfax
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-vik8cj
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-s5w7pf
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-nqrmx3
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-6r4vmx
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-jylk8t
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-zabyc2
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-r40gf1
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-3bug61
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-mj19ia
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-247zv5
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-4gwb7b
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-grfp4p
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-hsnrrk
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-hdfvtc
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-o73e8d
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-6lx4tj
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-r924u0
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-eos1sj
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-hdfqnh
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-6zhrww
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-i9bw3u
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-4fcfxe
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-nyic97
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-fg205h
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-nwgixp
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel-uhahpr
- dev-wkarts-dev/implement-idempotent-migration-command
- dev-wkarts-dev/implementar-migrador-idempotente-para-laravel
- dev-wkarts-dev/fix-git-dirty-state-error-z3q0bf
- dev-wkarts-dev/fix-git-dirty-state-error
- dev-wkarts-dev/fix-git-repository-dirty-state-error
- dev-revert-50-ShellRunner
- dev-ShellRunner
- dev-allowDirty
- dev-fix-15022026
- dev-laravel-updater-0.1.40-patched-composerbin-dirtyallowlist
- dev-fix-composer-update
- dev-new-fix-maintenance
- dev-139-maintenance
- dev-probable-fix-0138
- dev-fix-new-probable
- dev-fix-provavel-update
- dev-fix-update-main
- dev-revert-39-revert-38-codex/define-env-settings-and-documentation
- dev-revert-38-codex/define-env-settings-and-documentation
- dev-codex/define-env-settings-and-documentation
- dev-codex/fix-update-view-responsiveness-and-functionality-x14r9y
- dev-codex/fix-update-view-responsiveness-and-functionality-x333zk
- dev-codex/fix-update-view-responsiveness-and-functionality-qafs62
- dev-codex/fix-update-view-responsiveness-and-functionality-wqdx1l
- dev-codex/fix-update-view-responsiveness-and-functionality
- dev-codex/implement-advanced-features-for-updater-package-80aiep
- dev-codex/implement-advanced-features-for-updater-package-ltfbtn
- dev-codex/complete-updater-functionality-ywgqfn
- dev-codex/complete-updater-functionality-qjm1xc
- dev-codex/complete-updater-functionality-2a0lxu
- dev-codex/complete-updater-functionality-bt6y9p
- dev-codex/complete-updater-functionality-2qhi2r
- dev-codex/complete-updater-functionality-erpcji
- dev-codex/complete-updater-functionality
- dev-codex/implement-advanced-features-for-updater-package-m4m1ux
- dev-codex/implement-advanced-features-for-updater-package-v3ayft
- dev-codex/implement-advanced-features-for-updater-package-fqakkz
- dev-codex/implement-advanced-features-for-updater-package-gy14y8
- dev-codex/implement-advanced-features-for-updater-package-46a4ev
- dev-codex/implement-advanced-features-for-updater-package
- dev-codex/improve-login-ui-layout-and-responsiveness-053f3k
- dev-revert-15-codex/improve-login-ui-layout-and-responsiveness-uhtyld
- dev-codex/improve-login-ui-layout-and-responsiveness-uhtyld
- dev-codex/improve-login-ui-layout-and-responsiveness-09gt1b
- dev-codex/improve-login-ui-layout-and-responsiveness-qzbcja
- dev-codex/improve-login-ui-layout-and-responsiveness-l61739
- dev-codex/improve-login-ui-layout-and-responsiveness
- dev-codex/implementar-melhorias-no-painel-updater-manager-lqomru
- dev-codex/implementar-melhorias-no-painel-updater-manager
- dev-codex/add-professional-updater-manager-features-4fs10w
- dev-codex/add-professional-updater-manager-features-3mt8l9
- dev-codex/add-professional-updater-manager-features
- dev-codex/add-independent-authentication-system-with-2fa
- dev-codex/create-argws/laravel-updater-package-mdsobd
- dev-codex/create-argws/laravel-updater-package-1q4ajr
- dev-codex/create-argws/laravel-updater-package-ylt2ki
- dev-codex/create-argws/laravel-updater-package
This package is auto-updated.
Last update: 2026-02-16 18:18:45 UTC
README
Pacote Composer para autoatualização segura, idempotente e reversível de aplicações Laravel, agora com camada de Updater Manager (painel administrativo, auth independente, branding white-label e API de disparo).
Compatibilidade
- PHP: 8.2, 8.3, 8.4
- Laravel/Illuminate: 10, 11, 12
Instalação
composer require argws/laravel-updater php artisan vendor:publish --tag=updater-config
Atualização do config após update do pacote
Publicação automática de config/views (equivalente ao --force)
A partir desta versão, o updater pode sincronizar automaticamente (em execução de console) os arquivos publicados de config e views para manter o pacote atualizado, com comportamento equivalente ao vendor:publish --force.
Controle por .env:
UPDATER_AUTO_PUBLISH_ENABLED=true UPDATER_AUTO_PUBLISH_CONFIG=true UPDATER_AUTO_PUBLISH_VIEWS=true
Se quiser desativar a sincronização automática, ajuste para false.
Por padrão, o vendor:publish não sobrescreve config/updater.php se ele já existir no seu projeto.
Se uma nova versão do pacote trouxer chaves novas no config, você tem 2 opções:
# atualizar o arquivo de config do projeto com a versão do pacote (sobrescreve)
php artisan vendor:publish --tag=updater-config --force
Dica: se você personaliza
config/updater.php, recomendo versionar esse arquivo no seu repositório.
Os assets do updater são sincronizados automaticamente para
public/vendor/laravel-updaterdurante o boot do pacote. Assim, você não precisa rodarphp artisan vendor:publish --tag=updater-assets --forcea cada instalação/atualização.
Rotas principais
/_updater/_updater/login/_updater/security/_updater/settingsPOST /_updater/api/trigger
Variáveis de ambiente (principais)
UPDATER_UI_ENABLED=true UPDATER_UI_PREFIX=_updater UPDATER_UI_AUTH_ENABLED=true UPDATER_UI_AUTO_PROVISION_ADMIN=true UPDATER_UI_DEFAULT_EMAIL=admin@admin.com UPDATER_UI_DEFAULT_PASSWORD=123456 UPDATER_UI_DEFAULT_NAME=Admin UPDATER_UI_SESSION_TTL=120 UPDATER_UI_RATE_LIMIT_MAX=10 UPDATER_UI_RATE_LIMIT_WINDOW=600 UPDATER_UI_2FA_ENABLED=true UPDATER_UI_2FA_REQUIRED=false UPDATER_UI_2FA_ISSUER="Argws Updater" UPDATER_GIT_PATH=/var/www/seu-projeto UPDATER_GIT_REMOTE=origin UPDATER_GIT_BRANCH=main UPDATER_GIT_FF_ONLY=true # opcional para bootstrap automático quando a pasta ainda não é git UPDATER_GIT_AUTO_INIT=false UPDATER_GIT_REMOTE_URL= UPDATER_GIT_DEFAULT_UPDATE_MODE=merge UPDATER_SOURCES_ALLOW_MULTIPLE=false # Composer (somente se necessário) # Em alguns servidores (Supervisor/cron), o PATH pode vir reduzido. O updater tenta normalizar o PATH # e também detecta composer em locais comuns. Se ainda assim falhar, informe o caminho completo. UPDATER_COMPOSER_BIN=/usr/bin/composer # Se você edita arquivos em produção (ex.: config/updater.php), isso pode deixar o repositório "dirty". # Defina quais caminhos podem ficar sujos sem bloquear a atualização. UPDATER_GIT_DIRTY_ALLOWLIST="config/updater.php,.env,storage/,bootstrap/cache/" UPDATER_APP_NAME="ARGWS ERP - Updater" # opcional (default: APP_NAME) UPDATER_APP_SUFIX_NAME="Homolog" # opcional UPDATER_APP_DESC="Sistema em atualização" # opcional # Whitelabel (opcional) - URLs diretas (sem upload) UPDATER_BRAND_LOGO_URL="https://seu-dominio.com.br/assets/logo.png" UPDATER_BRAND_FAVICON_URL="https://seu-dominio.com.br/assets/favicon.ico" UPDATER_BRAND_PRIMARY_COLOR="#0d6efd" UPDATER_SYNC_TOKEN=
Padrão recomendado de .env por cenário
Importante: após qualquer alteração no
.env, executephp artisan config:clear.
1) Produção (recomendado)
UPDATER_TRIGGER_DRIVER=queue UPDATER_UI_FORCE_SYNC=false UPDATER_GIT_PATH=/var/www/sua-aplicacao UPDATER_GIT_REMOTE=origin UPDATER_GIT_BRANCH=main UPDATER_GIT_FF_ONLY=true UPDATER_GIT_AUTO_INIT=false UPDATER_GIT_DEFAULT_UPDATE_MODE=ff-only
Quando usar:
- aplicação com worker de fila ativo;
- deploy previsível e com menor bloqueio da requisição HTTP.
2) Homologação / teste manual pelo painel
UPDATER_TRIGGER_DRIVER=sync UPDATER_UI_FORCE_SYNC=true UPDATER_GIT_PATH=/home/seu-usuario/htdocs/seu-projeto UPDATER_GIT_REMOTE=origin UPDATER_GIT_BRANCH=main UPDATER_GIT_AUTO_INIT=true UPDATER_GIT_REMOTE_URL=https://github.com/wkarts/seu-repo.git UPDATER_GIT_DEFAULT_UPDATE_MODE=tag
Quando usar:
- você quer ver resultado imediato no painel;
- ambiente com menor volume de acesso;
- diretório pode precisar de bootstrap git automático.
3) Compatibilidade de variáveis antigas de login
O updater aceita os dois formatos abaixo para rate limit do login UI:
# formato novo (preferencial) UPDATER_UI_RATE_LIMIT_MAX=10 UPDATER_UI_RATE_LIMIT_WINDOW=600 # formato legado (compatível) UPDATER_UI_LOGIN_MAX_ATTEMPTS=10 UPDATER_UI_LOGIN_DECAY_MINUTES=10
Se ambos existirem, o formato novo (UPDATER_UI_RATE_LIMIT_*) tem prioridade.
.env do updater sem sobrescrever seu .env atual
Para reaproveitar o .env atual da aplicação (sem perder chaves já existentes), o pacote inclui:
stubs/env/updater.default.env.examplestubs/env/updater.production.env.examplestubs/env/updater.homolog.env.example
E um comando de sincronização não destrutiva:
# apenas lista chaves UPDATER_* ausentes php artisan system:update:env-sync --profile=default # adiciona somente as chaves ausentes no .env atual php artisan system:update:env-sync --profile=production --write
Perfis disponíveis em --profile:
defaultproductionhomolog
Esse fluxo mantém o .env existente e só acrescenta parâmetros do updater que ainda não existem.
Seed pós-update (comportamento padrão)
Por padrão, após cada update o updater tenta executar somente:
php artisan db:seed --class=Database\Seeders\ReformaTributariaSeeder --force
Se a classe não existir na aplicação host, o updater apenas registra log e segue o pipeline.
As seeds padrão do sistema (DatabaseSeeder) não rodam por padrão. Para instalação inicial (zero), habilite explicitamente:
php artisan system:update:run --seed --install-seed-default --force
Ou via .env:
UPDATER_SEED_ALLOW_DEFAULT_DATABASE_SEEDER=true
Também é possível trocar a classe da seed específica:
UPDATER_SEED_REFORMA_TRIBUTARIA_SEEDER="Database\Seeders\ReformaTributariaSeeder"
CI e release
- CI valida matrix real: PHP 8.2/8.3/8.4 + Laravel 10/11/12.
release-after-ci.ymlcria tag automática após CI verde namain(eventopush).- Para evitar erro 403 no push de tag, configure o secret
RELEASE_TOKENcom permissão decontents:write(fallback automático paraGITHUB_TOKEN). - Notificação Packagist usa
PACKAGIST_USERNAMEePACKAGIST_TOKENcomo secrets.
Segurança
- Auth interna opcional (
updater.auth) com SQLite do pacote. - Sessão própria com cookie HttpOnly + SameSite=Lax + Secure quando HTTPS.
- 2FA TOTP nativo (6 dígitos, janela +-1 step).
- Rate limit de login por email+IP.
- Permissões granulares por usuário (acesso por módulo/ação), com exceção de usuário master.
Usuário master + permissões por perfil
Defina no .env o usuário master que sempre terá acesso total, independente das permissões marcadas na UI:
UPDATER_UI_MASTER_EMAIL=wkarts@gmail.com
No menu /_updater/users você pode definir permissões específicas de cada usuário (dashboard, updates, backups, logs, fontes, perfis, usuários, settings etc.).
Comandos Artisan
php artisan system:update:check php artisan system:update:run --force php artisan system:update:rollback --force php artisan system:update:status
Notificação de nova atualização (tag/release)
Habilite no .env:
UPDATER_NOTIFY_ENABLED=true UPDATER_NOTIFY_TO=devops@empresa.com UPDATER_TRIGGER_DRIVER=auto
Agende no App\Console\Kernel da aplicação host:
$schedule->command('system:update:notify')->hourly();
Regra de fonte/perfil ativo
Você pode cadastrar várias fontes e perfis, mas apenas UMA fonte ativa e UM perfil ativo devem ficar selecionados por vez para evitar conflitos.
Guia rápido de uso de fontes de atualização
1) Cadastrar fonte
Na tela Fontes (/_updater/sources):
-
Informe nome, tipo, URL e branch.
-
Escolha autenticação (
none,token,ssh). -
Para GitHub HTTPS privado, use autenticação com:
auth_mode=token- Usuário:
x-access-token(ou seu usuário Git) - Senha/Token: seu PAT do GitHub
-
Marque Definir como fonte ativa se quiser usar imediatamente.
Você pode cadastrar várias fontes, mas apenas uma fica ativa por vez.
2) Editar e excluir fonte
Na listagem de fontes:
- Botão Editar abre a própria tela com os campos preenchidos.
- Botão Excluir remove a fonte após confirmação.
3) Testar conexão real
Na tela de fontes, use Testar conexão real da fonte.
O teste executa git ls-remote para validar acesso e listar versões/tags remotas.
Guia de atualização (fluxo recomendado)
- Vá em Atualizações (
/_updater/updates). - Selecione o perfil e a fonte.
- Escolha o modo (
merge,ff-only,tag,full updatese habilitado). - Mantenha Dry-run antes marcado (padrão).
- Clique em Simular (Dry-run).
- Na tela da execução, clique em Aprovar e executar e informe a senha de admin.
O backup FULL é obrigatório antes da atualização real via UI.
Notificações de atualização (opcional)
As notificações são opcionais e aceitam múltiplos destinatários:
UPDATER_NOTIFY_ENABLED=true UPDATER_NOTIFY_TO=devops@empresa.com,ti@empresa.com,owner@empresa.com UPDATER_TRIGGER_DRIVER=auto
Também é aceito ; como separador de e-mails.
Troubleshooting (erros mais comuns)
Erro: Falha ao aplicar atualização: O updater só pode ser executado via CLI.
Causa comum:
- execução sincronizada disparada pela UI sem permitir contexto HTTP.
Como resolver:
- Atualize para a versão mais recente do pacote (esta versão já trata o fluxo UI com
--allow-http). - Confirme
UPDATER_TRIGGER_DRIVER=sync(homologação) ouqueue(produção). - Rode:
php artisan config:clear php artisan cache:clear
Erro no composer install: "The HOME or COMPOSER_HOME environment variable must be set"
Isso acontece quando o updater roda em um ambiente sem variáveis de usuário (muito comum em cron, supervisor ou quando o PHP é executado com um usuário sem shell).
✅ A partir desta versão, o updater faz fallback automático:
- define
HOMEquando não existe; - define
COMPOSER_HOMEeCOMPOSER_CACHE_DIRautomaticamente; - cria os diretórios necessários se não existirem.
Se você quiser forçar valores específicos (opcional), pode exportar antes de rodar o comando:
export HOME=/home/seu-usuario export COMPOSER_HOME=/home/seu-usuario/.composer php artisan system:update:run --force
Página de manutenção (503) e Whitelabel
Durante uma atualização, o updater ativa o maintenance mode e exibe uma página 503 própria.
Default (sem .env)
Se você não configurar nada, o updater usa automaticamente a view padrão do pacote:
laravel-updater::maintenance
Whitelabel por painel (prioritário)
No painel /_updater/settings você pode configurar tudo pela UI:
- textos de manutenção;
- cor primária;
- upload de logo do painel, favicon do painel e logo exclusiva da manutenção;
- comportamento de primeira execução sem
.git; - entrada em manutenção no início da atualização.
Essas configurações salvas no painel têm prioridade em relação ao fallback de configuração do projeto.
Fallback por .env (opcional)
Se você preferir não usar upload no painel, também pode apontar logo/ícone por URL:
UPDATER_BRAND_LOGO_URL=https://seu-dominio.com.br/assets/logo.png UPDATER_BRAND_FAVICON_URL=https://seu-dominio.com.br/assets/favicon.ico UPDATER_BRAND_PRIMARY_COLOR=#0d6efd UPDATER_MAINTENANCE_LOGO_URL=https://seu-dominio.com.br/assets/logo-manutencao.png
Se existir upload no painel, ele tem prioridade sobre as URLs do .env.
Na tela de configurações de branding, os campos indicam claramente o que é cada ativo: logo do painel, favicon do painel e logo da manutenção.
Controles manuais de manutenção
No dashboard há botões para habilitar/desabilitar manutenção imediatamente.
Critérios de segurança aplicados:
- confirmação obrigatória digitando
MANUTENCAO; - quando autenticação da UI está habilitada, a ação exige usuário com 2FA ativo.
Além disso, o updater adiciona automaticamente exceção de manutenção para o prefixo configurado em UPDATER_UI_PREFIX (ex.: /_updater), para que o painel continue acessível durante a janela de manutenção.
Em versões de Laravel que não suportam php artisan down --except, o updater faz fallback automático sem --except para não quebrar o fluxo de update/manutenção.
No modo de atualização por tag, se a aplicação já estiver exatamente na tag alvo, o updater trata como execução válida (sem falso erro por revisão inalterada).
Atualização de arquivos publicados (config/views)
O Laravel não sobrescreve automaticamente arquivos publicados em config/ e resources/views/.
Se você publicou config/updater.php ou views e quer atualizar para a versão mais recente do pacote (atenção: isso pode sobrescrever alterações), rode:
php artisan vendor:publish --tag=updater-config --force php artisan vendor:publish --tag=updater-views --force
Erro: .git não é criado automaticamente
Checklist:
UPDATER_GIT_AUTO_INIT=trueUPDATER_GIT_REMOTE_URLpreenchida e acessívelUPDATER_GIT_PATHaponta para a pasta correta e com permissão de escrita do usuário do PHPgitdisponível no servidor (git --version)
Não aparecem atualizações disponíveis, mas o teste de conexão da fonte funciona
Isso normalmente indica divergência entre:
- a fonte ativa no painel (usada no teste de conexão), e
UPDATER_GIT_PATHlocal (usado para calcular revisão local/remota).
Valide:
- pasta de
UPDATER_GIT_PATHé o mesmo projeto conectado à fonte ativa; - branch da fonte ativa bate com
UPDATER_GIT_BRANCH; - repositório local possui upstream correto (
origin/mainpor exemplo); - execute
php artisan system:update:checkpara comparar com o status da UI.
Dica: por padrão, o updater não bloqueia o CHECK por working tree dirty (somente leitura). Se você quiser bloquear também, configure:
UPDATER_GIT_ALLOW_DIRTY_CHECK=false
Solução para erro “Diretório atual não é um repositório git válido”
Se a aplicação não estiver na mesma pasta do updater, configure UPDATER_GIT_PATH com o diretório real do projeto Laravel versionado em Git.
Exemplo:
UPDATER_GIT_PATH=/home/seu-usuario/htdocs/seu-projeto UPDATER_GIT_REMOTE=origin UPDATER_GIT_BRANCH=main
Se você quer inicializar um diretório vazio automaticamente (cenário avançado), habilite:
UPDATER_GIT_AUTO_INIT=true UPDATER_GIT_REMOTE_URL=https://github.com/org/repositorio.git
Recomendado para produção: manter
UPDATER_GIT_AUTO_INIT=falsee usar um diretório já versionado.
Quando houver uma fonte ativa no painel, o updater usa automaticamente a URL/branch dessa fonte para bootstrap git (com
UPDATER_GIT_AUTO_INIT=true), sem exigirUPDATER_GIT_REMOTE_URLmanualmente.
Após alterar variáveis do updater em produção, execute também:
php artisan config:clear php artisan cache:clear
Migrador idempotente definitivo (updater:migrate)
Por que acontece o erro SQLSTATE[42S01] / errno 1050
Esse erro indica que a migration tentou criar uma tabela/view que já existe no banco (Base table or view already exists).
Em ambientes reais isso ocorre por drift entre o banco e a tabela migrations (dump restore, merge manual, execução parcial/interrompida, ou banco adiantado).
Como a reconciliação evita a falha
O comando updater:migrate roda exatamente uma migration por vez e, quando a falha é classificada como ALREADY_EXISTS segura:
- confere se a migration já está na tabela
migrations; - se não estiver, reconcilia registrando a migration com batch correto;
- para constraints, valida via
information_schema.TABLE_CONSTRAINTS/KEY_COLUMN_USAGE(MySQL/MariaDB); - continua para a próxima migration.
No modo strict, qualquer dúvida de inferência/compatibilidade interrompe com erro orientando intervenção manual.
Configuração
UPDATER_MIGRATE_IDEMPOTENT=true UPDATER_MIGRATE_MODE=tolerant UPDATER_MIGRATE_RETRY_LOCKS=2 UPDATER_MIGRATE_RETRY_SLEEP_BASE=3 UPDATER_MIGRATE_DRY_RUN=false UPDATER_MIGRATE_LOG_CHANNEL=stack UPDATER_MIGRATE_RECONCILE_ALREADY_EXISTS=true UPDATER_MIGRATE_REPORT_PATH="storage/logs/updater-migrate-{timestamp}.log"
Comandos
# execução real (tolerante) php artisan updater:migrate --force # modo estrito php artisan updater:migrate --force --mode=strict # dry-run (não executa SQL) php artisan updater:migrate --force --dry-run
Retry/backoff de lock/deadlock
Para falhas LOCK_RETRYABLE (deadlock, lock wait timeout, metadata lock), o updater aplica retry com backoff progressivo
(retry_sleep_base * 2^(tentativa-1) + (tentativa-1)), por exemplo base=3: 3s, 7s, 15s.
Quando usar modo strict
Use strict em ambientes novos/limpos, onde drift não é esperado. Em produção com histórico heterogêneo,
mode=tolerant tende a reduzir falhas por objetos já existentes sem editar migrations antigas.
Nota sobre manutenção whitelabel
A view laravel-updater::maintenance agora possui fallback seguro: se o armazenamento de branding não estiver acessível no momento do artisan down --render, ela renderiza com valores de config (updater.app.* e updater.maintenance.*) em vez de falhar. Isso evita o cenário em que a aplicação não entra corretamente em manutenção por erro de renderização da view.
Caso idempotente adicional: DROP INDEX inexistente (MySQL errno 1091)
O migrador idempotente trata Can't DROP ... check that column/key exists (errno 1091) como drift idempotente no modo tolerante. Nesse caso, valida no information_schema.STATISTICS se o índice já está ausente, reconcilia a migration e segue o pipeline sem editar migrations antigas.
Correção de entrada em manutenção (REQUEST_URI no CLI)
Quando o host dispara erro Undefined array key "REQUEST_URI" durante artisan down --render, o updater agora injeta variáveis de servidor mínimas (REQUEST_URI, HTTP_HOST, SERVER_NAME, SERVER_PORT, HTTPS) no comando de manutenção. Com isso a aplicação volta a entrar em manutenção e exibir a view whitelabel do pacote.
Caso idempotente adicional: tabela inexistente em DROP (SQLSTATE 42S02 / errno 1146)
O classificador considera 42S02/1146 como idempotente somente quando o SQL indica operação de remoção segura (drop table, drop index, alter table ... drop, etc.).
Se for consulta/uso normal (select, update, etc.), permanece NON_RETRYABLE para não mascarar erro real.
Correção definitiva para erro de ENCRYPTION_KEY no route:cache
Em alguns projetos, providers/helpers consultam ENCRYPTION_KEY via env()/getenv() durante comandos Artisan. Em execução não-interativa do updater, isso pode falhar mesmo com chave no .env.
O ShellRunner do pacote agora preserva o ambiente do processo e também faz fallback de leitura do .env (chaves ENCRYPTION_KEY e APP_KEY) para o comando filho. Isso evita quebra no cache_clear por falso negativo de chave ausente.
Tratamento de falha de route:cache por nome de rota duplicado
Se o host tiver rotas com nomes duplicados, o Laravel lança LogicException no route:cache.
O updater agora pode seguir o pipeline sem abortar o update: registra warning e executa route:clear.
Controle por .env:
UPDATER_CACHE_IGNORE_ROUTE_CACHE_DUPLICATE_NAME=true
Healthcheck em localhost durante update
Para evitar falso negativo em ambientes onde APP_URL/healthcheck fica em localhost, o updater ignora healthcheck local por padrão.
Controle por .env:
UPDATER_HEALTHCHECK_SKIP_LOCALHOST=true
Painel lateral técnico (novo)
A barra superior de versões/hash foi removida da interface.
Agora, o updater exibe o resumo técnico em um card responsivo no menu lateral (abaixo da navegação), incluindo:
- nuvem conectada e status de credenciais,
- upload automático de backup,
- fonte e perfil ativos,
- status de serviços (cURL, OpenSSL, ZIP),
- versões relevantes (Laravel, updater e PHP),
- tag/hash git da aplicação alvo,
- usuário autenticado (nome, quando disponível),
- data/hora atual em tempo real.
Esse card foi desenhado para manter legibilidade em desktop e mobile sem poluição visual.
Upload em nuvem autocontido (Dropbox / Google Drive / S3 / MinIO)
O laravel-updater possui fluxo próprio de upload em nuvem para backups, sem depender de Storage::disk(...) da aplicação hospedeira.
Configuração na UI
Em /_updater/settings você encontra os campos específicos por provedor:
- Dropbox: Access Token;
- Google Drive: Client ID, Client Secret, Refresh Token e Folder ID opcional;
- S3 / MinIO: Endpoint, Region, Bucket, Access Key, Secret Key e Path-Style.
Também é possível definir:
- provider ativo,
- prefix remoto,
- auto_upload (upload automático pós-backup).
Comportamento
- O backup local continua concluindo mesmo se o upload em nuvem falhar.
- Upload manual por item de backup continua disponível na seção de backups.
- Configurações de nuvem são persistidas em runtime no banco do updater (
updater_runtime_settings).