argws / laravel-updater
Sistema genérico de autoatualização para aplicações Laravel.
Requires
- php: >=8.2
- guzzlehttp/guzzle: ^7.5
- 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
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.1.221
- v0.1.220
- v0.1.219
- v0.1.218
- v0.1.217
- v0.1.216
- v0.1.215
- v0.1.214
- v0.1.213
- v0.1.212
- v0.1.211
- v0.1.210
- v0.1.209
- v0.1.208
- v0.1.207
- v0.1.206
- v0.1.205
- v0.1.204
- v0.1.203
- v0.1.202
- v0.1.201
- v0.1.200
- v0.1.199
- v0.1.198
- v0.1.197
- v0.1.196
- v0.1.195
- v0.1.194
- v0.1.193
- v0.1.192
- v0.1.191
- v0.1.190
- v0.1.189
- v0.1.188
- v0.1.187
- v0.1.186
- v0.1.185
- v0.1.184
- v0.1.183
- v0.1.182
- v0.1.181
- v0.1.180
- v0.1.179
- v0.1.178
- v0.1.177
- v0.1.176
- v0.1.175
- v0.1.174
- v0.1.173
- v0.1.172
- v0.1.171
- v0.1.170
- v0.1.169
- v0.1.168
- v0.1.167
- v0.1.166
- v0.1.165
- v0.1.164
- v0.1.163
- v0.1.162
- v0.1.161
- v0.1.160
- v0.1.159
- v0.1.158
- v0.1.157
- v0.1.156
- v0.1.155
- v0.1.154
- v0.1.153
- v0.1.152
- v0.1.151
- v0.1.150
- v0.1.149
- v0.1.148
- v0.1.147
- v0.1.146
- v0.1.145
- v0.1.144
- v0.1.143
- v0.1.142
- v0.1.141
- v0.1.140
- v0.1.139
- v0.1.138
- v0.1.137
- v0.1.136
- v0.1.135
- v0.1.134
- v0.1.133
- v0.1.132
- v0.1.131
- v0.1.130
- v0.1.129
- v0.1.128
- v0.1.127
- v0.1.126
- v0.1.125
- v0.1.124
- v0.1.123
- v0.1.122
- v0.1.121
- v0.1.120
- v0.1.119
- v0.1.118
- v0.1.117
- v0.1.116
- v0.1.115
- v0.1.114
- v0.1.113
- v0.1.112
- v0.1.111
- v0.1.110
- v0.1.109
- v0.1.108
- v0.1.107
- v0.1.106
- v0.1.105
- v0.1.104
- v0.1.103
- v0.1.102
- v0.1.101
- v0.1.100
- v0.1.99
- v0.1.98
- v0.1.97
- v0.1.96
- v0.1.95
- v0.1.94
- v0.1.93
- v0.1.92
- v0.1.91
- v0.1.90
- v0.1.89
- 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/updater-assets-scalar
- dev-new-ui-16102026
- dev-fix/mutable-git-tags-checkout-20261015
- dev-fix/runs-view-missing-routes-20261015
- dev-fix/updater-health-cache-run-diagnostics-20261015
- dev-fix/healthcheck-soft-maintenance-20261015
- dev-fix/git-status-remote-tags-20261015
- dev-feat/branch-prerelease-updates-20261015-0442
- dev-fix/zip-close-retry-volatile-files-20260923
- dev-fix/schema-resolver-config-fallback-20260923
- dev-fix/schema-resolver-backward-compatible-20260923
- dev-feature/schema-compatibility-resolver-20260923
- dev-fix/stay-on-updates-page-20260919
- dev-fix/prevent-fpm-update-execution-20260919
- dev-fix/idempotent-migration-schema-warnings-20260919
- dev-fix/git-maintenance-pipeline-timeout-20260919
- dev-fix/resilient-update-recovery-20260919
- dev-wkarts-dev/fix-git-update-failure-due-to-missing-binary-xqcn1u
- dev-wkarts-dev/fix-git-update-failure-due-to-missing-binary-fyigkd
- dev-wkarts-dev/fix-git-update-failure-due-to-missing-binary-mz6wcp
- dev-wkarts-dev/fix-git-update-failure-due-to-missing-binary
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-06prw6
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-sls8gy
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-idmsmc
- dev-revert-189-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-kdnd0d
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-kdnd0d
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-316uo5
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-do9x95
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-g22zjj
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-t47qdx
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-wk1hii
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-g6bbb9
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-7ae5et
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-1dz970
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-0il1sw
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-67edya
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-qp7h0v
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-ao8mlh
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-dkkm3y
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-hklieb
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-f0oucy
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-z04tp5
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-127jno
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-69rs5p
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-1hgq7b
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector-9hrhaq
- dev-wkarts-dev/fix-invalid-regex-in-migrationdriftdetector
- dev-wkarts-dev/add-php-8.5-support-to-laravel-updater
- dev-wkarts-dev/fix-migration-error-for-abertura_caixas-table-su26k8
- dev-wkarts-dev/fix-migration-error-for-abertura_caixas-table-sjnevj
- dev-wkarts-dev/fix-migration-error-for-abertura_caixas-table
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-4c2vck
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-mit9vn
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-0jq8k8
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-ornryu
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-u0o55j
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-r2jzn9
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-ellijk
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-zrxsl7
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-g4lvuw
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-7z7pk0
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-mjzq0j
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-rhqkjd
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-0p1unt
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-waub0l
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-29y6f5
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-fxlmci
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-gzp5ki
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-2xjlcb
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-rmin6a
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-jv9mbf
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-iw1ooz
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-9qslnv
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-3xe8u4
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-hvrm84
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater-knp1fo
- dev-wkarts-dev/conduct-comprehensive-analysis-of-laravel-updater
- dev-UPDATER_UI_PREFIX
- dev-UPDATER_BACKUP_CREATE_FULL_ARCHIV
- dev-revert-138-BETA-VAI-QUEBRAR
- dev-BETA-VAI-QUEBRAR
- dev-fix-git-noninteractive-and-security-menu
- dev-soft-maintenance-updater-ui-safe
- dev-fix-gitmaintenancestep-interface-0.1.125
- dev-fix-gitmaintenance-lock-ui-guard
- dev-UPDATER_LOCK_BLOCK_SECONDS
- dev-git-maintenance-auto-cleanup-and-backup-hard-excludes
- dev-fix-exclude-git-from-backups-and-lock-wait
- dev-fix-snapshot-recursion-0.1.118
- dev-fix-snapshot-recursion-loop
- dev-fix-maintenanceonstep-parse-error
- dev-fix-autostash-include-ignored
- dev-fix-git-autostash-and-profile-backup
- dev-restore-full-backup-and-maintenance-hardening
- dev-fix-backup-grid-registration-update
- dev-fix-config-cache-and-maintenance-stability
- dev-fix-updater-maintenance-except-and-windows-driver
- dev-wkarts-dev/fix-maintenance-mode-updater-access
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-nn7fgh
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-1oj3nx
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-g0xqlh
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-r4yr94
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-tynyks
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-od4j68
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-zdow88
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-ix3n85
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-fft0cw
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-ysszrr
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-y8z6v2
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-3e4y0v
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-k6ll8b
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-woxadv
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup-irtbho
- dev-wkarts-dev/corrigir-problema-de-snapshot-no-backup
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-7o6kdq
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-idzhqp
- dev-wkarts-dev/implementar-melhorias-no-sistema-de-backup-2glt31
- dev-final-fix-0189
- dev-fix-sidebar-tentativa-1-16022026
- dev-fix-bar-side-16022026
- dev-fix-bar-16022026
- 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-10-16 05:51:01 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, 8.5
- Laravel/Illuminate: 10, 11, 12
Instalação
composer require argws/laravel-updater php artisan vendor:publish --tag=updater-config
O painel usa Vue 3 + TypeScript. O pacote Composer inclui o manifest e os assets compilados em resources/dist, servidos pelos endpoints do updater. A aplicação hospedeira não precisa de Node, npm, build nem publicação manual de assets. O prefixo continua configurável; autenticação, permissões, sessão e CSRF permanecem no Laravel.
Upgrade a partir de 0.1.219
- Faça backup do código, SQLite operacional e configurações; preserve o
APP_KEY. - Atualize o pacote pelo Composer, execute
php artisan optimize:cleare reconstrua os caches usados pela aplicação. - Reinicie os workers e mantenha o scheduler Laravel por minuto quando usar webhooks. Confira acesso, fonte/perfil, simulação e histórico antes de aplicar uma atualização real.
Credenciais antigas são cifradas gradualmente com a chave Laravel; campos vazios preservam o segredo e remoção/substituição são separadas. Overrides Blade publicados deixam de controlar a interface e precisam ser adaptados ao Vue ou ao branding do painel.
Rollback: suspenda novos jobs, reverta o pacote e restaure o snapshot correspondente de SQLite/configuração, preservando APP_KEY. O código 0.1.219 não entende os novos valores cifrados; reverter só o código pode falhar. Restaurar snapshot descarta alterações posteriores. Homologue atualização, restauração e rollback numa cópia representativa antes da produção.
Build somente para mantenedores
Com Node compatível com Vite 7 e npm, execute npm ci --no-audit --no-fund e npm run build. Versione resources/dist completo, incluindo .vite/manifest.json. Esse processo não faz parte da instalação na aplicação hospedeira.
Pré-requisito obrigatório: PDO SQLite
O updater usa SQLite para estado interno (runs, sessões e metadados).
Em qualquer ambiente (CLI/FPM/FrankenPHP), habilite a extensão pdo_sqlite.
Exemplo de verificação:
php -m | grep -i sqlite
Se o comando não listar pdo_sqlite, habilite no php.ini:
extension=pdo_sqlite
Atualização do config após update do pacote
Publicação automática de config/views (equivalente ao --force)
O updater pode sincronizar automaticamente (em execução de console) os arquivos publicados de config e as views legadas, com comportamento equivalente ao vendor:publish --force. Essas views são preservadas por compatibilidade; a apresentação do painel é Vue e não depende de publicá-las.
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.
A sincronização para
public/vendor/laravel-updaterconserva os assets legados. O painel Vue carrega os arquivos deresources/distdiretamente pelo pacote, sem depender dessa cópia nem devendor:publish --tag=updater-assets.
Rotas principais
/_updater/_updater/login/_updater/security/_updater/settingsPOST /_updater/api/trigger/_updater/api-docs/_updater/webhooks
API e webhooks
Os caminhos abaixo são relativos ao prefixo configurado (/_updater por padrão). A API aceita Authorization: Bearer <token> ou X-Updater-Token: <token> e preserva updater.sync_token/UPDATER_SYNC_TOKEN. Tokens administrativos novos têm hash, escopos mínimos, revogação/rotação e exibição única; não é possível recuperar seu valor pela listagem.
| Método e caminho | Escopo / finalidade |
|---|---|
GET /api/status |
status:read: estado operacional |
GET /api/check |
check:read: verificar atualização |
GET /api/runs |
runs:read: execuções recentes |
GET /api/release-notes?tag=v1.2.3-rc.1 |
releases:read: notas da tag exata; source_id opcional |
POST /api/trigger |
updates:simulate ou updates:apply: simular/aplicar |
GET /api/openapi.json |
status:read: contrato completo |
A documentação interna fica em /api-docs, protegida pela autenticação/permissões do painel. A especificação distribuída está em resources/openapi.json, com payloads, respostas, erros, limites e idempotência.
Para simular, envie {"dry_run":true} a /api/trigger. Para aplicar, use um token com updates:apply e envie {"dry_run":false,"confirmation":"ATUALIZAR"}. action=simulate e dry_run_before=true sempre simulam. Use Idempotency-Key para repetir a mesma solicitação sem duplicar o disparo. Aprovações com senha continuam no painel; comandos, SQL e seed remotos não são aceitos.
Webhooks são configurados em /webhooks. A entrada POST /api/webhooks/{endpointId} exige HMAC-SHA256, timestamp e ID único; aceita somente as ações permitidas status, check e simulate. Saídas exigem HTTPS público, cURL e scheduler/worker conforme a fila configurada; usam assinatura, proteção SSRF e tentativas auditáveis. Segredos de criação/rotação são exibidos uma única vez. O contrato de entrada consta no OpenAPI.
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 # opcional UPDATER_GIT_AUTO_DETECT_PATH=true # recomendado # Se esquecer qualquer um desses parâmetros, o updater tenta detectar automaticamente o diretório do 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 # opcional UPDATER_GIT_AUTO_DETECT_PATH=true 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 # opcional UPDATER_GIT_AUTO_DETECT_PATH=true 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/8.5 + 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.
- Credenciais existentes mostram apenas se estão configuradas; nunca são preenchidas novamente.
- 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.
- Opcionalmente informe uma branch alvo. Em branco, o updater usa a branch configurada na fonte selecionada.
- Escolha o modo (
merge,ff-only,tag,full updatese habilitado).- Para uma release de pré-lançamento, escolha
tage digite a tag exata, por exemplov1.2.3-rc.1. As tags sugeridas são atalhos; tags fora da lista também podem ser digitadas.
- Para uma release de pré-lançamento, escolha
- Escolha Apenas simular e clique em Executar somente simulação.
- Confira o plano e o resultado. As notas sempre correspondem à fonte/tag selecionadas; ausência de notas ou comparação não verificada são indicadas explicitamente.
- Para aplicar, escolha a ação real, revise fonte/branch/tag/perfil e digite
ATUALIZAR. Quando houver aprovação pendente, use Aprovar e executar após a simulação concluída, mantendo a senha e a confirmação exigidas.
No CLI, a branch alternativa pode ser informada com --branch; para pré-release, use --update-type=git_tag e --tag com a tag completa:
php artisan system:update:run --update-type=git_tag --tag=v1.2.3-rc.1 php artisan system:update:run --update-type=git_merge --branch=develop
O status de pré-release do GitHub não muda o mecanismo de checkout: o updater aplica a referência Git exata associada à tag.
Confira a política de backup configurada no servidor antes de aplicar. A interface não substitui a verificação de um backup recuperável.
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)
O Laravel não sobrescreve automaticamente arquivos publicados em config/ e resources/views/.
Se você publicou config/updater.php e quer substituí-lo pela versão do pacote (atenção: isso pode sobrescrever alterações), rode:
php artisan vendor:publish --tag=updater-config --force
Views publicadas não precisam ser atualizadas para carregar o painel Vue. Preserve personalizações antigas para adaptação; publicar views ou assets não é requisito de instalação dessa interface.
Erro: .git não é criado automaticamente
Checklist:
UPDATER_GIT_AUTO_INIT=trueUPDATER_GIT_REMOTE_URLpreenchida e acessívelUPDATER_GIT_PATH(se usado) aponta para a pasta correta e com permissão de escrita do usuário do PHP- mantenha
UPDATER_GIT_AUTO_DETECT_PATH=truepara fallback automático quando o path estiver inválido gitdisponí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 (se configurado) usado para calcular revisão local/remota.- com
UPDATER_GIT_AUTO_DETECT_PATH=true, caminho inválido cai para auto detecção do projeto.
Valide:
- se
UPDATER_GIT_PATHestiver configurado, a pasta deve ser 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, você pode configurar UPDATER_GIT_PATH com o diretório real do projeto Laravel versionado em Git.
Se preferir, deixe UPDATER_GIT_PATH vazio e use UPDATER_GIT_AUTO_DETECT_PATH=true para detecção automática.
Exemplo:
UPDATER_GIT_PATH=/home/seu-usuario/htdocs/seu-projeto # opcional UPDATER_GIT_AUTO_DETECT_PATH=true 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
Schema Compatibility Resolver
O migrador pode reparar automaticamente incompatibilidades seguras de schema em bancos legados sem adivinhar o tipo da coluna.
Casos suportados:
- MySQL errno 3780: FK incompatível após uma migration tentar perder atributos do tipo real;
- MySQL errno 1830/1832 em alterações de coluna vinculada a FK;
- guards de migration que reportam
Alteração depende de FK ativa (...): tabela.coluna.
Política de segurança:
- usa
SHOW CREATE TABLEcomo fonte de verdade do DDL atual; - preserva tipo real, inclusive
INT UNSIGNED, default, comment e demais atributos presentes no DDL; - aplica automaticamente apenas o alvo seguro
NOT NULL -> NULL; - captura, remove temporariamente e recria as FKs exatamente com a definição encontrada no banco;
- valida coluna e constraints antes de reconciliar a migration;
- grava journal em
storage/app/updater/schema-repairse recupera FK pendente na próxima execução caso haja interrupção entre operações DDL; - não reescreve arquivos PHP de migrations no servidor.
Configuração:
UPDATER_MIGRATE_SCHEMA_COMPATIBILITY=true UPDATER_MIGRATE_SCHEMA_AUTO_REPAIR=true UPDATER_MIGRATE_SCHEMA_SAFE_ONLY=true UPDATER_MIGRATE_SCHEMA_PRESERVE_TYPE=true UPDATER_MIGRATE_SCHEMA_PRESERVE_UNSIGNED=true UPDATER_MIGRATE_SCHEMA_PRESERVE_FKS=true
Quando o reparo é verificado, a migration é reconciliada no histórico e o fluxo segue para a próxima migration. Alterações destrutivas, redução de tamanho, perda de precisão ou reparos cuja intenção não possa ser comprovada continuam fora do auto-repair.
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 durante a manutenção
O Laravel Updater oferece GET /_updater/health (ou /<UPDATER_UI_PREFIX>/health), uma rota
pública somente leitura, sem sessões, comandos nem dados sensíveis. Ela informa apenas
{"updater_health":true,"status":"ok"} (HTTP 200) ou status: unhealthy (HTTP 503).
Quando a URL configurada para healthcheck é igual à APP_URL e a pipeline está
em manutenção, a verificação usa automaticamente essa rota para não interpretar
a página de manutenção HTTP 503 como indisponibilidade da aplicação. A verificação
acontece antes de liberar a manutenção e o lock; URLs personalizadas continuam
sendo usadas sem modificação, mantendo a exigência de HTTP 200.
Opcionalmente, ative a consulta ao banco padrão durante o healthcheck:
UPDATER_HEALTHCHECK_CHECK_DATABASE=true
A consulta HTTP registra código de resposta e tempo decorrido, sem expor corpo da
resposta ou informações de conexão nos logs. Se a aplicação usa um prefixo de URL
customizado, a rota utiliza o mesmo UPDATER_UI_PREFIX.
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).
Diagnóstico de execuções (JSON e ZIP)
Na página Execuções → Diagnóstico cada execução exibe o erro original antes do rollback, status de cada etapa, duração, rollback executado, logs com contexto e migrations relacionadas. O painel de progresso também exibe os nomes das etapas e a causa da falha.
Para baixar pela própria interface autenticada:
- `GET /_updater/runs/{id}/diagnostics/json` — relatório estruturado em JSON.
- `GET /_updater/runs/{id}/diagnostics/zip` — `diagnostico.json`, `eventos.jsonl`, `etapas.json`, `migrations.json` e `README.txt`.
A exportação lê somente os registros do Laravel Updater em seu SQLite. Não inclui `.env`, dumps, arquivos dos clientes ou logs do ERP. Senhas, tokens e URLs de credenciais são ocultados. Os últimos 5.000 eventos por execução são incluídos e o resumo informa se houve truncamento; a tela mostra até 300. Arquivos ZIP são temporários e removidos após o download.
Para evitar rota de saúde ausente após a troca do próprio pacote, `route:cache` é executado após os comandos posteriores. Em um HTTP 404 na rota interna o healthcheck ainda tenta regenerar o cache uma única vez, sem liberar o lock, e só marca sucesso após receber a resposta JSON esperada.