project-standalo-note-to-app/.claude/commands/eureka/deploy.md

422 lines
19 KiB
Markdown

---
description: Deploy application to Eureka platform (creates app if needed)
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---
# Eureka Deploy
**Input**: "$ARGUMENTS"
---
## PURPOSE
Deploy the current project to the Eureka platform. Automatically detects framework, validates/generates Dockerfile, creates app if needed, then triggers deployment.
---
## ⛔ CRITICAL RULES
### MUST DO
1. **MUST** detect framework and validate Dockerfile before deployment
2. **MUST** check for existing `app_id` in `.claude/eureka-factory.yaml` first
3. **MUST** create a new app via API if no `app_id` exists
4. **MUST** use `gitea.authenticatedCloneUrl` for git remote (NOT cloneUrl)
5. **MUST** save the new `app_id` to config after creation
6. **MUST** display deployment status after triggering
7. **MUST** consult `.claude/references/dockerfile-templates.md` for Dockerfile generation
### CANNOT DO
1. **CANNOT** deploy without valid API key
2. **CANNOT** skip app creation if `app_id` is missing
3. **CANNOT** proceed if API calls fail
4. **CANNOT** deploy without valid Dockerfile (generate if missing)
5. **CANNOT** use `gitea.cloneUrl` for git remote (it's Docker internal URL)
### CRITICAL: GITEA_EXTERNAL_URL
The backend **MUST** have `GITEA_EXTERNAL_URL` configured for external access:
```
Without GITEA_EXTERNAL_URL:
authenticatedCloneUrl = http://TOKEN@gitea:3000/... ← FAILS (Docker internal)
With GITEA_EXTERNAL_URL:
authenticatedCloneUrl = https://TOKEN@gitea.yourdomain.com/... ← WORKS
```
---
## EXECUTION FLOW
### ═══════════════════════════════════════════════════════════════
### PHASE 1: Configuration Check
### ═══════════════════════════════════════════════════════════════
#### 1.1: Display Start Banner
```
╔══════════════════════════════════════════════════════════════╗
║ 🚀 EUREKA DEPLOY ║
╠══════════════════════════════════════════════════════════════╣
║ Deploying to Eureka Platform... ║
╚══════════════════════════════════════════════════════════════╝
```
#### 1.2: Check Configuration
Read the configuration file:
```bash
# Check if config exists
cat .claude/eureka-factory.yaml 2>/dev/null || cat .claude/eureka-factory.yml 2>/dev/null || echo "NO_CONFIG"
```
**Extract from config:**
- `api_key` - Required for all operations
- `app_id` - If exists, skip app creation
- `api_endpoint` - Optional custom endpoint
#### 1.3: Validate API Key
If no `api_key` found:
```
╔══════════════════════════════════════════════════════════════╗
║ ❌ NO API KEY CONFIGURED ║
╠══════════════════════════════════════════════════════════════╣
║ Run `eureka setup` to configure your credentials. ║
╚══════════════════════════════════════════════════════════════╝
```
**STOP EXECUTION**
---
### ═══════════════════════════════════════════════════════════════
### PHASE 2: Framework Detection & Dockerfile Validation
### ═══════════════════════════════════════════════════════════════
#### 2.1: Detect Framework
Run framework detection script:
```bash
python3 skills/guardrail-orchestrator/scripts/detect_framework.py . --format summary
```
**Expected output:**
```
Framework: Next.js + Prisma
Base Image: node:20-alpine3.18
Port: 3000
Requirements: openssl1.1-compat, output: standalone
Validation Checks:
✅ Next.js standalone output: OK
❌ Dockerfile exists: Dockerfile will be generated
```
#### 2.2: Validate/Generate Dockerfile
**If Dockerfile exists:**
- Verify it matches detected framework
- Check for common issues (wrong base image, missing Prisma support)
**If Dockerfile is missing:**
- Generate from template in `.claude/references/dockerfile-templates.md`
- Match template to detected framework
```
╔══════════════════════════════════════════════════════════════╗
║ 🐳 DOCKERFILE STATUS ║
╠══════════════════════════════════════════════════════════════╣
║ Framework: Next.js + Prisma ║
║ Base Image: node:20-alpine3.18 ║
║ Port: 3000 ║
║ Status: Generated / Validated ║
╚══════════════════════════════════════════════════════════════╝
```
#### 2.3: Framework-Specific Validations
**For Next.js:**
- Check `next.config.js` has `output: 'standalone'`
- If missing, offer to add it
**For SPAs (React/Vue/Angular):**
- Check for `nginx.conf`
- If missing, generate SPA routing config
**For Prisma projects:**
- Verify `prisma/` directory exists
- Check Dockerfile uses `node:20-alpine3.18` with `openssl1.1-compat`
#### 2.4: Display Framework Summary
```
╔══════════════════════════════════════════════════════════════╗
║ ✅ FRAMEWORK DETECTION COMPLETE ║
╠══════════════════════════════════════════════════════════════╣
║ Detected: Next.js + Prisma ║
║ Dockerfile: ✅ Valid ║
║ Config: ✅ output: 'standalone' set ║
║ Ready to deploy! ║
╚══════════════════════════════════════════════════════════════╝
```
---
### ═══════════════════════════════════════════════════════════════
### PHASE 3: App Creation (if needed)
### ═══════════════════════════════════════════════════════════════
#### 3.1: Check for app_id
If `app_id` exists in config → **SKIP TO PHASE 4**
If `app_id` is missing:
```
╔══════════════════════════════════════════════════════════════╗
║ 📁 CREATING DIRECTORY APP ║
╠══════════════════════════════════════════════════════════════╣
║ No app_id found. Creating new app on Eureka... ║
╚══════════════════════════════════════════════════════════════╝
```
#### 3.2: Determine App Name
Use the project directory name as the default app name:
```bash
APP_NAME=$(basename $(pwd))
echo "App name: $APP_NAME"
```
Or use argument if provided: `$ARGUMENTS` as app name
#### 3.3: Create Repository with Deploy Access via API
```bash
API_KEY="<from config>"
API_ENDPOINT="<from config or default>"
curl -X POST "${API_ENDPOINT}/v1/repositories/create-with-gitea" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${API_KEY}" \
-d '{
"name": "<APP_NAME>",
"description": "<description>",
"type": "other",
"isPrivate": false,
"createDirectoryApp": true
}'
```
**Response structure:**
```json
{
"success": true,
"repository": { "id": "...", "name": "..." },
"gitea": {
"repoUrl": "http://gitea:3000/ai-apps/project-abc-myapp",
"cloneUrl": "http://gitea:3000/ai-apps/project-abc-myapp.git",
"authenticatedCloneUrl": "https://TOKEN@gitea.yourdomain.com/ai-apps/project-abc-myapp.git",
"deployUser": "deploy-project-abc-myapp",
"accessToken": "e0d1fd7fe75777..."
},
"directoryApp": { "id": "...", "slug": "my-app", "status": "COMING_SOON" }
}
```
#### 3.4: Add Git Remote
**IMPORTANT**: Use `authenticatedCloneUrl` (NOT `cloneUrl`):
```bash
git remote add eureka "<gitea.authenticatedCloneUrl>"
# Example: git remote add eureka "https://TOKEN@gitea.yourdomain.com/ai-apps/myapp.git"
```
#### 3.5: Push Code to Repository
```bash
git add .
git commit -m "Initial commit for Eureka deployment"
git push -u eureka $(git branch --show-current)
```
#### 3.6: Save Config
Extract IDs from API response and update config:
```yaml
# .claude/eureka-factory.yaml
api_key: <existing>
project_id: <existing>
repo_id: <repository.id>
app_id: <directoryApp.id>
slug: <directoryApp.slug>
```
```
╔══════════════════════════════════════════════════════════════╗
║ ✅ REPOSITORY & APP CREATED ║
╠══════════════════════════════════════════════════════════════╣
║ App ID: <directoryApp.id> ║
║ Slug: <directoryApp.slug> ║
║ Repo ID: <repository.id> ║
║ Git Remote: <gitea.authenticatedCloneUrl> ║
║ Saved to: .claude/eureka-factory.yaml ║
╚══════════════════════════════════════════════════════════════╝
```
#### 3.7: Get Clone URL for Existing App (Alternative)
If app exists but git remote not configured:
```bash
# Get clone URL by app_id
curl -s -X GET "${API_ENDPOINT}/v1/apps/${APP_ID}/git/clone-url" \
-H "X-API-Key: ${API_KEY}"
# Or by slug
curl -s -X GET "${API_ENDPOINT}/v1/apps/by-slug/${SLUG}/git/clone-url" \
-H "X-API-Key: ${API_KEY}"
```
Response includes `git.authenticatedCloneUrl` - use this for the remote.
---
### ═══════════════════════════════════════════════════════════════
### PHASE 4: Trigger Deployment
### ═══════════════════════════════════════════════════════════════
#### 4.1: Trigger Deploy
```bash
# Using eureka CLI
eureka deploy trigger --yes
# Or direct API call
curl -X POST "${API_ENDPOINT}/v1/apps/${APP_ID}/deployments" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${API_KEY}" \
-d '{"environment": "production"}'
```
#### 4.2: Display Deployment Status
```
╔══════════════════════════════════════════════════════════════╗
║ ✅ DEPLOYMENT TRIGGERED ║
╠══════════════════════════════════════════════════════════════╣
║ Deployment ID: <deployment_id> ║
║ Status: PENDING ║
║ Environment: production ║
║ Version: <version> ║
╠══════════════════════════════════════════════════════════════╣
║ Use `/eureka:deploy-status` to check progress ║
║ Use `/eureka:deploy-logs` to view logs ║
╚══════════════════════════════════════════════════════════════╝
```
---
## ARGUMENTS
| Argument | Default | Description |
|----------|---------|-------------|
| `[app-name]` | Directory name | Name for new app (only used if creating) |
| `--env <environment>` | `production` | Deployment environment |
| `--branch <branch>` | Current branch | Git branch to deploy |
| `--force` | `false` | Force deploy even if already deploying |
## EXAMPLES
```bash
# Deploy current project (creates app if needed)
/eureka:deploy
# Deploy with custom app name
/eureka:deploy my-awesome-app
# Deploy specific branch to staging
/eureka:deploy --env staging --branch develop
# Force redeploy
/eureka:deploy --force
```
---
## ERROR HANDLING
### No Configuration
```
❌ No configuration found.
Run `eureka setup` to configure credentials.
```
### App Creation Failed
```
❌ Failed to create app: <error message>
Check your API key and try again.
```
### Deployment Failed
```
❌ Deployment failed: <error message>
Use `/eureka:deploy-logs` to see details.
```
---
## FLOW DIAGRAM
```
┌─────────────────────────────────────────────────────────────────┐
│ /eureka:deploy │
├─────────────────────────────────────────────────────────────────┤
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Check Config │ │
│ └────────┬────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ Has API Key? │ │
│ └─────────┬─────────┘ │
│ │ │
│ NO │ YES │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ │
│ ┌───────────┐ ┌─────────────────┐ │
│ │ ERROR │ │ Has app_id? │ │
│ │ No Key │ └────────┬────────┘ │
│ └───────────┘ │ │
│ NO │ YES │
│ ┌───────────────────┼──────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌──────────────┐
│ │ Create App │ │ │
│ │ via API │ │ │
│ └────────┬────────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌─────────────────┐ │ │
│ │ Save app_id │ │ │
│ │ to Config │ │ │
│ └────────┬────────┘ │ │
│ │ │ │
│ └───────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Trigger Deploy │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Show Status │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```