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/commandsAtualiza 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.
| Campo | Tipo | Descrição |
|---|---|---|
start_command | string | Comando de inicialização, de 1 a 256 caracteres. |
pre_build_command | string | null | Comando executado antes do build, de 1 a 256 caracteres. null remove o comando. |
build_command | string | null | Comando de build, de 1 a 256 caracteres. null remove o comando. |
context_path | string | Diretó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
| HTTP | Quando ocorre |
|---|---|
400 | Corpo 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. |
401 | Credencial ausente ou inválida. |
403 | A credencial não tem project.source.update para o projeto. |
404 | O projeto não existe ou não está disponível para a organização atual. |
500 | A API não conseguiu salvar os comandos ou iniciar o build. |
Atualizar as configurações de deploy GitHub
PATCH /v1/project/:id/github/deploy-settingsEnvie 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.
| Campo | Tipo | Descrição |
|---|---|---|
auto_deploy | boolean | true seleciona Automático por branch. Essa opção não pode ficar ativa enquanto version_deploy.enabled for true. |
version_deploy | object | Configura 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.enabled | boolean | Habilita ou desabilita o modo por versão. |
version_deploy.event | tag | release | tag atualiza com uma nova tag; release atualiza quando uma release é publicada. |
version_deploy.tag_pattern | string | Padrã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_prereleases | boolean | Para 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:
| Modo | Corpo |
|---|---|
| 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
| HTTP | Quando ocorre |
|---|---|
400 | Corpo 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. |
401 | Credencial ausente ou inválida. |
403 | A credencial não tem project.source.update para o projeto. |
404 | O projeto não existe ou não está disponível para a organização atual. |
409 | A origem GitHub mudou durante a atualização das configurações; consulte os dados atuais do projeto e tente novamente. |
429 | O limite de 10 atualizações por minuto foi excedido. |
500 | A 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/deployLimite 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/buildsLimite 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/:buildIdLimite 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=200Limite 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/deployLimite de requisições: 10 por minuto (contado por IP de origem).
Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
branch | string | Não | Branch a ser usada no build. Quando omitida, a API usa a branch configurada no projeto |
commit_sha | string | Não | Commit 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/buildsLimite de requisições: 50 por minuto (contado por IP de origem).
Query
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | Página atual. Default 1 |
limit | number | Não | Tamanho da página. Default 10, máximo 50 |
branch | string | Não | Filtra por branch |
status | string | Não | Filtra 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/:buildIdLimite 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:
| Campo | Tipo | Descrição |
|---|---|---|
error_code | string | Código opcional que identifica uma causa conhecida |
error_message | string | Mensagem pública com o diagnóstico disponível |
diagnosis_status | string | Estado opcional do diagnóstico adicional: not_requested, available ou unavailable |
diagnosis_code | string | Motivo 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ódigo | Significado |
|---|---|
NPM_LOCKFILE_REQUIRED | O projeto Node.js não contém um package-lock.json utilizável no diretório esperado |
NPM_LOCKFILE_OUT_OF_SYNC | O package-lock.json não está sincronizado com o package.json |
GITHUB_COMMIT_UNAVAILABLE | O commit solicitado não está disponível no repositório e na branch selecionados |
GITHUB_REPOSITORY_AUTH_FAILED | A Zenifra não conseguiu acessar o repositório com a conexão GitHub atual |
NODE_BUILD_SCRIPT_MISSING | O build espera um script Node.js que não está declarado no package.json |
BUILD_FAILED_UNCLASSIFIED | A causa não pôde ser classificada automaticamente; consulte a mensagem e os Logs de Build |
GITHUB_REPOSITORY_REAUTHORIZATION_REQUIRED | A 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/logsLimite de requisições: 200 por minuto (contado por IP de origem).
Query
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
cursor | number | Não | Última sequência já consumida. Default 0 |
limit | number | Não | Quantidade 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
| Campo | Descrição |
|---|---|
logs | Lista incremental de linhas públicas do build |
next_cursor | Última sequência retornada |
status | Estado atual do build |
finished | true quando o build terminou com success ou failed |
truncated | true 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