home / skills / chunkytortoise / enterprisehub / workflow-automation-builder
This skill helps automate workflows and generate optimized CI/CD pipelines, reducing manual tasks and accelerating deployments across projects.
npx playbooks add skill chunkytortoise/enterprisehub --skill workflow-automation-builderReview the files below or copy the command above to add this skill to your agents.
---
name: Workflow Automation Builder
description: This skill should be used when the user asks to "automate workflows", "create CI/CD pipelines", "automate deployments", "setup GitHub Actions", "optimize build processes", "automate testing", or needs comprehensive workflow automation and process optimization.
version: 1.0.0
---
# Workflow Automation Builder: Time-Saving CI/CD & Process Automation
## Overview
The Workflow Automation Builder creates intelligent automation workflows that reduce manual overhead by 50-70%. It generates optimized CI/CD pipelines, automates repetitive tasks, and creates self-maintaining development workflows.
## Core Automation Areas
### 1. Intelligent CI/CD Pipeline Generation
**Smart Pipeline Analysis:**
```python
import yaml
import os
from pathlib import Path
from typing import Dict, List, Any
class CICDPipelineGenerator:
def __init__(self, project_path: str):
self.project_path = Path(project_path)
self.detected_technologies = self._detect_technologies()
self.deployment_targets = self._detect_deployment_targets()
def _detect_technologies(self) -> Dict[str, bool]:
"""Automatically detect project technologies"""
technologies = {
'python': (self.project_path / 'requirements.txt').exists() or
(self.project_path / 'pyproject.toml').exists(),
'nodejs': (self.project_path / 'package.json').exists(),
'typescript': (self.project_path / 'tsconfig.json').exists(),
'docker': (self.project_path / 'Dockerfile').exists(),
'streamlit': self._check_file_content('requirements.txt', 'streamlit'),
'fastapi': self._check_file_content('requirements.txt', 'fastapi'),
'react': self._check_file_content('package.json', 'react'),
'nextjs': (self.project_path / 'next.config.js').exists()
}
return {k: v for k, v in technologies.items() if v}
def _detect_deployment_targets(self) -> List[str]:
"""Detect deployment configurations"""
targets = []
if (self.project_path / 'railway.json').exists():
targets.append('railway')
if (self.project_path / 'vercel.json').exists():
targets.append('vercel')
if (self.project_path / 'render.yaml').exists():
targets.append('render')
if (self.project_path / 'fly.toml').exists():
targets.append('fly')
return targets
def _check_file_content(self, filename: str, search_term: str) -> bool:
"""Check if file contains specific term"""
file_path = self.project_path / filename
if file_path.exists():
try:
content = file_path.read_text()
return search_term in content.lower()
except:
return False
return False
def generate_optimized_pipeline(self) -> Dict[str, Any]:
"""Generate optimized CI/CD pipeline based on detected technologies"""
pipeline = {
'name': 'Automated CI/CD Pipeline',
'on': {
'push': {'branches': ['main', 'develop']},
'pull_request': {'branches': ['main']},
'schedule': [{'cron': '0 2 * * 0'}] # Weekly security scan
},
'jobs': {}
}
# Add jobs based on detected technologies
if self.detected_technologies.get('python'):
pipeline['jobs'].update(self._generate_python_jobs())
if self.detected_technologies.get('nodejs') or self.detected_technologies.get('typescript'):
pipeline['jobs'].update(self._generate_nodejs_jobs())
# Add deployment jobs
if self.deployment_targets:
pipeline['jobs'].update(self._generate_deployment_jobs())
# Add security and quality jobs
pipeline['jobs'].update(self._generate_security_jobs())
return pipeline
def _generate_python_jobs(self) -> Dict[str, Any]:
"""Generate Python-specific CI/CD jobs"""
return {
'python-quality': {
'name': 'Python Code Quality & Testing',
'runs-on': 'ubuntu-latest',
'strategy': {
'matrix': {
'python-version': ['3.10', '3.11', '3.12']
}
},
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Set up Python ${{ matrix.python-version }}',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '${{ matrix.python-version }}'}
},
{
'name': 'Cache pip dependencies',
'uses': 'actions/cache@v3',
'with': {
'path': '~/.cache/pip',
'key': '${{ runner.os }}-pip-${{ hashFiles(\'**/requirements*.txt\') }}',
'restore-keys': '${{ runner.os }}-pip-'
}
},
{
'name': 'Install dependencies',
'run': 'pip install -r requirements.txt && pip install pytest black isort flake8 bandit safety'
},
{
'name': 'Code formatting check (Black)',
'run': 'black --check .',
'continue-on-error': True
},
{
'name': 'Import sorting check (isort)',
'run': 'isort --check-only .',
'continue-on-error': True
},
{
'name': 'Linting (flake8)',
'run': 'flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics'
},
{
'name': 'Security check (Bandit)',
'run': 'bandit -r . -f json -o bandit-report.json',
'continue-on-error': True
},
{
'name': 'Dependency vulnerability check',
'run': 'safety check',
'continue-on-error': True
},
{
'name': 'Run tests with coverage',
'run': 'pytest --cov=. --cov-report=xml --cov-report=term-missing'
},
{
'name': 'Upload coverage to Codecov',
'uses': 'codecov/codecov-action@v3',
'with': {
'file': './coverage.xml',
'fail_ci_if_error': False
}
}
]
}
}
def _generate_nodejs_jobs(self) -> Dict[str, Any]:
"""Generate Node.js/TypeScript-specific CI/CD jobs"""
return {
'nodejs-quality': {
'name': 'Node.js Code Quality & Testing',
'runs-on': 'ubuntu-latest',
'strategy': {
'matrix': {
'node-version': ['18.x', '20.x', '21.x']
}
},
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Use Node.js ${{ matrix.node-version }}',
'uses': 'actions/setup-node@v3',
'with': {
'node-version': '${{ matrix.node-version }}',
'cache': 'npm'
}
},
{
'name': 'Install dependencies',
'run': 'npm ci'
},
{
'name': 'Type checking',
'run': 'npm run type-check',
'continue-on-error': True
},
{
'name': 'Linting',
'run': 'npm run lint',
'continue-on-error': True
},
{
'name': 'Format check',
'run': 'npm run format:check',
'continue-on-error': True
},
{
'name': 'Security audit',
'run': 'npm audit --audit-level high',
'continue-on-error': True
},
{
'name': 'Run tests',
'run': 'npm test -- --coverage'
},
{
'name': 'Build project',
'run': 'npm run build'
}
]
}
}
def _generate_deployment_jobs(self) -> Dict[str, Any]:
"""Generate deployment jobs based on detected targets"""
jobs = {}
if 'railway' in self.deployment_targets:
jobs['deploy-railway'] = {
'name': 'Deploy to Railway',
'runs-on': 'ubuntu-latest',
'needs': ['python-quality'] if 'python' in self.detected_technologies else ['nodejs-quality'],
'if': 'github.ref == \'refs/heads/main\' && github.event_name == \'push\'',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Deploy to Railway',
'uses': 'railwayapp/railway-deploy@v2',
'with': {
'railway-token': '${{ secrets.RAILWAY_TOKEN }}',
'service': 'production'
}
}
]
}
if 'vercel' in self.deployment_targets:
jobs['deploy-vercel'] = {
'name': 'Deploy to Vercel',
'runs-on': 'ubuntu-latest',
'needs': ['nodejs-quality'],
'if': 'github.ref == \'refs/heads/main\' && github.event_name == \'push\'',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Deploy to Vercel',
'uses': 'amondnet/vercel-action@v20',
'with': {
'vercel-token': '${{ secrets.VERCEL_TOKEN }}',
'vercel-org-id': '${{ secrets.ORG_ID }}',
'vercel-project-id': '${{ secrets.PROJECT_ID }}',
'vercel-args': '--prod'
}
}
]
}
return jobs
def _generate_security_jobs(self) -> Dict[str, Any]:
"""Generate security and monitoring jobs"""
return {
'security-scan': {
'name': 'Security Scanning',
'runs-on': 'ubuntu-latest',
'if': 'github.event_name == \'schedule\' || contains(github.event.head_commit.message, \'[security]\')',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Run Trivy vulnerability scanner',
'uses': 'aquasecurity/trivy-action@master',
'with': {
'scan-type': 'fs',
'scan-ref': '.',
'format': 'sarif',
'output': 'trivy-results.sarif'
}
},
{
'name': 'Upload Trivy scan results to GitHub Security tab',
'uses': 'github/codeql-action/upload-sarif@v2',
'if': 'always()',
'with': {'sarif_file': 'trivy-results.sarif'}
}
]
}
}
```
### 2. Automated Testing Workflows
**Smart Test Automation:**
```python
class TestAutomationBuilder:
def __init__(self, project_path: str):
self.project_path = Path(project_path)
def generate_test_automation(self) -> Dict[str, Any]:
"""Generate comprehensive test automation workflow"""
return {
'name': 'Automated Testing Suite',
'on': {
'push': {'branches': ['**']},
'pull_request': {'branches': ['main', 'develop']},
'schedule': [{'cron': '0 6 * * 1-5'}] # Weekday morning tests
},
'jobs': {
'test-matrix': self._generate_test_matrix(),
'integration-tests': self._generate_integration_tests(),
'performance-tests': self._generate_performance_tests(),
'security-tests': self._generate_security_tests()
}
}
def _generate_test_matrix(self) -> Dict[str, Any]:
"""Generate matrix testing across multiple environments"""
return {
'name': 'Matrix Testing',
'runs-on': 'ubuntu-latest',
'strategy': {
'matrix': {
'python-version': ['3.10', '3.11', '3.12'],
'dependency-version': ['latest', 'minimum'],
'include': [
{
'python-version': '3.10',
'dependency-version': 'latest',
'coverage': True
}
]
}
},
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Set up Python ${{ matrix.python-version }}',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '${{ matrix.python-version }}'}
},
{
'name': 'Install dependencies',
'run': '''
if [ "${{ matrix.dependency-version }}" == "minimum" ]; then
pip install -r requirements-min.txt
else
pip install -r requirements.txt
fi
pip install pytest pytest-cov pytest-xdist pytest-benchmark
'''
},
{
'name': 'Run tests with coverage',
'run': 'pytest -n auto --cov=. --cov-report=xml --benchmark-skip',
'if': 'matrix.coverage'
},
{
'name': 'Run tests without coverage',
'run': 'pytest -n auto --benchmark-skip',
'if': '!matrix.coverage'
}
]
}
def _generate_integration_tests(self) -> Dict[str, Any]:
"""Generate integration test workflow"""
return {
'name': 'Integration Tests',
'runs-on': 'ubuntu-latest',
'needs': ['test-matrix'],
'services': {
'postgres': {
'image': 'postgres:15',
'env': {
'POSTGRES_PASSWORD': 'postgres',
'POSTGRES_DB': 'test_db'
},
'options': '--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5'
},
'redis': {
'image': 'redis:7',
'options': '--health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5'
}
},
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Set up Python',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '3.11'}
},
{
'name': 'Install dependencies',
'run': 'pip install -r requirements.txt'
},
{
'name': 'Run integration tests',
'run': 'pytest tests/integration/ -v --tb=short',
'env': {
'DATABASE_URL': 'postgresql://postgres:postgres@localhost:5432/test_db',
'REDIS_URL': 'redis://localhost:6379/0'
}
}
]
}
def _generate_performance_tests(self) -> Dict[str, Any]:
"""Generate performance testing workflow"""
return {
'name': 'Performance Tests',
'runs-on': 'ubuntu-latest',
'if': 'github.event_name == \'schedule\' || contains(github.event.head_commit.message, \'[perf]\')',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Set up Python',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '3.11'}
},
{
'name': 'Install dependencies',
'run': 'pip install -r requirements.txt pytest-benchmark locust'
},
{
'name': 'Run benchmark tests',
'run': 'pytest tests/benchmark/ --benchmark-only --benchmark-json=benchmark.json'
},
{
'name': 'Run load tests',
'run': 'locust -f tests/load/locustfile.py --headless --users 50 --spawn-rate 5 --run-time 60s --host http://localhost:8501'
},
{
'name': 'Upload benchmark results',
'uses': 'actions/upload-artifact@v3',
'with': {
'name': 'benchmark-results',
'path': 'benchmark.json'
}
}
]
}
```
### 3. Deployment Automation
**Zero-Downtime Deployment:**
```python
class DeploymentAutomationBuilder:
def __init__(self):
self.deployment_strategies = {
'railway': self._railway_deployment,
'vercel': self._vercel_deployment,
'docker': self._docker_deployment
}
def generate_deployment_workflow(self, platform: str) -> Dict[str, Any]:
"""Generate platform-specific deployment workflow"""
if platform in self.deployment_strategies:
return self.deployment_strategies[platform]()
else:
raise ValueError(f"Unsupported platform: {platform}")
def _railway_deployment(self) -> Dict[str, Any]:
"""Generate Railway deployment with health checks"""
return {
'name': 'Railway Deployment',
'on': {
'push': {'branches': ['main']},
'workflow_dispatch': None
},
'jobs': {
'deploy': {
'name': 'Deploy to Railway',
'runs-on': 'ubuntu-latest',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Deploy to Railway',
'uses': 'railwayapp/railway-deploy@v2',
'with': {
'railway-token': '${{ secrets.RAILWAY_TOKEN }}',
'service': '${{ github.ref_name == \'main\' && \'production\' || \'staging\' }}'
}
},
{
'name': 'Health Check',
'run': '''
echo "Waiting for deployment to be ready..."
sleep 30
for i in {1..10}; do
if curl -f $HEALTH_CHECK_URL; then
echo "Deployment successful!"
exit 0
fi
echo "Attempt $i failed, retrying in 10s..."
sleep 10
done
echo "Deployment health check failed"
exit 1
''',
'env': {
'HEALTH_CHECK_URL': '${{ secrets.RAILWAY_HEALTH_URL }}'
}
},
{
'name': 'Rollback on failure',
'if': 'failure()',
'run': '''
echo "Deployment failed, initiating rollback..."
# Add rollback logic here
'''
}
]
}
}
}
def _vercel_deployment(self) -> Dict[str, Any]:
"""Generate Vercel deployment with preview environments"""
return {
'name': 'Vercel Deployment',
'on': {
'push': {'branches': ['main', 'develop']},
'pull_request': {'branches': ['main']},
'workflow_dispatch': None
},
'jobs': {
'deploy': {
'name': 'Deploy to Vercel',
'runs-on': 'ubuntu-latest',
'outputs': {
'preview-url': '${{ steps.vercel.outputs.preview-url }}'
},
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Install Node.js',
'uses': 'actions/setup-node@v3',
'with': {
'node-version': '18',
'cache': 'npm'
}
},
{
'name': 'Install dependencies',
'run': 'npm ci'
},
{
'name': 'Build project',
'run': 'npm run build'
},
{
'id': 'vercel',
'name': 'Deploy to Vercel',
'uses': 'amondnet/vercel-action@v20',
'with': {
'vercel-token': '${{ secrets.VERCEL_TOKEN }}',
'vercel-org-id': '${{ secrets.ORG_ID }}',
'vercel-project-id': '${{ secrets.PROJECT_ID }}',
'vercel-args': '${{ github.ref_name == \'main\' && \'--prod\' || \'\' }}'
}
}
]
},
'test-deployment': {
'name': 'Test Deployment',
'runs-on': 'ubuntu-latest',
'needs': ['deploy'],
'steps': [
{
'name': 'Test deployment URL',
'run': '''
URL="${{ needs.deploy.outputs.preview-url }}"
echo "Testing deployment at: $URL"
# Basic health check
if curl -f "$URL"; then
echo "Deployment is accessible"
else
echo "Deployment failed health check"
exit 1
fi
# Performance check
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' "$URL")
echo "Response time: ${RESPONSE_TIME}s"
if (( $(echo "$RESPONSE_TIME > 3.0" | bc -l) )); then
echo "Warning: Response time > 3s"
fi
'''
}
]
}
}
}
```
### 4. Automated Monitoring & Alerting
**Intelligent Monitoring Setup:**
```python
class MonitoringAutomationBuilder:
def __init__(self):
self.monitoring_configs = {}
def generate_monitoring_workflow(self) -> Dict[str, Any]:
"""Generate automated monitoring and alerting workflow"""
return {
'name': 'Automated Monitoring',
'on': {
'schedule': [
{'cron': '*/15 * * * *'}, # Every 15 minutes
{'cron': '0 9 * * MON'} # Weekly summary
],
'workflow_dispatch': None
},
'jobs': {
'health-check': self._generate_health_check_job(),
'performance-monitoring': self._generate_performance_monitoring_job(),
'cost-monitoring': self._generate_cost_monitoring_job(),
'security-monitoring': self._generate_security_monitoring_job()
}
}
def _generate_health_check_job(self) -> Dict[str, Any]:
"""Generate comprehensive health check job"""
return {
'name': 'Health Check Monitoring',
'runs-on': 'ubuntu-latest',
'steps': [
{
'name': 'Check Application Health',
'run': '''
# Check main application
if ! curl -f ${{ secrets.APP_URL }}/_health; then
echo "❌ Application health check failed"
echo "HEALTH_STATUS=FAILED" >> $GITHUB_ENV
else
echo "✅ Application health check passed"
echo "HEALTH_STATUS=PASSED" >> $GITHUB_ENV
fi
# Check database connectivity
if ! curl -f ${{ secrets.APP_URL }}/_health/db; then
echo "❌ Database health check failed"
echo "DB_STATUS=FAILED" >> $GITHUB_ENV
else
echo "✅ Database health check passed"
echo "DB_STATUS=PASSED" >> $GITHUB_ENV
fi
# Check external API dependencies
if ! curl -f ${{ secrets.APP_URL }}/_health/external; then
echo "⚠️ External API health check failed"
echo "EXTERNAL_STATUS=FAILED" >> $GITHUB_ENV
else
echo "✅ External API health check passed"
echo "EXTERNAL_STATUS=PASSED" >> $GITHUB_ENV
fi
'''
},
{
'name': 'Send Slack Alert on Failure',
'if': 'env.HEALTH_STATUS == \'FAILED\' || env.DB_STATUS == \'FAILED\'',
'uses': '8398a7/action-slack@v3',
'with': {
'status': 'failure',
'text': '🚨 Critical system failure detected!\nHealth: ${{ env.HEALTH_STATUS }}\nDB: ${{ env.DB_STATUS }}',
'webhook_url': '${{ secrets.SLACK_WEBHOOK }}'
}
}
]
}
def _generate_performance_monitoring_job(self) -> Dict[str, Any]:
"""Generate performance monitoring job"""
return {
'name': 'Performance Monitoring',
'runs-on': 'ubuntu-latest',
'if': 'github.event.schedule == \'*/15 * * * *\'',
'steps': [
{
'name': 'Performance Check',
'run': '''
# Measure response times
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' ${{ secrets.APP_URL }})
TTFB=$(curl -o /dev/null -s -w '%{time_starttransfer}' ${{ secrets.APP_URL }})
echo "Response Time: ${RESPONSE_TIME}s"
echo "Time to First Byte: ${TTFB}s"
# Check if performance is degraded
if (( $(echo "$RESPONSE_TIME > 5.0" | bc -l) )); then
echo "⚠️ Performance degradation detected"
echo "PERF_ALERT=true" >> $GITHUB_ENV
echo "RESPONSE_TIME=$RESPONSE_TIME" >> $GITHUB_ENV
fi
# Store metrics for trending
echo "$(date '+%Y-%m-%d %H:%M:%S'),$RESPONSE_TIME,$TTFB" >> performance_metrics.csv
'''
},
{
'name': 'Upload Performance Metrics',
'uses': 'actions/upload-artifact@v3',
'with': {
'name': 'performance-metrics',
'path': 'performance_metrics.csv'
}
},
{
'name': 'Performance Alert',
'if': 'env.PERF_ALERT == \'true\'',
'uses': '8398a7/action-slack@v3',
'with': {
'status': 'warning',
'text': '🐌 Performance degradation detected!\nResponse Time: ${{ env.RESPONSE_TIME }}s (threshold: 5s)',
'webhook_url': '${{ secrets.SLACK_WEBHOOK }}'
}
}
]
}
def _generate_cost_monitoring_job(self) -> Dict[str, Any]:
"""Generate cost monitoring job"""
return {
'name': 'Cost Monitoring',
'runs-on': 'ubuntu-latest',
'if': 'github.event.schedule == \'0 9 * * MON\'',
'steps': [
{
'name': 'Monitor Infrastructure Costs',
'run': '''
# Fetch Railway costs (example)
RAILWAY_USAGE=$(curl -H "Authorization: Bearer ${{ secrets.RAILWAY_API_TOKEN }}" \
"https://backboard.railway.app/graphql" \
-d '{"query": "{ me { projects { name usage { current } } } }"}')
echo "Railway Usage: $RAILWAY_USAGE"
# Fetch Vercel costs (example)
VERCEL_USAGE=$(curl -H "Authorization: Bearer ${{ secrets.VERCEL_TOKEN }}" \
"https://api.vercel.com/v1/teams/usage")
echo "Vercel Usage: $VERCEL_USAGE"
# Calculate total monthly costs
# This would parse the JSON responses and calculate costs
python3 - << 'EOF'
import json
import os
# Parse usage data and calculate costs
# Send alert if costs exceed threshold
monthly_threshold = float(os.environ.get('MONTHLY_COST_THRESHOLD', '100'))
current_cost = 75 # Example calculation
if current_cost > monthly_threshold * 0.8:
print(f"COST_ALERT=true")
print(f"CURRENT_COST={current_cost}")
with open(os.environ['GITHUB_ENV'], 'a') as f:
f.write(f"COST_ALERT=true\\n")
f.write(f"CURRENT_COST={current_cost}\\n")
EOF
''',
'env': {
'MONTHLY_COST_THRESHOLD': '100'
}
},
{
'name': 'Cost Alert',
'if': 'env.COST_ALERT == \'true\'',
'uses': '8398a7/action-slack@v3',
'with': {
'status': 'warning',
'text': '💰 Cost threshold alert!\nCurrent monthly cost: ${{ env.CURRENT_COST }}\nThreshold: $100',
'webhook_url': '${{ secrets.SLACK_WEBHOOK }}'
}
}
]
}
```
### 5. Automated Code Quality & Security
**Continuous Quality Enforcement:**
```python
class QualityAutomationBuilder:
def generate_quality_workflow(self) -> Dict[str, Any]:
"""Generate automated code quality workflow"""
return {
'name': 'Automated Quality Assurance',
'on': {
'pull_request': {'branches': ['main', 'develop']},
'push': {'branches': ['main']},
'schedule': [{'cron': '0 3 * * 2,5'}] # Tue & Fri at 3 AM
},
'jobs': {
'code-quality': {
'name': 'Code Quality Analysis',
'runs-on': 'ubuntu-latest',
'steps': [
{'uses': 'actions/checkout@v4'},
{
'name': 'Set up Python',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '3.11'}
},
{
'name': 'Install quality tools',
'run': '''
pip install black isort flake8 bandit safety mypy pylint
pip install radon xenon complexity-report
pip install -r requirements.txt
'''
},
{
'name': 'Code Formatting Analysis',
'run': '''
echo "## Code Formatting Report" >> quality_report.md
echo "### Black (Code Formatting)" >> quality_report.md
if black --check . --diff; then
echo "✅ Code formatting is correct" >> quality_report.md
else
echo "❌ Code formatting issues found" >> quality_report.md
echo "FORMATTING_ISSUES=true" >> $GITHUB_ENV
fi
echo "### isort (Import Sorting)" >> quality_report.md
if isort --check-only . --diff; then
echo "✅ Import sorting is correct" >> quality_report.md
else
echo "❌ Import sorting issues found" >> quality_report.md
echo "IMPORT_ISSUES=true" >> $GITHUB_ENV
fi
'''
},
{
'name': 'Code Complexity Analysis',
'run': '''
echo "### Code Complexity Analysis" >> quality_report.md
# Cyclomatic complexity
radon cc . -s --total-average >> complexity_report.txt
COMPLEXITY_SCORE=$(radon cc . -s --total-average | tail -1 | awk '{print $NF}' | tr -d '()')
echo "Average Complexity: $COMPLEXITY_SCORE" >> quality_report.md
# Maintainability index
radon mi . -s >> maintainability_report.txt
# Check for high complexity functions
HIGH_COMPLEXITY=$(radon cc . --min C)
if [ ! -z "$HIGH_COMPLEXITY" ]; then
echo "⚠️ High complexity functions found:" >> quality_report.md
echo "$HIGH_COMPLEXITY" >> quality_report.md
echo "COMPLEXITY_ISSUES=true" >> $GITHUB_ENV
fi
'''
},
{
'name': 'Security Analysis',
'run': '''
echo "### Security Analysis" >> quality_report.md
# Bandit security check
bandit -r . -f json -o bandit_report.json || true
if [ -f bandit_report.json ]; then
SECURITY_ISSUES=$(cat bandit_report.json | jq '.results | length')
echo "Security issues found: $SECURITY_ISSUES" >> quality_report.md
if [ "$SECURITY_ISSUES" -gt "0" ]; then
echo "SECURITY_ISSUES=true" >> $GITHUB_ENV
echo "SECURITY_COUNT=$SECURITY_ISSUES" >> $GITHUB_ENV
fi
fi
# Dependency vulnerability check
safety check --json --output safety_report.json || true
if [ -f safety_report.json ]; then
VULN_COUNT=$(cat safety_report.json | jq '. | length')
echo "Vulnerable dependencies: $VULN_COUNT" >> quality_report.md
if [ "$VULN_COUNT" -gt "0" ]; then
echo "DEPENDENCY_VULNS=true" >> $GITHUB_ENV
echo "VULN_COUNT=$VULN_COUNT" >> $GITHUB_ENV
fi
fi
'''
},
{
'name': 'Type Checking',
'run': '''
echo "### Type Checking (mypy)" >> quality_report.md
if mypy . --ignore-missing-imports --strict-optional; then
echo "✅ Type checking passed" >> quality_report.md
else
echo "❌ Type checking issues found" >> quality_report.md
echo "TYPE_ISSUES=true" >> $GITHUB_ENV
fi
'''
},
{
'name': 'Generate Quality Score',
'run': '''
python3 - << 'EOF'
import os
# Calculate quality score based on issues found
score = 100
if os.environ.get('FORMATTING_ISSUES') == 'true':
score -= 10
if os.environ.get('IMPORT_ISSUES') == 'true':
score -= 5
if os.environ.get('COMPLEXITY_ISSUES') == 'true':
score -= 15
if os.environ.get('SECURITY_ISSUES') == 'true':
security_count = int(os.environ.get('SECURITY_COUNT', '0'))
score -= min(25, security_count * 5)
if os.environ.get('DEPENDENCY_VULNS') == 'true':
vuln_count = int(os.environ.get('VULN_COUNT', '0'))
score -= min(20, vuln_count * 2)
if os.environ.get('TYPE_ISSUES') == 'true':
score -= 10
score = max(0, score)
with open('quality_report.md', 'a') as f:
f.write(f"\\n## Overall Quality Score: {score}/100\\n")
with open(os.environ['GITHUB_ENV'], 'a') as f:
f.write(f"QUALITY_SCORE={score}\\n")
# Set quality gate
if score < 80:
f.write("QUALITY_GATE_FAILED=true\\n")
print(f"❌ Quality gate failed: {score}/100")
else:
print(f"✅ Quality gate passed: {score}/100")
EOF
'''
},
{
'name': 'Comment Quality Report on PR',
'if': 'github.event_name == \'pull_request\'',
'uses': 'actions/github-script@v6',
'with': {
'script': '''
const fs = require('fs');
const qualityReport = fs.readFileSync('quality_report.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: qualityReport
});
'''
}
},
{
'name': 'Fail if Quality Gate Not Met',
'if': 'env.QUALITY_GATE_FAILED == \'true\'',
'run': '''
echo "❌ Quality gate failed with score: $QUALITY_SCORE/100"
echo "Please fix the issues identified in the quality report."
exit 1
'''
}
]
}
}
}
```
## Workflow Templates
### 1. Full-Stack Application Template
```yaml
# .github/workflows/full-stack-ci-cd.yml
name: Full-Stack CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# Parallel quality checks
backend-quality:
name: Backend Quality & Testing
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
# Backend testing steps...
frontend-quality:
name: Frontend Quality & Testing
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['18.x', '20.x']
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
# Frontend testing steps...
# Integration testing
integration-tests:
name: Integration Tests
needs: [backend-quality, frontend-quality]
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
# Integration test steps...
# Deployment
deploy-staging:
name: Deploy to Staging
needs: [integration-tests]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
# Staging deployment steps...
deploy-production:
name: Deploy to Production
needs: [integration-tests]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
# Production deployment steps...
```
## ROI Measurement for Workflow Automation
### Time Savings Calculator
```python
class WorkflowROICalculator:
def __init__(self):
self.hourly_rate = 150 # Developer hourly rate
self.automation_savings = {}
def calculate_manual_vs_automated_time(self, workflow_name: str,
manual_time_minutes: float,
automated_time_minutes: float,
frequency_per_week: int) -> Dict[str, float]:
"""Calculate time savings from workflow automation"""
# Convert to hours
manual_time_hours = manual_time_minutes / 60
automated_time_hours = automated_time_minutes / 60
# Weekly savings
weekly_time_savings = (manual_time_hours - automated_time_hours) * frequency_per_week
weekly_cost_savings = weekly_time_savings * self.hourly_rate
# Annual projections
annual_time_savings = weekly_time_savings * 52
annual_cost_savings = weekly_cost_savings * 52
savings_data = {
'workflow': workflow_name,
'manual_time_hours': manual_time_hours,
'automated_time_hours': automated_time_hours,
'time_saved_per_execution': manual_time_hours - automated_time_hours,
'frequency_per_week': frequency_per_week,
'weekly_time_savings': weekly_time_savings,
'weekly_cost_savings': weekly_cost_savings,
'annual_time_savings': annual_time_savings,
'annual_cost_savings': annual_cost_savings,
'efficiency_improvement': ((manual_time_hours - automated_time_hours) / manual_time_hours) * 100
}
self.automation_savings[workflow_name] = savings_data
return savings_data
def generate_roi_dashboard(self) -> None:
"""Generate ROI dashboard for workflow automation"""
import streamlit as st
import plotly.express as px
import pandas as pd
st.title("🤖 Workflow Automation ROI Dashboard")
if not self.automation_savings:
st.warning("No automation data available. Run workflow analysis first.")
return
# Convert to DataFrame for analysis
df = pd.DataFrame.from_dict(self.automation_savings, orient='index')
# Summary metrics
col1, col2, col3, col4 = st.columns(4)
total_weekly_savings = df['weekly_time_savings'].sum()
total_annual_savings = df['annual_cost_savings'].sum()
avg_efficiency_gain = df['efficiency_improvement'].mean()
with col1:
st.metric("Weekly Time Saved", f"{total_weekly_savings:.1f} hrs")
with col2:
st.metric("Annual Cost Savings", f"${total_annual_savings:,.0f}")
with col3:
st.metric("Avg Efficiency Gain", f"{avg_efficiency_gain:.1f}%")
with col4:
total_workflows = len(df)
st.metric("Automated Workflows", total_workflows)
# Savings breakdown
st.subheader("💰 Cost Savings by Workflow")
fig_savings = px.bar(
df.reset_index(),
x='index',
y='annual_cost_savings',
title="Annual Cost Savings by Workflow",
labels={'index': 'Workflow', 'annual_cost_savings': 'Annual Savings ($)'}
)
st.plotly_chart(fig_savings)
# Time efficiency
st.subheader("⚡ Time Efficiency Gains")
fig_efficiency = px.scatter(
df.reset_index(),
x='frequency_per_week',
y='efficiency_improvement',
size='annual_cost_savings',
hover_data=['workflow'],
title="Efficiency vs Frequency",
labels={
'frequency_per_week': 'Frequency (per week)',
'efficiency_improvement': 'Efficiency Improvement (%)'
}
)
st.plotly_chart(fig_efficiency)
# Detailed breakdown table
st.subheader("📊 Detailed Breakdown")
display_df = df.round(2)
st.dataframe(display_df)
# Example usage with common automation scenarios
def setup_common_automation_scenarios():
calculator = WorkflowROICalculator()
# Common workflow automations and their typical time savings
scenarios = [
{
'name': 'Manual Testing',
'manual_time': 120, # 2 hours manual testing
'automated_time': 15, # 15 minutes for automated tests to run
'frequency': 10 # 10 times per week
},
{
'name': 'Code Deployment',
'manual_time': 45, # 45 minutes manual deployment
'automated_time': 5, # 5 minutes automated deployment
'frequency': 5 # 5 deployments per week
},
{
'name': 'Code Quality Checks',
'manual_time': 30, # 30 minutes manual review
'automated_time': 3, # 3 minutes automated checks
'frequency': 15 # 15 times per week
},
{
'name': 'Security Scanning',
'manual_time': 60, # 1 hour manual security review
'automated_time': 10, # 10 minutes automated scan
'frequency': 2 # 2 times per week
},
{
'name': 'Performance Testing',
'manual_time': 90, # 1.5 hours manual performance testing
'automated_time': 20, # 20 minutes automated performance tests
'frequency': 3 # 3 times per week
}
]
total_annual_savings = 0
print("🤖 Workflow Automation ROI Analysis")
print("=" * 50)
for scenario in scenarios:
savings = calculator.calculate_manual_vs_automated_time(
scenario['name'],
scenario['manual_time'],
scenario['automated_time'],
scenario['frequency']
)
total_annual_savings += savings['annual_cost_savings']
print(f"\n📊 {scenario['name']}:")
print(f" Time saved per execution: {savings['time_saved_per_execution']:.1f} hours")
print(f" Efficiency improvement: {savings['efficiency_improvement']:.1f}%")
print(f" Annual cost savings: ${savings['annual_cost_savings']:,.0f}")
print(f"\n💰 Total Annual Savings: ${total_annual_savings:,.0f}")
print(f"📈 ROI: {(total_annual_savings / (150 * 40)) * 100:.1f}% annual return") # Assuming 40 hours to set up all automation
return calculator
if __name__ == "__main__":
setup_common_automation_scenarios()
```
## Implementation Quick Start
### 1. Setup Automation (10 minutes)
```bash
# Clone automation templates
curl -o .github/workflows/ci-cd.yml https://raw.githubusercontent.com/your-repo/workflow-templates/main/ci-cd.yml
# Install automation tools
pip install pyyaml jinja2 github-actions-runner
# Generate project-specific workflows
python generate_workflows.py --project-type full-stack --platform railway
```
### 2. Configure Secrets (5 minutes)
```bash
# Set up GitHub secrets for automation
gh secret set RAILWAY_TOKEN --body "$RAILWAY_TOKEN"
gh secret set SLACK_WEBHOOK --body "$SLACK_WEBHOOK"
gh secret set MONTHLY_COST_THRESHOLD --body "100"
```
### 3. Enable Monitoring (5 minutes)
```bash
# Set up monitoring workflows
python setup_monitoring.py --enable-all
# Configure alerting
python configure_alerts.py --slack-webhook "$SLACK_WEBHOOK"
```
## Success Metrics & ROI Targets
### Time Savings (Target: 50-70% reduction)
- **Manual Testing:** 2 hours → 15 minutes (87.5% reduction)
- **Code Deployment:** 45 minutes → 5 minutes (88.9% reduction)
- **Quality Checks:** 30 minutes → 3 minutes (90% reduction)
- **Security Scanning:** 60 minutes → 10 minutes (83.3% reduction)
### Cost Optimization (Target: 20-30% infrastructure savings)
- **Automated right-sizing:** 25% reduction in compute costs
- **Intelligent caching:** 40% reduction in API costs
- **Performance optimization:** 30% improvement in resource efficiency
### Quality Improvement (Target: 90% issue prevention)
- **Automated testing:** 95% bug detection before production
- **Security scanning:** 100% vulnerability detection
- **Performance monitoring:** 90% performance regression prevention
### Development Velocity (Target: 2x faster delivery)
- **Deployment frequency:** Daily → Multiple times per day
- **Lead time:** 1 week → 1 day
- **Mean time to recovery:** 4 hours → 30 minutes
This Workflow Automation Builder skill provides comprehensive automation across the entire development lifecycle, delivering measurable time savings and cost optimization while improving code quality and deployment reliability.This skill builds end-to-end workflow automation for development teams, generating optimized CI/CD pipelines, test suites, deployment jobs, and security scans. It reduces manual effort and accelerates delivery by producing ready-to-run GitHub Actions, deployment steps, and automated testing workflows tailored to the project stack.
The skill inspects the project repository to detect languages, frameworks, and deployment targets (Python, Node.js/TypeScript, Docker, Vercel, Railway, etc.). It synthesizes pipelines that include matrix testing, linting, formatting, security scans, dependency checks, and conditional deployment jobs. Outputs are structured CI/CD definitions and job templates you can drop into your repository and tweak.
Can the generated pipelines deploy only from main?
Yes. Deployment jobs are conditional and can be configured to run only on pushes to main or other branches you choose.
How do secrets and tokens get handled?
The generated jobs reference repository secrets (for example VERCEL_TOKEN or RAILWAY_TOKEN). You must add credentials to your repository or organization secrets before deployment runs.