image: hivesolutions/ubuntu_dev

variables:
  NETLIFY_SITE_ID: boytacean
  NETLIFY_AUTH_TOKEN: $NETLIFY_AUTH_TOKEN
  CLOUDFLARE_API_TOKEN: $CLOUDFLARE_API_TOKEN
  CRATES_TOKEN: $CRATES_TOKEN
  NPM_TOKEN: $NPM_TOKEN

stages:
  - build
  - test
  - deploy

before_script:
  - source ./.gitlab/common.sh
  - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q pkg-config g++ cmake jq
  - curl -sf -L https://static.rust-lang.org/rustup.sh | sh -s -- -y
  - export PATH=$PATH:$HOME/.cargo/bin
  - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
  - export NVM_DIR="$HOME/.nvm"
  - \[ -s "$NVM_DIR/nvm.sh" \] && \. "$NVM_DIR/nvm.sh"
  - \[ -s "$NVM_DIR/bash_completion" \] && \. "$NVM_DIR/bash_completion"
  - nvm install 18

build-rust:
  stage: build
  parallel:
    matrix:
      - RUST_VERSION: ["1.74.0", "1.75.0", "stable", "nightly"]
  script:
    - rustup toolchain install $RUST_VERSION
    - rustup override set $RUST_VERSION
    - rustup component add rustfmt
    - rustup component add clippy
    - rustc --version
    - cargo fmt --all -- --check
    - if [[ $RUST_VERSION != nightly ]]; then cargo clippy -- -D warnings -A unknown-lints; fi
    - cargo build --features gen-mock
    - cargo build --release --features gen-mock

build-wasm:
  stage: build
  parallel:
    matrix:
      - RUST_VERSION: ["1.74.0"]
  script:
    - rustup toolchain install $RUST_VERSION
    - rustup override set $RUST_VERSION
    - rustc --version
    - cargo install wasm-pack
    - wasm-pack build --release --target=web --out-dir=frontends/web/lib -- --features wasm
    - cd frontends/web && npm install && NODE_ENV=production npm run build && npm run lint
  artifacts:
    paths:
      - frontends/web/dist
      - frontends/web/lib
    expire_in: 1 day

build-pyo3:
  stage: build
  parallel:
    matrix:
      - RUST_VERSION: ["1.74.0"]
  script:
    - rustup toolchain install $RUST_VERSION
    - rustup override set $RUST_VERSION
    - rustc --version
    - cargo build --features python
    - cargo build --release --features python

build-boot:
  stage: build
  script:
    - install_rgbds
    - cd src/boot
    - make

test-rust:
  stage: test
  parallel:
    matrix:
      - RUST_VERSION: ["1.74.0", "1.75.0", "stable", "nightly"]
  script:
    - rustup toolchain install $RUST_VERSION
    - rustup override set $RUST_VERSION
    - rustc --version
    - if [[ $RUST_VERSION != nightly ]]; then cargo test; fi
    - if [[ $RUST_VERSION != nightly ]]; then cargo bench --features gen-mock; fi
    - if [[ $RUST_VERSION == nightly ]]; then cargo bench --features gen-mock,simd; fi

test-pyo3:
  stage: test
  parallel:
    matrix:
      - RUST_VERSION: ["1.74.0"]
  script:
    - rustup toolchain install $RUST_VERSION
    - rustup override set $RUST_VERSION
    - rustc --version
    - python3 setup.py test

deploy-netlify-preview:
  stage: deploy
  script:
    - cd frontends/web/dist
    - cp -rp ../static/* .
    - npm_config_yes=true npx --loglevel verbose --package=netlify-cli netlify deploy --dir=.
  dependencies:
    - build-wasm
  only:
    - master

deploy-netlify-prod:
  stage: deploy
  script:
    - cd frontends/web/dist
    - cp -rp ../static/* .
    - npm_config_yes=true npx --loglevel verbose --package=netlify-cli netlify deploy --dir=. --prod
  dependencies:
    - build-wasm
  only:
    - tags

deploy-cloudflare-master:
  stage: deploy
  script:
    - cd frontends/web/dist
    - cp -rp ../static/* .
    - npm_config_yes=true npx --loglevel verbose wrangler pages deploy . --project-name=boytacean --branch master
  dependencies:
    - build-wasm
  only:
    - master

deploy-cloudflare-stable:
  stage: deploy
  script:
    - cd frontends/web/dist
    - cp -rp ../static/* .
    - npm_config_yes=true npx --loglevel verbose wrangler pages deploy . --project-name=boytacean --branch stable
  dependencies:
    - build-wasm
  only:
    - stable

deploy-cloudflare-prod:
  stage: deploy
  script:
    - cd frontends/web/dist
    - cp -rp ../static/* .
    - npm_config_yes=true npx --loglevel verbose wrangler pages deploy . --project-name=boytacean --branch prod
    - npm_config_yes=true npx --loglevel verbose wrangler pages deploy . --project-name=boytacean --branch production
    - npm_config_yes=true npx --loglevel verbose wrangler pages deploy . --project-name=boytacean --branch main
  dependencies:
    - build-wasm
  only:
    - tags

deploy-crates:
  stage: deploy
  script:
    - cargo login $CRATES_TOKEN
    - cargo publish --package boytacean-common --no-verify
    - cargo publish --package boytacean-hashing --no-verify
    - cargo publish --package boytacean-encoding --no-verify
    - cargo publish --package boytacean --no-verify
  dependencies:
    - build-rust
  only:
    - tags

deploy-npm:
  stage: deploy
  script:
    - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
    - cd frontends/web/lib && npm publish
  dependencies:
    - build-wasm
  only:
    - tags

deploy-pypi:
  stage: deploy
  script:
    - pip3 install twine wheel
    - python3 setup.py sdist
    - python3 -m twine upload -u ${PYPI_USERNAME} -p ${PYPI_PASSWORD} dist/*
  dependencies:
    - build-pyo3
  only:
    - tags
