Builds de repositórios Git

Use estas rotas para disparar builds de repositórios Git manualmente, consultar o histórico e ler logs incrementais. Os nomes antigos de rota continuam disponíveis para projetos GitHub existentes.

Permissões necessárias

Use project.deploy.trigger em project:<project-id> para disparar um deploy e project.logs.read para consultar builds e logs. Configuração da origem e dos comandos exige project.source.update. owner tem acesso completo; assistant, member e API Keys precisam do grant correspondente.

Atualizar os comandos e o diretório raiz GitHub

PATCH /v1/project/:id/github/commands

Atualiza os comandos e o diretório raiz de um projeto GitHub e inicia um novo build. Exige project.source.update. Envie ao menos um dos campos abaixo; os campos omitidos mantêm o valor atual.

CampoTipoDescrição
start_commandstringComando de inicialização, de 1 a 256 caracteres.
pre_build_commandstring | nullComando executado antes do build, de 1 a 256 caracteres. null remove o comando.
build_commandstring | nullComando de build, de 1 a 256 caracteres. null remove o comando.
context_pathstringDiretório raiz do build, relativo à raiz do repositório. Padrão ".". Segue as regras de Diretório raiz do build.
{
  "start_command": "npm start",
  "build_command": "npm run build",
  "context_path": "apps/api"
}

Resposta

{
  "status": "success",
  "message": "GitHub commands updated and build triggered successfully",
  "data": {
    "build_id": "6650f1a2b3c4d5e6f7a8b9c1"
  }
}

A resposta 202 traz o build_id do build iniciado; acompanhe-o com as rotas de builds abaixo.

Erros

HTTPQuando ocorre
400Corpo vazio, comando fora do limite, context_path inválido (caminho absoluto, .., barra invertida ou mais de 256 caracteres) ou projeto sem repositório GitHub conectado.
401Credencial ausente ou inválida.
403A credencial não tem project.source.update para o projeto.
404O projeto não existe ou não está disponível para a organização atual.
500A API não conseguiu salvar os comandos ou iniciar o build.

Atualizar as configurações de deploy GitHub

PATCH /v1/project/:id/github/deploy-settings

Envie ao menos um dos campos abaixo. As propriedades informadas são aplicadas às configurações atuais; ao atualizar um modo, a combinação final é validada.

CampoTipoDescrição
auto_deploybooleantrue seleciona Automático por branch. Essa opção não pode ficar ativa enquanto version_deploy.enabled for true.
version_deployobjectConfigura os modos Por Tag e Por Release. Com enabled: false, os padrões dos demais campos são event: "tag", tag_pattern: "*" e include_prereleases: false. A ausência desse objeto em configurações antigas mantém o comportamento legado, sem ativar tags ou releases.
version_deploy.enabledbooleanHabilita ou desabilita o modo por versão.
version_deploy.eventtag | releasetag atualiza com uma nova tag; release atualiza quando uma release é publicada.
version_deploy.tag_patternstringPadrão obrigatório ao habilitar o modo por versão. Corresponde ao nome completo da tag, diferencia maiúsculas de minúsculas e aceita de 1 a 255 caracteres.
version_deploy.include_prereleasesbooleanPara event: "release", permite incluir pré-releases. O padrão é false; rascunhos não iniciam publicações.

O padrão aceita apenas * (qualquer sequência de caracteres) e ? (um caractere). Por exemplo, v* corresponde a v1.2.0; classes como [12], caracteres de controle e outras sintaxes de glob não são aceitos. No modo tag, somente a criação de uma tag inicia a publicação; alterações e exclusões de tags não iniciam publicações.

Os modos são exclusivos. Para alternar da forma atual, envie as propriedades necessárias para deixar o estado final em um único modo. Estes exemplos mostram o corpo completo para cada opção:

ModoCorpo
Manual{"auto_deploy":false,"version_deploy":{"enabled":false,"event":"tag","tag_pattern":"*","include_prereleases":false}}
Automático por branch{"auto_deploy":true,"version_deploy":{"enabled":false,"event":"tag","tag_pattern":"*","include_prereleases":false}}
Por Tag{"auto_deploy":false,"version_deploy":{"enabled":true,"event":"tag","tag_pattern":"v*","include_prereleases":false}}
Por Release{"auto_deploy":false,"version_deploy":{"enabled":true,"event":"release","tag_pattern":"v*","include_prereleases":false}}

Exemplo de solicitação para publicar quando uma nova tag v* for criada:

PATCH /v1/project/507f1f77bcf86cd799439011/github/deploy-settings
Content-Type: application/json
{
  "auto_deploy": false,
  "version_deploy": {
    "enabled": true,
    "event": "tag",
    "tag_pattern": "v*",
    "include_prereleases": false
  }
}

Resposta

Por brevidade, este exemplo mostra os campos públicos relacionados à forma de atualização; a resposta também pode incluir runtime e comandos configurados no projeto.

{
  "status": "success",
  "message": "GitHub deploy settings updated successfully",
  "data": {
    "repository_owner": "example-org",
    "repository_name": "web-app",
    "branch": "main",
    "auto_deploy": false,
    "version_deploy": {
      "enabled": true,
      "event": "tag",
      "tag_pattern": "v*",
      "include_prereleases": false
    }
  }
}

data contém a configuração pública do GitHub. Configurações antigas podem não incluir version_deploy; sem esse objeto, publicações por tag e release ficam desativadas, e auto_deploy indica se o projeto usa o modo manual ou automático por branch.

Erros

HTTPQuando ocorre
400Corpo vazio, padrão inválido, modos contraditórios (por exemplo, auto_deploy: true com version_deploy.enabled: true) ou necessidade de reconectar o repositório GitHub antes de habilitar tags ou releases.
401Credencial ausente ou inválida.
403A credencial não tem project.source.update para o projeto.
404O projeto não existe ou não está disponível para a organização atual.
409A origem GitHub mudou durante a atualização das configurações; consulte os dados atuais do projeto e tente novamente.
429O limite de 10 atualizações por minuto foi excedido.
500A API não conseguiu salvar as configurações.

Estes logs são diferentes de GET /v1/project/:id/logs, que retorna logs da aplicação em execução. As rotas de build retornam o histórico e os logs da publicação.

Rotas neutras para builds Git

Use as rotas abaixo para projetos com uma origem Git. Os envelopes de resposta mantêm os campos públicos de build e logs existentes.

Disparar um deploy manual

POST /v1/project/:id/deploy

Limite de requisições: 10 por minuto (contado por IP de origem).

O corpo aceita branch e commit_sha, ambos opcionais; commit_sha deve ter 40 ou 64 caracteres hexadecimais. Sem substituição, o projeto usa sua branch configurada. A resposta é 202:

{
  "status": "success",
  "message": "Build triggered successfully",
  "data": {
    "build_id": "665f1f77bcf86cd799439011"
  }
}

Listar builds

GET /v1/project/:id/builds

Limite de requisições: 60 por minuto (contado por IP de origem).

Os parâmetros opcionais são page, limit, branch e status.

{
  "status": "success",
  "data": [],
  "pagination": {
    "total": 0,
    "page": 1,
    "limit": 10
  }
}

Consultar um build

GET /v1/project/:id/builds/:buildId

Limite de requisições: 60 por minuto (contado por IP de origem).

A resposta usa { "status": "success", "data": Build }. Os campos de build permanecem os campos públicos existentes; as respostas não incluem credenciais nem identificadores internos da origem.

Consultar logs incrementais

GET /v1/project/:id/builds/:buildId/logs?cursor=0&limit=200

Limite de requisições: 120 por minuto (contado por IP de origem).

cursor e limit são valores numéricos. A resposta contém os chunks novos, o próximo cursor e o estado atual:

{
  "status": "success",
  "data": {
    "logs": [],
    "next_cursor": 0,
    "status": "building",
    "finished": false,
    "truncated": false
  }
}

Use next_cursor na chamada seguinte para buscar apenas novas linhas. finished indica que a build chegou ao estado final; truncated informa quando o log público foi limitado.

Rotas de compatibilidade para GitHub

As rotas /github/* abaixo mantêm a compatibilidade com projetos GitHub existentes. Para uma origem genérica Git, use as rotas neutras desta página.

Disparar build manual

POST /v1/project/:id/github/deploy

Limite de requisições: 10 por minuto (contado por IP de origem).

Body

CampoTipoObrigatórioDescrição
branchstringNãoBranch a ser usada no build. Quando omitida, a API usa a branch configurada no projeto
commit_shastringNãoCommit específico para disparar a build (40 caracteres hexadecimais)

Resposta

A resposta é 202:

{
  "status": "success",
  "message": "Build triggered successfully",
  "data": {
    "build_id": "665f1f77bcf86cd799439011"
  }
}

Listar builds do projeto

GET /v1/project/:id/github/builds

Limite de requisições: 50 por minuto (contado por IP de origem).

Query

CampoTipoObrigatórioDescrição
pagenumberNãoPágina atual. Default 1
limitnumberNãoTamanho da página. Default 10, máximo 50
branchstringNãoFiltra por branch
statusstringNãoFiltra por pending, building, success ou failed

Resposta

{
  "status": "success",
  "message": "builds listed successfully",
  "data": [
    {
      "id": "665f1f77bcf86cd799439011",
      "commit_sha": "abc123def456789012345678901234567890abcd",
      "branch": "main",
      "status": "failed",
      "started_at": "2026-06-03T14:10:00.000Z",
      "finished_at": "2026-06-03T14:11:09.000Z",
      "error_code": "NPM_LOCKFILE_REQUIRED",
      "error_message": "O package-lock.json não foi encontrado no diretório raiz da aplicação.",
      "triggered_by": "manual",
      "created_at": "2026-06-03T14:10:00.000Z",
      "updated_at": "2026-06-03T14:11:09.000Z"
    }
  ],
  "pagination": {
    "total": 12,
    "page": 1,
    "limit": 10
  }
}

Obter um build específico

GET /v1/project/:id/github/builds/:buildId

Limite de requisições: 50 por minuto (contado por IP de origem).

Resposta

{
  "status": "success",
  "message": "build retrieved successfully",
  "data": {
    "id": "665f1f77bcf86cd799439011",
    "commit_sha": "abc123def456789012345678901234567890abcd",
    "branch": "main",
    "status": "failed",
    "started_at": "2026-06-03T14:10:00.000Z",
    "finished_at": "2026-06-03T14:11:09.000Z",
    "error_code": "NPM_LOCKFILE_REQUIRED",
    "error_message": "O package-lock.json não foi encontrado no diretório raiz da aplicação.",
    "triggered_by": "manual",
    "created_at": "2026-06-03T14:10:00.000Z",
    "updated_at": "2026-06-03T14:10:00.000Z"
  }
}

Campos de falha

Os códigos abaixo documentam as rotas de compatibilidade GitHub. As rotas neutras podem acrescentar códigos genéricos de build; clientes devem manter error_message como fallback.

As respostas de listagem e detalhe podem incluir estes campos quando uma build falha:

CampoTipoDescrição
error_codestringCódigo opcional que identifica uma causa conhecida
error_messagestringMensagem pública com o diagnóstico disponível
diagnosis_statusstringEstado opcional do diagnóstico adicional: not_requested, available ou unavailable
diagnosis_codestringMotivo opcional de indisponibilidade do diagnóstico adicional

Builds antigas podem não ter error_code. Clientes da API devem usar error_message como fallback quando error_code estiver ausente ou não for reconhecido. O texto e o idioma de error_message não são um contrato estável de localização; clientes devem preferir error_code para apresentar mensagens traduzidas.

Os códigos conhecidos são:

CódigoSignificado
NPM_LOCKFILE_REQUIREDO projeto Node.js não contém um package-lock.json utilizável no diretório esperado
NPM_LOCKFILE_OUT_OF_SYNCO package-lock.json não está sincronizado com o package.json
GITHUB_COMMIT_UNAVAILABLEO commit solicitado não está disponível no repositório e na branch selecionados
GITHUB_REPOSITORY_AUTH_FAILEDA Zenifra não conseguiu acessar o repositório com a conexão GitHub atual
NODE_BUILD_SCRIPT_MISSINGO build espera um script Node.js que não está declarado no package.json
BUILD_FAILED_UNCLASSIFIEDA causa não pôde ser classificada automaticamente; consulte a mensagem e os Logs de Build
GITHUB_REPOSITORY_REAUTHORIZATION_REQUIREDA Zenifra não conseguiu renovar o acesso ao mesmo repositório; reconecte-o no projeto

AI_DIAGNOSIS_UNAVAILABLE e AI_DIAGNOSIS_MISCONFIGURED podem aparecer somente em diagnosis_code. Eles descrevem o diagnóstico adicional e nunca substituem error_code, que representa a causa principal disponível.

Para corrigir erros de lockfile e validar os comandos Node.js, consulte Dependências Node.js.

Obter logs incrementais do build

GET /v1/project/:id/github/builds/:buildId/logs

Limite de requisições: 200 por minuto (contado por IP de origem).

Query

CampoTipoObrigatórioDescrição
cursornumberNãoÚltima sequência já consumida. Default 0
limitnumberNãoQuantidade máxima de chunks. Default 200, máximo 500

Resposta

{
  "status": "success",
  "message": "build logs retrieved successfully",
  "data": {
    "logs": [
      {
        "sequence": 1,
        "timestamp": "2026-06-03T14:10:01.000Z",
        "level": "info",
        "step": "build",
        "message": "npm ci",
        "final": false
      }
    ],
    "next_cursor": 1,
    "status": "building",
    "finished": false,
    "truncated": false
  }
}

Use next_cursor na próxima chamada para buscar apenas novas linhas.

Como interpretar

CampoDescrição
logsLista incremental de linhas públicas do build
next_cursorÚltima sequência retornada
statusEstado atual do build
finishedtrue quando o build terminou com success ou failed
truncatedtrue quando o log público foi truncado para proteger a estabilidade da plataforma

Retenção

O histórico de builds GitHub é mantido por até:

  • 30 builds por projeto
  • 30 dias de idade

O que vencer primeiro remove os registros mais antigos, junto com os chunks de log associados.

Exemplo de polling

curl -X GET "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011/github/builds/665f1f77bcf86cd799439011/logs?cursor=0&limit=200" \
  -H "x-api-key: sua-api-key" \
  -H "x-organization-id: sua-organization-id"

Próximos passos

Última atualização em

Nessa página