Skip to main content
Skip to content

Otimizando a CI para pull requests empilhadas

Entenda como os GitHub Actions fluxos de trabalho são executados para uma pilha, acesse metadados de pilha em seus fluxos de trabalho e reduza o uso redundante de CI.

Cada pull request em uma pilha é avaliada como se tivesse como destino a base da pilha, como main. Isso mantém a qualidade consistente em todas as camadas, mas também significa que um fluxo de trabalho pode ser executado muitas vezes para uma única pilha. Este artigo explica como os workflows são executados para uma stack e como reduzir o uso redundante de CI.

Como os fluxos de trabalho são executados para uma pilha

GitHub Os fluxos de trabalho de ações disparam como se cada pull request na pilha tivesse como destino a base da pilha. Um fluxo de trabalho configurado para ser executado em eventos direcionados a main``pull_request é executado para cada solicitação de pull na pilha, não apenas a solicitação na base, portanto, nenhuma alteração de fluxo de trabalho é necessária para que suas verificações sejam executadas em toda a pilha.

Como um fluxo de trabalho é executado uma vez por pull request, uma pilha grande multiplica seu uso de CI. No entanto, você pode usar metadados de pilha para executar trabalhos caros somente onde eles são necessários.

Acessando metadados de pilha

Metadados de pilha estão disponíveis em expressões de fluxo de trabalho por meio de github.event.pull_request.stack. Essa propriedade só está presente quando o pull request pertence a uma stack, portanto, verifique se os fluxos de trabalho filtram por ela antes de ler qualquer um de seus campos.

ExpressionDescrição
github.event.pull_request.stack.numberO número da pilha, com escopo para o repositório.
github.event.pull_request.stack.sizeNúmero total de pull requests na stack.
github.event.pull_request.stack.positionPosição baseada em 1 dessa solicitação de pull dentro da pilha (1 é a parte inferior).
github.event.pull_request.stack.base.refA branch para a qual toda a pilha aponta no fim, como main.
github.event.pull_request.stack.base.shaO HEAD SHA do branch base da pilha.

Por exemplo, o fluxo de trabalho a seguir lê metadados de pilha e executa a segunda etapa somente quando a pilha tem como destino uma branch cujo nome começa com release/.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Show stack info
        if: github.event.pull_request.stack != null
        run: |
          echo "Stack base ref: ${{ github.event.pull_request.stack.base.ref }}"
          echo "PR ${{ github.event.pull_request.stack.position }} of ${{ github.event.pull_request.stack.size }} in the stack"

      - name: Run only when the stack targets a release branch
        if: github.event.pull_request.stack != null && startsWith(github.event.pull_request.stack.base.ref, 'release/')
        run: echo "This stack targets a release branch"

Reduzindo o uso de CI

Como um fluxo de trabalho é executado para cada pull request em uma pilha, você pode usar as propriedades stack para executar trabalhos caros apenas nas posições que importam. Duas condições são especialmente úteis:

  • Última pull request não mesclada — a pull request atualmente na parte inferior da pilha restante, direcionada diretamente à base da pilha. É o pull request em que github.event.pull_request.stack.base.ref é igual a github.event.pull_request.base.ref.
  • Pull request superior — a última pull request na pilha, contendo o conjunto completo de alterações. É o pull request em que github.event.pull_request.stack.position é igual a github.event.pull_request.stack.size.
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Run for the lowest unmerged pull request in the stack
        if: github.event.pull_request.stack != null && github.event.pull_request.stack.base.ref == github.event.pull_request.base.ref
        run: echo "Lowest unmerged pull request in the stack"

      - name: Run for the top pull request in the stack
        if: github.event.pull_request.stack != null && github.event.pull_request.stack.position == github.event.pull_request.stack.size
        run: echo "Top pull request in the stack"

À medida que as pull requests são mescladas de baixo para cima, a pull request não mesclada mais baixa muda. Depois que o pull request mais abaixo for mesclado, o próximo pull request será rebaseado para ter como destino diretamente a base da pilha, portanto ele se tornará o novo pull request não mesclado mais abaixo na execução do fluxo de trabalho seguinte.

Você também pode aplicar o gate na pull request original na base com github.event.pull_request.stack.position == 1, ou aplicar o gate em qualquer camada específica usando position.