didi-website-erp-crm/website/.gitlab-ci.yml

151 lines
3.3 KiB
YAML

# DiDi Website (Next.js 16) — GitLab CI/CD
# =========================================
stages:
- prepare
- security
- lint
- test
- build
- deploy
- release
variables:
NODE_ENV: "test"
npm_config_cache: "$CI_PROJECT_DIR/.npm"
.node-cache: &node-cache
cache:
key: node-${CI_COMMIT_REF_SLUG}
paths:
- .npm/
- node_modules/
policy: pull-push
install:
stage: prepare
image: node:20-slim
<<: *node-cache
script:
- npm ci --prefer-offline
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "staging"
security:audit:
stage: security
image: node:20-slim
needs: [install]
script:
- npm audit --audit-level=moderate || true
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
security:gitleaks:
stage: security
image:
name: zricethezav/gitleaks:latest
entrypoint: [""]
script:
- gitleaks detect --source . --no-banner --report-format json --report-path gitleaks-report.json
artifacts:
when: on_failure
paths: [gitleaks-report.json]
expire_in: 1 month
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
lint:
stage: lint
image: node:20-slim
needs: [install]
<<: *node-cache
script:
- npx tsc --noEmit
- npm run lint
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
test:
stage: test
image: node:20-slim
needs: [install]
<<: *node-cache
script:
- npm test -- --run --coverage 2>&1 || echo "tests pending — add Vitest suite"
allow_failure: true
artifacts:
when: always
paths: [coverage/]
expire_in: 1 week
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
build:
stage: build
image: node:20-slim
needs: [lint]
<<: *node-cache
script:
- npm run build
artifacts:
paths: [.next/]
expire_in: 1 week
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "staging"
build:docker:
stage: build
needs: [build]
script:
- docker build -t didi-website:${CI_COMMIT_SHORT_SHA} -t didi-website:latest .
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "staging"
tags: [shell, docker]
deploy:staging:
stage: deploy
needs: [build:docker]
script:
- docker compose up -d --force-recreate didi-website
environment:
name: staging
url: https://website.example.com
rules:
- if: $CI_COMMIT_BRANCH == "staging"
when: manual
tags: [shell, docker]
deploy:prod:
stage: deploy
needs: [build:docker]
script:
- docker compose up -d --force-recreate didi-website
environment:
name: production
url: https://didi365.eu
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
tags: [shell, docker]
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo "Release ${CI_COMMIT_TAG}"
release:
tag_name: '$CI_COMMIT_TAG'
name: 'Release $CI_COMMIT_TAG'
description: 'Automated release for $CI_COMMIT_TAG'
rules:
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/