Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 12 additions & 24 deletions .github/workflows/generate-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ on:
required: false
default: ''

workflow_run:
workflows: ["Build and Test for PRs"]
types: [completed]
pull_request:
types: [closed]

permissions:
contents: write
Expand All @@ -24,28 +23,17 @@ jobs:
if: |
github.event_name == 'workflow_dispatch' ||
(
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.actor.login != 'github-actions[bot]'
github.event.pull_request.merged == true &&
github.event.pull_request.base.ref == 'main' &&
github.event.pull_request.user.login != 'github-actions[bot]'
)

steps:
# ── 1. Normaliza contexto para os dois gatilhos ───────────────────────────
- name: Resolve trigger context
id: ctx
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "head_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
echo "pr_number=manual" >> "$GITHUB_OUTPUT"
else
echo "head_sha=${{ github.event.workflow_run.head_sha }}" >> "$GITHUB_OUTPUT"
echo "pr_number=${{ github.event.workflow_run.pull_requests[0].number }}" >> "$GITHUB_OUTPUT"
fi

# ── 2. Checkout ───────────────────────────────────────────────────────────
# ── 1. Checkout ───────────────────────────────────────────────────────────
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ steps.ctx.outputs.head_sha }}
ref: ${{ github.event_name == 'workflow_dispatch' && github.sha || github.event.pull_request.merge_commit_sha }}
fetch-depth: 0

# ── 3. Verifica se há arquivos .kt modificados ───────────────────────────
Expand All @@ -56,7 +44,7 @@ jobs:
echo "has_kotlin=true" >> "$GITHUB_OUTPUT"
echo "workflow_dispatch — pulando verificação de .kt"
else
KT=$(git diff --name-only origin/main...HEAD | grep '\.kt$' || true)
KT=$(git diff --name-only ${{ github.event.pull_request.base.sha }}...HEAD | grep '\.kt$' || true)
if [ -n "$KT" ]; then
echo "has_kotlin=true" >> "$GITHUB_OUTPUT"
echo "Arquivos .kt detectados:"
Expand Down Expand Up @@ -96,8 +84,8 @@ jobs:
UNCOVERED_COUNT=$(echo "$UNCOVERED" | grep -v "^$" | wc -l | tr -d ' ')
echo "Modo override — arquivos informados manualmente:"

elif [ "${{ github.event_name }}" = "workflow_run" ]; then
# Modo automático (PR) — apenas .kt modificados no PR sem teste ainda
elif [ "${{ github.event_name }}" = "pull_request" ]; then
# Modo automático (PR mergeado) — apenas .kt modificados no PR sem teste ainda
echo "Modo PR — apenas arquivos .kt modificados neste PR sem cobertura..."
UNCOVERED=""
while IFS= read -r SRC; do
Expand All @@ -111,7 +99,7 @@ jobs:
UNCOVERED="$UNCOVERED"$'\n'"$SRC"
fi
fi
done < <(git diff --name-only origin/main...HEAD | grep '\.kt$' | grep -v "Test\.kt" | sort)
done < <(git diff --name-only ${{ github.event.pull_request.base.sha }}...HEAD | grep '\.kt$' | grep -v "Test\.kt" | sort)
UNCOVERED=$(echo "$UNCOVERED" | grep -v "^$" || true)
UNCOVERED_COUNT=$(echo "$UNCOVERED" | grep -v "^$" | wc -l | tr -d ' ')

Expand Down Expand Up @@ -223,7 +211,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
run: |
PR_NUMBER="${{ steps.ctx.outputs.pr_number }}"
PR_NUMBER="${{ github.event_name == 'workflow_dispatch' && 'manual' || github.event.pull_request.number }}"
BRANCH="${{ steps.commit.outputs.branch }}"
COVERED="${{ steps.check.outputs.covered_names }}"
TOTAL="${{ steps.changed.outputs.total }}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-04-24
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## Context

O workflow `generate-tests.yml` usa `workflow_run` como gatilho, o que faz com que ele execute toda vez que o workflow "Build and Test for PRs" conclui com sucesso — independentemente de haver um merge. Isso significa que a geração de testes (e o custo associado à Claude API) ocorre a cada push em branches com PR aberto.

O estado atual do gatilho:
```yaml
workflow_run:
workflows: ["Build and Test for PRs"]
types: [completed]
```

A mudança substitui esse gatilho por `pull_request` com tipo `closed`, filtrando apenas merges reais.

## Goals / Non-Goals

**Goals:**
- Garantir que `generate-tests.yml` rode apenas quando um PR é mergeado no `main`
- Manter o `workflow_dispatch` para acionamento manual com `override_files`
- Simplificar a lógica de contexto eliminando a ramificação `workflow_run`

**Non-Goals:**
- Não alterar a lógica de geração de testes em si (Python script, Claude API, PR criado)
- Não modificar outros workflows (`pr.yml`)
- Não mudar o comportamento do `workflow_dispatch`

## Decisions

### Gatilho: `pull_request` com tipo `closed` + condição `merged`

**Decisão:** Usar `on: pull_request: types: [closed]` com `if: github.event.pull_request.merged == true` no job.

**Alternativas consideradas:**
- `push` no branch `main` — funcionaria, mas perderia o número do PR de origem, que é usado no corpo do PR de testes gerados.
- Manter `workflow_run` com filtro extra — não é possível filtrar por merge via `workflow_run`; exigiria lógica de shell para verificar via `gh api`, mais frágil.

**Rationale:** O evento `pull_request.closed` com `merged == true` é a forma idiomática do GitHub Actions para "PR mergeado". Fornece `github.event.pull_request.number` diretamente, mantendo a rastreabilidade no PR gerado.

### Base do diff: `github.event.pull_request.base.sha`

**Decisão:** No step "Check for Kotlin file changes", substituir `origin/main...HEAD` por `${{ github.event.pull_request.base.sha }}...HEAD` quando o gatilho for `pull_request`.

**Rationale:** Com `pull_request.closed`, o checkout ocorre no merge commit. Usar o SHA base do PR garante que o diff cubra exatamente os arquivos modificados naquele PR — o mesmo conjunto analisado pelo CI.

### Remoção do step "Resolve trigger context"

**Decisão:** Remover o step `ctx` que normalizava `head_sha` e `pr_number` entre os dois gatilhos (`workflow_dispatch` vs `workflow_run`).

**Rationale:** Com apenas `pull_request` e `workflow_dispatch`, os valores são obtidos diretamente:
- `pr_number`: `github.event.pull_request.number` (ou `"manual"` no dispatch)
- `head_sha`: `github.event.pull_request.merge_commit_sha` (ou `github.sha` no dispatch)

Isso elimina a indireção e simplifica os steps subsequentes.

## Risks / Trade-offs

- **[Risco] PRs mergeados em branches que não `main`** → O job pode ser restrito adicionando `if: github.event.pull_request.base.ref == 'main'`. Incluir essa condição como precaução.
- **[Trade-off] Geração só ocorre pós-merge** → Antes, testes podiam ser gerados ainda com o PR aberto (como efeito colateral). Agora é intencional — só pós-merge. Aceito como comportamento desejado.

## Migration Plan

1. Editar `.github/workflows/generate-tests.yml`:
- Substituir bloco `workflow_run` por `pull_request: types: [closed]`
- Remover step `Resolve trigger context`
- Atualizar condição `if` do job para verificar `merged == true` e base `main`
- Atualizar referências de `steps.ctx.outputs.*` nos steps seguintes
2. Fazer commit e push — sem necessidade de rollback especial; reverter o arquivo restaura o comportamento anterior.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Why

O workflow `generate-tests.yml` dispara a cada commit em qualquer branch porque o gatilho `workflow_run` reage à conclusão de "Build and Test for PRs" independente de o PR ter sido mergeado ou não. Isso gera execuções desnecessárias e custo de API durante o desenvolvimento, quando o ideal é gerar testes apenas uma vez — ao merge no `main`.

## What Changes

- Substituir o gatilho `workflow_run` por `pull_request` com o tipo `closed` + filtro `merged == true`
- Remover a lógica de resolução de contexto para o gatilho `workflow_run` (step "Resolve trigger context")
- Ajustar o step "Check for Kotlin file changes" para usar `github.event.pull_request.base.sha` como base do diff em vez de `origin/main`
- Manter o gatilho `workflow_dispatch` inalterado para acionamento manual

## Capabilities

### New Capabilities

- `generate-tests-trigger`: Controle de gatilho do workflow de geração de testes — restringe execução a PRs mergeados no `main`

### Modified Capabilities

<!-- Nenhuma spec existente a alterar -->

## Impact

- **Arquivo afetado:** `.github/workflows/generate-tests.yml`
- **Comportamento anterior:** workflow roda a cada push que passe no CI de qualquer branch com PR aberto
- **Comportamento novo:** workflow roda apenas quando um PR é mergeado no `main`
- **Sem impacto** em outros workflows, código da lib ou testes existentes
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## ADDED Requirements

### Requirement: Workflow executa apenas em PRs mergeados no main
O workflow `generate-tests.yml` SHALL ser acionado automaticamente somente quando um pull request for mergeado na branch `main`.

#### Scenario: PR mergeado no main dispara o workflow
- **WHEN** um pull request é fechado com `merged == true` e `base.ref == 'main'`
- **THEN** o job `generate-tests` é executado

#### Scenario: PR fechado sem merge não dispara o workflow
- **WHEN** um pull request é fechado com `merged == false`
- **THEN** o job `generate-tests` NÃO é executado

#### Scenario: Push em branch sem merge não dispara o workflow
- **WHEN** um commit é feito em qualquer branch sem que haja um merge no main
- **THEN** o job `generate-tests` NÃO é executado

#### Scenario: PR mergeado em branch que não main não dispara o workflow
- **WHEN** um pull request é mergeado em uma branch diferente de `main` (ex: `develop`)
- **THEN** o job `generate-tests` NÃO é executado

### Requirement: Workflow_dispatch mantido para acionamento manual
O workflow SHALL continuar suportando acionamento manual via `workflow_dispatch` com o parâmetro opcional `override_files`.

#### Scenario: Disparo manual sem override roda scan completo
- **WHEN** o workflow é acionado via `workflow_dispatch` sem `override_files`
- **THEN** o job escaneia todos os arquivos `.kt` sem cobertura em `craftd-core`

#### Scenario: Disparo manual com override_files usa arquivos informados
- **WHEN** o workflow é acionado via `workflow_dispatch` com `override_files` preenchido
- **THEN** o job processa apenas os arquivos listados em `override_files`

### Requirement: Número do PR de origem preservado no PR gerado
O workflow SHALL incluir o número do PR que disparou a geração no corpo do PR de testes criado automaticamente.

#### Scenario: PR de testes referencia o PR de origem
- **WHEN** o workflow é disparado por um merge de PR número `N`
- **THEN** o corpo do PR gerado contém `Triggered by PR #N`

#### Scenario: Disparo manual usa label "manual"
- **WHEN** o workflow é acionado via `workflow_dispatch`
- **THEN** o corpo do PR gerado contém `Triggered by PR #manual`
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## 1. Substituir gatilho do workflow

- [x] 1.1 Remover o bloco `workflow_run` de `.github/workflows/generate-tests.yml`
- [x] 1.2 Adicionar gatilho `pull_request: types: [closed]` no lugar

## 2. Atualizar condição do job

- [x] 2.1 Adicionar condição `if` no job `generate-tests` para verificar `github.event.pull_request.merged == true`
- [x] 2.2 Adicionar filtro `github.event.pull_request.base.ref == 'main'` na condição do job (ou manter para `workflow_dispatch`)

## 3. Remover e simplificar lógica de contexto

- [x] 3.1 Remover o step "Resolve trigger context" (`id: ctx`) inteiramente
- [x] 3.2 Atualizar o step "Checkout" para usar `github.event.pull_request.merge_commit_sha` (ou `github.sha` para dispatch)
- [x] 3.3 Atualizar referências `steps.ctx.outputs.pr_number` e `steps.ctx.outputs.head_sha` nos steps seguintes para usar os valores diretos do evento

## 4. Ajustar diff de Kotlin

- [x] 4.1 No step "Check for Kotlin file changes", substituir a base do diff de `origin/main...HEAD` por `${{ github.event.pull_request.base.sha }}...HEAD` para o gatilho `pull_request`
- [x] 4.2 Garantir que o modo `workflow_dispatch` continue usando o scan completo (sem base SHA de PR)

## 5. Validação

- [x] 5.1 Revisar o YAML final e confirmar que a sintaxe está correta (sem erros de indentação ou referências quebradas)
- [x] 5.2 Confirmar que `pr_number` no body do PR gerado continua referenciando o número correto (ou "manual" para dispatch)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-04-24
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## Context

O workflow `generate-tests.yml` usa `workflow_run` como gatilho, o que faz com que ele execute toda vez que o workflow "Build and Test for PRs" conclui com sucesso — independentemente de haver um merge. Isso significa que a geração de testes (e o custo associado à Claude API) ocorre a cada push em branches com PR aberto.

O estado atual do gatilho:
```yaml
workflow_run:
workflows: ["Build and Test for PRs"]
types: [completed]
```

A mudança substitui esse gatilho por `pull_request` com tipo `closed`, filtrando apenas merges reais.

## Goals / Non-Goals

**Goals:**
- Garantir que `generate-tests.yml` rode apenas quando um PR é mergeado no `main`
- Manter o `workflow_dispatch` para acionamento manual com `override_files`
- Simplificar a lógica de contexto eliminando a ramificação `workflow_run`

**Non-Goals:**
- Não alterar a lógica de geração de testes em si (Python script, Claude API, PR criado)
- Não modificar outros workflows (`pr.yml`)
- Não mudar o comportamento do `workflow_dispatch`

## Decisions

### Gatilho: `pull_request` com tipo `closed` + condição `merged`

**Decisão:** Usar `on: pull_request: types: [closed]` com `if: github.event.pull_request.merged == true` no job.

**Alternativas consideradas:**
- `push` no branch `main` — funcionaria, mas perderia o número do PR de origem, que é usado no corpo do PR de testes gerados.
- Manter `workflow_run` com filtro extra — não é possível filtrar por merge via `workflow_run`; exigiria lógica de shell para verificar via `gh api`, mais frágil.

**Rationale:** O evento `pull_request.closed` com `merged == true` é a forma idiomática do GitHub Actions para "PR mergeado". Fornece `github.event.pull_request.number` diretamente, mantendo a rastreabilidade no PR gerado.

### Base do diff: `github.event.pull_request.base.sha`

**Decisão:** No step "Check for Kotlin file changes", substituir `origin/main...HEAD` por `${{ github.event.pull_request.base.sha }}...HEAD` quando o gatilho for `pull_request`.

**Rationale:** Com `pull_request.closed`, o checkout ocorre no merge commit. Usar o SHA base do PR garante que o diff cubra exatamente os arquivos modificados naquele PR — o mesmo conjunto analisado pelo CI.

### Remoção do step "Resolve trigger context"

**Decisão:** Remover o step `ctx` que normalizava `head_sha` e `pr_number` entre os dois gatilhos (`workflow_dispatch` vs `workflow_run`).

**Rationale:** Com apenas `pull_request` e `workflow_dispatch`, os valores são obtidos diretamente:
- `pr_number`: `github.event.pull_request.number` (ou `"manual"` no dispatch)
- `head_sha`: `github.event.pull_request.merge_commit_sha` (ou `github.sha` no dispatch)

Isso elimina a indireção e simplifica os steps subsequentes.

## Risks / Trade-offs

- **[Risco] PRs mergeados em branches que não `main`** → O job pode ser restrito adicionando `if: github.event.pull_request.base.ref == 'main'`. Incluir essa condição como precaução.
- **[Trade-off] Geração só ocorre pós-merge** → Antes, testes podiam ser gerados ainda com o PR aberto (como efeito colateral). Agora é intencional — só pós-merge. Aceito como comportamento desejado.

## Migration Plan

1. Editar `.github/workflows/generate-tests.yml`:
- Substituir bloco `workflow_run` por `pull_request: types: [closed]`
- Remover step `Resolve trigger context`
- Atualizar condição `if` do job para verificar `merged == true` e base `main`
- Atualizar referências de `steps.ctx.outputs.*` nos steps seguintes
2. Fazer commit e push — sem necessidade de rollback especial; reverter o arquivo restaura o comportamento anterior.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Why

O workflow `generate-tests.yml` dispara a cada commit em qualquer branch porque o gatilho `workflow_run` reage à conclusão de "Build and Test for PRs" independente de o PR ter sido mergeado ou não. Isso gera execuções desnecessárias e custo de API durante o desenvolvimento, quando o ideal é gerar testes apenas uma vez — ao merge no `main`.

## What Changes

- Substituir o gatilho `workflow_run` por `pull_request` com o tipo `closed` + filtro `merged == true`
- Remover a lógica de resolução de contexto para o gatilho `workflow_run` (step "Resolve trigger context")
- Ajustar o step "Check for Kotlin file changes" para usar `github.event.pull_request.base.sha` como base do diff em vez de `origin/main`
- Manter o gatilho `workflow_dispatch` inalterado para acionamento manual

## Capabilities

### New Capabilities

- `generate-tests-trigger`: Controle de gatilho do workflow de geração de testes — restringe execução a PRs mergeados no `main`

### Modified Capabilities

<!-- Nenhuma spec existente a alterar -->

## Impact

- **Arquivo afetado:** `.github/workflows/generate-tests.yml`
- **Comportamento anterior:** workflow roda a cada push que passe no CI de qualquer branch com PR aberto
- **Comportamento novo:** workflow roda apenas quando um PR é mergeado no `main`
- **Sem impacto** em outros workflows, código da lib ou testes existentes
Loading
Loading