stages:
  - build
  - verify
  - push

default:
  image: repo.nstart.cloud/nstart/node:24-trixie-slim
  cache:
    paths:
      - .npm/

install:
  stage: build
  script:
    - npm ci --cache .npm --prefer-offline
  artifacts:
    expire_in: 1h
    paths:
      - node_modules/

oci:
  stage: build
  image: repo.nstart.cloud/nstart/docker-cli-buildx:1.0.0
  services:
    - name: repo.nstart.cloud/library/docker:29.1.2-dind
      alias: docker
      command: ["--tls=false"]
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
  script:
    - |
      export VERSION=$(jq -r '.version' package.json)
      export IMAGE_NAME=$CI_PROJECT_NAME

      docker bake save

      docker bake app --print \
        | jq -r '.target.app.tags[]' \
        > dist/tags.txt
  artifacts:
    paths:
      - dist/
    expire_in: 1 day

trivy:
  stage: verify
  image:
    name: repo.nstart.cloud/aquasec/trivy:0.69.3
    entrypoint: [""]
  needs:
    - job: oci
      artifacts: true
  variables:
    TRIVY_CACHE_DIR: .trivycache
  cache:
    paths:
      - .trivycache/
  script:
    - |
      mkdir -p dist/oci-layout
      OCI_TAR="$(find dist -maxdepth 1 -type f -name '*.tar' -print -quit)"

      tar -xf "$OCI_TAR" -C dist/oci-layout

      trivy image --input "dist/oci-layout" \
        --format table \
        --table-mode detailed \
        --scanners vuln,secret,misconfig \
        --image-config-scanners misconfig,secret \
        --pkg-types os,library \
        --severity HIGH,CRITICAL \
        --ignore-unfixed \
        --exit-code 1

build:
  stage: verify
  needs: ["install"]
  script:
    - npm run build

semgrep:
  stage: verify
  image: repo.nstart.cloud/semgrep/semgrep:1.160.0
  script:
    - semgrep scan --config auto --error .

.push_oci:
  image:
    name: repo.nstart.cloud/skopeo/stable:latest
    entrypoint: [""]
  script:
    - |
      skopeo login "$REGISTRY" -u "$REGISTRY_USER" -p "$REGISTRY_PASSWORD"

      OCI_TAR="$(find dist -maxdepth 1 -type f -name '*.tar' -print -quit)"

      while IFS= read -r DEST_TAG; do
        [ -n "$DEST_TAG" ] || continue

        skopeo copy --dest-tls-verify=false \
          "oci-archive:${OCI_TAR}:latest" \
          "docker://${DEST_TAG}"
      done < dist/tags.txt

manual:
  stage: push
  extends: .push_oci
  needs:
    - job: oci
      artifacts: true
  rules:
    - if: $CI_COMMIT_TAG
      when: manual
      allow_failure: true
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
      allow_failure: true
    - when: never
  manual_confirmation: "Вы уверены, что хотите запустить push в registry?"

auto:
  stage: push
  extends: .push_oci
  needs:
    - job: oci
      artifacts: true
    - job: trivy
  rules:
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - when: never
