Files
links/scripts/ci/publish.sh
Andrey K. Choi d5f1809f5a
Some checks failed
continuous-integration/drone Build is failing
Drone CD/CD PipeLine added
2025-11-02 06:23:39 +09:00

286 lines
9.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# scripts/ci/publish.sh - Публикация Docker образов в registry
set -e
echo "📤 Publishing Docker images to registry..."
# Переменные
REGISTRY=${DOCKER_REGISTRY:-"registry.hub.docker.com"}
PROJECT_NAME="catlink"
VERSION=${DRONE_TAG:-${DRONE_COMMIT_SHA:0:8}}
DOCKER_USERNAME=${DOCKER_USERNAME}
DOCKER_PASSWORD=${DOCKER_PASSWORD}
echo "📋 Publish information:"
echo " • Registry: $REGISTRY"
echo " • Project: $PROJECT_NAME"
echo " • Version: $VERSION"
echo " • Username: ${DOCKER_USERNAME:0:3}***"
# Проверка учетных данных
if [ -z "$DOCKER_USERNAME" ] || [ -z "$DOCKER_PASSWORD" ]; then
echo "❌ Docker registry credentials not found!"
echo "Please set DOCKER_USERNAME and DOCKER_PASSWORD environment variables"
exit 1
fi
# Вход в Docker registry
echo "🔐 Authenticating with Docker registry..."
echo "$DOCKER_PASSWORD" | docker login "$REGISTRY" -u "$DOCKER_USERNAME" --password-stdin
if [ $? -ne 0 ]; then
echo "❌ Failed to authenticate with Docker registry"
exit 1
fi
echo "✅ Successfully authenticated with registry"
# Список образов для публикации
IMAGES=(
"$REGISTRY/$PROJECT_NAME-backend:$VERSION"
"$REGISTRY/$PROJECT_NAME-backend:latest"
"$REGISTRY/$PROJECT_NAME-frontend:$VERSION"
"$REGISTRY/$PROJECT_NAME-frontend:latest"
)
# Проверка существования образов локально
echo "🔍 Checking local images..."
for image in "${IMAGES[@]}"; do
if docker images --format "table {{.Repository}}:{{.Tag}}" | grep -q "${image#*/}"; then
echo " ✅ Found: $image"
else
echo " ❌ Missing: $image"
echo "Error: Local image $image not found. Please run build first."
exit 1
fi
done
# Публикация образов
echo "🚀 Publishing images..."
for image in "${IMAGES[@]}"; do
echo " • Publishing $image..."
# Проверка размера образа
size=$(docker images --format "table {{.Size}}" "$image" | tail -n +2)
echo " Size: $size"
# Публикация с повторными попытками
for attempt in 1 2 3; do
echo " Attempt $attempt/3..."
if docker push "$image"; then
echo " ✅ Successfully pushed $image"
break
else
echo " ❌ Failed to push $image (attempt $attempt/3)"
if [ $attempt -eq 3 ]; then
echo "Error: Failed to push $image after 3 attempts"
exit 1
fi
sleep 5
fi
done
done
# Проверка опубликованных образов
echo "🔍 Verifying published images..."
for image in "${IMAGES[@]}"; do
echo " • Verifying $image..."
# Попытка скачать manifest
if docker manifest inspect "$image" > /dev/null 2>&1; then
echo " ✅ Manifest verified for $image"
else
echo " ❌ Failed to verify manifest for $image"
exit 1
fi
done
# Создание release notes
echo "📝 Creating release notes..."
cat > /tmp/release-notes.md << EOF
# Release $VERSION
## 🚀 What's New
### Features
- Updated to version $VERSION
- Production-ready Docker images
- Enhanced security configurations
- Performance optimizations
### Technical Details
- **Backend Image**: \`$REGISTRY/$PROJECT_NAME-backend:$VERSION\`
- **Frontend Image**: \`$REGISTRY/$PROJECT_NAME-frontend:$VERSION\`
- **Build Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
- **Git Commit**: ${DRONE_COMMIT_SHA:-$(git rev-parse HEAD)}
### Docker Images
\`\`\`bash
# Pull latest images
docker pull $REGISTRY/$PROJECT_NAME-backend:$VERSION
docker pull $REGISTRY/$PROJECT_NAME-frontend:$VERSION
# Or use latest tags
docker pull $REGISTRY/$PROJECT_NAME-backend:latest
docker pull $REGISTRY/$PROJECT_NAME-frontend:latest
\`\`\`
### Quick Start
\`\`\`bash
# Download and run with docker-compose
curl -sSL https://raw.githubusercontent.com/smartsoltech/links/main/docker-compose.production.yml -o docker-compose.yml
docker-compose up -d
\`\`\`
### Migration Notes
- No breaking changes in this release
- Database migrations included
- Backward compatible
## 📊 Image Information
| Component | Image | Size | Layers |
|-----------|-------|------|--------|
| Backend | \`$PROJECT_NAME-backend:$VERSION\` | $(docker images --format "{{.Size}}" "$REGISTRY/$PROJECT_NAME-backend:$VERSION" 2>/dev/null || echo "N/A") | $(docker history "$REGISTRY/$PROJECT_NAME-backend:$VERSION" 2>/dev/null | wc -l || echo "N/A") |
| Frontend | \`$PROJECT_NAME-frontend:$VERSION\` | $(docker images --format "{{.Size}}" "$REGISTRY/$PROJECT_NAME-frontend:$VERSION" 2>/dev/null || echo "N/A") | $(docker history "$REGISTRY/$PROJECT_NAME-frontend:$VERSION" 2>/dev/null | wc -l || echo "N/A") |
## 🔐 Security
All images are scanned for vulnerabilities and follow security best practices:
- Non-root user execution
- Minimal base images
- Regular security updates
- Dependency vulnerability scanning
## 📖 Documentation
- [Installation Guide](./docs/INSTALLATION.md)
- [Configuration Guide](./docs/CONFIGURATION.md)
- [API Documentation](./docs/API.md)
- [Makefile Commands](./docs/MAKEFILE.md)
---
**Full Changelog**: https://github.com/smartsoltech/links/compare/previous...${DRONE_TAG:-$VERSION}
EOF
# Уведомления о публикации
echo "📢 Sending publication notifications..."
# Slack уведомление (если настроено)
if [ -n "$SLACK_WEBHOOK_URL" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{
\"text\": \"🚀 *CatLink $VERSION* published successfully!\",
\"attachments\": [
{
\"color\": \"good\",
\"fields\": [
{
\"title\": \"Backend Image\",
\"value\": \"\`$REGISTRY/$PROJECT_NAME-backend:$VERSION\`\",
\"short\": true
},
{
\"title\": \"Frontend Image\",
\"value\": \"\`$REGISTRY/$PROJECT_NAME-frontend:$VERSION\`\",
\"short\": true
},
{
\"title\": \"Registry\",
\"value\": \"\`$REGISTRY\`\",
\"short\": true
},
{
\"title\": \"Build\",
\"value\": \"#${DRONE_BUILD_NUMBER:-$(date +%s)}\",
\"short\": true
}
]
}
]
}" \
"$SLACK_WEBHOOK_URL" || echo "Failed to send Slack notification"
fi
# Discord уведомление (если настроено)
if [ -n "$DISCORD_WEBHOOK_URL" ]; then
curl -H "Content-Type: application/json" \
-d "{
\"embeds\": [
{
\"title\": \"🚀 CatLink $VERSION Published\",
\"color\": 65280,
\"fields\": [
{
\"name\": \"Backend Image\",
\"value\": \"\`$REGISTRY/$PROJECT_NAME-backend:$VERSION\`\",
\"inline\": true
},
{
\"name\": \"Frontend Image\",
\"value\": \"\`$REGISTRY/$PROJECT_NAME-frontend:$VERSION\`\",
\"inline\": true
},
{
\"name\": \"Registry\",
\"value\": \"\`$REGISTRY\`\",
\"inline\": true
}
],
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
}
]
}" \
"$DISCORD_WEBHOOK_URL" || echo "Failed to send Discord notification"
fi
# Создание статистики публикации
echo "📊 Creating publication statistics..."
cat > /tmp/publish-stats.json << EOF
{
"version": "$VERSION",
"registry": "$REGISTRY",
"project": "$PROJECT_NAME",
"images": [
{
"name": "$PROJECT_NAME-backend",
"tag": "$VERSION",
"size": "$(docker images --format "{{.Size}}" "$REGISTRY/$PROJECT_NAME-backend:$VERSION" 2>/dev/null || echo "unknown")",
"published_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
},
{
"name": "$PROJECT_NAME-frontend",
"tag": "$VERSION",
"size": "$(docker images --format "{{.Size}}" "$REGISTRY/$PROJECT_NAME-frontend:$VERSION" 2>/dev/null || echo "unknown")",
"published_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
],
"build_info": {
"build_number": "${DRONE_BUILD_NUMBER:-unknown}",
"commit_sha": "${DRONE_COMMIT_SHA:-$(git rev-parse HEAD 2>/dev/null || echo "unknown")}",
"build_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"branch": "${DRONE_BRANCH:-$(git branch --show-current 2>/dev/null || echo "unknown")}"
}
}
EOF
# Очистка временных файлов
echo "🧹 Cleaning up..."
docker system prune -f > /dev/null 2>&1 || true
# Выход из registry
docker logout "$REGISTRY" > /dev/null 2>&1 || true
echo "✅ Publication completed successfully!"
echo ""
echo "📦 Published Images:"
echo " 🔗 Backend: $REGISTRY/$PROJECT_NAME-backend:$VERSION"
echo " 🔗 Frontend: $REGISTRY/$PROJECT_NAME-frontend:$VERSION"
echo ""
echo "📄 Release notes: /tmp/release-notes.md"
echo "📊 Statistics: /tmp/publish-stats.json"
echo ""
echo "🚀 Ready for deployment!"