mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
Penyesuaian flow repo
This commit is contained in:
+134
-170
@@ -1,185 +1,149 @@
|
||||
stages:
|
||||
- build
|
||||
- migrate
|
||||
- deploy
|
||||
- seed
|
||||
|
||||
# ==========================================================
|
||||
# ✅ Global defaults
|
||||
# ==========================================================
|
||||
default:
|
||||
tags:
|
||||
- server-development-biznet
|
||||
interruptible: true
|
||||
- self-hosted-stg
|
||||
|
||||
# ==========================================================
|
||||
# 🏗️ Build Template
|
||||
# ==========================================================
|
||||
.build_template: &build_template
|
||||
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
|
||||
image: node:20-alpine
|
||||
cache:
|
||||
key: npm-cache
|
||||
paths:
|
||||
- node_modules/
|
||||
variables:
|
||||
NPM_CONFIG_PRODUCTION: 'false'
|
||||
NODE_ENV: ''
|
||||
script:
|
||||
- echo "Installing dependencies..."
|
||||
- npm ci --no-audit --no-fund
|
||||
- echo "Build env used:"
|
||||
- echo "NEXT_PUBLIC_LTI_URL=$NEXT_PUBLIC_LTI_URL"
|
||||
- echo "NEXT_PUBLIC_SSO_LOGIN_URL=$NEXT_PUBLIC_SSO_LOGIN_URL"
|
||||
- echo "NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL"
|
||||
- echo "Building Next.js static export..."
|
||||
- npx next build
|
||||
- |
|
||||
mkdir -p out
|
||||
cat <<EOF > out/build-info.json
|
||||
{
|
||||
"commit": "$CI_COMMIT_SHORT_SHA",
|
||||
"pipeline": "$CI_PIPELINE_ID",
|
||||
"built_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
||||
"NEXT_PUBLIC_LTI_URL": "$NEXT_PUBLIC_LTI_URL",
|
||||
"NEXT_PUBLIC_SSO_LOGIN_URL": "$NEXT_PUBLIC_SSO_LOGIN_URL",
|
||||
"NEXT_PUBLIC_API_BASE_URL": "$NEXT_PUBLIC_API_BASE_URL"
|
||||
}
|
||||
EOF
|
||||
artifacts:
|
||||
name: 'out-$CI_COMMIT_SHORT_SHA'
|
||||
paths:
|
||||
- out/
|
||||
expire_in: 1 week
|
||||
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"
|
||||
|
||||
# ==========================================================
|
||||
# 🚀 Deploy Template
|
||||
# ==========================================================
|
||||
.deploy_template: &deploy_template
|
||||
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
|
||||
image:
|
||||
name: amazon/aws-cli:latest
|
||||
entrypoint: ['/bin/sh', '-c']
|
||||
script:
|
||||
- set -e
|
||||
- aws --version
|
||||
- echo "Cleaning up newline characters in AWS credentials..."
|
||||
- export AWS_ACCESS_KEY_ID=$(echo $AWS_ACCESS_KEY_ID | tr -d '\r\n')
|
||||
- export AWS_SECRET_ACCESS_KEY=$(echo $AWS_SECRET_ACCESS_KEY | tr -d '\r\n')
|
||||
- echo "Deploying to s3://$S3_BUCKET in region $AWS_REGION"
|
||||
- aws s3api head-bucket --bucket "$S3_BUCKET" --region "$AWS_REGION" || aws s3api create-bucket --bucket "$S3_BUCKET" --region "$AWS_REGION" --create-bucket-configuration LocationConstraint="$AWS_REGION"
|
||||
- aws s3 sync ./out "s3://$S3_BUCKET" --delete --region "$AWS_REGION" --endpoint-url "https://s3.ap-southeast-3.amazonaws.com"
|
||||
|
||||
# CloudFront invalidation
|
||||
- |
|
||||
STATUS="success"
|
||||
if [ -n "$CLOUDFRONT_DISTRIBUTION_ID" ]; then
|
||||
echo "Invalidating CloudFront cache..."
|
||||
if ! aws cloudfront create-invalidation --distribution-id "$CLOUDFRONT_DISTRIBUTION_ID" --paths "/*"; then
|
||||
echo "CloudFront invalidation failed."
|
||||
STATUS="failed"
|
||||
fi
|
||||
else
|
||||
echo "No CloudFront distribution specified — skipping invalidation"
|
||||
fi
|
||||
|
||||
# Notifikasi Discord
|
||||
- |
|
||||
RUN_URL="${CI_PROJECT_URL}/-/pipelines/${CI_PIPELINE_ID}"
|
||||
|
||||
if [ "$CI_COMMIT_BRANCH" = "development" ]; then
|
||||
ENVIRONMENT_NAME="WEB-LTI-DEV"
|
||||
elif [ "$CI_COMMIT_BRANCH" = "staging" ]; then
|
||||
ENVIRONMENT_NAME="WEB-LTI-STAGING"
|
||||
else
|
||||
ENVIRONMENT_NAME="UNKNOWN"
|
||||
fi
|
||||
|
||||
if [ "$STATUS" = "success" ]; then
|
||||
COLOR=3066993
|
||||
TITLE="✅ Deployment ${ENVIRONMENT_NAME} Succeeded"
|
||||
DESC="Deployment job on branch \${CI_COMMIT_REF_NAME}\ completed successfully."
|
||||
else
|
||||
COLOR=15158332
|
||||
TITLE="❌ Deployment ${ENVIRONMENT_NAME} Failed"
|
||||
DESC="Deployment job on branch \${CI_COMMIT_REF_NAME}\ encountered issues."
|
||||
fi
|
||||
|
||||
jq -n \
|
||||
--arg title "$TITLE" \
|
||||
--arg desc "$DESC" \
|
||||
--arg color "$COLOR" \
|
||||
--arg repo "$CI_PROJECT_PATH" \
|
||||
--arg actor "$GITLAB_USER_LOGIN" \
|
||||
--arg commit "$CI_COMMIT_SHA" \
|
||||
--arg run_url "$RUN_URL" \
|
||||
'{
|
||||
username: "CI Bot - LTI WEB",
|
||||
embeds: [{
|
||||
title: $title,
|
||||
description: $desc,
|
||||
color: ($color|tonumber),
|
||||
fields: [
|
||||
{name: "Repository", value: $repo, inline: true},
|
||||
{name: "Actor", value: $actor, inline: true},
|
||||
{name: "Commit", value: $commit, inline: false},
|
||||
{name: "Pipeline", value: ("[Open run](" + $run_url + ")"), inline: false}
|
||||
]
|
||||
}]
|
||||
}' > payload.json
|
||||
|
||||
curl -sS -H "Content-Type: application/json" -d @payload.json "$DISCORD_WEBHOOK_URL"
|
||||
|
||||
# ==========================================================
|
||||
# ==== DEVELOPMENT (Branch development) ======
|
||||
# ==========================================================
|
||||
build:dev:
|
||||
<<: *build_template
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "development"'
|
||||
environment:
|
||||
name: development
|
||||
variables:
|
||||
NEXT_PUBLIC_LTI_URL: 'https://dev-lti-erp.mbugroup.id'
|
||||
NEXT_PUBLIC_SSO_LOGIN_URL: 'https://dev-auth-erp.mbugroup.id'
|
||||
NEXT_PUBLIC_API_BASE_URL: 'https://dev-api-lti.mbugroup.id/api'
|
||||
NEXT_PUBLIC_CLIENT_ID: 'Lumbung-Telur-Indonesia'
|
||||
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
|
||||
needs:
|
||||
- job: migrate_staging
|
||||
artifacts: false
|
||||
- job: build_staging
|
||||
artifacts: false
|
||||
script: |
|
||||
set -e
|
||||
|
||||
deploy:dev:
|
||||
<<: *deploy_template
|
||||
needs: ['build:dev']
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "development"'
|
||||
variables:
|
||||
S3_BUCKET: 'dev-lti-erp.mbugroup.id'
|
||||
AWS_REGION: 'ap-southeast-3'
|
||||
CLOUDFRONT_DISTRIBUTION_ID: 'E1Z8XTA8XF1GIV'
|
||||
environment:
|
||||
name: development
|
||||
url: https://dev-lti-erp.mbugroup.id
|
||||
docker info
|
||||
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
||||
|
||||
# ==========================================================
|
||||
# ====== STAGING (Branch staging) ======
|
||||
# ==========================================================
|
||||
build:staging:
|
||||
<<: *build_template
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "staging"'
|
||||
environment:
|
||||
name: staging
|
||||
variables:
|
||||
NEXT_PUBLIC_LTI_URL: 'https://stg-lti-erp.mbugroup.id'
|
||||
NEXT_PUBLIC_SSO_LOGIN_URL: 'https://stg-auth-erp.mbugroup.id'
|
||||
NEXT_PUBLIC_API_BASE_URL: 'https://stg-api-lti.mbugroup.id/api'
|
||||
NEXT_PUBLIC_CLIENT_ID: 'Lumbung-Telur-Indonesia'
|
||||
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)
|
||||
|
||||
deploy:staging:
|
||||
<<: *deploy_template
|
||||
needs: ['build:staging']
|
||||
docker compose pull
|
||||
docker compose up -d --force-recreate
|
||||
docker image prune -f
|
||||
|
||||
# =========================
|
||||
# SEED (MANUAL)
|
||||
# =========================
|
||||
seed_staging:
|
||||
stage: seed
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "staging"'
|
||||
variables:
|
||||
S3_BUCKET: 'stg-lti-erp.mbugroup.id'
|
||||
AWS_REGION: 'ap-southeast-3'
|
||||
CLOUDFRONT_DISTRIBUTION_ID: 'E2V6PPO1AUIU7H'
|
||||
environment:
|
||||
name: staging
|
||||
url: https://stg-lti-erp.mbugroup.id
|
||||
- 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"
|
||||
|
||||
Reference in New Issue
Block a user