From 1ca6c6a104fb9bb8669b5b4abea66049a81658b5 Mon Sep 17 00:00:00 2001 From: M1 AIR Date: Thu, 22 Jan 2026 14:12:20 +0700 Subject: [PATCH] Fixing staging cicd --- ci/staging.yml | 122 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 41 deletions(-) diff --git a/ci/staging.yml b/ci/staging.yml index 511a9eff..e3eaabb0 100644 --- a/ci/staging.yml +++ b/ci/staging.yml @@ -6,31 +6,31 @@ stages: default: tags: - - self-hosted-prod + - self-hosted-stg workflow: rules: - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"' when: always - when: never variables: DOCKER_BUILDKIT: "1" - IMAGE_TAG: "production_${CI_COMMIT_SHORT_SHA}" + IMAGE_TAG: "staging_${CI_COMMIT_SHORT_SHA}" IMAGE_NAME: "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}" - IMAGE_LATEST: "${CI_REGISTRY_IMAGE}:production_latest" + IMAGE_LATEST: "${CI_REGISTRY_IMAGE}:staging_latest" - DEPLOY_DIR: "/opt/deploy/lti" + DEPLOY_DIR: "/opt/deploy/stg-lti-api" COMPOSE_FILE: "docker-compose.yaml" # ========================= -# BUILD (AUTO) +# BUILD (AUTO) # ========================= -build_production: +build_staging: stage: build rules: - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"' script: | set -e docker info @@ -49,54 +49,93 @@ build_production: # ========================= -# MIGRATE (PRODUCTION - MANUAL) +# MIGRATE (AUTO) # ========================= -migrate_production: +migrate_staging: stage: migrate rules: - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"' - when: manual - allow_failure: false + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"' needs: - - job: build_production + - job: build_staging artifacts: false script: | set -e - cd /opt/deploy/lti - test -f .env || (echo "❌ .env not found" && exit 1) + echo "✅ Running migrations (staging) ..." + cd "$DEPLOY_DIR" + test -f "$COMPOSE_FILE" || (echo "❌ $COMPOSE_FILE not found in $DEPLOY_DIR" && exit 1) + test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1) + + # ✅ load env dari server set -a . ./.env set +a - # Validasi env wajib - : "${DB_HOST:?DB_HOST not set}" - : "${DB_PORT:?DB_PORT not set}" - : "${DB_USER:?DB_USER not set}" - : "${DB_PASSWORD:?DB_PASSWORD not set}" - : "${DB_NAME:?DB_NAME not set}" + # ✅ validasi + test -n "$DB_HOST" || (echo "❌ DB_HOST empty" && exit 1) + test -n "$DB_PORT" || (echo "❌ DB_PORT empty" && exit 1) + test -n "$DB_USER" || (echo "❌ DB_USER empty" && exit 1) + test -n "$DB_PASSWORD" || (echo "❌ DB_PASSWORD empty" && exit 1) + test -n "$DB_NAME" || (echo "❌ DB_NAME empty" && exit 1) - DB_SSLMODE="${DB_SSLMODE:-require}" - export DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE}" + export DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE:-disable}" + echo "✅ DATABASE_URL=$DATABASE_URL" - echo "✅ Running migrations (production)..." - docker run --rm \ + # ✅ Pastikan postgres & redis ON (sesuaikan nama service compose kamu!) + echo "✅ Ensuring postgres & redis running ..." + docker compose -f "$COMPOSE_FILE" up -d stg-postgres-lti stg-redis-lti || true + + # ✅ Ambil network key dari compose + COMPOSE_NETWORK_KEY="$(docker compose -f "$COMPOSE_FILE" config | awk '/networks:/ {getline; print $1}' | tr -d ':')" + echo "✅ Compose network key: $COMPOSE_NETWORK_KEY" + + # ✅ Cari network name yang dipakai docker + NETWORK_NAME="$(docker network ls --format '{{.Name}}' | grep "_${COMPOSE_NETWORK_KEY}$" | head -n 1)" + test -n "$NETWORK_NAME" || (echo "❌ Cannot find docker network for compose ($COMPOSE_NETWORK_KEY)" && exit 1) + + echo "✅ Docker network detected: $NETWORK_NAME" + + # ✅ Migrations dari repo (CI workspace) + echo "✅ Checking migrations from repo..." + ls -lah "$CI_PROJECT_DIR/internal/database/migrations" + + echo "✅ Running migrations via migrate/migrate container" + set +e + out=$(docker run --rm \ + --network "$NETWORK_NAME" \ -v "$CI_PROJECT_DIR/internal/database/migrations:/migrations:ro" \ migrate/migrate:v4.15.2 \ - -path=/migrations -database "$DATABASE_URL" up + -path=/migrations -database "$DATABASE_URL" up 2>&1) + code=$? + set -e + + echo "$out" + + # ✅ Handle no change dengan benar (tidak false-success) + if echo "$out" | grep -qi "no change"; then + echo "✅ No change (already up to date)" + exit 0 + fi + + if [ $code -ne 0 ]; then + echo "❌ Migration failed with exit code $code" + exit $code + fi + + echo "✅ Migration applied successfully" # ========================= # DEPLOY (AUTO) # ========================= -deploy_production: +deploy_staging: stage: deploy rules: - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"' needs: - - job: migrate_production + - job: migrate_staging artifacts: false - - job: build_production + - job: build_staging artifacts: false script: | set -e @@ -115,19 +154,20 @@ deploy_production: # ========================= # SEED (MANUAL) # ========================= -seed_production: +seed_staging: stage: seed rules: - - if: '$CI_COMMIT_BRANCH == "production"' - when: manual + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"' + needs: + - job: deploy_staging + artifacts: false + when: manual + allow_failure: false script: | set -e - cd /opt/deploy/lti + cd "$DEPLOY_DIR" + test -f "$COMPOSE_FILE" || (echo "❌ $COMPOSE_FILE not found" && exit 1) test -f .env || (echo "❌ .env not found" && exit 1) - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" - - docker compose --env-file .env pull seed - docker compose --env-file .env run --rm seed - - + docker compose -f "$COMPOSE_FILE" pull seed || true + docker compose -f "$COMPOSE_FILE" run --rm seed%