Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled

Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

348
marketing-agent/.github/workflows/cd.yml vendored Normal file
View File

@@ -0,0 +1,348 @@
name: CD Pipeline
on:
push:
branches: [ main ]
tags: [ 'v*.*.*' ]
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
version:
description: 'Version to deploy (leave empty for latest)'
required: false
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
HELM_VERSION: '3.13.0'
jobs:
# Prepare deployment
prepare-deployment:
name: Prepare Deployment
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.determine-env.outputs.environment }}
version: ${{ steps.determine-version.outputs.version }}
should-deploy: ${{ steps.check-deploy.outputs.should-deploy }}
steps:
- uses: actions/checkout@v4
- name: Determine environment
id: determine-env
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "environment=staging" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "environment=production" >> $GITHUB_OUTPUT
else
echo "environment=development" >> $GITHUB_OUTPUT
fi
- name: Determine version
id: determine-version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.version }}" ]]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
else
echo "version=${{ github.sha }}" >> $GITHUB_OUTPUT
fi
- name: Check deployment conditions
id: check-deploy
run: |
ENV="${{ steps.determine-env.outputs.environment }}"
if [[ "$ENV" == "production" && ! "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "should-deploy=false" >> $GITHUB_OUTPUT
echo "::warning::Production deployment requires a semantic version tag"
else
echo "should-deploy=true" >> $GITHUB_OUTPUT
fi
# Database Migration
database-migration:
name: Database Migration
runs-on: ubuntu-latest
needs: [prepare-deployment]
if: needs.prepare-deployment.outputs.should-deploy == 'true'
environment: ${{ needs.prepare-deployment.outputs.environment }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
- name: Get database connection string
id: get-db-connection
run: |
SECRET_ARN="${{ secrets.DB_SECRET_ARN }}"
DB_SECRET=$(aws secretsmanager get-secret-value --secret-id $SECRET_ARN --query SecretString --output text)
echo "::add-mask::$DB_SECRET"
echo "DB_CONNECTION=$DB_SECRET" >> $GITHUB_ENV
- name: Run migrations
run: |
cd migrations
npm ci
npm run migrate:up
env:
MONGODB_URI: ${{ env.DB_CONNECTION }}
MIGRATION_ENV: ${{ needs.prepare-deployment.outputs.environment }}
# Deploy to Kubernetes
deploy-kubernetes:
name: Deploy to Kubernetes
runs-on: ubuntu-latest
needs: [prepare-deployment, database-migration]
if: needs.prepare-deployment.outputs.should-deploy == 'true'
environment:
name: ${{ needs.prepare-deployment.outputs.environment }}
url: ${{ steps.deploy.outputs.app-url }}
strategy:
matrix:
region: [us-east-1, eu-west-1, ap-southeast-1]
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ matrix.region }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Setup Helm
uses: azure/setup-helm@v3
with:
version: ${{ env.HELM_VERSION }}
- name: Update kubeconfig
run: |
aws eks update-kubeconfig --name marketing-agent-${{ needs.prepare-deployment.outputs.environment }}-${{ matrix.region }}
- name: Create namespace
run: |
kubectl create namespace marketing-agent-${{ needs.prepare-deployment.outputs.environment }} --dry-run=client -o yaml | kubectl apply -f -
- name: Deploy with Helm
id: deploy
run: |
NAMESPACE="marketing-agent-${{ needs.prepare-deployment.outputs.environment }}"
RELEASE_NAME="marketing-agent"
helm upgrade --install $RELEASE_NAME ./helm/marketing-agent \
--namespace $NAMESPACE \
--values ./helm/marketing-agent/values.yaml \
--values ./helm/marketing-agent/values.${{ needs.prepare-deployment.outputs.environment }}.yaml \
--set global.image.tag=${{ needs.prepare-deployment.outputs.version }} \
--set global.image.registry=${{ steps.login-ecr.outputs.registry }} \
--set global.region=${{ matrix.region }} \
--set-string global.environment=${{ needs.prepare-deployment.outputs.environment }} \
--wait \
--timeout 10m
# Get the application URL
APP_URL=$(kubectl get ingress -n $NAMESPACE -o jsonpath='{.items[0].spec.rules[0].host}')
echo "app-url=https://$APP_URL" >> $GITHUB_OUTPUT
- name: Verify deployment
run: |
NAMESPACE="marketing-agent-${{ needs.prepare-deployment.outputs.environment }}"
kubectl rollout status deployment -n $NAMESPACE --timeout=5m
kubectl get pods -n $NAMESPACE
- name: Run smoke tests
run: |
APP_URL="${{ steps.deploy.outputs.app-url }}"
./scripts/smoke-tests.sh $APP_URL
# Deploy Static Assets to CDN
deploy-cdn:
name: Deploy Static Assets to CDN
runs-on: ubuntu-latest
needs: [prepare-deployment, database-migration]
if: needs.prepare-deployment.outputs.should-deploy == 'true'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'
- name: Build frontend
working-directory: ./frontend
run: |
npm ci
npm run build
env:
VITE_API_URL: ${{ vars.API_URL }}
VITE_ENVIRONMENT: ${{ needs.prepare-deployment.outputs.environment }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to S3
run: |
BUCKET_NAME="marketing-agent-frontend-${{ needs.prepare-deployment.outputs.environment }}"
aws s3 sync ./frontend/dist s3://$BUCKET_NAME \
--delete \
--cache-control "public, max-age=31536000" \
--exclude "index.html" \
--exclude "*.map"
# Upload index.html with no-cache
aws s3 cp ./frontend/dist/index.html s3://$BUCKET_NAME/index.html \
--cache-control "no-cache, no-store, must-revalidate"
- name: Invalidate CloudFront
run: |
DISTRIBUTION_ID="${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}"
aws cloudfront create-invalidation \
--distribution-id $DISTRIBUTION_ID \
--paths "/*"
# Post-deployment tasks
post-deployment:
name: Post Deployment Tasks
runs-on: ubuntu-latest
needs: [prepare-deployment, deploy-kubernetes, deploy-cdn]
if: always() && needs.prepare-deployment.outputs.should-deploy == 'true'
steps:
- uses: actions/checkout@v4
- name: Update deployment status
uses: actions/github-script@v7
with:
script: |
const environment = '${{ needs.prepare-deployment.outputs.environment }}';
const version = '${{ needs.prepare-deployment.outputs.version }}';
const status = '${{ needs.deploy-kubernetes.result }}';
// Create deployment status
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: context.payload.deployment.id,
state: status === 'success' ? 'success' : 'failure',
environment_url: status === 'success' ? '${{ needs.deploy-kubernetes.outputs.app-url }}' : '',
description: `Deployed version ${version} to ${environment}`
});
- name: Send deployment notification
if: success()
uses: 8398a7/action-slack@v3
with:
status: custom
custom_payload: |
{
"text": "Deployment Successful! :rocket:",
"attachments": [{
"color": "good",
"fields": [
{ "title": "Environment", "value": "${{ needs.prepare-deployment.outputs.environment }}", "short": true },
{ "title": "Version", "value": "${{ needs.prepare-deployment.outputs.version }}", "short": true },
{ "title": "Deployed By", "value": "${{ github.actor }}", "short": true },
{ "title": "Repository", "value": "${{ github.repository }}", "short": true }
]
}]
}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
- name: Create release notes
if: startsWith(github.ref, 'refs/tags/')
uses: actions/github-script@v7
with:
script: |
const tag = context.ref.replace('refs/tags/', '');
const { data: commits } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: 'v1.0.0', // Previous release tag
head: tag
});
const releaseNotes = commits.commits
.map(commit => `- ${commit.commit.message}`)
.join('\n');
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name: `Release ${tag}`,
body: releaseNotes,
draft: false,
prerelease: false
});
# Rollback on failure
rollback:
name: Rollback Deployment
runs-on: ubuntu-latest
needs: [prepare-deployment, deploy-kubernetes]
if: failure() && needs.prepare-deployment.outputs.environment == 'production'
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
- name: Rollback Kubernetes deployment
run: |
aws eks update-kubeconfig --name marketing-agent-production
NAMESPACE="marketing-agent-production"
helm rollback marketing-agent -n $NAMESPACE
- name: Send rollback notification
uses: 8398a7/action-slack@v3
with:
status: custom
custom_payload: |
{
"text": "Production Deployment Failed - Rollback Initiated! :warning:",
"attachments": [{
"color": "danger",
"fields": [
{ "title": "Environment", "value": "production", "short": true },
{ "title": "Failed Version", "value": "${{ needs.prepare-deployment.outputs.version }}", "short": true }
]
}]
}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}

356
marketing-agent/.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,356 @@
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
NODE_VERSION: '18.x'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# Code Quality Checks
lint-and-format:
name: Lint and Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Check code formatting
run: npm run format:check
# Security Scanning
security-scan:
name: Security Vulnerability Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run security audit
run: npm audit --audit-level=moderate
- name: Run Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
# Unit Tests
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
strategy:
matrix:
service: [api-gateway, orchestrator, scheduler, analytics, workflow]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
working-directory: ./services/${{ matrix.service }}
run: npm ci
- name: Run unit tests
working-directory: ./services/${{ matrix.service }}
run: npm test
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
file: ./services/${{ matrix.service }}/coverage/lcov.info
flags: ${{ matrix.service }}
name: ${{ matrix.service }}-coverage
# Integration Tests
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: [unit-tests]
services:
mongodb:
image: mongo:6
ports:
- 27017:27017
options: >-
--health-cmd "mongosh --eval 'db.adminCommand({ping: 1})'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
elasticsearch:
image: elasticsearch:8.12.0
ports:
- 9200:9200
env:
discovery.type: single-node
xpack.security.enabled: false
options: >-
--health-cmd "curl -f http://localhost:9200/_cluster/health"
--health-interval 10s
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run integration tests
env:
MONGODB_URI: mongodb://localhost:27017/test
REDIS_HOST: localhost
ELASTICSEARCH_NODE: http://localhost:9200
run: npm run test:integration
# Build Docker Images
build-images:
name: Build Docker Images
runs-on: ubuntu-latest
needs: [lint-and-format, security-scan, unit-tests]
strategy:
matrix:
service:
- api-gateway
- orchestrator
- claude-agent
- gramjs-adapter
- safety-guard
- analytics
- compliance-guard
- ab-testing
- workflow
- webhook
- template
- i18n
- user-management
- scheduler
- logging
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./services/${{ matrix.service }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VCS_REF=${{ github.sha }}
VERSION=${{ steps.meta.outputs.version }}
# Build Frontend
build-frontend:
name: Build Frontend
runs-on: ubuntu-latest
needs: [lint-and-format, security-scan]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
working-directory: ./frontend
run: npm ci
- name: Build frontend
working-directory: ./frontend
run: npm run build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v10
with:
uploadArtifacts: true
temporaryPublicStorage: true
runs: 3
configPath: ./frontend/.lighthouserc.json
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: frontend-build
path: ./frontend/dist
retention-days: 7
# E2E Tests
e2e-tests:
name: End-to-End Tests
runs-on: ubuntu-latest
needs: [integration-tests, build-frontend]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Download frontend build
uses: actions/download-artifact@v4
with:
name: frontend-build
path: ./frontend/dist
- name: Start services with docker-compose
run: |
docker-compose -f docker-compose.test.yml up -d
./scripts/wait-for-services.sh
- name: Run E2E tests
run: npm run test:e2e
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-test-results
path: ./tests/e2e/results
retention-days: 7
# Performance Tests
performance-tests:
name: Performance Tests
runs-on: ubuntu-latest
needs: [build-images, build-frontend]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Setup k6
run: |
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Start services
run: |
docker-compose -f docker-compose.perf.yml up -d
./scripts/wait-for-services.sh
- name: Run performance tests
run: |
k6 run ./tests/performance/load-test.js
k6 run ./tests/performance/stress-test.js
k6 run ./tests/performance/spike-test.js
- name: Upload performance results
uses: actions/upload-artifact@v4
with:
name: performance-results
path: ./tests/performance/results
retention-days: 30
# Dependency Check
dependency-check:
name: Dependency License Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check dependency licenses
uses: fossa-contrib/fossa-action@v2
with:
api-key: ${{ secrets.FOSSA_API_KEY }}
# SonarQube Analysis
sonarqube:
name: SonarQube Analysis
runs-on: ubuntu-latest
needs: [unit-tests, integration-tests]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
# Notify on failure
notify-failure:
name: Notify on Failure
runs-on: ubuntu-latest
needs: [lint-and-format, security-scan, unit-tests, integration-tests, build-images, build-frontend, e2e-tests]
if: failure()
steps:
- name: Send Slack notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'CI Pipeline Failed for ${{ github.repository }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
channel: '#ci-notifications'
username: 'GitHub Actions'
icon_emoji: ':warning:'

View File

@@ -0,0 +1,247 @@
name: Security Scanning
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM UTC
workflow_dispatch:
push:
branches: [ main, develop ]
jobs:
# Container Security Scanning
container-scan:
name: Container Security Scan
runs-on: ubuntu-latest
strategy:
matrix:
service:
- api-gateway
- orchestrator
- claude-agent
- analytics
- logging
steps:
- uses: actions/checkout@v4
- name: Run Trivy scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: './services/${{ matrix.service }}'
format: 'sarif'
output: 'trivy-${{ matrix.service }}.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-${{ matrix.service }}.sarif'
category: 'trivy-${{ matrix.service }}'
# SAST - Static Application Security Testing
sast-scan:
name: SAST Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript, typescript
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/nodejs
p/typescript
p/mongodb
p/jwt
# Secret Scanning
secret-scan:
name: Secret Scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: TruffleHog scan
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --debug --only-verified
- name: GitLeaks scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Dependency Security Audit
dependency-audit:
name: Dependency Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run npm audit
run: |
find . -name package.json -not -path "*/node_modules/*" -execdir npm audit --audit-level=moderate \;
- name: Run OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'marketing-agent'
path: '.'
format: 'HTML'
args: >
--enableRetired
--enableExperimental
- name: Upload dependency check results
uses: actions/upload-artifact@v4
with:
name: dependency-check-report
path: reports/
retention-days: 30
# Infrastructure Security Scan
infrastructure-scan:
name: Infrastructure Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkov scan
uses: bridgecrewio/checkov-action@master
with:
directory: .
framework: all
output_format: sarif
output_file_path: checkov.sarif
download_external_modules: true
- name: Upload Checkov results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: checkov.sarif
category: infrastructure
- name: Terraform security scan
uses: aquasecurity/tfsec-action@v1.0.0
with:
working_directory: ./infrastructure/terraform
# API Security Testing
api-security-test:
name: API Security Testing
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- name: Setup OWASP ZAP
run: |
docker pull owasp/zap2docker-stable
- name: Start application
run: |
docker-compose -f docker-compose.security.yml up -d
./scripts/wait-for-services.sh
- name: Run ZAP API scan
run: |
docker run -v $(pwd):/zap/wrk/:rw \
-t owasp/zap2docker-stable zap-api-scan.py \
-t http://host.docker.internal:3000/api-docs.json \
-f openapi \
-r zap-api-report.html \
-w zap-api-report.md
- name: Upload ZAP results
uses: actions/upload-artifact@v4
with:
name: zap-api-report
path: |
zap-api-report.html
zap-api-report.md
retention-days: 30
# Compliance Checks
compliance-check:
name: Compliance Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: License compliance check
uses: fossa-contrib/fossa-action@v2
with:
api-key: ${{ secrets.FOSSA_API_KEY }}
run-tests: true
- name: GDPR compliance check
run: |
# Check for PII handling
./scripts/compliance/gdpr-check.sh
- name: SOC2 compliance check
run: |
# Check security controls
./scripts/compliance/soc2-check.sh
# Security Report Generation
generate-report:
name: Generate Security Report
runs-on: ubuntu-latest
needs: [container-scan, sast-scan, secret-scan, dependency-audit, infrastructure-scan]
if: always()
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: security-reports/
- name: Generate consolidated report
run: |
python scripts/security/generate-security-report.py \
--input security-reports/ \
--output security-summary.html
- name: Upload security summary
uses: actions/upload-artifact@v4
with:
name: security-summary
path: security-summary.html
retention-days: 90
- name: Create security issue if critical findings
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('security-summary.json', 'utf8'));
if (report.critical_findings > 0) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🚨 ${report.critical_findings} Critical Security Findings`,
body: report.summary,
labels: ['security', 'critical']
});
}

View File

@@ -0,0 +1,126 @@
name: Test
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
mongodb-version: ['6.0', '7.0']
redis-version: ['7']
services:
mongodb:
image: mongo:${{ matrix.mongodb-version }}
ports:
- 27017:27017
options: >-
--health-cmd mongosh
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:${{ matrix.redis-version }}
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v3
- 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
cd services/api-gateway && npm ci
cd ../orchestrator && npm ci
cd ../analytics && npm ci
cd ../scheduler && npm ci
cd ../user-management && npm ci
cd ../..
- name: Run linter
run: npm run lint
- name: Run unit tests
env:
NODE_ENV: test
JWT_SECRET: test-jwt-secret
MONGODB_URI: mongodb://localhost:27017/test
REDIS_URL: redis://localhost:6379
run: npm run test:unit
- name: Run integration tests
env:
NODE_ENV: test
JWT_SECRET: test-jwt-secret
MONGODB_URI: mongodb://localhost:27017/test
REDIS_URL: redis://localhost:6379
run: npm run test:integration
- name: Run E2E tests
env:
NODE_ENV: test
JWT_SECRET: test-jwt-secret
MONGODB_URI: mongodb://localhost:27017/test
REDIS_URL: redis://localhost:6379
run: npm run test:e2e
- name: Generate coverage report
run: npm run test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.node-version }}-${{ matrix.mongodb-version }}
path: test-results/junit.xml
- name: Upload coverage artifacts
uses: actions/upload-artifact@v3
with:
name: coverage-${{ matrix.node-version }}-${{ matrix.mongodb-version }}
path: coverage/
test-summary:
needs: test
runs-on: ubuntu-latest
if: always()
steps:
- name: Download artifacts
uses: actions/download-artifact@v3
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: '**/junit.xml'
check_name: Test Results
comment_title: Test Results Summary