image: oven/bun:latest stages: - validate - test - build - security - docker variables: DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: '' cache: key: files: - bun.lock paths: - .bun/ .node_setup: before_script: - bun install --frozen-lockfile # -- Validate Stage -- lint: extends: .node_setup stage: validate script: - bunx eslint "src/**/*.ts" prettier: extends: .node_setup stage: validate script: - bunx prettier --check "src/**/*.{ts,html,scss,css,json}" type-check: extends: .node_setup stage: validate script: - bunx tsc --noEmit # -- Test Stage -- test: image: node:24.21.0 extends: .node_setup stage: test before_script: - npm install --global bun@1.4.2 - bun install --frozen-lockfile script: - bun run test --watch=false --coverage artifacts: when: always paths: - coverage/ reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xml expire_in: 7 days # -- Build Stage -- build: image: node:24.21.0 extends: .node_setup stage: build before_script: - npm install --global bun@1.4.2 - bun install --frozen-lockfile script: - bun run build -- --configuration production artifacts: paths: - dist/ expire_in: 7 days # -- Security Stage -- include: - template: Security/SAST.gitlab-ci.yml trivy_scan: stage: security image: name: aquasec/trivy:latest entrypoint: [''] before_script: [] # override global before_script script: # Trivy will scan the project directory - trivy fs --format sarif --output trivy-results.sarif . artifacts: reports: sast: trivy-results.sarif expire_in: 7 days # -- Docker Stage -- docker-build: stage: docker image: docker:29.8.2 services: - docker:29.8.2-dind before_script: - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin script: - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" -t "$CI_REGISTRY_IMAGE:latest" . - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" - docker push "$CI_REGISTRY_IMAGE:latest" rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH