# 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]+$/