GitHub torna GA a API de merge assíncrono e muda o retry de CI/CD em Python, Node e Go
A API de merge assíncrono do GitHub, liberada em disponibilidade geral em 1º de outubro de 2026, troca a resposta imediata de merge por um request ID que precisa ser consultado via polling, exigindo ajuste em scripts de CI/CD que ainda dependem do comportamento síncrono antigo.

O que a API assíncrona de merge faz diferente
Em 1º de outubro de 2026, o GitHub anunciou no changelog oficial que a API assíncrona de merge saiu do preview e virou disponibilidade geral (GA). Ela serve para mergear pull requests individuais, PRs empilhados (stacked), ou adicionar um PR a uma merge queue, com opção de pular regras de proteção quando o chamador tem permissão para isso.

O fluxo muda de forma concreta. Em vez de uma chamada síncrona que devolve o resultado do merge na mesma resposta, o padrão agora é submeter a requisição com PUT e receber de volta um request ID; o status real do merge só aparece depois, numa chamada GET separada usando esse ID. O GitHub descreve o motivo assim:
A API processa merges de forma assíncrona, ajudando as automações a lidar com repositórios movimentados sem esperar que merges complexos terminem em uma única requisição.
The API processes merges asynchronously, helping your automations handle busy repositories without waiting for complex merges to finish in a single request.GitHub Changelog
O changelog também deixa claro que essa é agora a via recomendada para mergear PRs programaticamente, no lugar do endpoint REST síncrono e da mutation GraphQL mergePullRequest que a maioria das integrações usa hoje. É, segundo o próprio anúncio, a única API de merge que suporta PRs empilhados.
Da resposta imediata ao request ID: o que quebra em quem já automatiza merge
O ponto que o changelog não detalha, e que importa para quem mantém pipeline, é o seguinte: trocar o endpoint sem mudar a lógica do script não falha com um erro óbvio, falha de forma silenciosa. Muita automação de CI/CD↳CI/CD23 conteúdosCI/CD Mobile: o caos invisível que separa times comuns de times de alta performanceDev (Back & Front) · abr 2026Lambda: implementando com GitLab CI/CD e Terraform para Integração SFTP, S3 e Databricks em GoDev (Back & Front) · nov 2023Publicando sua aplicação Web Python no WebApp do Azure e configurando o CI/CD da sua aplicaçãoDevSecOps · abr 2019Ver tudo em DevSecOps → em produção hoje assume que a resposta do merge vem pronta na mesma chamada: o script lê um campo como merged no corpo JSON e segue o pipeline a partir dali.
Isso vale tanto para scripts caseiros em Python↳Python56 conteúdosVSCode + Python + Alexa: Desenvolva e teste skills para alexa localmente com pythonDev (Back & Front) · out 2025Dominando decoradores em Python: um guia completo com exemplosDev (Back & Front) · jan 2025Desenvolvimento de software: diferenças entre Python, JavaScript e JavaGestão Dev & TI · nov 2024Ver tudo em Dev (Back & Front) → usando requests quanto para integrações em Node.js via Octokit e em Go via go-github. Muitos desses scripts já têm sua própria camada de retry construída por cima do endpoint síncrono: capturam um 405 quando a branch base mudou, esperam alguns segundos e tentam de novo, ou fazem polling manual no estado do PR via webhook de pull_request com evento closed.
Com a API assíncrona, esse retry caseiro perde o sentido e pode até conflitar com o novo fluxo. A resposta do PUT não é mais o resultado do merge, é só a confirmação de que a requisição foi aceita. Quem não adaptar o parsing vai simplesmente nunca encontrar o campo que esperava, e o pipeline segue adiante achando que o merge não aconteceu (ou aconteceu, dependendo de como o try/except foi escrito).
Como fica o polling na prática
A chamada exata e os nomes de campo estão na documentação linkada no próprio changelog, mas o padrão que toda automação precisa implementar é o mesmo nas três linguagens: submeter, guardar o ID, consultar em loop até sair do estado pendente.
Em Python, o esqueleto fica assim:
import requests, time
resp = requests.put(merge_endpoint, headers=headers, json=payload)
request_id = resp.json()["id"]
while True:
status = requests.get(f"{merges_endpoint}/{request_id}", headers=headers).json()
if status["state"] in ("success", "failed"):
break
time.sleep(2)Em Node.js, com Octokit, a diferença é a mesma: a chamada de merge não resolve mais com o PR mergeado, resolve com um ID que alimenta um setInterval ou uma função de polling com backoff exponencial. Em Go, quem usa go-github precisa trocar a checagem do retorno de PullRequests.Merge() por um loop que consulta o endpoint de status repetidamente, geralmente dentro de um context.WithTimeout para não rodar para sempre.
Em resumo: o código de negócio (decidir squash, rebase ou merge commit) não muda. O que muda é a camada de orquestração em volta da chamada, que agora precisa de um laço de consulta com timeout, e não de uma leitura direta de resposta.
Stacked PRs e merge queue: quando o assíncrono compensa de verdade
O changelog é explícito num ponto que justifica a migração para quem usa certos workflows: a API assíncrona é a única que mergeia PRs empilhados. Times que trabalham com stacks de PRs dependentes entre si (um padrão comum em fluxos de trunk-based development com ferramentas como Graphite) não tinham, até agora, um jeito oficial de mergear a cadeia inteira numa chamada só pela API REST ou GraphQL.
O mesmo vale para quem usa merge queue de forma intensiva em repositórios com muito tráfego de PRs simultâneos. Nesses casos, esperar uma chamada síncrona terminar significa segurar a conexão aberta enquanto o GitHub resolve conflitos, reexecuta checks e processa a fila, o que é exatamente o cenário que a API assíncrona foi desenhada para não bloquear.
Quando não vale a pena trocar
Nem toda automação precisa migrar agora. Para quem mantém um repositório pequeno, sem merge queue e sem PRs empilhados, e só automatiza um merge simples (por exemplo, auto-merge de PR do Dependabot depois que os checks passam), o endpoint REST síncrono e a mutation GraphQL continuam funcionando e são mais simples de manter: uma chamada, uma resposta, sem laço de polling para escrever e testar.
A tabela resume o trade-off:
| Cenário | Vale migrar para o async |
|---|---|
| PRs empilhados (stacked) | Sim, é a única API que suporta |
| Merge queue com tráfego alto | Sim, evita conexão bloqueada |
| Merge simples, repo de baixo tráfego | Não necessariamente, sync ainda resolve |
Script legado lendo merged na resposta | Precisa reescrever antes de trocar |
Para quem decidir migrar, o caminho prático é auditar todo script que lê o corpo da resposta de merge esperando o resultado final, trocar essa leitura por um laço de GET com backoff e teto de tentativas, e só então apontar a chamada de escrita para o novo endpoint assíncrono. Pular essa auditoria é a forma mais comum de transformar uma atualização recomendada pelo GitHub num pipeline que trava sem aviso.
Fonte: GitHub Changelog
Este artigo foi escrito por Bisneto Braga, colunista de back-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
PostgreSQL 18 tem uuidv7 nativo para reduzir o index bloat do UUID aleatório
PostgreSQL 18 tem uuidv7 nativo para reduzir o index bloat do UUID aleatório















