runner fetch
Verifica atualizacoes nas apps registradas e opcionalmente executa deploy.
Sintaxe
runner fetch [OPTIONS] [APP_PATH]Parametros
| Parametro | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
APP_PATH |
path | Nao | Caminho de uma app especifica |
Opcoes
| Opcao | Tipo | Default | Descricao |
|---|---|---|---|
--deploy, -d |
flag | - | Executa deploy automatico se houver mudancas |
--json |
flag | - | Output em formato JSON |
--force, -F |
flag | - | Forca git pull antes de carregar config |
--check, -C |
flag | - | Apenas verifica, nao baixa (dry-run) |
--verbose, -v |
flag | - | Output detalhado (logs INFO) |
--quiet, -q |
flag | - | Output silencioso (apenas erros) |
--skip-last |
flag | - | (v2.61.0+) Marca a alteracao pendente como JA CONSIDERADA sem deployar. Requer <app>; conflita com --deploy/--check. Ver secao abaixo |
-x, --exact |
flag | - | Desliga a resolucao por query: um alvo so |
-y, --yes |
flag | - | Confirma quando a query casa varios alvos do mesmo projeto. Nao autoriza atravessar projetos |
Qual instancia o `--deploy` deploya
Com --deploy, a instancia e resolvida nesta ordem — a primeira que existir vence:
| Prioridade | Consulta | Fonte |
|---|---|---|
| 1 | state.instance |
state do registro (/opt/runner/state/<app>.yml), fixado por runner add --instance <N> |
| 2 | default do manifesto | .deploy.yml: production se declarada, senao a primeira instancia |
| 3 | production (literal) |
fallback quando o manifesto nao declara instancias |
runner fetch --deploy sempre honrou o passo 1. Desde a v2.55.1, runner deploy e runner deploy --all usam a mesma resolucao.
Sem
productione semstate.instance, o passo 2 usa a primeira instancia declarada no.deploy.yml(deterministico desde a v2.55.2). Ainda assim, declareproductionou registre com--instancepara deixar explicito.
Pular uma alteracao sem deployar (`--skip-last`, v2.61.0+)
Fez um push que NAO quer deployar (docs, config de CI, ajuste que nao muda runtime)? Marque-o como considerado:
runner fetch meu-app --skip-last
# ⏭ meu-app: alteracao c14b621 PULADA — marcada como considerada, sem deploy.- O cron (
fetch --deploy) passa a ver atualizado e nao sobe aquela alteracao. - Um novo push diverge de novo → volta a "disponivel" → deploya normal.
- Mudou de ideia?
runner deploy <app> --forcedeploya o pulado.
Funciona para source de branch e de tag (type: tag).
Exemplos
Verificar Atualizacoes
runner fetchOutput ordenado alfabeticamente por projeto/sistema:
Runner v1.2.0
Verificando 7 app(s)...
✓ auth/api - atualizado
✓ cdn-front/front v2.6.0 atualizado
✓ cdn-sys/sys - atualizado
✓ app/front v1.0.2 atualizado
✓ app/sys v1.0.0 atualizado
✓ app/worker - atualizado
✓ runner-docs/front - atualizado
✓ 7 apps atualizadasVerificar e Deployar
runner fetch --deployOutput JSON (para cron)
runner fetch --jsonForcar Atualizacao
runner fetch --forceUtil quando o .deploy.yml no servidor esta desatualizado.
Verificar sem Baixar (dry-run)
runner fetch --checkApenas verifica se ha atualizacoes disponiveis, sem fazer git pull.
Mostra status disponivel para apps com updates no remoto.
↑ │ meu-app/sys │ dist │ v1.0.0 │ abc123 │ v1.0.0 │ def456 │ disponívelApp Especifica
runner fetch /data/apps/meu-projetoVerbose (debugging)
runner fetch --verboseProcesso de Fetch
Lista apps registradas
- Escaneia
apps_pathpor diretorios com.deploy.yml
- Escaneia
Para cada app (ordenado alfabeticamente):
- Se
--force:git pullantes de ler config - Le
.deploy.ymle estado - Compara commit local com remoto (via
git fetchougit ls-remote)
- Se
Verifica estado do container
- Mesmo com git em dia, verifica se o container esta rodando
- Se o container morreu ou foi removido (
docker rm -f), marca comoneeds_deploy - Isso garante recuperacao automatica de servicos caidos
Se houver mudancas ou container ausente:
- Com
--deploy: executa deploy automaticamente - Sem
--deploy: apenas reporta status
- Com
Atualiza estado
- Registra timestamp do fetch
- Registra versao encontrada
- Salva em
/opt/runner/state/{app}.yml
Deteccao de Container Morto (v1.3.3)
O fetch verifica nao apenas a versao do codigo, mas tambem se o container esta vivo. Cenarios detectados:
| Cenario | Git | Container | Status |
|---|---|---|---|
| Tudo ok | em dia | healthy | up_to_date |
| Codigo novo | desatualizado | qualquer | needs_update |
| Container morto | em dia | ausente | needs_deploy |
| Container errado | em dia | versao diferente | needs_deploy |
Isso permite crash recovery completo com um unico comando:
# Container morreu? fetch --deploy detecta e recupera
runner fetch --deployAntes da v1.3.3, se o container morresse mas o codigo nao mudasse, o fetch dizia "up_to_date" e nao deployava. Agora detecta a ausencia do container e aciona o deploy automaticamente.
Output
Indicadores Visuais
| Simbolo | Cor | Status | Significado |
|---|---|---|---|
✓ |
Verde | atualizado | App atualizada, nenhuma acao necessaria |
↑ |
Amarelo | desatualizado | Container desatualizado em relacao ao repo |
↑ |
Amarelo | disponivel | Update disponivel no remoto (--check mode) |
↓ |
Ciano | baixado | Artefatos baixados com sucesso |
✗ |
Vermelho | erro | Erro durante o processo |
- |
Dim | sem git | Diretorio sem repositorio git |
Output JSON
{
"timestamp": "2026-02-16T10:30:00Z",
"total": 7,
"updated": 1,
"up_to_date": 5,
"errors": 1,
"no_git": 0,
"deployed": 0,
"apps": [
{
"app_name": "auth_api",
"app_path": "/data/apps/auth_api",
"project": "auth",
"system": "api",
"current_version": "v1.0.0",
"new_version": null,
"has_updates": false,
"pulled": false,
"deployed": false,
"status": "up_to_date",
"error": null
},
{
"app_name": "cdn_front",
"app_path": "/data/apps/cdn_front",
"project": "cdn-front",
"system": "front",
"current_version": "v2.6.0",
"new_version": "v2.7.0",
"has_updates": true,
"pulled": true,
"deployed": false,
"status": "updated",
"error": null
}
]
}Configuracao de Cron
Recomendado executar a cada 5 minutos:
# crontab -e
*/5 * * * * /opt/runner/runner fetch --deploy --json >> /var/log/runner-fetch.json 2>&1Ou use runner serve para webhook + canary scheduler integrados.
Log de Fetch
O Runner mantem um log em /opt/runner/logs/fetch-audit.json:
{"timestamp":"2026-02-16T10:30:00Z","total":7,"updated":1,"up_to_date":5,"errors":1,"no_git":0,"deployed":0}Estados de App
| Status (interno) | Display | Descricao |
|---|---|---|
up_to_date |
atualizado | Nenhuma atualizacao disponivel |
updated |
baixado | Artefatos baixados (git pull executado) |
needs_deploy |
desatualizado | Atualizacao disponivel no remoto |
deployed |
implantado | Atualizado e deployado |
error |
erro | Erro durante o processo |
no_git |
sem git | Sem diretorio .git |
Exit Codes
| Codigo | Significado |
|---|---|
| 0 | Sucesso (com ou sem deploys) |
| 1 | Erro ao acessar alguma app |
Flag --force
A flag --force (-F) executa git pull antes de carregar o .deploy.yml:
runner fetch --forceQuando usar:
- Apos migrar formato do
.deploy.yml - Quando o servidor esta com config desatualizada
- Resolver problemas de parsing
O que faz:
- Detecta branch dist do estado salvo (ou usa "dist")
- Executa
git pull origin {branch}antes de ler config - Se houver conflitos, faz
git reset --hard origin/{branch} - Continua com fetch normal
Dicas
Verificar Log de Fetch
tail -50 /opt/runner/logs/fetch-audit.json | jq .Fetch Manual de App Especifica
Para forcar update de uma app:
runner fetch --force /data/apps/meu-projetoIntegracao com runner serve
Em vez de cron, considere usar:
runner serveQue combina:
- Webhook server para eventos GitHub
- Canary scheduler para auto-promocao
Multiplos alvos e a fronteira do projeto (v2.80.0+)
<app> nao e um nome exato: e uma query, casada por segmento. runner fetch ccs
alcanca ccs/sys, ccs/front e ccs/worker — replicar o comando nos sistemas de um
projeto e o desenho do runner, nao um acidente.
| Situacao | Comportamento |
|---|---|
| 1 alvo | Executa direto, sem cerimonia |
| N alvos, mesmo projeto | Lista os alvos e pede confirmacao. -y, --yes dispensa |
| N alvos, projetos distintos | Terminal: pergunta. Cron/CI (sem TTY): aborta com exit != 0. Nenhuma flag autoriza |
O "projeto" aqui e a raiz antes do primeiro hifen: ccs-front e ccs-sys sao o
mesmo projeto (ccs); ccs-front e nfse-front nao sao.
Por que `--yes` nao autoriza atravessar
--yes e passado por habito, em script e cron. Se valesse para o cruzamento, o gate
morreria exatamente onde ninguem esta olhando. Uma query casa por segmento e deveria
cair dentro de uma familia — atravessar e anomalia, nao intencao.
ERROR fetch atravessa 2 projetos (ccs, nfse) em 4 alvos:
- ccs/sys
- ccs/front
- nfse/sys
- nfse/front
Uma query casa por segmento e deveria cair dentro de UMA família — atravessar aqui é anomalia, não intenção, e por isso nenhuma flag autoriza.
Este comando não opera em massa entre projetos: rode um projeto por vez.
Para um alvo só: -xEm terminal interativo o cruzamento pergunta em vez de abortar. Em cron/CI (sem TTY) aborta com exit != 0.
Saidas:
-x, --exact— desliga a query e mira um alvo so- rodar um projeto por vez