mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 17:24:12 +00:00
feat: add staging deployment workflow and script
- Add GitHub Actions workflow for automatic staging deployment on develop branch - Add manual deploy script with --skip-build and --skip-migrations options - Update CLAUDE.md with deployment documentation - Mark staging-deployment TODO as complete Deployment target: pl.c2sgmbh.de (37.24.237.181) Triggers: push to develop, manual workflow_dispatch 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
05fba7f1d7
commit
e3c7d92121
4 changed files with 395 additions and 8 deletions
189
.github/workflows/deploy-staging.yml
vendored
Normal file
189
.github/workflows/deploy-staging.yml
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
name: Deploy to Staging
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [develop]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
skip_tests:
|
||||||
|
description: 'Skip tests before deployment'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: staging-deployment
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_VERSION: '20'
|
||||||
|
PNPM_VERSION: '9'
|
||||||
|
STAGING_HOST: '37.24.237.181'
|
||||||
|
STAGING_USER: 'payload'
|
||||||
|
STAGING_PATH: '/home/payload/payload-cms'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# ===========================================================================
|
||||||
|
# Pre-deployment checks (optional, can be skipped via workflow_dispatch)
|
||||||
|
# ===========================================================================
|
||||||
|
pre-checks:
|
||||||
|
name: Pre-deployment Checks
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event.inputs.skip_tests != 'true' }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.PNPM_VERSION }}
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: pnpm lint
|
||||||
|
|
||||||
|
- name: Run Unit Tests
|
||||||
|
run: pnpm test:unit
|
||||||
|
env:
|
||||||
|
CSRF_SECRET: test-csrf-secret
|
||||||
|
PAYLOAD_SECRET: test-payload-secret
|
||||||
|
PAYLOAD_PUBLIC_SERVER_URL: https://test.example.com
|
||||||
|
NEXT_PUBLIC_SERVER_URL: https://test.example.com
|
||||||
|
EMAIL_DELIVERY_DISABLED: 'true'
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Deploy to Staging Server
|
||||||
|
# ===========================================================================
|
||||||
|
deploy:
|
||||||
|
name: Deploy to Staging
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [pre-checks]
|
||||||
|
if: always() && (needs.pre-checks.result == 'success' || needs.pre-checks.result == 'skipped')
|
||||||
|
environment:
|
||||||
|
name: staging
|
||||||
|
url: https://pl.c2sgmbh.de
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configure SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.STAGING_SSH_KEY }}" > ~/.ssh/staging_key
|
||||||
|
chmod 600 ~/.ssh/staging_key
|
||||||
|
cat >> ~/.ssh/config << EOF
|
||||||
|
Host staging
|
||||||
|
HostName ${{ env.STAGING_HOST }}
|
||||||
|
User ${{ env.STAGING_USER }}
|
||||||
|
IdentityFile ~/.ssh/staging_key
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
UserKnownHostsFile /dev/null
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Deploy to Staging
|
||||||
|
run: |
|
||||||
|
ssh staging << 'ENDSSH'
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=== Staging Deployment Started ==="
|
||||||
|
echo "Time: $(date)"
|
||||||
|
echo "Branch: ${{ github.ref_name }}"
|
||||||
|
echo "Commit: ${{ github.sha }}"
|
||||||
|
|
||||||
|
cd ${{ env.STAGING_PATH }}
|
||||||
|
|
||||||
|
# Stash any local changes
|
||||||
|
git stash --include-untracked || true
|
||||||
|
|
||||||
|
# Fetch and checkout
|
||||||
|
echo "=== Fetching latest code ==="
|
||||||
|
git fetch origin develop
|
||||||
|
git checkout develop
|
||||||
|
git reset --hard origin/develop
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
echo "=== Installing dependencies ==="
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Run migrations if any
|
||||||
|
echo "=== Running migrations ==="
|
||||||
|
pnpm payload migrate || echo "No migrations to run"
|
||||||
|
|
||||||
|
# Build application
|
||||||
|
echo "=== Building application ==="
|
||||||
|
NODE_OPTIONS="--max-old-space-size=2048" pnpm build
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
echo "=== Restarting services ==="
|
||||||
|
pm2 restart payload --update-env || pm2 start ecosystem.config.cjs --only payload
|
||||||
|
pm2 restart queue-worker --update-env || pm2 start ecosystem.config.cjs --only queue-worker
|
||||||
|
|
||||||
|
# Wait for service to be healthy
|
||||||
|
echo "=== Waiting for service to start ==="
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
echo "=== Running health check ==="
|
||||||
|
curl -sf http://localhost:3000/api/health || curl -sf http://localhost:3000/admin || echo "Health check endpoint not available"
|
||||||
|
|
||||||
|
# Show status
|
||||||
|
echo "=== Deployment Complete ==="
|
||||||
|
pm2 status
|
||||||
|
echo "Time: $(date)"
|
||||||
|
ENDSSH
|
||||||
|
|
||||||
|
- name: Verify Deployment
|
||||||
|
run: |
|
||||||
|
echo "Verifying staging deployment..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Check if staging is responding
|
||||||
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://pl.c2sgmbh.de/admin || echo "000")
|
||||||
|
|
||||||
|
if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 400 ]; then
|
||||||
|
echo "Staging is responding with HTTP $HTTP_STATUS"
|
||||||
|
else
|
||||||
|
echo "Warning: Staging returned HTTP $HTTP_STATUS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create deployment summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo "## Staging Deployment Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Environment | Staging |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| URL | https://pl.c2sgmbh.de |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Branch | ${{ github.ref_name }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Commit | \`${{ github.sha }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Triggered by | ${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Time | $(date -u '+%Y-%m-%d %H:%M:%S UTC') |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Notify on failure
|
||||||
|
# ===========================================================================
|
||||||
|
notify-failure:
|
||||||
|
name: Notify on Failure
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [deploy]
|
||||||
|
if: failure()
|
||||||
|
steps:
|
||||||
|
- name: Create failure summary
|
||||||
|
run: |
|
||||||
|
echo "## Staging Deployment Failed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "The deployment to staging failed. Please check the logs above for details." >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Actor:** ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
|
||||||
33
CLAUDE.md
33
CLAUDE.md
|
|
@ -831,6 +831,39 @@ pnpm build # Production Build
|
||||||
- **CodeQL**: Static Analysis (SAST)
|
- **CodeQL**: Static Analysis (SAST)
|
||||||
- **Security Tests**: Unit & Integration Tests für Security-Module
|
- **Security Tests**: Unit & Integration Tests für Security-Module
|
||||||
|
|
||||||
|
### deploy-staging.yml (Staging Deployment)
|
||||||
|
Automatisches Deployment auf Staging-Server bei Push auf `develop`:
|
||||||
|
|
||||||
|
| Trigger | Aktion |
|
||||||
|
|---------|--------|
|
||||||
|
| Push auf `develop` | Automatisches Deployment |
|
||||||
|
| `workflow_dispatch` | Manuelles Deployment (optional: skip_tests) |
|
||||||
|
|
||||||
|
**Deployment-Ziel:**
|
||||||
|
- **URL:** https://pl.c2sgmbh.de
|
||||||
|
- **Server:** 37.24.237.181 (sv-payload)
|
||||||
|
|
||||||
|
**Ablauf:**
|
||||||
|
1. Pre-deployment Checks (Lint, Tests)
|
||||||
|
2. SSH-Verbindung zum Staging-Server
|
||||||
|
3. Git Pull + Dependencies installieren
|
||||||
|
4. Migrations ausführen
|
||||||
|
5. Build + PM2 Restart
|
||||||
|
6. Health Check
|
||||||
|
|
||||||
|
**Manuelles Staging-Deployment:**
|
||||||
|
```bash
|
||||||
|
# Auf dem Staging-Server (pl.c2sgmbh.de)
|
||||||
|
./scripts/deploy-staging.sh
|
||||||
|
|
||||||
|
# Mit Optionen
|
||||||
|
./scripts/deploy-staging.sh --skip-build # Nur Code-Update
|
||||||
|
./scripts/deploy-staging.sh --skip-migrations # Ohne Migrationen
|
||||||
|
```
|
||||||
|
|
||||||
|
**GitHub Secret erforderlich:**
|
||||||
|
- `STAGING_SSH_KEY` - SSH Private Key für `payload@37.24.237.181`
|
||||||
|
|
||||||
## Dokumentation
|
## Dokumentation
|
||||||
|
|
||||||
- `CLAUDE.md` - Diese Datei (Projekt-Übersicht)
|
- `CLAUDE.md` - Diese Datei (Projekt-Übersicht)
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
|--------|------|---------|
|
|--------|------|---------|
|
||||||
| [ ] | Media-Backup zu S3/MinIO | Backup |
|
| [ ] | Media-Backup zu S3/MinIO | Backup |
|
||||||
| [ ] | CDN-Integration (Cloudflare) | Caching |
|
| [ ] | CDN-Integration (Cloudflare) | Caching |
|
||||||
| [ ] | CI/CD Pipeline erweitern (Lint/Test/Build) | DevOps |
|
| [x] | CI/CD Pipeline erweitern (Lint/Test/Build) | DevOps |
|
||||||
| [ ] | Staging-Deployment | DevOps |
|
| [x] | Staging-Deployment | DevOps |
|
||||||
| [ ] | Memory-Problem lösen (Swap) | Infrastruktur |
|
| [ ] | Memory-Problem lösen (Swap) | Infrastruktur |
|
||||||
| [ ] | PM2 Cluster Mode testen | Infrastruktur |
|
| [ ] | PM2 Cluster Mode testen | Infrastruktur |
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
| [ ] | Email-Log Cleanup Cron | Data Retention |
|
| [ ] | Email-Log Cleanup Cron | Data Retention |
|
||||||
| [ ] | Dashboard-Widget für Email-Status | Admin UX |
|
| [ ] | Dashboard-Widget für Email-Status | Admin UX |
|
||||||
| [ ] | TypeScript Strict Mode | Tech Debt |
|
| [ ] | TypeScript Strict Mode | Tech Debt |
|
||||||
| [ ] | E2E Tests für kritische Flows | Testing |
|
| [x] | E2E Tests für kritische Flows | Testing |
|
||||||
|
|
||||||
### Dokumentation
|
### Dokumentation
|
||||||
| Status | Task |
|
| Status | Task |
|
||||||
|
|
@ -117,11 +117,11 @@
|
||||||
|
|
||||||
## Testing & CI/CD
|
## Testing & CI/CD
|
||||||
|
|
||||||
- [ ] **CI/CD Pipeline**
|
- [x] **CI/CD Pipeline** *(erledigt: `.github/workflows/ci.yml`)*
|
||||||
- [ ] Automatisches Lint/Test/Build Workflow
|
- [x] Automatisches Lint/Test/Build Workflow
|
||||||
- [ ] Staging-Deployment
|
- [x] Staging-Deployment *(erledigt: `.github/workflows/deploy-staging.yml`)*
|
||||||
|
|
||||||
- [ ] **E2E Tests für kritische Flows**
|
- [x] **E2E Tests für kritische Flows** *(erledigt: `tests/e2e/`)*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@
|
||||||
## Technische Schulden
|
## Technische Schulden
|
||||||
|
|
||||||
- [ ] TypeScript Strict Mode aktivieren
|
- [ ] TypeScript Strict Mode aktivieren
|
||||||
- [ ] E2E Tests für kritische Flows
|
- [x] E2E Tests für kritische Flows
|
||||||
- [ ] Code-Review für Security-relevante Bereiche
|
- [ ] Code-Review für Security-relevante Bereiche
|
||||||
- [ ] Performance-Audit der Datenbank-Queries
|
- [ ] Performance-Audit der Datenbank-Queries
|
||||||
|
|
||||||
|
|
|
||||||
165
scripts/deploy-staging.sh
Executable file
165
scripts/deploy-staging.sh
Executable file
|
|
@ -0,0 +1,165 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Staging Deployment Script
|
||||||
|
# =============================================================================
|
||||||
|
# Usage: ./scripts/deploy-staging.sh [--skip-build] [--skip-migrations]
|
||||||
|
#
|
||||||
|
# This script deploys the current develop branch to the staging environment.
|
||||||
|
# Run this on the staging server (pl.c2sgmbh.de) or via SSH.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
PROJECT_DIR="/home/payload/payload-cms"
|
||||||
|
BRANCH="${DEPLOY_BRANCH:-develop}" # Use env var or default to develop
|
||||||
|
LOG_FILE="/home/payload/logs/deploy-staging.log"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
SKIP_BUILD=false
|
||||||
|
SKIP_MIGRATIONS=false
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $arg in
|
||||||
|
--skip-build)
|
||||||
|
SKIP_BUILD=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--skip-migrations)
|
||||||
|
SKIP_MIGRATIONS=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
log() {
|
||||||
|
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure log directory exists
|
||||||
|
mkdir -p "$(dirname "$LOG_FILE")"
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Staging Deployment Script"
|
||||||
|
echo " Environment: pl.c2sgmbh.de"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
log "Starting staging deployment..."
|
||||||
|
log "Branch: $BRANCH"
|
||||||
|
log "Skip build: $SKIP_BUILD"
|
||||||
|
log "Skip migrations: $SKIP_MIGRATIONS"
|
||||||
|
|
||||||
|
# Change to project directory
|
||||||
|
cd "$PROJECT_DIR" || error "Could not change to project directory: $PROJECT_DIR"
|
||||||
|
log "Working directory: $(pwd)"
|
||||||
|
|
||||||
|
# Check current branch and stash changes
|
||||||
|
log "Checking git status..."
|
||||||
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
|
if [ "$CURRENT_BRANCH" != "$BRANCH" ]; then
|
||||||
|
warn "Currently on branch '$CURRENT_BRANCH', switching to '$BRANCH'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stash any local changes
|
||||||
|
if [ -n "$(git status --porcelain)" ]; then
|
||||||
|
warn "Stashing local changes..."
|
||||||
|
git stash --include-untracked
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fetch and reset to origin
|
||||||
|
log "Fetching latest code from origin/$BRANCH..."
|
||||||
|
git fetch origin "$BRANCH"
|
||||||
|
git checkout "$BRANCH"
|
||||||
|
git reset --hard "origin/$BRANCH"
|
||||||
|
success "Code updated to latest origin/$BRANCH"
|
||||||
|
|
||||||
|
# Show current commit
|
||||||
|
COMMIT_SHA=$(git rev-parse --short HEAD)
|
||||||
|
COMMIT_MSG=$(git log -1 --pretty=%s)
|
||||||
|
log "Current commit: $COMMIT_SHA - $COMMIT_MSG"
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
log "Installing dependencies..."
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
success "Dependencies installed"
|
||||||
|
|
||||||
|
# Run migrations (unless skipped)
|
||||||
|
if [ "$SKIP_MIGRATIONS" = false ]; then
|
||||||
|
log "Running database migrations..."
|
||||||
|
pnpm payload migrate || warn "No migrations to run or migration failed"
|
||||||
|
else
|
||||||
|
warn "Skipping migrations (--skip-migrations flag)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build (unless skipped)
|
||||||
|
if [ "$SKIP_BUILD" = false ]; then
|
||||||
|
log "Building application..."
|
||||||
|
|
||||||
|
# Stop PM2 to free memory for build
|
||||||
|
pm2 stop payload 2>/dev/null || true
|
||||||
|
pm2 stop queue-worker 2>/dev/null || true
|
||||||
|
|
||||||
|
# Build with memory limit
|
||||||
|
NODE_OPTIONS="--max-old-space-size=2048" pnpm build
|
||||||
|
success "Build completed"
|
||||||
|
else
|
||||||
|
warn "Skipping build (--skip-build flag)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
log "Restarting PM2 services..."
|
||||||
|
pm2 restart payload --update-env 2>/dev/null || pm2 start ecosystem.config.cjs --only payload
|
||||||
|
pm2 restart queue-worker --update-env 2>/dev/null || pm2 start ecosystem.config.cjs --only queue-worker
|
||||||
|
success "Services restarted"
|
||||||
|
|
||||||
|
# Wait for service to start
|
||||||
|
log "Waiting for service to start..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
log "Running health check..."
|
||||||
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/admin 2>/dev/null || echo "000")
|
||||||
|
if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 400 ]; then
|
||||||
|
success "Health check passed (HTTP $HTTP_STATUS)"
|
||||||
|
else
|
||||||
|
warn "Health check returned HTTP $HTTP_STATUS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show PM2 status
|
||||||
|
echo ""
|
||||||
|
log "PM2 Status:"
|
||||||
|
pm2 status
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo -e "${GREEN} Staging Deployment Complete!${NC}"
|
||||||
|
echo "=============================================="
|
||||||
|
echo " URL: https://pl.c2sgmbh.de"
|
||||||
|
echo " Admin: https://pl.c2sgmbh.de/admin"
|
||||||
|
echo " Commit: $COMMIT_SHA"
|
||||||
|
echo " Time: $(date)"
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
log "Deployment finished successfully"
|
||||||
Loading…
Reference in a new issue