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 production e sem state.instance, o passo 2 usa a primeira instancia declarada no .deploy.yml (deterministico desde a v2.55.2). Ainda assim, declare production ou registre com --instance para 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> --force deploya o pulado.

Funciona para source de branch e de tag (type: tag).

Exemplos

Verificar Atualizacoes

runner fetch

Output 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 atualizadas

Verificar e Deployar

runner fetch --deploy

Output JSON (para cron)

runner fetch --json

Forcar Atualizacao

runner fetch --force

Util quando o .deploy.yml no servidor esta desatualizado.

Verificar sem Baixar (dry-run)

runner fetch --check

Apenas 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ível

App Especifica

runner fetch /data/apps/meu-projeto

Verbose (debugging)

runner fetch --verbose

Processo de Fetch

  1. Lista apps registradas

    • Escaneia apps_path por diretorios com .deploy.yml
  2. Para cada app (ordenado alfabeticamente):

    • Se --force: git pull antes de ler config
    • Le .deploy.yml e estado
    • Compara commit local com remoto (via git fetch ou git ls-remote)
  3. 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 como needs_deploy
    • Isso garante recuperacao automatica de servicos caidos
  4. Se houver mudancas ou container ausente:

    • Com --deploy: executa deploy automaticamente
    • Sem --deploy: apenas reporta status
  5. 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 --deploy

Antes 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>&1

Ou 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 --force

Quando usar:

  • Apos migrar formato do .deploy.yml
  • Quando o servidor esta com config desatualizada
  • Resolver problemas de parsing

O que faz:

  1. Detecta branch dist do estado salvo (ou usa "dist")
  2. Executa git pull origin {branch} antes de ler config
  3. Se houver conflitos, faz git reset --hard origin/{branch}
  4. 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-projeto

Integracao com runner serve

Em vez de cron, considere usar:

runner serve

Que 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ó: -x

Em 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
By Borlot.com.br on 16/02/2026