Skip to content

Commit b6f6fe8

Browse files
committed
feat: complete technical test setup with intentional errors and CI/CD validation
- Add comprehensive project structure with auth, dashboard, and products modules - Include intentional TypeScript errors for candidates to fix: * Incorrect FormData typing in LoginForm.tsx * Missing searchProducts method in productApi.ts - Implement automated structure validation tests using Vitest - Configure GitHub Actions workflows for CI/CD: * structure-validation.yml for PR validation * promote-to-main.yml for deployment pipeline - Add validation scripts (validate, validate:full, check-status) - Create detailed README with technical test instructions - Set up Tailwind CSS for modern UI styling - Include project status checker script for immediate feedback
1 parent 16b9a72 commit b6f6fe8

33 files changed

Lines changed: 6050 additions & 556 deletions
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
name: 🚀 Promote to Main
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
types: [opened, synchronize, reopened]
8+
9+
push:
10+
branches:
11+
- developer
12+
- develop
13+
14+
workflow_dispatch:
15+
inputs:
16+
force_deploy:
17+
description: 'Force deploy to main'
18+
required: false
19+
default: 'false'
20+
type: boolean
21+
22+
env:
23+
NODE_VERSION: '18'
24+
25+
jobs:
26+
validate-for-production:
27+
name: 🔍 Production Validation
28+
runs-on: ubuntu-latest
29+
if: github.event_name == 'pull_request' && (github.base_ref == 'main' || github.head_ref == 'developer')
30+
31+
steps:
32+
- name: 📥 Checkout Repository
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
37+
- name: 🏷️ Extract Branch Info
38+
id: branch-info
39+
run: |
40+
echo "source_branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
41+
echo "target_branch=${GITHUB_BASE_REF:-main}" >> $GITHUB_OUTPUT
42+
echo "is_developer_branch=$([[ ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} == developer ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
43+
44+
- name: ✅ Validate Source Branch
45+
run: |
46+
echo "🌿 Source: ${{ steps.branch-info.outputs.source_branch }}"
47+
echo "🎯 Target: ${{ steps.branch-info.outputs.target_branch }}"
48+
49+
# Solo permitir developer -> main
50+
if [ "${{ steps.branch-info.outputs.target_branch }}" == "main" ] && [ "${{ steps.branch-info.outputs.source_branch }}" != "developer" ]; then
51+
echo "❌ ERROR: Solo la rama 'developer' puede hacer PR hacia 'main'"
52+
echo " Rama origen actual: ${{ steps.branch-info.outputs.source_branch }}"
53+
exit 1
54+
fi
55+
56+
echo "✅ Rama origen válida para producción"
57+
58+
- name: ⚡ Setup Node.js
59+
uses: actions/setup-node@v4
60+
with:
61+
node-version: ${{ env.NODE_VERSION }}
62+
cache: 'npm'
63+
64+
- name: 🔧 Install Dependencies
65+
run: |
66+
echo "📦 Installing dependencies for production validation..."
67+
npm ci --prefer-offline --no-audit
68+
69+
- name: 🔍 TypeScript Production Check
70+
id: typescript-check
71+
run: |
72+
echo "🔍 Validando tipos TypeScript para producción..."
73+
npx tsc --noEmit
74+
echo "✅ TypeScript validation pasó"
75+
76+
- name: 🧪 Run Full Test Suite
77+
id: full-tests
78+
run: |
79+
echo "🧪 Ejecutando suite completa de tests para producción..."
80+
npm run test:structure
81+
echo "✅ Tests de estructura pasaron"
82+
83+
- name: 🔍 Validate Module Content
84+
id: content-validation
85+
run: |
86+
echo "🔍 Validando contenido de módulos..."
87+
88+
# Verificar que los módulos no estén vacíos
89+
MODULES_WITH_CONTENT=0
90+
TOTAL_MODULES=0
91+
92+
for module_dir in src/core/*/; do
93+
if [ -d "$module_dir" ] && [ "$(basename "$module_dir")" != "shared" ]; then
94+
TOTAL_MODULES=$((TOTAL_MODULES + 1))
95+
module_name=$(basename "$module_dir")
96+
97+
echo "📂 Verificando módulo: $module_name"
98+
99+
# Contar archivos en el módulo (excluyendo directorios vacíos)
100+
FILE_COUNT=$(find "$module_dir" -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | wc -l)
101+
102+
if [ "$FILE_COUNT" -gt 0 ]; then
103+
MODULES_WITH_CONTENT=$((MODULES_WITH_CONTENT + 1))
104+
echo " ✅ $module_name tiene $FILE_COUNT archivos"
105+
else
106+
echo " ⚠️ $module_name está vacío"
107+
fi
108+
fi
109+
done
110+
111+
echo "📊 Módulos con contenido: $MODULES_WITH_CONTENT/$TOTAL_MODULES"
112+
113+
if [ "$MODULES_WITH_CONTENT" -eq 0 ]; then
114+
echo "❌ ERROR: Ningún módulo tiene contenido. No se puede promover a main."
115+
exit 1
116+
fi
117+
118+
# Requerir al menos 1 módulo con contenido para pasar a main
119+
if [ "$MODULES_WITH_CONTENT" -lt 1 ]; then
120+
echo "❌ ERROR: Se requiere al menos 1 módulo con contenido para promover a main"
121+
exit 1
122+
fi
123+
124+
echo "✅ Validación de contenido pasó: $MODULES_WITH_CONTENT módulos tienen contenido"
125+
echo "modules_with_content=$MODULES_WITH_CONTENT" >> $GITHUB_OUTPUT
126+
echo "total_modules=$TOTAL_MODULES" >> $GITHUB_OUTPUT
127+
128+
- name: 🏗️ Build for Production
129+
run: |
130+
echo "🏗️ Building for production..."
131+
npm run build
132+
echo "✅ Build completado exitosamente"
133+
134+
- name: 📊 Generate Production Report
135+
run: |
136+
echo "📊 Generando reporte de producción..."
137+
138+
echo "## 🚀 Production Readiness Report" > production-report.md
139+
echo "" >> production-report.md
140+
echo "- ✅ Structure validation: **PASSED**" >> production-report.md
141+
echo "- ✅ Build process: **PASSED**" >> production-report.md
142+
echo "- ✅ Content validation: **PASSED**" >> production-report.md
143+
echo "- 📊 Modules with content: **${{ steps.content-validation.outputs.modules_with_content }}/${{ steps.content-validation.outputs.total_modules }}**" >> production-report.md
144+
echo "" >> production-report.md
145+
echo "### Module Status:" >> production-report.md
146+
147+
for module_dir in src/core/*/; do
148+
if [ -d "$module_dir" ] && [ "$(basename "$module_dir")" != "shared" ]; then
149+
module_name=$(basename "$module_dir")
150+
FILE_COUNT=$(find "$module_dir" -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | wc -l)
151+
152+
if [ "$FILE_COUNT" -gt 0 ]; then
153+
echo "- ✅ **$module_name**: $FILE_COUNT files" >> production-report.md
154+
else
155+
echo "- ⚠️ **$module_name**: Empty module" >> production-report.md
156+
fi
157+
fi
158+
done
159+
160+
- name: 📤 Upload Production Report
161+
uses: actions/upload-artifact@v4
162+
with:
163+
name: production-readiness-report
164+
path: production-report.md
165+
166+
- name: 💬 Comment Production Report on PR
167+
if: github.event_name == 'pull_request'
168+
uses: actions/github-script@v7
169+
with:
170+
script: |
171+
const fs = require('fs');
172+
173+
let comment = `## 🚀 Production Readiness Report\\n\\n`;
174+
comment += `✅ **Ready for Main Branch!**\\n\\n`;
175+
comment += `📊 **Validation Results:**\\n`;
176+
comment += `- Structure Tests: ✅ PASSED\\n`;
177+
comment += `- Content Validation: ✅ PASSED\\n`;
178+
comment += `- Production Build: ✅ PASSED\\n`;
179+
comment += `- Modules with Content: **${{ steps.content-validation.outputs.modules_with_content }}/${{ steps.content-validation.outputs.total_modules }}**\\n\\n`;
180+
181+
comment += `🎯 **This PR is approved for production deployment!**\\n\\n`;
182+
comment += `🔗 [View detailed report in Actions](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
183+
184+
github.rest.issues.createComment({
185+
issue_number: context.issue.number,
186+
owner: context.repo.owner,
187+
repo: context.repo.repo,
188+
body: comment
189+
});
190+
191+
auto-promote-to-main:
192+
name: 🔄 Auto-promote to Main
193+
runs-on: ubuntu-latest
194+
needs: [validate-for-production]
195+
if: github.event_name == 'push' && github.ref == 'refs/heads/developer'
196+
197+
steps:
198+
- name: 📥 Checkout Repository
199+
uses: actions/checkout@v4
200+
with:
201+
token: ${{ secrets.GITHUB_TOKEN }}
202+
fetch-depth: 0
203+
204+
- name: 🚀 Create PR to Main
205+
uses: actions/github-script@v7
206+
with:
207+
script: |
208+
const { data: existingPRs } = await github.rest.pulls.list({
209+
owner: context.repo.owner,
210+
repo: context.repo.repo,
211+
head: 'developer',
212+
base: 'main',
213+
state: 'open'
214+
});
215+
216+
if (existingPRs.length === 0) {
217+
const { data: pr } = await github.rest.pulls.create({
218+
owner: context.repo.owner,
219+
repo: context.repo.repo,
220+
title: '🚀 Deploy to Production',
221+
head: 'developer',
222+
base: 'main',
223+
body: `## 🚀 Automated Production Deployment
224+
225+
This PR was automatically created after successful validation on the \`developer\` branch.
226+
227+
### ✅ Pre-deployment Validations Completed:
228+
- Structure tests passed
229+
- All modules validated
230+
- Content validation passed
231+
- Production build successful
232+
233+
### 📋 Review Checklist:
234+
- [ ] Code review completed
235+
- [ ] All tests passing
236+
- [ ] Documentation updated
237+
- [ ] Ready for production
238+
239+
**Auto-generated from developer branch**
240+
`
241+
});
242+
243+
console.log(\`Created PR #\${pr.number}: \${pr.html_url}\`);
244+
} else {
245+
console.log('PR from developer to main already exists');
246+
}

0 commit comments

Comments
 (0)