# GitLab CI/CD Pipeline for Datacenter Documentation System stages: - lint - test - build - deploy - docs variables: POETRY_VERSION: "1.8.0" PYTHON_VERSION: "3.13" DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "/certs" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" cache: key: ${CI_COMMIT_REF_SLUG} paths: - .cache/pip - .venv/ # Template for Python jobs .python-base: image: python:${PYTHON_VERSION} before_script: - pip install poetry==${POETRY_VERSION} - poetry config virtualenvs.in-project true - poetry install --no-root # Lint stage lint:black: extends: .python-base stage: lint script: - poetry run black --check src/ tests/ only: - merge_requests - main - develop lint:ruff: extends: .python-base stage: lint script: - poetry run ruff check src/ tests/ only: - merge_requests - main - develop lint:mypy: extends: .python-base stage: lint script: - poetry run mypy src/ allow_failure: true only: - merge_requests - main - develop # Test stage test:unit: extends: .python-base stage: test services: - mongo:7-jammy variables: MONGODB_URL: mongodb://mongo:27017 MONGODB_DATABASE: testdb script: - poetry run pytest tests/unit -v --cov --cov-report=xml --cov-report=term coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage.xml paths: - htmlcov/ expire_in: 30 days only: - merge_requests - main - develop test:integration: extends: .python-base stage: test services: - mongo:7-jammy variables: MONGODB_URL: mongodb://mongo:27017 MONGODB_DATABASE: testdb script: - poetry run pytest tests/integration -v only: - merge_requests - main - develop when: manual # Security scanning security:bandit: extends: .python-base stage: test script: - poetry add --group dev bandit - poetry run bandit -r src/ -f json -o bandit-report.json artifacts: paths: - bandit-report.json expire_in: 30 days allow_failure: true only: - merge_requests - main security:safety: extends: .python-base stage: test script: - poetry export -f requirements.txt --output requirements.txt --without-hashes - poetry add --group dev safety - poetry run safety check --file requirements.txt allow_failure: true only: - merge_requests - main # Build stage build:docker:api: stage: build image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -f deploy/docker/Dockerfile.api -t $CI_REGISTRY_IMAGE/api:$CI_COMMIT_SHORT_SHA . - docker build -f deploy/docker/Dockerfile.api -t $CI_REGISTRY_IMAGE/api:latest . - docker push $CI_REGISTRY_IMAGE/api:$CI_COMMIT_SHORT_SHA - docker push $CI_REGISTRY_IMAGE/api:latest only: - main - tags build:docker:chat: stage: build image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -f deploy/docker/Dockerfile.chat -t $CI_REGISTRY_IMAGE/chat:$CI_COMMIT_SHORT_SHA . - docker build -f deploy/docker/Dockerfile.chat -t $CI_REGISTRY_IMAGE/chat:latest . - docker push $CI_REGISTRY_IMAGE/chat:$CI_COMMIT_SHORT_SHA - docker push $CI_REGISTRY_IMAGE/chat:latest only: - main - tags build:docker:worker: stage: build image: docker:24.0.5 services: - docker:24.0.5-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -f deploy/docker/Dockerfile.worker -t $CI_REGISTRY_IMAGE/worker:$CI_COMMIT_SHORT_SHA . - docker build -f deploy/docker/Dockerfile.worker -t $CI_REGISTRY_IMAGE/worker:latest . - docker push $CI_REGISTRY_IMAGE/worker:$CI_COMMIT_SHORT_SHA - docker push $CI_REGISTRY_IMAGE/worker:latest only: - main - tags build:frontend: stage: build image: node:20-alpine script: - cd frontend - npm ci - npm run build artifacts: paths: - frontend/dist/ expire_in: 7 days only: - main - tags # Deploy stage deploy:staging: stage: deploy image: bitnami/kubectl:latest script: - kubectl config use-context staging - kubectl set image deployment/api api=$CI_REGISTRY_IMAGE/api:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl set image deployment/chat chat=$CI_REGISTRY_IMAGE/chat:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl set image deployment/worker worker=$CI_REGISTRY_IMAGE/worker:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl rollout status deployment/api -n datacenter-docs - kubectl rollout status deployment/chat -n datacenter-docs - kubectl rollout status deployment/worker -n datacenter-docs environment: name: staging url: https://staging-docs.company.local only: - main when: manual deploy:production: stage: deploy image: bitnami/kubectl:latest script: - kubectl config use-context production - kubectl set image deployment/api api=$CI_REGISTRY_IMAGE/api:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl set image deployment/chat chat=$CI_REGISTRY_IMAGE/chat:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl set image deployment/worker worker=$CI_REGISTRY_IMAGE/worker:$CI_COMMIT_SHORT_SHA -n datacenter-docs - kubectl rollout status deployment/api -n datacenter-docs - kubectl rollout status deployment/chat -n datacenter-docs - kubectl rollout status deployment/worker -n datacenter-docs environment: name: production url: https://docs.company.local only: - tags when: manual # Documentation generation docs:generate: extends: .python-base stage: docs script: - poetry run python -m datacenter_docs.cli generate-all --dry-run artifacts: paths: - output/ expire_in: 7 days only: - schedules - main docs:publish: stage: docs image: node:20-alpine script: - npm install -g @gitbook/cli - gitbook build ./docs - gitbook pdf ./docs ./datacenter-docs.pdf artifacts: paths: - _book/ - datacenter-docs.pdf expire_in: 30 days only: - tags