atualizacoes-sistema.php aceita execução CLI e fluxo web. O modo completo baixa ou usa um artefato local, confere SHA-256 quando há arquivo de checksum, extrai para staging e valida arquivos críticos. Primeiro substitui o próprio script de atualização e o executa novamente na versão nova; depois aplica arquivos e atualiza o banco. No fluxo web, as etapas são start, deploy, db e finalize, vinculadas por um identificador de sessão.
As pastas contents/, logs/, backups/, temp/ e autenticacoes/ são protegidas da sobreposição de arquivos. --dry-run simula, --backup cria backup antes da alteração, --only-files e --only-db executam partes específicas; essas duas últimas são mutuamente exclusivas. O atualizador de banco aplica as regras declaradas em schema-metadata.json, incluindo preservação de campos alterados pelo usuário. Veja recursos.
Antes de mover o staging, as migrações do core que o artefato não traz mais saem de db/migrations (req-194, atualizacoes-migracoes.php). A pasta tem dois donos — core e projeto —, cada um com seu manifesto (db/.c2f-migrations-core.json, db/.c2f-migrations-projeto.json); a atualização do core nunca apaga migração do projeto e registra no log os choques de versão ou classe.
Depois do banco, db/ fica no lugar, no CLI e no web (req-197): a pasta tem as migrações dos dois donos e os manifestos acima.
Trava de deploy (req-197). Toda atualização, menos --dry-run, roda com a trava do ambiente em temp/deploy.lock, a mesma do deploy de projeto por API. Com outro deploy em execução, o CLI recusa com código de saída 8 e o web recusa o start com locked; a mensagem diz quem está com a trava. Trava vencida (processo que morreu) é assumida com aviso no log. No CLI, o processo do bootstrap pega a trava e passa o token ao filho (--lock-token), que a adota. No web, start pega e finalize/cancel liberam. --backup copia a instalação inteira para backups/atualizacoes/full/<data>/, sem as pastas protegidas, antes de mexer em qualquer arquivo.
Camadas e choques (req-198). Cada entrega grava o que entregou em installation/manifests/<camada>.json (caminho e sha256), e a precedência é projeto > plugin:<id> > core. Antes de mover o staging, a atualização do core:
-
não sobrescreve um arquivo que o projeto ou um plugin sobrepõe: a versão nova vai para
backups/overrides/<versão>/e vira choquesobreposto; -
preserva um arquivo mudado no servidor sem que nenhuma camada tenha entregue aquele conteúdo (choque
editado); -
retira o que o core deixou de entregar, se estiver intacto; editado, vira choque
retirado-editado.
A primeira entrega, sem manifesto, se comporta como antes e grava a linha de base. Os choques ficam em installation/choques/ e, depois da etapa de banco, na tabela atualizacoes_choques (o mesmo choque ainda pendente não vira outra linha a cada atualização); a aba "Choques das entregas" do admin-atualizacoes mostra a lista e o diff, e no detalhe fica a decisão por arquivo: sobrescrever, manter ou mesclar (req-199; também pela API e por c2f update:conflicts / update:resolve). "Manter" vira regra para as próximas entregas do mesmo arquivo, e a camada que entrega o mesmo conteúdo de antes não gera choque. installation/ é pasta protegida.
Dados que saem (req-199 / BATCH-207). A sincronização do banco também retira o que o dono deixou de entregar:
-
cada entrega grava, por dono (
coreou o id do projeto), a chave natural de cada registro entregue, eminstallation/manifests/recursos-<dono>.json; -
na entrega seguinte, o que saiu da lista do mesmo dono sai do banco:
status='D'quando a tabela tem status, senão o registro é apagado; -
registro editado online (
user_modified=1) não sai: vira choque de registro (db:<tabela>?<chave>), e "sobrescrever" aceita a retirada; -
valem só as tabelas de chave natural (páginas, layouts, componentes, variáveis, templates…). O core só retira registros sem
project, e o projeto só os dele. O que foi criado no painel nunca entrou numa lista, então nunca sai; -
o que a retirada marcou volta sozinho: o manifesto guarda, em
retirados, cada chave marcada e ostatusque o registro tinha. Quando o mesmo dono volta a entregar a chave, o registro retorna a essestatus. Só volta o que a própria rotina retirou; registro desativado por outra via nunca entra na lista; -
a primeira entrega de um dono numa tabela só grava a lista.
--dry-runsó simula;--no-resource-removal(noatualizacoes-banco-de-dados.php) desliga. A lista imperativadeletardoschema-metadata.jsoncontinua para casos pontuais.
Descida de arquivos (req-200). /_api/project/files compara disco e manifestos e permite baixar divergências. c2f project:recover-files usa o mesmo motor de três decisões quando o arquivo do projeto também mudou no repositório local; uma cópia baixada serve como versão nova e as decisões são registradas em temp/recover-files/.../relatorio.json. Arquivos do core e plugins ficam disponíveis para análise, sem serem aplicados ao projeto local.
Snapshot, verificação e rollback (req-198). Antes de aplicar, a atualização guarda em backups/atualizacoes/snapshots/exec-<id>/:
-
só os arquivos que vão ser sobrescritos ou removidos, a lista dos novos e os manifestos;
-
o dump do banco (
banco.sql.gz, pelomysqldump), antes da etapa de banco.
Depois, verifica se há erro fatal novo no logs/php-error.log e se a raiz do site responde abaixo de 500:
-
a requisição vai para
https://<domínio>/, pelo DNS normal e, se não conectar, por127.0.0.1; -
--health-url=<url>e--health-ip=<ip>(ouATUALIZACOES_SAUDE_URLeATUALIZACOES_SAUDE_IPno.env) apontam outro endereço, por exemplo um nginx numa porta interna; -
sem conexão em nenhuma tentativa, o HTTP fica como aviso e não reprova (o servidor pode escutar só no IP público);
-
espera 3 s antes da requisição, porque o OPcache do PHP-FPM ainda serve o código antigo por alguns segundos. Se a verificação falhar, os arquivos voltam sozinhos (código de saída 6). O banco só volta com decisão do operador:
--rollback=exec-<id> --com-banco.--rollback=exec-<id>sozinho volta só os arquivos;--no-healthe--no-rollbackdesligam a verificação ou a volta automática. Ficam os 5 snapshots mais recentes. O deploy de projeto por API faz o mesmo (snapshotsapi-…), e o rollback também pode ser disparado da máquina de desenvolvimento comc2f update:rollbackou porPOST /_api/project/rollback(BATCH-204). A atualização completa também pode ser disparada pela API, em segundo plano, com as mesmas opções e acompanhamento porrun-status(API do sistema, req-201).