Skip to content

ci(contracts): contracts/06 — add Contract Tests pipeline#57

Merged
adm01-debug merged 1 commit into
mainfrom
feat/contracts-06-ci-pipeline
May 22, 2026
Merged

ci(contracts): contracts/06 — add Contract Tests pipeline#57
adm01-debug merged 1 commit into
mainfrom
feat/contracts-06-ci-pipeline

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 22, 2026

Sumário

Pipeline GitHub Actions que roda contract tests automaticamente em PRs que tocam contratos/edge functions.

Por quê

PR #45 entregou a base de validação (_shared/contracts + 43 testes vitest + script smoke HTTP). Sem CI esses testes só rodam quando alguém lembra. Com CI, qualquer regressão de schema vira status check vermelho antes do merge.

O que faz

Dois jobs:

Job O que valida Tempo Required?
unit vitest tests/contracts/ — schemas Zod isolados, sem rede ~1min sim, após merge
smoke supabase functions serve + npm run test:contract (HTTP real) ~5min advisory por 2 sprints, depois required

Triggers (paths):

  • supabase/functions/_shared/contracts/**
  • supabase/functions/**/index.ts
  • tests/contracts/**
  • scripts/contract-testing.mjs
  • arquivos do próprio workflow + package-lock

Comportamento extra:

  • concurrency cancela runs antigas do mesmo PR (economiza minutos)
  • Smoke só roda em PRs do próprio repo (forks não têm secrets)
  • Dump do log de functions serve em caso de falha (debug fácil)
  • Cleanup garantido (if: always())

Risco

Baixo. Workflow é additivo — não bloqueia mergeio enquanto não for marcado required no branch protection. Janela natural pra observar runs e ajustar.

Validação

Próximo passo após merge

  1. Aguardar 1ª run em PR de teste
  2. Marcar unit como required no branch protection de main
  3. Após ~2 sprints com smoke estável, marcá-lo required também

Closes #50


Summary by cubic

Adds a GitHub Actions “Contract Tests” pipeline that runs on PRs touching contract schemas and edge functions. It runs fast vitest unit tests and a real HTTP smoke test to catch schema regressions before merge.

  • New Features

    • New workflow .github/workflows/contract-tests.yml with two jobs:
      • unit: vitest against Zod schemas (fast, intended required check)
      • smoke: start local Supabase functions and run npm run test:contract against HTTP (advisory first)
    • Triggers on changes to contracts, edge function index.ts, contract tests, the smoke script, and workflow/lock files.
    • Concurrency cancels older runs for the same PR; smoke runs only on same-repo PRs (secrets), has timeouts, log dump on failure, and always cleans up.
  • Migration

    • After merge, mark the unit job as a required status check on main.
    • Keep smoke advisory for ~2 sprints, then mark required when stable.

Written for commit f3ba5f8. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

Release Notes

  • Chores
    • Implementação de testes automatizados em pull requests para validação de contratos e funcionalidade de integração, garantindo qualidade e confiabilidade do código antes de merge.

Review Change Stack

Triggers on PRs touching contracts/edge functions/tests. Runs vitest
unit tests against Zod schemas (fast, always required), then spins up
supabase functions serve and runs contract-testing.mjs against real
HTTP endpoints (advisory until adoption stabilizes).

Closes #50
Copilot AI review requested due to automatic review settings May 22, 2026 00:38
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 22, 2026 12:39am

@supabase
Copy link
Copy Markdown

supabase Bot commented May 22, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Walkthrough

O PR cria .github/workflows/contract-tests.yml, um workflow de CI/CD que valida contratos Zod em cada PR acionado por mudanças em funções, testes ou scripts de contrato. Implementa dois jobs sequenciais: testes unitários locais (obrigatório) e testes smoke integrados contra Supabase com Edge Functions, com proteção contra exposição de secrets em forks.

Changes

Automação de Testes de Contrato

Layer / File(s) Summary
Configuração do workflow e testes unitários
.github/workflows/contract-tests.yml (linhas 1–56)
Gatilhos por paths e dispatch, permissões read-only, concorrência com cancelamento, job unit com setup Node, instalação de deps via npm ci, execução de testes Vitest contra tests/contracts/ e consolidação de resumo no GITHUB_STEP_SUMMARY.
Testes smoke com Supabase e Edge Functions
.github/workflows/contract-tests.yml (linhas 57–113)
Job smoke (restrito ao repo principal) que sobe stack Supabase, exporta variáveis de ambiente, inicia servidor de funções em background com polling de prontidão HTTP, executa npm run test:contract e garante cleanup e dump de logs em falha.

Detalhes Críticos de Segurança

🔒 Secrets: Valor SUPABASE_LOCAL_ANON_KEY referenciado via ${{ secrets.SUPABASE_LOCAL_ANON_KEY }} — verifique se essa secret existe no repositório; se não existir, o job smoke falhará.

🔒 Proteção de Forks: Condicional if: github.event.pull_request.head.repo.full_name == github.repository bloqueia execução do job smoke em PRs de forks, evitando exposição de secrets. Confirme que isso está correto para sua política de contribuição externas.

⚙️ Polling de Prontidão: Job smoke aguarda via curl até /functions/v1/ responder 200; timeout pode ocorrer se Edge Functions demorar mais do que o padrão — considere aumentar sleep/retries se flakiness for observada.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título descreve claramente a mudança principal: adição de um pipeline de testes de contrato (Contract Tests pipeline) no CI, especificamente para a issue contracts/06.
Linked Issues check ✅ Passed O PR atende todos os objetivos da issue #50: workflow criado em .github/workflows/contract-tests.yml com jobs unit e smoke, paths corretos, permissões de leitura, concurrency configurada, smoke restrito ao próprio repo e limpeza garantida.
Out of Scope Changes check ✅ Passed Única alteração é a criação do arquivo .github/workflows/contract-tests.yml. Nenhuma mudança fora do escopo foi introduzida; tudo está alinhado com os objetivos do issue #50.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/contracts-06-ci-pipeline

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/contract-tests.yml:
- Around line 91-94: O polling com for/seq e curl pode sair sem garantir
readiness; after the loop check the curl result and fail fast with a non-zero
exit and descriptive error before running npm run test:contract — i.e., capture
the success of the readiness check (the curl call inside the for loop) and if it
never succeeded, print an error like "Functions endpoint did not become ready in
time" and exit 1 so the workflow stops immediately instead of proceeding to npm
run test:contract.
- Around line 52-55: O if que checa a existência de tests/contracts usa
atualmente "-f tests/contracts" (arquivo), o que falha para diretórios; troque
essa condição para testar diretório (por exemplo "-d tests/contracts" ou "-e
tests/contracts") para que o bloco que executa find sobre tests/contracts seja
executado corretamente; atualize a condição if envolvendo o caminho
"tests/contracts" no trecho que produz o resumo para garantir que a contagem de
arquivos seja sempre registrada quando a pasta existir.
- Around line 40-41: Pin mutable GitHub Actions by replacing actions/checkout@v4
and actions/setup-node@v4 with immutable SHA-pinned refs and avoid version:
latest for supabase/setup-cli by using a specific release SHA; also add with:
persist-credentials: false to the actions/checkout step. Change the test-summary
existence check from if [ -f tests/contracts ] to a directory check (e.g., -d)
or directly detect the test files (*.contract.test.ts) so the summary isn't
empty. After the readiness loop (the for loop that polls readiness), add an
explicit timeout check that fails the job (exit 1) if the service never became
ready and include or tail /tmp/functions.log in the failure output. Finally,
validate SUPABASE_ANON_KEY and SUPABASE_URL are non-empty before running npm run
test:contract and fail fast with a clear error if either is missing.
- Around line 83-85: The workflow currently writes SUPABASE_ANON_KEY and
SUPABASE_URL directly to $GITHUB_ENV even when supabase status returns
null/empty; change the step that runs the two supabase status | jq commands to
capture each value into a shell variable (e.g., anon_key and api_url), validate
that they are non-empty/non-null, and if either is missing echo a clear error to
stderr and exit 1; only when both pass the check should you append them to
$GITHUB_ENV (references: the SUPABASE_ANON_KEY and SUPABASE_URL assignments that
call `supabase status --output json | jq -r ...`).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b7dd1d8-2018-44c2-bf34-43e94f8b4315

📥 Commits

Reviewing files that changed from the base of the PR and between 4383445 and f3ba5f8.

📒 Files selected for processing (1)
  • .github/workflows/contract-tests.yml

Comment on lines +40 to +41
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/contract-tests.yml"
echo "== File: $FILE =="
ls -l "$FILE"
sed -n '1,200p' "$FILE" | nl -ba | sed -n '1,200p'

Repository: adm01-debug/promo-gifts-v4

Length of output: 266


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/contract-tests.yml"

echo "== File: $FILE =="
sed -n '1,220p' "$FILE" | awk '{printf "%4d\t%s\n", NR, $0}'

echo
echo "== Grep: persist-credentials =="
rg -n "persist-credentials" "$FILE" || true

echo
echo "== Grep: uses: actions/checkout/setup-node/supabase/setup-cli =="
rg -n "uses:\s*(actions/checkout|actions/setup-node|supabase/setup-cli)@" "$FILE" || true

Repository: adm01-debug/promo-gifts-v4

Length of output: 4482


Corrigir pinagem de actions, persistência de credenciais e falhas de confiabilidade no contract-tests

  • Segurança (supply-chain + credenciais): actions/checkout@v4 e actions/setup-node@v4 (lin. 40-41 e 66-68) usam tags mutáveis e o checkout não tem with: persist-credentials: false. supabase/setup-cli@v1 (lin. 73-75) está com version: latest (mutável). Pin por SHA e adicione persist-credentials: false no checkout.
  • Bug funcional no resumo: if [ -f tests/contracts ] (lin. 52) verifica arquivo, mas tests/contracts é diretório → o resumo pode ficar vazio. Trocar para -d (ou checar diretamente os *.contract.test.ts).
  • Confiabilidade do smoke: loop de readiness (lin. 90-94) não falha explicitamente em timeout; o workflow segue e pode quebrar de forma opaca depois. Após o for, verificar se ficou pronto e exit 1 (idealmente anexando /tmp/functions.log).
  • Validação de env ausente: SUPABASE_ANON_KEY/SUPABASE_URL (lin. 83-84) podem virar null/vazio sem abortar cedo. Validar não-empty e falhar antes do npm run test:contract.
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 40-40: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 40-40: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 41-41: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/contract-tests.yml around lines 40 - 41, Pin mutable
GitHub Actions by replacing actions/checkout@v4 and actions/setup-node@v4 with
immutable SHA-pinned refs and avoid version: latest for supabase/setup-cli by
using a specific release SHA; also add with: persist-credentials: false to the
actions/checkout step. Change the test-summary existence check from if [ -f
tests/contracts ] to a directory check (e.g., -d) or directly detect the test
files (*.contract.test.ts) so the summary isn't empty. After the readiness loop
(the for loop that polls readiness), add an explicit timeout check that fails
the job (exit 1) if the service never became ready and include or tail
/tmp/functions.log in the failure output. Finally, validate SUPABASE_ANON_KEY
and SUPABASE_URL are non-empty before running npm run test:contract and fail
fast with a clear error if either is missing.

Comment on lines +52 to +55
if [ -f tests/contracts ]; then
find tests/contracts -name '*.contract.test.ts' | wc -l \
| xargs -I{} echo "{} contract test files" >> "$GITHUB_STEP_SUMMARY"
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Corrija a verificação de existência da pasta de testes.

Em Line 52 foi usado -f tests/contracts, mas isso é diretório. Do jeito atual o resumo pode nunca contar os arquivos.

Diff sugerido
-          if [ -f tests/contracts ]; then
+          if [ -d tests/contracts ]; then
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/contract-tests.yml around lines 52 - 55, O if que checa a
existência de tests/contracts usa atualmente "-f tests/contracts" (arquivo), o
que falha para diretórios; troque essa condição para testar diretório (por
exemplo "-d tests/contracts" ou "-e tests/contracts") para que o bloco que
executa find sobre tests/contracts seja executado corretamente; atualize a
condição if envolvendo o caminho "tests/contracts" no trecho que produz o resumo
para garantir que a contagem de arquivos seja sempre registrada quando a pasta
existir.

Comment on lines +83 to +85
echo "SUPABASE_ANON_KEY=$(supabase status --output json | jq -r '.ANON_KEY // .API.anon_key')" >> "$GITHUB_ENV"
echo "SUPABASE_URL=$(supabase status --output json | jq -r '.API_URL // .API.url')" >> "$GITHUB_ENV"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the workflow file
ls -la .github/workflows/contract-tests.yml 2>/dev/null || true

# Show the relevant section around the reported lines
nl -ba .github/workflows/contract-tests.yml | sed -n '60,120p'

# Find all usages of SUPABASE_ANON_KEY / SUPABASE_URL in the workflow
rg -n "SUPABASE_(ANON_KEY|URL)" .github/workflows/contract-tests.yml

# Show nearby context where they are used (a bit more than matches)
rg -n "SUPABASE_(ANON_KEY|URL)" -n .github/workflows/contract-tests.yml -C 3

Repository: adm01-debug/promo-gifts-v4

Length of output: 217


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the file exists
ls -la .github/workflows/contract-tests.yml

# Print with line numbers (nl is unavailable)
cat -n .github/workflows/contract-tests.yml | sed -n '60,120p'

# Find all usages of the env vars in the workflow
rg -n "SUPABASE_(ANON_KEY|URL)" .github/workflows/contract-tests.yml

# Show a wider context around their usages
rg -n "SUPABASE_(ANON_KEY|URL)" -C 3 .github/workflows/contract-tests.yml

Repository: adm01-debug/promo-gifts-v4

Length of output: 3676


Falhar rápido se SUPABASE_URL/SUPABASE_ANON_KEY não vierem do supabase status
Hoje o workflow só faz jq -r ... >> $GITHUB_ENV; quando os campos não existem, jq pode acabar populando null/vazio e o job segue (readiness via curl e depois npm run test:contract) falhando de forma opaca. Faça um guard-rail e exit 1 se estiver ausente.

Diff sugerido
       - name: Start Supabase stack
         run: |
           supabase start
-          # captura anon key local
-          echo "SUPABASE_ANON_KEY=$(supabase status --output json | jq -r '.ANON_KEY // .API.anon_key')" >> "$GITHUB_ENV"
-          echo "SUPABASE_URL=$(supabase status --output json | jq -r '.API_URL // .API.url')" >> "$GITHUB_ENV"
+          STATUS_JSON="$(supabase status --output json)"
+          ANON_KEY="$(echo "$STATUS_JSON" | jq -r '.ANON_KEY // .API.anon_key // empty')"
+          API_URL="$(echo "$STATUS_JSON" | jq -r '.API_URL // .API.url // empty')"
+          [ -n "$ANON_KEY" ] || { echo "SUPABASE_ANON_KEY ausente"; exit 1; }
+          [ -n "$API_URL" ] || { echo "SUPABASE_URL ausente"; exit 1; }
+          echo "SUPABASE_ANON_KEY=$ANON_KEY" >> "$GITHUB_ENV"
+          echo "SUPABASE_URL=$API_URL" >> "$GITHUB_ENV"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "SUPABASE_ANON_KEY=$(supabase status --output json | jq -r '.ANON_KEY // .API.anon_key')" >> "$GITHUB_ENV"
echo "SUPABASE_URL=$(supabase status --output json | jq -r '.API_URL // .API.url')" >> "$GITHUB_ENV"
STATUS_JSON="$(supabase status --output json)"
ANON_KEY="$(echo "$STATUS_JSON" | jq -r '.ANON_KEY // .API.anon_key // empty')"
API_URL="$(echo "$STATUS_JSON" | jq -r '.API_URL // .API.url // empty')"
[ -n "$ANON_KEY" ] || { echo "SUPABASE_ANON_KEY ausente"; exit 1; }
[ -n "$API_URL" ] || { echo "SUPABASE_URL ausente"; exit 1; }
echo "SUPABASE_ANON_KEY=$ANON_KEY" >> "$GITHUB_ENV"
echo "SUPABASE_URL=$API_URL" >> "$GITHUB_ENV"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/contract-tests.yml around lines 83 - 85, The workflow
currently writes SUPABASE_ANON_KEY and SUPABASE_URL directly to $GITHUB_ENV even
when supabase status returns null/empty; change the step that runs the two
supabase status | jq commands to capture each value into a shell variable (e.g.,
anon_key and api_url), validate that they are non-empty/non-null, and if either
is missing echo a clear error to stderr and exit 1; only when both pass the
check should you append them to $GITHUB_ENV (references: the SUPABASE_ANON_KEY
and SUPABASE_URL assignments that call `supabase status --output json | jq -r
...`).

Comment on lines +91 to +94
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
sleep 1
done
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Faça fail explícito se o endpoint não ficar pronto no tempo limite.

O loop de polling pode terminar sem readiness e seguir para npm run test:contract, gerando falha menos diagnóstica e desperdício de tempo.

Diff sugerido
-          for i in $(seq 1 30); do
-            if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
-            sleep 1
-          done
+          ready=0
+          for i in $(seq 1 30); do
+            if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then
+              ready=1
+              break
+            fi
+            sleep 1
+          done
+          if [ "$ready" -ne 1 ]; then
+            echo "Edge Functions não ficaram prontas em 30s"
+            exit 1
+          fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/contract-tests.yml around lines 91 - 94, O polling com
for/seq e curl pode sair sem garantir readiness; after the loop check the curl
result and fail fast with a non-zero exit and descriptive error before running
npm run test:contract — i.e., capture the success of the readiness check (the
curl call inside the for loop) and if it never succeeded, print an error like
"Functions endpoint did not become ready in time" and exit 1 so the workflow
stops immediately instead of proceeding to npm run test:contract.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated Contract Tests GitHub Actions workflow intended to run lightweight contract validation when PRs touch Edge Function contract surfaces, keeping schema regressions from slipping in unnoticed.

Changes:

  • Introduces .github/workflows/contract-tests.yml with path-based pull_request triggers plus workflow_dispatch.
  • Adds two jobs: unit (Vitest) and smoke (local Supabase stack + supabase functions serve + npm run test:contract).
  • Adds concurrency cancellation, failure log dump for functions serve, and always() cleanup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +47 to +52
run: npm test -- tests/contracts/ --run
- name: Report coverage summary
if: always()
run: |
echo "### Contract test summary" >> "$GITHUB_STEP_SUMMARY"
if [ -f tests/contracts ]; then
if: always()
run: |
echo "### Contract test summary" >> "$GITHUB_STEP_SUMMARY"
if [ -f tests/contracts ]; then
Comment on lines +90 to +95
# espera readiness
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
sleep 1
done

needs: unit
# Só roda em PRs do próprio repo (forks não têm acesso a secrets, e
# supabase CLI exige tokens válidos pra subir o stack)
if: github.event.pull_request.head.repo.full_name == github.repository

- uses: supabase/setup-cli@v1
with:
version: latest
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3ba5f84c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

cache: 'npm'
- run: npm ci --no-audit --no-fund
- name: Run vitest contract tests
run: npm test -- tests/contracts/ --run
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point unit job to existing contract tests

npm test -- tests/contracts/ --run currently targets a path that does not exist in this repository, so the unit job will fail with “No test files found” whenever this workflow is triggered, blocking the smoke job and making the new pipeline unusable as a status check. Please run Vitest against the actual contract test locations (or add --passWithNoTests if empty suites are intentional).

Useful? React with 👍 / 👎.

pull_request:
paths:
- 'supabase/functions/_shared/contracts/**'
- 'supabase/functions/**/index.ts'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include non-index function files in path trigger

This workflow only watches supabase/functions/**/index.ts, so contract-impacting changes in other edge-function files (for example shared helpers under supabase/functions/_shared/*.ts that are imported by handlers) will not trigger contract CI at all. That creates silent coverage gaps where a PR can break function request/response contracts without running this status check.

Useful? React with 👍 / 👎.

echo $! > /tmp/functions.pid
# espera readiness
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Probe a real function endpoint for readiness

The readiness loop curls $SUPABASE_URL/functions/v1/ which is not a valid function route (Supabase requires a function name after /functions/v1/), so this check never becomes healthy and only waits 30 seconds before continuing. In cases where the runtime is still starting (or failed), the smoke tests run anyway and become flaky/fail for the wrong reason; the probe should hit a real function URL and fail fast if readiness is never reached.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/contract-tests.yml">

<violation number="1" location=".github/workflows/contract-tests.yml:52">
P3: The summary guard uses `-f` on a directory, so the contract test count is never reported.</violation>

<violation number="2" location=".github/workflows/contract-tests.yml:91">
P2: The readiness loop never errors after timeout, so the job can continue with an unready Supabase Functions server.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment on lines +91 to +94
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
sleep 1
done
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The readiness loop never errors after timeout, so the job can continue with an unready Supabase Functions server.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/contract-tests.yml, line 91:

<comment>The readiness loop never errors after timeout, so the job can continue with an unready Supabase Functions server.</comment>

<file context>
@@ -0,0 +1,113 @@
+          nohup supabase functions serve --no-verify-jwt > /tmp/functions.log 2>&1 &
+          echo $! > /tmp/functions.pid
+          # espera readiness
+          for i in $(seq 1 30); do
+            if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
+            sleep 1
</file context>
Suggested change
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then break; fi
sleep 1
done
ready=false
for i in $(seq 1 30); do
if curl -sf "$SUPABASE_URL/functions/v1/" -o /dev/null; then ready=true; break; fi
sleep 1
done
[ "$ready" = true ] || { echo "Supabase Functions did not become ready in time"; exit 1; }

if: always()
run: |
echo "### Contract test summary" >> "$GITHUB_STEP_SUMMARY"
if [ -f tests/contracts ]; then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The summary guard uses -f on a directory, so the contract test count is never reported.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/contract-tests.yml, line 52:

<comment>The summary guard uses `-f` on a directory, so the contract test count is never reported.</comment>

<file context>
@@ -0,0 +1,113 @@
+        if: always()
+        run: |
+          echo "### Contract test summary" >> "$GITHUB_STEP_SUMMARY"
+          if [ -f tests/contracts ]; then
+            find tests/contracts -name '*.contract.test.ts' | wc -l \
+              | xargs -I{} echo "{} contract test files" >> "$GITHUB_STEP_SUMMARY"
</file context>
Suggested change
if [ -f tests/contracts ]; then
if [ -d tests/contracts ]; then

@adm01-debug adm01-debug merged commit 9e51c3d into main May 22, 2026
30 of 34 checks passed
adm01-debug pushed a commit that referenced this pull request May 22, 2026
Same pattern as the ESLint baseline absorb: main pushed multiple PRs
without refreshing the TSC baseline, so this PR's gate flags 238 new
file:rule pairs that aren't this PR's fault.

Net: 1262 → 1373 errors. All drift comes from main (PRs #45, #57, #71-#74
introducing personalization-manager features, contracts module, and
storage/db hardening migrations).

The drift is identical to what runs on origin/main HEAD — verified by
running typecheck on the merge of this branch with origin/main.
adm01-debug added a commit that referenced this pull request May 22, 2026
* chore(docs): move stale audit notes to docs/historico/

Root README clutter cleanup: AUDITORIA_REDEPLOY_PROMO_GIFTS_2026-05-13 and
RECOVERY_PLAN are dated artifacts from closed contexts. docs/historico/
already collects this kind of post-mortem material — keeps the root README
focused on entrypoints (README, CHANGELOG, CONTRIBUTING, SECURITY).

Also drops the " (1)" suffix from the audit filename.

* chore: remove orphan barrel/alias files (zero consumers)

- src/hooks/stock/index.ts: empty barrel (only a comment, no exports, no
  importers in src/, tests/, e2e/).
- src/components/categories/CategoryTreeNavigator.tsx: semantic alias for
  CategoryTreeNavigation, never imported anywhere.
- src/hooks/products/useColors.ts: alias for useColorSystem. Only consumer
  was the re-export at src/hooks/products/index.ts:13 — removed that line
  too. The underlying useColorSystem hook stays available through the same
  barrel.

Verified with grep across src/, tests/, e2e/.

* refactor(logs): route KitBuilder fallback notices through logger.info

The two mock-data fallback notices in useKitBuilderQueries were emitting
via raw console.info while the error branches in the same file already use
logger.warn. Routes both through the central logger for consistency:
- dev console still receives the message
- prod stays silent (logger.info is no-op outside DEV)
- removes 2 entries from the no-console eslint baseline

* chore(baseline): refresh eslint baseline after pass-1 cleanup

Drops 3 entries from the baseline:
- useKitBuilderQueries.ts: 2x no-console (console.info → logger.info)
- OptimizedImage.tsx: 1x no-explicit-any (pre-existing drift, now captured)

Net: 473 → 472 errors. No regressions.

* fix(scripts): unbreak build:dev by removing missing generate-health.mjs

scripts/generate-health.mjs doesn't exist in the repo (no commit history),
yet build:dev tried to invoke it before vite, causing MODULE_NOT_FOUND on
every npm run build:dev. The script is unused by CI (which calls
ci:build → check-build-warnings.mjs) and unused by Vercel (which calls
vercel build directly), so build:dev was effectively dead.

Drop the dangling prelude so build:dev runs vite build --mode development
as the name implies.

* Revert "chore(baseline): refresh eslint baseline after pass-1 cleanup"

This reverts commit e1bb9eb.

* chore(baseline): absorb lint drift after merge with main

Two new ESLint violations landed on main since this branch started
(PRs #71-#74) without an accompanying baseline update:

- src/contexts/AuthContext.test.tsx:38 — consistent-type-imports (error)
- src/tests/AdminLayout.test.tsx:58 — no-explicit-any (warning)

CI runs the lint gate against the merge of this branch into main, so
the gate fails on every PR until main's drift is absorbed. Refreshing
the baseline here so this PR's gate evaluates only its own delta.

Also captures the positive drift this PR's changes produce:
- useKitBuilderQueries.ts: -2 no-console (console.info → logger.info)
- OptimizedImage.tsx: -1 no-explicit-any (pre-existing positive drift)

Net totalErrors stays at 473 (warnings shift, errors stay flat).

* chore(baseline): absorb TypeScript drift after merge with main

Same pattern as the ESLint baseline absorb: main pushed multiple PRs
without refreshing the TSC baseline, so this PR's gate flags 238 new
file:rule pairs that aren't this PR's fault.

Net: 1262 → 1373 errors. All drift comes from main (PRs #45, #57, #71-#74
introducing personalization-manager features, contracts module, and
storage/db hardening migrations).

The drift is identical to what runs on origin/main HEAD — verified by
running typecheck on the merge of this branch with origin/main.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contracts/06 — Rodar npm run test:contract na pipeline de PR

2 participants