The regex r'[:/]([^/]+/[^/]+?)(?:\.git)?$' fails on URLs with trailing slashes like 'https://git.softuniq.eu/UniqueSoft/APAW/' because the final '/' breaks the pattern. Added .rstrip('/') in Python and sed 's:/*' in Bash to all get_target_repo() implementations across 11 files.
23 KiB
23 KiB
description, mode, model, color, permission
| description | mode | model | color | permission | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Run complete workflow with Gitea tracking and quality gates | workflow | ollama-cloud/glm-5 | #7C3AED |
|
Workflow Executor
Executes complete workflow with Gitea tracking, quality gates, and guaranteed delivery. Ensures no partial results - only complete, tested, documented products.
Parameters
workflow_type: Type - 'landing-page', 'commerce', 'blog', 'booking' (required)project_name: Project name (required)issue: Gitea issue number (auto-created if not provided)options: Workflow-specific options (optional)
Execution Flow
Issue Creation → Requirements → Architecture → Backend → Frontend → Testing → Review → Docker → Documentation → Delivery
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
Gitea #N Gate Check Gate Check Gate Check Gate Check Gate Check Gate Check Gate Check Gate Check Final Check
Step 0: Issue Creation
Mandatory First Step
Every workflow MUST start with Gitea issue creation:
import urllib.request, json, base64, os, re, subprocess
def get_target_repo():
"""Detect target project from git remote — see .kilo/shared/gitea-auth.md"""
try:
result = subprocess.run(['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True)
match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip().rstrip('/'))
if match:
return match.group(1)
except Exception:
pass
return os.environ.get('GITEA_TARGET_REPO', 'UniqueSoft/APAW')
def create_or_get_issue(project_name, workflow_type, issue_number=None):
"""Create Gitea issue for workflow tracking"""
if issue_number:
return issue_number
# Get token from env vars — see .kilo/shared/gitea-auth.md
token = os.environ.get('GITEA_TOKEN', '')
username = os.environ.get('GITEA_USER', '')
api_url = os.environ.get('GITEA_API_URL', 'https://git.softuniq.eu/api/v1')
if not token and username:
password = os.environ.get('GITEA_PASS', '')
credentials = base64.b64encode(f"{username}:{password}".encode()).decode()
token_req = urllib.request.Request(
f"{api_url}/users/{username}/tokens",
data=json.dumps({"name": f"workflow-{os.getpid()}", "scopes": ["all"]}).encode(),
headers={'Content-Type': 'application/json', 'Authorization': f'Basic {credentials}'},
method='POST'
)
with urllib.request.urlopen(token_req) as r:
token = json.loads(r.read())['sha1']
elif not token:
raise ValueError('Set GITEA_TOKEN or GITEA_USER+GITEA_PASS env vars')
# Create issue
body = f"""## Overview
Create {workflow_type} for {project_name}.
## Workflow Progress
| Step | Status | Agent | Duration |
|------|--------|-------|----------|
| 1. Requirements | ⏳ Pending | - | - |
| 2. Architecture | ⏳ Pending | - | - |
| 3. Backend | ⏳ Pending | - | - |
| 4. Frontend | ⏳ Pending | - | - |
| 5. Testing | ⏳ Pending | - | - |
| 6. Review | ⏳ Pending | - | - |
| 7. Docker | ⏳ Pending | - | - |
| 8. Documentation | ⏳ Pending | - | - |
| 9. Delivery | ⏳ Pending | - | - |
## Quality Gates
| Gate | Status | Score |
|------|--------|-------|
| Requirements | ⏳ | - |
| Architecture | ⏳ | - |
| Implementation | ⏳ | - |
| Testing | ⏳ | - |
| Security | ⏳ | - |
| Docker | ⏳ | - |
| Documentation | ⏳ | - |
| Delivery | ⏳ | - |
## Labels
- workflow
- {workflow_type}
- status: new
"""
issue_req = urllib.request.Request(
f"{api_url}/repos/{get_target_repo()}/issues",
data=json.dumps({
"title": f"[{workflow_type}] {project_name}",
"body": body,
"labels": ["workflow", workflow_type, "status: new"]
}).encode(),
headers={'Content-Type': 'application/json', 'Authorization': f'token {token}'},
method='POST'
)
with urllib.request.urlopen(issue_req) as r:
issue = json.loads(r.read())
return issue['number']
Step 1: Requirements
Agent: @RequirementRefiner
def execute_requirements(issue_number, project_name, workflow_type):
"""Step 1: Requirements gathering"""
# Post start
post_comment(issue_number, f"""## 🔄 Requirements Started
**Agent**: @requirement-refiner
**Step**: 1/9
**Time**: {timestamp()}
""")
try:
# Load workflow-specific requirements
requirements = load_requirements(workflow_type)
# Refine requirements
agent = RequirementRefiner()
result = agent.refine(requirements)
# Validate
if not validate_requirements(result):
raise ValidationError("Requirements incomplete")
# Save artifacts
save_artifact('requirements', 'requirements.md', result.document)
save_artifact('requirements', 'user-stories.md', result.stories)
# Post success
post_comment(issue_number, f"""## ✅ Requirements Complete
**Duration**: {duration()}
**Files**: {count_files()}
### User Stories: {result.stories_count}
### Acceptance Criteria: {result.criteria_count}
### Artifacts:
- `.workflow/requirements.md`
- `.workflow/user-stories.md`
### Gate: Requirements
| Check | Status |
|-------|--------|
| User stories defined | ✅ |
| Acceptance criteria | ✅ |
| Technical constraints | ✅ |
**Next**: Architecture
""")
update_progress(issue_number, 1, 'Requirements', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Requirements', e)
raise
Step 2: Architecture
Agent: @SystemAnalyst
def execute_architecture(issue_number, project_name, workflow_type):
"""Step 2: Architecture design"""
post_comment(issue_number, f"""## 🔄 Architecture Started
**Agent**: @system-analyst
**Step**: 2/9
**Time**: {timestamp()}
""")
try:
requirements = load_artifact('requirements', 'requirements.md')
agent = SystemAnalyst()
result = agent.design(requirements, workflow_type)
# Validate
if not validate_architecture(result):
raise ValidationError("Architecture incomplete")
# Save artifacts
save_artifact('architecture', 'database-schema.sql', result.schema)
save_artifact('architecture', 'api-endpoints.md', result.api)
save_artifact('architecture', 'tech-stack.md', result.stack)
# Create backend structure
create_project_structure(result.structure)
post_comment(issue_number, f"""## ✅ Architecture Complete
**Duration**: {duration()}
### Database Tables: {result.tables_count}
### API Endpoints: {result.endpoints_count}
### Tech Stack:
- Frontend: {result.frontend}
- Backend: {result.backend}
- Database: {result.database}
### Artifacts:
- `.workflow/database-schema.sql`
- `.workflow/api-endpoints.md`
- `.workflow/tech-stack.md`
### Gate: Architecture
| Check | Status |
|-------|--------|
| Database schema | ✅ |
| API documented | ✅ |
| Tech stack | ✅ |
**Next**: Backend Implementation
""")
update_progress(issue_number, 2, 'Architecture', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Architecture', e)
raise
Step 3: Backend
Agent: @BackendDeveloper
def execute_backend(issue_number, project_name, workflow_type):
"""Step 3: Backend implementation"""
post_comment(issue_number, f"""## 🔄 Backend Started
**Agent**: @backend-developer
**Step**: 3/9
**Time**: {timestamp()}
""")
try:
architecture = load_artifact('architecture', 'database-schema.sql')
agent = BackendDeveloper()
result = agent.implement(architecture, workflow_type)
# Validate
if not validate_backend(result):
raise ValidationError("Backend incomplete")
# Check build
if not build_backend():
raise BuildError("Backend build failed")
post_comment(issue_number, f"""## ✅ Backend Complete
**Duration**: {duration()}
**Files**: {result.files_count}
### API Endpoints: {result.endpoints}
### Database Tables: {result.tables}
### Build Status: ✅ Success
### Gate: Implementation
| Check | Status |
|-------|--------|
| Code written | ✅ |
| No errors | ✅ |
| Builds | ✅ |
**Next**: Frontend Implementation
""")
update_progress(issue_number, 3, 'Backend', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Backend', e)
raise
Step 4: Frontend
Agent: @FrontendDeveloper
def execute_frontend(issue_number, project_name, workflow_type):
"""Step 4: Frontend implementation"""
post_comment(issue_number, f"""## 🔄 Frontend Started
**Agent**: @frontend-developer
**Step**: 4/9
**Time**: {timestamp()}
""")
try:
architecture = load_artifact('architecture', 'tech-stack.md')
backend = get_backend_endpoints()
agent = FrontendDeveloper()
result = agent.implement(architecture, backend, workflow_type)
# Validate
if not validate_frontend(result):
raise ValidationError("Frontend incomplete")
# Check build
if not build_frontend():
raise BuildError("Frontend build failed")
post_comment(issue_number, f"""## ✅ Frontend Complete
**Duration**: {duration()}
**Files**: {result.files_count}
### Pages: {result.pages}
### Components: {result.components}
### Routes: {result.routes}
### Build Status: ✅ Success
### Gate: Implementation
| Check | Status |
|-------|--------|
| Pages created | ✅ |
| Components | ✅ |
| Builds | ✅ |
**Next**: Testing
""")
update_progress(issue_number, 4, 'Frontend', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Frontend', e)
raise
Step 5: Testing
Agent: @SDETEngineer + @browser-automation
def execute_testing(issue_number, project_name, workflow_type):
"""Step 5: E2E Testing"""
post_comment(issue_number, f"""## 🔄 Testing Started
**Agent**: @sdet-engineer
**Step**: 5/9
**Time**: {timestamp()}
""")
try:
agent = SDETEngineer()
result = agent.test_all(workflow_type)
# Validate
if result.failed > 0:
raise TestError(f"{result.failed} tests failed")
if result.coverage < 80:
raise TestError(f"Coverage {result.coverage}% < 80%")
post_comment(issue_number, f"""## ✅ Testing Complete
**Duration**: {duration()}
### Test Results:
| Suite | Passed | Failed | Coverage |
|-------|--------|--------|----------|
| Unit | {result.unit.passed}/{result.unit.total} | {result.unit.failed} | {result.unit.coverage}% |
| Integration | {result.integration.passed}/{result.integration.total} | {result.integration.failed} | - |
| E2E | {result.e2e.passed}/{result.e2e.total} | {result.e2e.failed} | - |
### Total: {result.passed}/{result.total} tests passed
### Coverage: {result.coverage}%
### Gate: Testing
| Check | Status |
|-------|--------|
| All tests pass | ✅ |
| Coverage > 80% | ✅ |
| No critical bugs | ✅ |
**Next**: Code Review
""")
update_progress(issue_number, 5, 'Testing', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Testing', e)
raise
Step 6: Review
Agent: @CodeSkeptic + @SecurityAuditor
def execute_review(issue_number, project_name, workflow_type):
"""Step 6: Code Review + Security Audit"""
post_comment(issue_number, f"""## 🔄 Review Started
**Agents**: @code-skeptic, @security-auditor
**Step**: 6/9
**Time**: {timestamp()}
""")
try:
# Code review
skeptic = CodeSkeptic()
review_result = skeptic.review_all()
if review_result.critical_issues > 0:
raise ReviewError(f"{review_result.critical_issues} critical issues found")
# Security audit
auditor = SecurityAuditor()
security_result = auditor.audit_all()
if security_result.vulnerabilities > 0:
raise SecurityError(f"{security_result.vulnerabilities} vulnerabilities found")
post_comment(issue_number, f"""## ✅ Review Complete
**Duration**: {duration()}
### Code Review:
| Category | Issues | Severity |
|----------|--------|----------|
| Critical | {review_result.critical} | 🔴 |
| Major | {review_result.major} | 🟡 |
| Minor | {review_result.minor} | 🟢 |
### Security Audit:
| Vulnerability | Count | Severity |
|---------------|-------|----------|
| High | {security_result.high} | 🔴 |
| Medium | {security_result.medium} | 🟡 |
| Low | {security_result.low} | 🟢 |
### Gate: Review
| Check | Status |
|-------|--------|
| No critical issues | ✅ |
| No vulnerabilities | ✅ |
| Performance OK | ✅ |
**Next**: Docker
""")
update_progress(issue_number, 6, 'Review', '✅')
return {review: review_result, security: security_result}
except Exception as e:
handle_error(issue_number, 'Review', e)
raise
Step 7: Docker
Agent: @ReleaseManager
def execute_docker(issue_number, project_name, workflow_type):
"""Step 7: Docker deployment"""
post_comment(issue_number, f"""## 🔄 Docker Started
**Agent**: @release-manager
**Step**: 7/9
**Time**: {timestamp()}
""")
try:
agent = ReleaseManager()
result = agent.dockerize(project_name, workflow_type)
# Validate
if not build_docker():
raise DockerError("Docker build failed")
if not health_check():
raise DockerError("Health check failed")
post_comment(issue_number, f"""## ✅ Docker Complete
**Duration**: {duration()}
### Images:
- Frontend: `{result.frontend_image}` ({result.frontend_size}MB)
- Backend: `{result.backend_image}` ({result.backend_size}MB)
### Health Check: ✅ Passing
### Port: 8080
### Commands:
```bash
docker-compose up -d
# Access: http://localhost:8080
Gate: Docker
| Check | Status |
|---|---|
| Builds | ✅ |
| Starts | ✅ |
| Health | ✅ |
Next: Documentation """)
update_progress(issue_number, 7, 'Docker', '✅')
return result
except Exception as e:
handle_error(issue_number, 'Docker', e)
raise
## Step 8: Documentation
**Agent**: `@SystemAnalyst`
```python
def execute_documentation(issue_number, project_name, workflow_type):
"""Step 8: Documentation"""
post_comment(issue_number, f"""## 🔄 Documentation Started
**Agent**: @system-analyst
**Step**: 8/9
**Time**: {timestamp()}
""")
try:
# Create documentation
docs = create_documentation(project_name, workflow_type)
# Validate
if not validate_documentation(docs):
raise DocError("Documentation incomplete")
post_comment(issue_number, f"""## ✅ Documentation Complete
**Duration**: {duration()}
**Files**: {len(docs)} documents
### Documentation Created:
| Document | Status | Sections |
|----------|--------|----------|
| README.md | ✅ | {docs.readme_sections} |
| docs/API.md | ✅ | {docs.api_sections} |
| docs/DEPLOYMENT.md | ✅ | {docs.deploy_sections} |
| docs/ADMIN.md | ✅ | {docs.admin_sections} |
### Gate: Documentation
| Check | Status |
|-------|--------|
| README | ✅ |
| API docs | ✅ |
| Deployment guide | ✅ |
| Admin guide | ✅ |
**Next**: Final Delivery
""")
update_progress(issue_number, 8, 'Documentation', '✅')
return docs
except Exception as e:
handle_error(issue_number, 'Documentation', e)
raise
Step 9: Final Delivery
Agent: @Evaluator
def execute_delivery(issue_number, project_name, workflow_type):
"""Step 9: Final delivery validation"""
post_comment(issue_number, f"""## 🔄 Final Delivery Started
**Agent**: @evaluator
**Step**: 9/9
**Time**: {timestamp()}
""")
try:
# Run all checks
checks = validate_final_delivery(project_name)
if not checks.all_passed:
raise DeliveryError("Some checks failed")
# Create delivery comment
post_final_delivery(issue_number, project_name, workflow_type, checks)
# Close issue
close_issue(issue_number, "Workflow completed successfully")
return checks
except Exception as e:
handle_error(issue_number, 'Delivery', e)
raise
Error Handling
def handle_error(issue_number, step_name, error):
"""Handle workflow error - BLOCK and report"""
post_comment(issue_number, f"""## ❌ {step_name} Failed
**Error**: {str(error)}
**Type**: {type(error).__name__}
**Time**: {timestamp()}
### Blocker:
{error.blocker if hasattr(error, 'blocker') else error}
### How to Fix:
{error.fix_steps if hasattr(error, 'fix_steps') else 'Review error and fix manually'}
### Cannot Proceed Until:
- [ ] Error is resolved
- [ ] Step is re-run successfully
**Workflow PAUSED** - waiting for fix.
Reply with "retry" to re-run step after fixing.
""")
# DO NOT proceed to next step
# Workflow is BLOCKED until error is fixed
Post Final Delivery
def post_final_delivery(issue_number, project_name, workflow_type, checks):
"""Post final delivery comment"""
post_comment(issue_number, f"""## 🎉 Workflow Complete - READY FOR DELIVERY
**Project**: {project_name}
**Type**: {workflow_type}
**Issue**: #{issue_number}
---
## 📦 Delivery Package
### Source Code
- **Repository**: {target_repo}
- **Branch**: main
- **Commit**: {get_last_commit()}
### Docker
- **Image**: `{project_name}:latest`
- **Size**: {checks.docker_size}MB
- **Health**: ✅ Passing
### Quality Score: {checks.score}/100
---
## ✅ All Quality Gates Passed
| Gate | Status | Score |
|------|--------|-------|
| Requirements | ✅ | {checks.gates.requirements}/10 |
| Architecture | ✅ | {checks.gates.architecture}/10 |
| Backend | ✅ | {checks.gates.backend}/10 |
| Frontend | ✅ | {checks.gates.frontend}/10 |
| Testing | ✅ | {checks.gates.testing}/10 |
| Security | ✅ | {checks.gates.security}/10 |
| Docker | ✅ | {checks.gates.docker}/10 |
| Documentation | ✅ | {checks.gates.docs}/10 |
| **Total** | ✅ | **{checks.total}** |
---
## 🚀 Quick Start
```bash
# Run locally
git clone https://git.softuniq.eu/{target_repo}.git
cd {project_name}
docker-compose up -d
# Access
# Frontend: http://localhost
# Admin: http://localhost/admin
# API: http://localhost/api
📋 Client Handoff Checklist
- Source code in repository
- Docker builds successfully
- All tests passing
- Documentation complete
- Security audit passed
- Client can deploy independently
Status: 🟢 READY FOR CLIENT DELIVERY Completed: {timestamp()} """)
# Add completion label
add_label(issue_number, "status: completed")
remove_label(issue_number, "status: new")
## Main Workflow Function
```python
def run_workflow(workflow_type, project_name, issue_number=None):
"""Execute complete workflow with Gitea tracking"""
# Step 0: Create/Get Issue (MANDATORY)
issue = create_or_get_issue(project_name, workflow_type, issue_number)
try:
# Step 1: Requirements
requirements = execute_requirements(issue, project_name, workflow_type)
checkpoint('requirements', 'architecture', issue)
# Step 2: Architecture
architecture = execute_architecture(issue, project_name, workflow_type)
checkpoint('architecture', 'backend', issue)
# Step 3: Backend
backend = execute_backend(issue, project_name, workflow_type)
checkpoint('backend', 'frontend', issue)
# Step 4: Frontend
frontend = execute_frontend(issue, project_name, workflow_type)
checkpoint('frontend', 'testing', issue)
# Step 5: Testing
testing = execute_testing(issue, project_name, workflow_type)
checkpoint('testing', 'review', issue)
# Step 6: Review
review = execute_review(issue, project_name, workflow_type)
checkpoint('review', 'docker', issue)
# Step 7: Docker
docker = execute_docker(issue, project_name, workflow_type)
checkpoint('docker', 'documentation', issue)
# Step 8: Documentation
docs = execute_documentation(issue, project_name, workflow_type)
checkpoint('documentation', 'delivery', issue)
# Step 9: Final Delivery
delivery = execute_delivery(issue, project_name, workflow_type)
return {
'success': True,
'issue': issue,
'project': project_name,
'type': workflow_type
}
except WorkflowError as e:
# Workflow is BLOCKED
# DO NOT proceed to next step
# Error already posted to Gitea
return {
'success': False,
'issue': issue,
'error': str(e),
'step': e.step
}
Usage
User: /workflow landing-page --project_name="MySite"
Agent:
1. Creates Gitea issue #N
2. Executes all 9 steps
3. Posts progress to issue after each step
4. Validates quality gates
5. Blocks on errors (no partial results)
6. Delivers complete package
7. Posts final delivery comment
8. Closes issue