Files
lti-api/.gitlab-ci.yml
T
2026-01-09 10:58:11 +07:00

150 lines
4.1 KiB
YAML

stages:
- build
- migrate
- deploy
- seed
default:
tags:
- self-hosted-stg
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
when: always
- when: never
variables:
DOCKER_BUILDKIT: "1"
IMAGE_TAG: "staging_${CI_COMMIT_SHORT_SHA}"
IMAGE_NAME: "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}"
IMAGE_LATEST: "${CI_REGISTRY_IMAGE}:staging_latest"
DEPLOY_DIR: "/opt/deploy/stg-lti-api"
# =========================
# BUILD (AUTO)
# =========================
build_staging:
stage: build
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
script: |
set -e
docker info
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
echo "✅ Build image: $IMAGE_NAME"
docker build -t "$IMAGE_NAME" -f Dockerfile .
echo "✅ Push image: $IMAGE_NAME"
docker push "$IMAGE_NAME"
echo "✅ Tag latest: $IMAGE_LATEST"
docker tag "$IMAGE_NAME" "$IMAGE_LATEST"
docker push "$IMAGE_LATEST"
# =========================
# MIGRATE (AUTO) - migrations diambil dari repo GitLab
# =========================
migrate_staging:
stage: migrate
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
needs:
- job: build_staging
artifacts: false
script: |
set -e
# ✅ Load env dari server (.env hanya ada di server)
cd "$DEPLOY_DIR"
test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1)
set -a
. ./.env
set +a
# ✅ Generate DATABASE_URL dari DB_*
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)
export DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE:-disable}"
echo "✅ DATABASE_URL ready"
# ✅ migrations dari repo
echo "✅ Checking migrations from repo..."
ls -lah "$CI_PROJECT_DIR/internal/database/migrations"
echo "✅ Running migrations via migrate/migrate container"
set +e
docker run --rm \
-v "$CI_PROJECT_DIR/internal/database/migrations:/migrations:ro" \
migrate/migrate:v4.15.2 \
-path=/migrations -database "$DATABASE_URL" up
code=$?
set -e
if [ $code -eq 0 ]; then
echo "✅ Migration applied successfully"
elif [ $code -eq 1 ]; then
echo "✅ No change (already up to date)"
else
echo "❌ Migration failed with exit code $code"
exit $code
fi
# =========================
# DEPLOY (AUTO)
# =========================
deploy_staging:
stage: deploy
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
needs:
- job: migrate_staging
artifacts: false
- job: build_staging
artifacts: false
script: |
set -e
docker info
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
cd "$DEPLOY_DIR"
test -f docker-compose.yaml || (echo "❌ docker-compose.yaml not found in $DEPLOY_DIR" && exit 1)
test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1)
docker compose pull
docker compose up -d --force-recreate
docker image prune -f
# =========================
# SEED (MANUAL)
# =========================
seed_staging:
stage: seed
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
needs:
- job: deploy_staging
artifacts: false
when: manual
allow_failure: false
script: |
set -e
cd "$DEPLOY_DIR"
test -f docker-compose.yaml || (echo "❌ docker-compose.yaml not found in $DEPLOY_DIR" && exit 1)
test -f .env || (echo "❌ .env not found in $DEPLOY_DIR" && exit 1)
echo "✅ Pull latest seed image"
docker compose pull seed || true
echo "🌱 Running seeder..."
docker compose run --rm seed
echo "✅ Seed completed"