2929 )
3030
3131 steps :
32+ # ── 1. Normaliza contexto para os dois gatilhos ───────────────────────────
3233 - name : Resolve trigger context
3334 id : ctx
3435 run : |
@@ -40,12 +41,14 @@ jobs:
4041 echo "pr_number=${{ github.event.workflow_run.pull_requests[0].number }}" >> "$GITHUB_OUTPUT"
4142 fi
4243
44+ # ── 2. Checkout ───────────────────────────────────────────────────────────
4345 - name : Checkout
4446 uses : actions/checkout@v4
4547 with :
4648 ref : ${{ steps.ctx.outputs.head_sha }}
4749 fetch-depth : 0
4850
51+ # ── 3. Python ─────────────────────────────────────────────────────────────
4952 - name : Set up Python
5053 uses : actions/setup-python@v5
5154 with :
@@ -54,16 +57,23 @@ jobs:
5457 - name : Install Python dependencies
5558 run : pip install anthropic
5659
60+ # ── 4. Escaneia craftd-core buscando arquivos sem cobertura ──────────────
5761 - name : Find uncovered Kotlin files in craftd-core
5862 id : changed
5963 run : |
6064 OVERRIDE="${{ github.event.inputs.override_files }}"
6165
66+ # Conta total de arquivos fonte
67+ TOTAL=$(find android_kmp/craftd-core/src \
68+ \( -path "*/commonMain/kotlin/*.kt" -o -path "*/androidMain/kotlin/*.kt" \) \
69+ | grep -v "Test\.kt" | wc -l | tr -d ' ')
70+
6271 if [ -n "$OVERRIDE" ]; then
6372 UNCOVERED=$(echo "$OVERRIDE" | tr ' ' '\n' | grep -v "^$" || true)
64- echo "Modo override, arquivos informados manualmente:"
73+ UNCOVERED_COUNT=$(echo "$UNCOVERED" | grep -v "^$" | wc -l | tr -d ' ')
74+ echo "Modo override — arquivos informados manualmente:"
6575 else
66- echo "Scan completo, buscando arquivos sem cobertura em craftd-core..."
76+ echo "Scan completo — buscando arquivos sem cobertura em craftd-core..."
6777 UNCOVERED=""
6878 while IFS= read -r SRC; do
6979 TEST=$(echo "$SRC" \
@@ -77,10 +87,28 @@ jobs:
7787 \( -path "*/commonMain/kotlin/*.kt" -o -path "*/androidMain/kotlin/*.kt" \) \
7888 | grep -v "Test\.kt" | sort)
7989 UNCOVERED=$(echo "$UNCOVERED" | grep -v "^$" || true)
90+ UNCOVERED_COUNT=$(echo "$UNCOVERED" | grep -v "^$" | wc -l | tr -d ' ')
8091 fi
8192
8293 echo "$UNCOVERED"
8394
95+ COVERED_BEFORE=$((TOTAL - UNCOVERED_COUNT))
96+ COVERED_AFTER=$TOTAL
97+
98+ if [ "$TOTAL" -gt "0" ]; then
99+ PCT_BEFORE=$(( (COVERED_BEFORE * 100) / TOTAL ))
100+ PCT_AFTER=100
101+ else
102+ PCT_BEFORE=0
103+ PCT_AFTER=0
104+ fi
105+
106+ echo "total=$TOTAL" >> "$GITHUB_OUTPUT"
107+ echo "covered_before=$COVERED_BEFORE" >> "$GITHUB_OUTPUT"
108+ echo "covered_after=$COVERED_AFTER" >> "$GITHUB_OUTPUT"
109+ echo "pct_before=$PCT_BEFORE" >> "$GITHUB_OUTPUT"
110+ echo "pct_after=$PCT_AFTER" >> "$GITHUB_OUTPUT"
111+
84112 if [ -z "$UNCOVERED" ]; then
85113 echo "has_changes=false" >> "$GITHUB_OUTPUT"
86114 echo "Nenhum arquivo sem cobertura. Nada a fazer."
@@ -89,13 +117,15 @@ jobs:
89117 printf "files<<EOF\n%s\nEOF\n" "$UNCOVERED" >> "$GITHUB_OUTPUT"
90118 fi
91119
120+ # ── 5. Chama Claude API para gerar os testes ─────────────────────────────
92121 - name : Generate unit tests with Claude API
93122 if : steps.changed.outputs.has_changes == 'true'
94123 env :
95124 ANTHROPIC_API_KEY : ${{ secrets.ANTHROPIC_API_KEY }}
96125 CHANGED_FILES : ${{ steps.changed.outputs.files }}
97126 run : python .github/scripts/generate_tests.py
98127
128+ # ── 6. Verifica se arquivos foram gerados ─────────────────────────────────
99129 - name : Check generated files
100130 if : steps.changed.outputs.has_changes == 'true'
101131 id : check
@@ -115,26 +145,35 @@ jobs:
115145 echo "has_tests=false" >> "$GITHUB_OUTPUT"
116146 fi
117147
148+ # ── 7. Cria branch com nome incremental e commita os testes ──────────────
118149 - name : Commit generated tests
119150 if : steps.check.outputs.has_tests == 'true'
120151 id : commit
121152 run : |
122- PR_NUMBER="${{ steps.ctx.outputs.pr_number }}"
123- BRANCH="chore/add-tests-craftd-core-pr-${PR_NUMBER}"
124-
125- git config user.name "github-actions[bot]"
153+ git config user.name "github-actions[bot]"
126154 git config user.email "github-actions[bot]@users.noreply.github.com"
127155
128156 # Autentica o push com GH_PAT via URL do remote
129157 git remote set-url origin https://x-access-token:${{ secrets.GH_PAT }}@github.com/CodandoTV/CraftD.git
130158
159+ # Determina nome do branch com auto-incremento: cover/test, cover/test-1, cover/test-2 ...
160+ BASE="cover/test"
161+ BRANCH="$BASE"
162+ N=1
163+ while git ls-remote --exit-code --heads origin "$BRANCH" > /dev/null 2>&1; do
164+ BRANCH="${BASE}-${N}"
165+ N=$((N + 1))
166+ done
167+ echo "Branch escolhido: $BRANCH"
168+
131169 git checkout -b "$BRANCH"
132170 git add --force android_kmp/craftd-core/src/test/
133171 git commit -m "test: add unit tests for craftd-core (auto-generated via Claude)"
134172 git push origin "$BRANCH"
135173
136174 echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
137175
176+ # ── 8. Abre PR com os testes gerados e evolução de cobertura ─────────────
138177 - name : Open Pull Request with generated tests
139178 if : steps.check.outputs.has_tests == 'true'
140179 env :
@@ -143,6 +182,11 @@ jobs:
143182 PR_NUMBER="${{ steps.ctx.outputs.pr_number }}"
144183 BRANCH="${{ steps.commit.outputs.branch }}"
145184 COVERED="${{ steps.check.outputs.covered_names }}"
185+ TOTAL="${{ steps.changed.outputs.total }}"
186+ COV_BEFORE="${{ steps.changed.outputs.covered_before }}"
187+ COV_AFTER="${{ steps.changed.outputs.covered_after }}"
188+ PCT_BEFORE="${{ steps.changed.outputs.pct_before }}"
189+ PCT_AFTER="${{ steps.changed.outputs.pct_after }}"
146190
147191 gh pr create \
148192 --base "main" \
@@ -153,6 +197,13 @@ jobs:
153197
154198 Este PR foi gerado automaticamente pelo workflow **Auto Generate Cover+Test** usando a Claude API.
155199
200+ ### Evolução de cobertura
201+
202+ | | Arquivos | Cobertura |
203+ |---|---|---|
204+ | Antes | ${COV_BEFORE} / ${TOTAL} | ${PCT_BEFORE}% |
205+ | Depois | ${COV_AFTER} / ${TOTAL} | ${PCT_AFTER}% |
206+
156207 ### Arquivos cobertos
157208 \`\`\`
158209 ${COVERED}
0 commit comments