image: docker.io/rust:slim-bookworm

services:
  - name: docker.io/groonga/pgroonga:latest-alpine-12-slim
    alias: postgres
    pull_policy: if-not-present
  - name: docker.io/redis:7-alpine
    alias: redis
    pull_policy: if-not-present

workflow:
  rules:
    - if: $CI_PROJECT_PATH == 'firefish/firefish' || $CI_MERGE_REQUEST_PROJECT_PATH == 'firefish/firefish'
      changes:
        paths:
          - packages/**/*
          - locales/**/*
          - scripts/**/*
          - package.json
          - Cargo.toml
          - Cargo.lock
          - Dockerfile
          - .dockerignore
      when: always
    - when: never

stages:
  - test
  - doc
  - build
  - dependency
  - clean

variables:
  POSTGRES_DB: 'firefish_db'
  POSTGRES_USER: 'firefish'
  POSTGRES_PASSWORD: 'password'
  POSTGRES_HOST_AUTH_METHOD: 'trust'
  DEBIAN_FRONTEND: 'noninteractive'
  NODE_OPTIONS: '--max_old_space_size=3072'
  CARGO_PROFILE_DEV_OPT_LEVEL: '0'
  CARGO_PROFILE_DEV_LTO: 'off'
  CARGO_PROFILE_DEV_DEBUG: 'none'
  CARGO_TERM_COLOR: 'always'
  GIT_CLEAN_FLAGS: -ffdx -e node_modules/ -e built/ -e target/ -e packages/backend-rs/built/

default:
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get -y --no-install-recommends install curl
    - curl -fsSL 'https://deb.nodesource.com/setup_18.x' | bash -
    - apt-get install -y --no-install-recommends build-essential clang mold python3 perl nodejs postgresql-client
    - corepack enable
    - corepack prepare pnpm@latest --activate
    - cp .config/ci.yml .config/default.yml
    - cp ci/cargo/config.toml /usr/local/cargo/config.toml
    - export PGPASSWORD="${POSTGRES_PASSWORD}"
    - psql --host postgres --user "${POSTGRES_USER}" --dbname "${POSTGRES_DB}" --command 'CREATE EXTENSION pgroonga'

test:build:
  stage: test
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - scripts/**/*
          - package.json
          - Cargo.toml
          - Cargo.lock
      when: always
  needs:
    - job: cargo:clippy
      optional: true
    - job: cargo:test
      optional: true
  script:
    - pnpm install --frozen-lockfile
    - pnpm run build:debug
    - pnpm run migrate
    - psql --host postgres --user "${POSTGRES_USER}" --dbname "${POSTGRES_DB}" --command "$(cat docs/downgrade.sql)"

test:build:backend_ts:
  stage: test
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - scripts/**/*
          - package.json
          - Cargo.toml
          - Cargo.lock
          - docs/downgrade.sql
      when: never 
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend/**/*
          - packages/firefish-js/**/*
          - packages/megalodon/**/*
      when: always
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get -y --no-install-recommends install curl
    - curl -fsSL 'https://deb.nodesource.com/setup_18.x' | bash -
    - apt-get install -y --no-install-recommends build-essential clang mold python3 perl nodejs postgresql-client
    - corepack enable
    - corepack prepare pnpm@latest --activate
    - mkdir -p packages/backend-rs/built
    - cp packages/backend-rs/index.js packages/backend-rs/built/index.js
    - cp packages/backend-rs/index.d.ts packages/backend-rs/built/index.d.ts
    - cp ci/cargo/config.toml /usr/local/cargo/config.toml
    - test -f packages/backend-rs/built/backend-rs.linux-x64-gnu.node || pnpm install --frozen-lockfile
    - test -f packages/backend-rs/built/backend-rs.linux-x64-gnu.node || pnpm --filter 'backend-rs' run build:debug
    - cp .config/ci.yml .config/default.yml
    - export PGPASSWORD="${POSTGRES_PASSWORD}"
    - psql --host postgres --user "${POSTGRES_USER}" --dbname "${POSTGRES_DB}" --command 'CREATE EXTENSION pgroonga'
  script:
    - pnpm install --frozen-lockfile
    - pnpm --filter 'backend' --filter 'firefish-js' --filter 'megalodon' run build:debug
    - pnpm run migrate
    - psql --host postgres --user "${POSTGRES_USER}" --dbname "${POSTGRES_DB}" --command "$(cat docs/downgrade.sql)"

test:build:client:
  stage: test
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - scripts/**/*
          - package.json
          - Cargo.toml
          - Cargo.lock
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/client/**/*
          - packages/firefish-js/**/*
          - packages/sw/**/*
          - locales/**/*
      when: always
  services: []
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get -y --no-install-recommends install curl
    - curl -fsSL 'https://deb.nodesource.com/setup_18.x' | bash -
    - apt-get install -y --no-install-recommends build-essential python3 perl nodejs
    - corepack enable
    - corepack prepare pnpm@latest --activate
    - cp .config/ci.yml .config/default.yml
  script:
    - pnpm install --frozen-lockfile
    - pnpm --filter 'firefish-js' --filter 'client' --filter 'sw' run build:debug

build:container:
  stage: build
  image: docker.io/debian:trixie-slim
  services: []
  rules:
    - if: $BUILD == 'true'
      when: always
    - if: $BUILD == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop'
      changes:
        paths:
          - packages/**/*
          - locales/**/*
          - scripts/copy-assets.mjs
          - package.json
          - Cargo.toml
          - Cargo.lock
          - Dockerfile
          - .dockerignore
      when: always
  needs:
    - job: test:build
      optional: true
    - job: test:build:backend_ts_only
      optional: true
    - job: test:build:client_only
      optional: true
  variables:
    STORAGE_DRIVER: overlay
  before_script:
    - apt-get update && apt-get -y upgrade
    - |-
      sed -i -r 's/"version": "([-0-9]+)",/"version": "\1-dev",/' package.json
    - apt-get install -y --no-install-recommends ca-certificates fuse-overlayfs buildah
    - echo "${CI_REGISTRY_PASSWORD}" | buildah login --username "${CI_REGISTRY_USER}" --password-stdin "${CI_REGISTRY}"
    - export IMAGE_TAG="${CI_REGISTRY}/${CI_PROJECT_PATH}/develop:not-for-production"
    - export IMAGE_CACHE="${CI_REGISTRY}/${CI_PROJECT_PATH}/develop/cache"
    - buildah version
  script:
    - |-
      buildah build \
        --isolation chroot \
        --device=/dev/fuse:rw \
        --security-opt seccomp=unconfined \
        --security-opt apparmor=unconfined \
        --cap-add all \
        --platform linux/amd64 \
        --layers \
        --cache-to "${IMAGE_CACHE}" \
        --cache-from "${IMAGE_CACHE}" \
        --tag "${IMAGE_TAG}" \
        .
    - buildah inspect "${IMAGE_TAG}"
    - buildah push "${IMAGE_TAG}"

cargo:check:msrv:
  stage: test
  image: docker.io/rust:1.74-slim-bookworm
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - Cargo.toml
          - Cargo.lock
      when: always
  services: []
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get install -y --no-install-recommends build-essential clang mold python3 perl nodejs postgresql-client
    - cp ci/cargo/config.toml /usr/local/cargo/config.toml
  script:
    - cargo fetch --locked --manifest-path Cargo.toml
    - cargo check --locked --frozen --all-features

cargo:test:
  stage: test
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - Cargo.toml
          - Cargo.lock
      when: always
  script:
    - curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/cargo/bin
    - cargo test --doc
    - cargo nextest run

cargo:clippy:
  stage: test
  rules:
    - if: $TEST == 'true'
      when: always
    - if: $TEST == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
      when: always
  services: []
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get install -y --no-install-recommends build-essential clang mold perl
    - cp ci/cargo/config.toml /usr/local/cargo/config.toml
    - rustup component add clippy
  script:
    - cargo clippy -- -D warnings

cargo:doc:
  stage: doc
  rules:
    - if: $DOC == 'true'
      when: always
    - if: $DOC == 'false'
      when: never
    - if: $CI_COMMIT_BRANCH == 'develop'
      changes:
        paths:
          - packages/backend-rs/**/*
          - packages/macro-rs/**/*
          - Cargo.toml
          - Cargo.lock
          - package.json
      when: always
  services: []
  before_script:
    - apt-get update
    - apt-get install -y --no-install-recommends build-essential clang mold nodejs npm
    - cp ci/cargo/config.toml /usr/local/cargo/config.toml
  script:
    - cargo doc --document-private-items
    - printf 'window.ALL_CRATES = ["backend_rs", "macros", "macros_impl"];' > target/doc/crates.js
    - printf '<meta http-equiv="refresh" content="0; url=%s">' 'backend_rs' > target/doc/index.html
    - cd target/doc
    - npx --yes netlify-cli deploy --prod --site="${CARGO_DOC_SITE_ID}" --dir=.

renovate:
  stage: dependency
  image:
    name: docker.io/renovate/renovate:37-slim
    entrypoint: [""]
  rules:
    - if: $RENOVATE && $CI_PIPELINE_SOURCE == 'schedule'
  services: []
  before_script: []
  script:
    - renovate --platform gitlab --token "${API_TOKEN}" --endpoint "${CI_SERVER_URL}/api/v4" "${CI_PROJECT_PATH}"

clean:
  stage: clean
  rules:
    - if: $CLEAN && $CI_PIPELINE_SOURCE == 'schedule'
  services: []
  before_script:
    - apt-get update && apt-get -y upgrade
    - apt-get -y --no-install-recommends install curl
    - curl -fsSL 'https://deb.nodesource.com/setup_18.x' | bash -
    - apt-get install -y --no-install-recommends nodejs
    - corepack enable
    - corepack prepare pnpm@latest --activate
    - pnpm install --frozen-lockfile
  script:
    - pnpm run clean-all