diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f829f049..345f305f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,62 +1,147 @@ stages: - build - deploy - -variables: - DOCKER_BUILDKIT: "1" - COMPOSE_DOCKER_CLI_BUILD: "1" - DOCKER_DRIVER: overlay2 - BUILDKIT_PROGRESS: plain - IMAGE_NAME: "$CI_REGISTRY_IMAGE/web-lti:development_${CI_COMMIT_SHORT_SHA}" - NODE_ENV: "production" - HUSKY_SKIP_INSTALL: "1" - NEXT_PUBLIC_API_BASE_URL: "${NEXT_PUBLIC_API_BASE_URL}" - NEXT_PUBLIC_LTI_API_START_URL: "${NEXT_PUBLIC_LTI_API_START_URL}" - -build-image: + +.build_template: &build_template stage: build - image: docker:27.0.3 - services: - - docker:dind - - before_script: - - echo "Login to registry" - - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" - + image: node:20-alpine + cache: + key: npm-cache + paths: + - node_modules/ + variables: + NPM_CONFIG_PRODUCTION: "false" + NODE_ENV: "" script: - - | - docker build \ - --build-arg NEXT_PUBLIC_API_BASE_URL="$NEXT_PUBLIC_API_BASE_URL" \ - --build-arg NEXT_PUBLIC_LTI_API_START_URL="$NEXT_PUBLIC_LTI_API_START_URL" \ - --build-arg NODE_ENV="$NODE_ENV" \ - --build-arg HUSKY_SKIP_INSTALL="$HUSKY_SKIP_INSTALL" \ - --cache-from "$CI_REGISTRY_IMAGE/web-lti:latest" \ - -t "$IMAGE_NAME" . - - docker push "$IMAGE_NAME" - - docker image prune -af --filter "until=72h" + - echo "Installing dependencies..." + - npm ci --no-audit --no-fund + - echo "Building Next.js static export..." + - npx next build + artifacts: + name: "out-$CI_COMMIT_SHORT_SHA" + paths: + - out/ + expire_in: 1 week - after_script: "echo 'Build complete: $IMAGE_NAME' && docker system prune -af || true && docker volume prune -f || true" +.deploy_template: &deploy_template + 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" = "master" ]; then + ENVIRONMENT_NAME="WEB-LTI-PROD" + 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_API_BASE_URL: "https://dev-api-lti.mbugroup.id" + NEXT_PUBLIC_SSO_LOGIN_URL: "https://dev-api-sso.mbugroup.id" -deploy-dev: - stage: deploy - image: alpine:3.20 - - before_script: - - apk add --no-cache openssh curl - - mkdir -p ~/.ssh - - echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa - - chmod 600 ~/.ssh/id_rsa - - eval $(ssh-agent -s) - - ssh-add ~/.ssh/id_rsa - - ssh-keyscan -H "$SERVER_IP" >> ~/.ssh/known_hosts - - script: - - ssh -o StrictHostKeyChecking=no \"$SERVER_USER@$SERVER_IP\" \"docker stop dev-web-lti || true && docker rm dev-web-lti || true && docker pull $CI_REGISTRY_IMAGE/web-lti:development_${CI_COMMIT_SHORT_SHA} && docker run -d --name dev-web-lti --network dev-lti-network -p 3002:3000 $CI_REGISTRY_IMAGE/web-lti:development_${CI_COMMIT_SHORT_SHA}\" - - after_script: "echo 'Deploy finished for $IMAGE_NAME'" - +deploy:dev: + <<: *deploy_template + needs: ["build:dev"] rules: - - if: '$CI_COMMIT_BRANCH == "development"' \ No newline at end of file + - 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 + +# ====== PRODUCTION ====== +# build:production: +# <<: *build_template +# rules: +# # pilih salah satu: pakai branch master ATAU pakai tags rilis +# - if: '$CI_COMMIT_BRANCH == "master"' +# # - if: '$CI_COMMIT_TAG' # kalau mau rilis via tag, uncomment ini dan hapus baris di atas +# environment: +# name: production + +# deploy:production: +# <<: *deploy_template +# needs: ["build:production"] +# rules: +# - if: '$CI_COMMIT_BRANCH == "master"' +# # - if: '$CI_COMMIT_TAG' # selaras dengan rule di build:production +# variables: +# S3_BUCKET: "lti-erp.mbugroup.id" +# CLOUDFRONT_DISTRIBUTION_ID: "ddfd" +# environment: +# name: production + # url: https://royalgoldcapital.com +