Compose, Makefile, .infra e workflows de CI
TLDR: Makefile delegador,
compose.ymlunificado,.infra/por módulo e por projeto, e workflows de CI com detected changes — o padrão wehive adaptado para multi-módulo.
Estado atual: PR 2 (Makefile + compose +
.module/) e PR 4 (workflows) estão entregues —.github/workflows/temreview-pr.yml,check-main.yml,deploy-staging.ymledeploy-production.yml. Do PR 3, os dois módulos têm.infra/(build-args,k8s,terraform); falta apenas o.infra/compartilhado na raiz (VPC, RDS, Redis). Por isso o status seguein_progress.
Contexto
O projeto tem a estrutura modules/ estabelecida mas sem Makefile, compose.yml, .infra ou CI.
Precisa de tudo isso seguindo os padrões wehive, adaptados para multi-módulo.
Referências: marketing/ (Makefile delegador), messenger-api (workflows, nomes), trgclub
(padrão review-pr + main).
Objetivos
- Makefile na raiz delega para cada módulo:
make frontend.<target>,make backend.<target>. compose.ymlna raiz inclui o stack do commons + overrides por módulo via.module/docker/..infra/na raiz para infra compartilhada (RDS, VPC, Redis);.infra/em cada módulo para k8s + terraform do módulo.- Workflows de CI com detected changes — um arquivo por responsabilidade, duas trilhas no deploy.
Fora de escopo
- Conteúdo de deploy do back-end — o módulo do back ainda não tem app quando esta spec começa.
- Qualquer mudança no código dos módulos.
Mudanças
Layout resultado
nectar-charges/
├── Makefile # delega: frontend.%, backend.% ✓ PR2
├── compose.yml # inclui stack react + .module/docker/ ✓ PR2
├── .env.example # ✓ PR2
├── .infra/ # infra compartilhada (RDS, VPC, Redis) ✗ pendente
│ ├── terraform/
│ └── k8s/
├── modules/
│ ├── frontend/
│ │ ├── .module/ # ✓ PR2
│ │ │ ├── make/main.mk
│ │ │ └── docker/compose.yml
│ │ ├── .infra/ # ✓ PR3
│ │ │ ├── k8s/
│ │ │ │ ├── base/ # deployments: web, worker
│ │ │ │ └── overlays/staging/ + production/
│ │ │ └── terraform/ # secrets, DNS do frontend
│ │ ├── Makefile # ✓ PR2
│ │ └── src/ ...
│ └── backend/
│ ├── .module/ # ✓ PR2
│ ├── .infra/ # ✓ PR3
│ └── Makefile # ✓ PR2
└── .github/
└── workflows/ # ✓ PR4
├── review-pr.yml # PR: checks + infra plan com detected changes
├── check-main.yml # push main: checks + infra apply com detected changes
├── deploy-staging.yml # push tag v*: duas trilhas frontend + backend
└── deploy-production.yml # workflow_dispatch: delivery manual
Decisão: infra de projeto vs. infra de módulo
| Onde | O que fica |
|---|---|
.infra/ raiz |
Recursos compartilhados: VPC, RDS, Redis, namespace k8s base |
modules/frontend/.infra/ |
Manifests k8s do frontend, secrets específicos, DNS do frontend |
modules/backend/.infra/ |
Manifests k8s do backend, secrets específicos, DNS do backend |
O terraform do módulo referencia outputs do terraform do projeto.
Decisão: namespace k8s e nomenclatura de pods
Namespace único por ambiente — frontend e backend escalam independentemente via Deployment + HPA, não via namespace separado:
namespace: nectar-charges--staging
deployment: frontend-web ← HPA independente
deployment: frontend-worker ← HPA independente (se existir)
deployment: backend-web ← HPA independente
deployment: backend-worker ← HPA independente (se existir)
app_name por módulo: nectar-charges-frontend, nectar-charges-backend — usado como nome da imagem
no ECR e prefixo dos manifests k8s.
Decisão: nomes e organização dos workflows
Padrão trgclub. Infra não tem arquivo separado — o plan entra no review-pr.yml, o apply entra no
workflow de main.
| Arquivo | Nome do workflow | Trigger |
|---|---|---|
review-pr.yml |
review -> pr |
pull_request |
check-main.yml |
check -> main |
push em main |
deploy-staging.yml |
deploy -> staging |
push de tag v* |
deploy-production.yml |
deploy -> production [manual] |
workflow_dispatch |
Detected changes (review-pr e main)
```yaml jobs: changes: outputs: frontend: ${{ steps.filter.outputs.frontend }} backend: ${{ steps.filter.outputs.backend }} frontend-infra: ${{ steps.filter.outputs.frontend_infra }} backend-infra: ${{ steps.filter.outputs.backend_infra }} project-infra: ${{ steps.filter.outputs.project_infra }} steps: - uses: dorny/paths-filter@v3 with: filters: | frontend: [‘modules/frontend/’, ‘!modules/frontend/.infra/’] backend: [‘modules/backend/’, ‘!modules/backend/.infra/’] frontend_infra: [‘modules/frontend/.infra/’] backend_infra: [‘modules/backend/.infra/’] project_infra: [‘.infra/**’]
check-frontend: needs: changes if: needs.changes.outputs.frontend == ‘true’ uses: ibft-corp/pipelines/.github/workflows/check-react.yml@v1
check-backend: needs: changes if: needs.changes.outputs.backend == ‘true’ uses: ibft-corp/pipelines/.github/workflows/check.yml@v1
infra-frontend: # plan no review-pr, apply no main needs: changes if: needs.changes.outputs.frontend-infra == ‘true’
infra-backend: needs: changes if: needs.changes.outputs.backend-infra == ‘true’
infra: # infra compartilhada do projeto needs: changes if: needs.changes.outputs.project-infra == ‘true’ ```
deploy-staging — duas trilhas, uma tag
A tag v* dispara o workflow. Detected changes (diff entre a tag atual e a anterior) decide quais
trilhas rodam. Cada trilha é independente:
```yaml check-frontend: uses: ibft-corp/pipelines/.github/workflows/check-react.yml@v1
infra-frontend: needs: changes if: needs.changes.outputs.frontend_infra == ‘true’ uses: ibft-corp/pipelines/.github/workflows/infra.yml@v3 with: app_name: nectar-charges-frontend working_directory: modules/frontend
package-frontend: needs: [check-frontend, infra-frontend] if: | always() && needs.check-frontend.result == ‘success’ && needs.infra-frontend.result != ‘failure’ uses: ibft-corp/pipelines/.github/workflows/package.yml@v1 with: app_name: nectar-charges-frontend
delivery-frontend: needs: package-frontend uses: ibft-corp/pipelines/.github/workflows/delivery.yml@v1 with: app_name: nectar-charges-frontend environment: staging
trilha backend — mesma estrutura
```
O if: always() em package-* torna explícito no log quando infra-* foi skipped. O guard
!= 'failure' bloqueia o deploy se o apply quebrar.
Sequência de entrega
| PR | Entrega | Estado |
|---|---|---|
| PR 2 | Makefile + compose + .module/ |
✓ concluído |
| PR 3 | .infra/terraform/ da raiz; modules/frontend/.infra/ e modules/backend/.infra/ (k8s base + overlays staging/production, terraform de secrets e DNS) |
parcial — os dois módulos prontos, falta o da raiz |
| PR 4 | Os 4 workflows + atualizar as skills commons:ci e commons:structure |
✓ concluído |
Como verificar
PR 3:
ls modules/frontend/.infra/k8s/overlays/staging/— manifests presentesls .infra/terraform/— scaffold presente
PR 4:
- PR alterando só
modules/frontend/src/→ apenascheck-frontendroda - PR alterando só
modules/frontend/.infra/→ apenasinfra-frontendroda - PR alterando ambos → ambos rodam
- Push da tag
v1.0.0com mudança só no frontend → trilha frontend roda, backend skipped - Push em main com mudança em
.infra/terraform/→infra(projeto) roda
Documentação
- Convenção de módulos — seção
.infra/por módulo vs. projeto - Skill
commons:structure— layout completo - Skill
commons:infra—.infradentro de módulo vs. na raiz - Skill
commons:ci— padrão de detected changes multi-módulo