5050 didn't match the configured pattern. Please ensure that the subject
5151 doesn't start with an uppercase character.
5252
53+ - name : Run comprehensive checks
54+ run : |
55+ echo "🔍 Running comprehensive PR validation..."
56+
57+ # Run linting, tests, and build
58+ npm run check
59+
60+ echo "✅ All checks passed"
61+
62+ - name : Test CLI functionality
63+ run : |
64+ echo "🧪 Testing CLI functionality..."
65+
66+ # Test basic CLI commands
67+ node dist/index.js --version
68+ node dist/index.js --help
69+ node dist/index.js list --json
70+ node dist/index.js doctor --json
71+
72+ # Test JSON output validation
73+ OUTPUT=$(node dist/index.js list --json)
74+ echo "$OUTPUT" | jq . > /dev/null || (echo "❌ Invalid JSON output" && exit 1)
75+
76+ echo "✅ CLI functionality tests passed"
77+
5378 - name : Check for breaking changes
5479 run : |
5580 # Check if this PR might contain breaking changes
@@ -67,39 +92,198 @@ jobs:
6792 echo "📊 Change statistics:"
6893 git diff --stat origin/main...HEAD
6994
95+ template-integrity :
96+ runs-on : ubuntu-latest
97+
98+ steps :
99+ - name : Checkout
100+ uses : actions/checkout@v4
101+
102+ - name : Setup Node.js
103+ uses : actions/setup-node@v4
104+ with :
105+ node-version : " 20"
106+ cache : " npm"
107+
108+ - name : Install dependencies
109+ run : npm ci
110+
70111 - name : Check template integrity
71112 run : |
72- # Verify that template changes don't break existing functionality
73- if git diff --name-only origin/main...HEAD | grep "templates/" > /dev/null; then
74- echo "🔍 Template changes detected, running integrity checks..."
75-
76- # Check that all hero templates still have required structure
77- for template in nextjs-fullstack express-fullstack react-spa-advanced; do
78- if [ -d "templates/$template" ]; then
79- echo "Checking $template structure..."
80- test -f "templates/$template/package.json" || (echo "❌ Missing package.json in $template" && exit 1)
113+ echo "🔍 Running comprehensive template integrity checks..."
114+
115+ # Check all templates, not just when changed
116+ TEMPLATES_DIR="templates"
117+ FAILED_TEMPLATES=()
118+
119+ if [ -d "$TEMPLATES_DIR" ]; then
120+ for template_path in "$TEMPLATES_DIR"/*; do
121+ if [ -d "$template_path" ]; then
122+ template=$(basename "$template_path")
123+ echo "Checking $template template..."
124+
125+ # Basic structure checks
126+ if [ ! -f "$template_path/package.json" ]; then
127+ echo "❌ Missing package.json in $template"
128+ FAILED_TEMPLATES+=("$template")
129+ continue
130+ fi
131+
132+ # Validate package.json is valid JSON
133+ if ! jq . "$template_path/package.json" > /dev/null 2>&1; then
134+ echo "❌ Invalid package.json in $template"
135+ FAILED_TEMPLATES+=("$template")
136+ continue
137+ fi
81138
82139 # Check for required directories based on template type
83140 case $template in
84141 "nextjs-fullstack")
85- test -d "templates/$template/src/components" || (echo "❌ Missing components dir in $template" && exit 1)
86- test -d "templates/$template/src/app" || (echo "❌ Missing app dir in $template" && exit 1)
142+ [ -d "$template_path/src/components" ] || { echo "❌ Missing components dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
143+ [ -d "$template_path/src/app" ] || { echo "❌ Missing app dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
144+ [ -f "$template_path/next.config.js" ] || [ -f "$template_path/next.config.mjs" ] || { echo "❌ Missing Next.js config in $template"; FAILED_TEMPLATES+=("$template"); continue; }
87145 ;;
88146 "express-fullstack")
89- test -d "templates/$template /src/client" || ( echo "❌ Missing client dir in $template" && exit 1)
90- test -d "templates/$template /src/server" || ( echo "❌ Missing server dir in $template" && exit 1)
147+ [ -d "$template_path /src/client" ] || { echo "❌ Missing client dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
148+ [ -d "$template_path /src/server" ] || { echo "❌ Missing server dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
91149 ;;
92150 "react-spa-advanced")
93- test -d "templates/$template/src/components" || (echo "❌ Missing components dir in $template" && exit 1)
94- test -d "templates/$template/src/pages" || (echo "❌ Missing pages dir in $template" && exit 1)
151+ [ -d "$template_path/src/components" ] || { echo "❌ Missing components dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
152+ [ -d "$template_path/src/pages" ] || { echo "❌ Missing pages dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
153+ [ -f "$template_path/vite.config.ts" ] || [ -f "$template_path/vite.config.js" ] || { echo "❌ Missing Vite config in $template"; FAILED_TEMPLATES+=("$template"); continue; }
154+ ;;
155+ "bun-react-tailwind"|"vite-vue-tailwind")
156+ [ -d "$template_path/src" ] || { echo "❌ Missing src dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
157+ [ -f "$template_path/vite.config.ts" ] || [ -f "$template_path/vite.config.js" ] || { echo "❌ Missing Vite config in $template"; FAILED_TEMPLATES+=("$template"); continue; }
158+ ;;
159+ "flask"|"fastapi")
160+ [ -f "$template_path/app.py" ] || [ -f "$template_path/main.py" ] || [ -d "$template_path/src" ] || { echo "❌ Missing Python entry point in $template"; FAILED_TEMPLATES+=("$template"); continue; }
161+ [ -f "$template_path/requirements.txt" ] || { echo "❌ Missing requirements.txt in $template"; FAILED_TEMPLATES+=("$template"); continue; }
162+ ;;
163+ "nextjs-app-router")
164+ [ -d "$template_path/src/app" ] || { echo "❌ Missing app dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
165+ [ -f "$template_path/next.config.js" ] || [ -f "$template_path/next.config.mjs" ] || { echo "❌ Missing Next.js config in $template"; FAILED_TEMPLATES+=("$template"); continue; }
166+ ;;
167+ "express-typescript")
168+ [ -d "$template_path/src" ] || { echo "❌ Missing src dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
169+ [ -f "$template_path/tsconfig.json" ] || { echo "❌ Missing TypeScript config in $template"; FAILED_TEMPLATES+=("$template"); continue; }
170+ ;;
171+ "flask-bun-hybrid")
172+ [ -f "$template_path/app.py" ] || [ -f "$template_path/main.py" ] || [ -d "$template_path/backend" ] || { echo "❌ Missing Python backend in $template"; FAILED_TEMPLATES+=("$template"); continue; }
173+ [ -d "$template_path/frontend" ] || [ -d "$template_path/client" ] || { echo "❌ Missing frontend dir in $template"; FAILED_TEMPLATES+=("$template"); continue; }
95174 ;;
96175 esac
97176
177+ # Check for common required files
178+ [ -f "$template_path/.gitignore" ] || { echo "⚠️ Missing .gitignore in $template (recommended)"; }
179+ [ -f "$template_path/README.md" ] || { echo "⚠️ Missing README.md in $template (recommended)"; }
180+
98181 echo "✅ $template structure is valid"
99182 fi
100183 done
184+
185+ # Report results
186+ if [ ${#FAILED_TEMPLATES[@]} -gt 0 ]; then
187+ echo ""
188+ echo "❌ Template integrity check failed for: ${FAILED_TEMPLATES[*]}"
189+ exit 1
190+ else
191+ echo ""
192+ echo "✅ All templates passed integrity checks"
193+ fi
194+ else
195+ echo "⚠️ Templates directory not found"
101196 fi
102197
198+ version-consistency :
199+ runs-on : ubuntu-latest
200+
201+ steps :
202+ - name : Checkout
203+ uses : actions/checkout@v4
204+
205+ - name : Check version consistency
206+ run : |
207+ echo "🔍 Checking version consistency across files..."
208+
209+ # Get version from package.json
210+ PACKAGE_VERSION=$(jq -r '.version' package.json)
211+ echo "📦 package.json version: $PACKAGE_VERSION"
212+
213+ # Check CLI version string in src/index.ts
214+ if grep -q "\.version(\"$PACKAGE_VERSION\")" src/index.ts; then
215+ echo "✅ CLI version string matches: $PACKAGE_VERSION"
216+ else
217+ echo "❌ CLI version string doesn't match package.json"
218+ echo "Expected: .version(\"$PACKAGE_VERSION\")"
219+ echo "Found in src/index.ts:"
220+ grep "\.version(" src/index.ts || echo "No version string found"
221+ exit 1
222+ fi
223+
224+ # Check if version follows semver
225+ SEMVER_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$'
226+ if echo "$PACKAGE_VERSION" | grep -E "$SEMVER_PATTERN" > /dev/null; then
227+ echo "✅ Version follows semantic versioning"
228+ else
229+ echo "❌ Version doesn't follow semantic versioning: $PACKAGE_VERSION"
230+ exit 1
231+ fi
232+
233+ registry-validation :
234+ runs-on : ubuntu-latest
235+
236+ steps :
237+ - name : Checkout
238+ uses : actions/checkout@v4
239+
240+ - name : Setup Node.js
241+ uses : actions/setup-node@v4
242+ with :
243+ node-version : " 20"
244+ cache : " npm"
245+
246+ - name : Install dependencies
247+ run : npm ci
248+
249+ - name : Validate template registry
250+ run : |
251+ echo "🔍 Validating template registry..."
252+
253+ # Build first to ensure TypeScript compiles
254+ npm run build
255+
256+ # Test registry loading
257+ node -e "
258+ import('./dist/registry.js').then(({ registry, getOrderedTemplates }) => {
259+ console.log('📋 Registry loaded successfully');
260+ console.log('Templates found:', Object.keys(registry).length);
261+
262+ const ordered = getOrderedTemplates();
263+ console.log('Ordered templates:', ordered.length);
264+
265+ // Validate each template entry
266+ for (const [key, template] of Object.entries(registry)) {
267+ if (!template.title) {
268+ console.error(\`❌ Template \${key} missing title\`);
269+ process.exit(1);
270+ }
271+
272+ if (typeof template.popular !== 'boolean') {
273+ console.error(\`❌ Template \${key} missing or invalid popular flag\`);
274+ process.exit(1);
275+ }
276+
277+ console.log(\`✅ \${key}: \${template.title}\`);
278+ }
279+
280+ console.log('✅ Registry validation passed');
281+ }).catch(err => {
282+ console.error('❌ Registry validation failed:', err);
283+ process.exit(1);
284+ });
285+ "
286+
103287 size-impact :
104288 runs-on : ubuntu-latest
105289
@@ -126,12 +310,20 @@ jobs:
126310 # Calculate current build size
127311 CURRENT_SIZE=$(du -sb dist/ | cut -f1)
128312
313+ # Store current branch name
314+ CURRENT_BRANCH=$(git branch --show-current)
315+
129316 # Checkout main and build
317+ git stash push -m "temp stash for size comparison" || true
130318 git checkout origin/main
131319 npm ci
132320 npm run build
133321 MAIN_SIZE=$(du -sb dist/ | cut -f1)
134322
323+ # Return to original branch
324+ git checkout "$CURRENT_BRANCH" || git checkout -
325+ git stash pop || true
326+
135327 # Calculate difference
136328 SIZE_DIFF=$((CURRENT_SIZE - MAIN_SIZE))
137329 SIZE_DIFF_KB=$((SIZE_DIFF / 1024))
0 commit comments