ci: implement 3-stage deployment pipeline with semantic-release
This commit is contained in:
parent
af8d86dedb
commit
d4d84ad0db
13 changed files with 271 additions and 169 deletions
|
|
@ -1,6 +1,6 @@
|
|||
services:
|
||||
portfolio:
|
||||
image: badbl0cks/portfolio:${IMAGE_TAG:-stable}
|
||||
image: ${IMAGE_NAME:-portfolio:latest}
|
||||
# image: ghcr.io/xe/x/httpdebug
|
||||
# entrypoint: ["/ko-app/httpdebug", "--bind", ":3000"]
|
||||
container_name: portfolio-${RELEASE_TYPE}-${DEPLOYMENT_COLOR}
|
||||
|
|
@ -10,7 +10,7 @@ services:
|
|||
- portfolio-${RELEASE_TYPE}
|
||||
expose:
|
||||
- "3000"
|
||||
env_file:
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
|
|
@ -21,7 +21,16 @@ services:
|
|||
- "deployment.release_type=${RELEASE_TYPE}"
|
||||
user: "1000:1000"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "-s", "--max-time", "5", "http://localhost:3000/api/health"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"curl",
|
||||
"-f",
|
||||
"-s",
|
||||
"--max-time",
|
||||
"5",
|
||||
"http://localhost:3000/api/health",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 15s
|
||||
retries: 3
|
||||
|
|
@ -47,7 +56,8 @@ services:
|
|||
aliases:
|
||||
- wireguard-${RELEASE_TYPE}
|
||||
healthcheck:
|
||||
test: ["CMD", "ping", "-c", "1", "-W", "3", "$$NUXT_ANDROID_SMS_GATEWAY_IP"]
|
||||
test:
|
||||
["CMD", "ping", "-c", "1", "-W", "3", "$$NUXT_ANDROID_SMS_GATEWAY_IP"]
|
||||
interval: 30s
|
||||
timeout: 15s
|
||||
retries: 3
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Validate common required environment variables
|
||||
require_var "DEPLOY_HOST"
|
||||
|
||||
readonly HAPROXY_BASE_DIR="/srv/haproxy"
|
||||
readonly HAPROXY_CONFIGS_DIR="${HAPROXY_BASE_DIR}/configs"
|
||||
readonly HAPROXY_COMPOSE_FILE="${HAPROXY_BASE_DIR}/docker-compose.yml"
|
||||
|
|
|
|||
|
|
@ -9,14 +9,12 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
source "${SCRIPT_DIR}/common-lib.sh"
|
||||
|
||||
# Validate required environment variables
|
||||
require_var "DOCKER_HOST"
|
||||
require_var "REPO_PROJECT_PATH"
|
||||
require_var "REPO_NAME_ONLY"
|
||||
require_var "REPO"
|
||||
require_var "IMAGE_TAR"
|
||||
require_var "PROD"
|
||||
require_var "DOMAIN"
|
||||
require_var "WIREGUARD_ENDPOINT_HOST"
|
||||
require_var "REPO_PROJECT_PATH"
|
||||
require_var "DEPLOY_HOST"
|
||||
|
||||
validate_deployment_env
|
||||
|
||||
|
|
@ -76,10 +74,18 @@ echo "DEPLOYMENT_COLOR=\"${NEW_COLOR}\"" >> .env
|
|||
echo "RELEASE_TYPE=\"${RELEASE_TYPE}\"" >> .env
|
||||
echo "WIREGUARD_ENDPOINT_IP=\"${WIREGUARD_ENDPOINT_IP}\"" >> .env
|
||||
|
||||
# Set computed image name based on release type
|
||||
if [ "$RELEASE_TYPE" = "staging" ]; then
|
||||
IMAGE_NAME="portfolio-dev:${IMAGE_TAG}"
|
||||
else
|
||||
IMAGE_NAME="portfolio:${IMAGE_TAG}"
|
||||
fi
|
||||
echo "IMAGE_NAME=\"${IMAGE_NAME}\"" >> .env
|
||||
|
||||
echo "📋 Copying deployment files..."
|
||||
scp deploy/docker-compose.yml deploy/haproxy.cfg .env deploy:"${NEW_RELEASE_PATH}/"
|
||||
|
||||
echo "🐳 Loading Docker image..."
|
||||
echo "🐳 Loading Docker image (${IMAGE_TAR})..."
|
||||
docker load -i "${IMAGE_TAR}"
|
||||
|
||||
PROJECT_NAME=$(get_project_name "$NEW_COLOR")
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Generate Docker tags based on git ref and environment
|
||||
# Usage: ./generate-docker-tags.sh IMAGE_BASE GIT_SHA GIT_REF PROD
|
||||
|
||||
if [ $# -ne 4 ]; then
|
||||
echo "Error: Invalid number of arguments" > /dev/stderr
|
||||
echo "Usage: $0 IMAGE_BASE GIT_SHA GIT_REF PROD" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IMAGE_BASE="$1"
|
||||
GIT_SHA="$2"
|
||||
GIT_REF="$3"
|
||||
PROD="$4"
|
||||
|
||||
# Validate inputs
|
||||
if [ -z "$IMAGE_BASE" ] || [ -z "$GIT_SHA" ]; then
|
||||
echo "Error: IMAGE_BASE and GIT_SHA cannot be empty" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Always include SHA tags
|
||||
echo "${IMAGE_BASE}:sha-${GIT_SHA:0:7}"
|
||||
echo "${IMAGE_BASE}:sha-${GIT_SHA}"
|
||||
|
||||
# Handle version tags
|
||||
if [[ "$GIT_REF" =~ ^refs/tags/v([0-9]+)\.([0-9]+)\.([0-9]+)(-.*)?$ ]]; then
|
||||
MAJOR="${BASH_REMATCH[1]}"
|
||||
MINOR="${BASH_REMATCH[2]}"
|
||||
PATCH="${BASH_REMATCH[3]}"
|
||||
PRERELEASE="${BASH_REMATCH[4]}"
|
||||
|
||||
if [[ -z "$PRERELEASE" ]] && [[ "$PROD" == "true" ]]; then
|
||||
echo "${IMAGE_BASE}:latest"
|
||||
echo "${IMAGE_BASE}:stable"
|
||||
[[ "$MAJOR" -gt 0 ]] && echo "${IMAGE_BASE}:v${MAJOR}"
|
||||
echo "${IMAGE_BASE}:v${MAJOR}.${MINOR}"
|
||||
echo "${IMAGE_BASE}:v${MAJOR}.${MINOR}.${PATCH}"
|
||||
else
|
||||
echo "${IMAGE_BASE}:latest-staging"
|
||||
echo "${IMAGE_BASE}:staging"
|
||||
echo "${IMAGE_BASE}:v${MAJOR}.${MINOR}.${PATCH}-prerelease"
|
||||
fi
|
||||
elif [[ "$PROD" == "false" ]]; then
|
||||
echo "${IMAGE_BASE}:latest-staging"
|
||||
echo "${IMAGE_BASE}:staging"
|
||||
fi
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Parse repository name and generate project paths
|
||||
# Usage: ./parse-repository-name.sh GITHUB_REPOSITORY
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Error: No repository name provided" > /dev/stderr
|
||||
echo "Usage: $0 GITHUB_REPOSITORY" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GITHUB_REPOSITORY="$1"
|
||||
|
||||
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY" > /dev/stderr
|
||||
|
||||
if [[ "$GITHUB_REPOSITORY" == *".git" ]]; then
|
||||
if [[ "$GITHUB_REPOSITORY" == "https://"* ]]; then
|
||||
echo "GITHUB_REPOSITORY ends in .git and is an HTTPS URI" > /dev/stderr
|
||||
REPO=$(echo "$GITHUB_REPOSITORY" | sed 's/\.git$//' | cut -d'/' -f4-5 | sed 's/[^a-zA-Z0-9\/-]/-/g')
|
||||
elif [[ "$GITHUB_REPOSITORY" == "git@"* ]]; then
|
||||
echo "GITHUB_REPOSITORY ends in .git and is an SSH URI" > /dev/stderr
|
||||
REPO=$(echo "$GITHUB_REPOSITORY" | sed 's/\.git$//' | cut -d':' -f2 | sed 's/[^a-zA-Z0-9\/-]/-/g')
|
||||
else
|
||||
echo "GITHUB_REPOSITORY ends in .git and is not a URI" > /dev/stderr
|
||||
REPO=$(echo "$GITHUB_REPOSITORY" | sed 's/\.git$//' | sed 's/[^a-zA-Z0-9\/-]/-/g')
|
||||
fi
|
||||
else
|
||||
echo "GITHUB_REPOSITORY is not a URI" > /dev/stderr
|
||||
REPO=$(echo "$GITHUB_REPOSITORY" | sed 's/[^a-zA-Z0-9\/-]/-/g')
|
||||
fi
|
||||
|
||||
REPO_NAME_ONLY=$(echo "$REPO" | cut -d'/' -f2)
|
||||
# Default path - will be modified by deployment script based on environment
|
||||
REPO_PROJECT_PATH="/srv/${REPO_NAME_ONLY}"
|
||||
|
||||
# Output in format that can be sourced - using printf %q for proper escaping
|
||||
printf "export REPO=%q\n" "$REPO"
|
||||
printf "export REPO_NAME_ONLY=%q\n" "$REPO_NAME_ONLY"
|
||||
printf "export REPO_PROJECT_PATH=%q\n" "$REPO_PROJECT_PATH"
|
||||
Loading…
Add table
Add a link
Reference in a new issue