Communitygithub.com

desempilhar-prs-empilhados

Desfaz uma cadeia de PRs empilhados (cada PR baseado no branch do PR anterior) e os integra no branch base (develop/main/master) uma camada de cada vez, sem precisar de uma lista de permissões de CI para branches intermediários. Lida com pilhas nativas do GitHub via a API merge-async. Aciona em: integrar a pilha, desfazer os PRs empilhados, mesclar a pilha de PRs no develop, redirecionar a pilha para main, parte de uma pilha, merge-async, auto-merge não é suportado para pull requests empilhados.

O que é desempilhar-prs-empilhados?

Esta skill automatiza o processo de integrar uma cadeia de Pull Requests empilhados (stacked PRs) no branch base do repositório. Em vez de mesclar cada PR em seu branch predecessor, ela retargeta cada camada diretamente para o branch base (como develop ou main) uma por vez, garantindo que a validação do CI seja feita contra as regras de proteção do branch base e não contra branches intermediários. A skill também lida com pilhas nativas do GitHub usando a API `merge-async`, que é necessária quando o GitHub impede operações padrão como `gh pr edit --base`. Ela executa uma série de passos: estabelece a ordem de mesclagem baseada em dependências reais, detecta conflitos contra o base, sincroniza o base em cada camada, aguarda o CI e realiza o merge de forma segura. É útil para desenvolvedores que trabalham com fluxos de PRs encadeados e precisam de uma automação confiável para integrá-los sem quebrar a cadeia ou exigir configurações especiais de CI para branches intermediários. Funciona com qualquer repositório GitHub que use o sistema de branches e PRs padrão, com suporte adicional para o recurso nativo de pilhas do GitHub.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sblattj/agent-chandlery/tree/main/skills/landing-stacked-prs

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Integrando PRs empilhados no branch base

Use quando vários PRs estão encadeados (PR N baseado no branch do PR N-1) e precisam chegar ao branch base real. O princípio chave: o CI do branch intermediário não é o portão. A proteção do branch base é. Então, redirecione cada camada para o base bem a tempo e deixe o CI nativo validá-lo. Nunca dependa de nomes de branches intermediários codificados em gatilhos de CI.

Repositório: passe -R owner/repo para gh, ou execute a partir do clone (gh repo view --json nameWithOwner -q .nameWithOwner resolve). Abaixo, R é esse owner/repo.

Princípios

  • A ordem de mesclagem é ditada por dependências reais (dependências de conteúdo + arquivos editados por mais de uma camada). Estabeleça essa ordem primeiro; não reordene para ser conveniente.
  • Apenas mescle uma camada no branch base, uma de cada vez. Nunca mescle um filho no seu antigo branch pré-requisito.
  • Antes que o CI de uma camada seja relevante, mescle o base atual nessa camada para que seu diff se reduza a apenas sua própria mudança e ela veja tudo já integrado.
  • O branch de ponta contém cada camada cumulativamente; uma execução de CI na ponta (redirecionada para o base) valida toda a pilha montada. Use-a como uma verificação prévia opcional.

Passo 0: estabelecer ordem e detectar conflitos

Resolva o base real do repositório (branch padrão do remote git, ex.: develop ou main; o arquivo de instruções do agente do usuário (AGENTS.md / CLAUDE.md) pode nomear bases conhecidas). Para cada PR, teste conflitos contra o base, não contra seu base empilhado obsoleto (que lerá LIMPO e enganará você):

git fetch origin <base> <head> --quiet
git merge-tree --write-tree origin/<base> origin/<head> | grep -iE 'CONFLICT|changed in both' || echo "limpo vs base"

Regra prática de ordem: conteúdo pré-requisito antes do portão que precisa dele (ex.: limpeza de lint antes de habilitar lint); quando duas camadas editam o mesmo arquivo, a primeira mescla primeiro.

Passo 1..N: por camada, em ordem

PR=<numero>
gh pr edit $PR -R $R --base <base>     # redirecionar do branch empilhado
# uma worktree separada para o branch head mantém seu checkout principal limpo:
WT=../<repo>-<head>                    # qualquer caminho fora do seu checkout principal
git worktree add "$WT" <head> 2>/dev/null || true
git -C "$WT" fetch origin --quiet
git -C "$WT" merge origin/<base>       # sincronizar o base; resolver conflitos (veja abaixo)
git -C "$WT" push
gh pr ready $PR -R $R                  # quando é a camada ativa
gh pr checks $PR -R $R --watch         # CI nativo, base=<base>
# após aprovação da revisão apenas:
gh pr merge $PR -R $R --squash --delete-branch
# então vá para a próxima camada (seu redirecionamento+sincronização de base absorverá esta)

Pilhas nativas do GitHub (merge-async)

Um PR feito com o recurso de pilha nativa do GitHub recusa os passos clássicos acima:

  • gh pr edit --base: GraphQL: Cannot change the base branch because the pull request is part of a stack. (updatePullRequest)
  • gh pr merge --auto: GraphQL: Auto-merge is not supported for stacked pull requests.
  • gh pr merge: This pull request is part of a stack and must be merged using the asynchronous merge REST API.

Use a API assíncrona, primeiro o PR inferior (o GitHub redireciona o próximo para o base sozinho, aguarde ~30s):

sha=$(gh pr view $PR -R $R --json headRefOid -q .headRefOid)
u=$(gh api -X PUT repos/$R/pulls/$PR/merge-async -f merge_method=squash -f sha=$sha \
      -f merge_action=direct_merge --jq '.details.uuid // .status')
gh api repos/$R/pulls/$PR/merge-async/$u --jq '.status+" "+(.details.message//"")'   # poll até não ser "pending"
  • Mesclar um PR empilhado dessa forma também mescla cada PR aberto abaixo dele, então mescle apenas a camada que você pretende integrar.
  • Após cada squash, a próxima camada geralmente fica SUJA em arquivos que ambos tocaram (um ADR, uma lista de versões): mescle o base nela, resolva, envie, aguarde o CI, então faça merge-async.
  • Aprovações sobrevivem a sincronizações de base em repositórios que não descartam revisões obsoletas (verifique required_pull_request_reviews.dismiss_stale_reviews na proteção de branch). O portão real é frequentemente a aprovação de CODEOWNERS para cada caminho tocado, não a contagem de aprovações (pr-approval-gate lista as lacunas).
  • Para manter cada PR aberto atualizado com seu base entre as integrações, execute uma passagem de sincronização de base: mescle o base em cada branch de PR aberto e envie (merges simples, sem force-push).

Resolução de conflitos

  • Arquivos de workflow editados por múltiplas camadas (workflows de build reutilizáveis, um workflow orquestrador de CI): mantenha AMBAS as edições, não escolha um lado.
  • Colisões de varredura de formatação (uma camada de aplicação de Spotless/Prettier vs mudanças de conteúdo no base): pegue o CONTEÚDO do base para o arquivo em conflito, então reexecute o formatador nele (mvn -pl <module> -am spotless:apply ou pnpm fmt). Pegar o lado da varredura descarta mudanças reais; pegar o base sem reformatar falha no portão de formatação. Execuções do formatador precisam do build para resolver (alguns repositórios puxam dependências de um registro privado que precisa de login em nuvem primeiro; atualize-o se o build não conseguir buscar dependências).

Segurança

  • Não faça force-push, reescreva histórico ou envie para branches protegidos.
  • Siga as convenções de autoria de commit do repositório (alguns proíbem trailers de co-autoria de IA).
  • Pause para aprovação de revisão humana antes de cada merge no branch base.
  • Se existir um PR de lista de permissões de CI para branch intermediário (o antipadrão que esta skill substitui), recomende fechá-lo; se já foi mesclado, reverta os nomes de branch e tipos de evento adicionados.

Relacionados

  • opening-a-stacked-pr-sequence: abrir a pilha (bases, ordem de merge) e o reajuste por tipo de merge (stack.sh restack).
  • pr-approval-gate: quais code owners cada camada ainda precisa.
  • resolve-pr-threads-and-conflicts-and-merge: integrar uma camada uma vez que seus comentários e aprovações estão resolvidos.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas