151 lines
3.3 KiB
YAML
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]+$/
|