image: node:18

variables:
  NODE_ENV: test

default:
  interruptible: true

cache: &cache
  key:
    files:
      - yarn.lock
  paths:
    - node_modules/
  policy: pull

stages:
  - deps
  - test
  - deploy
  - release

deps:
  stage: deps
  script: yarn install --ignore-scripts
  only:
    changes:
      - yarn.lock
  cache:
    <<: *cache
    policy: push

danger:
  stage: test
  script:
    # https://github.com/danger/danger-js/issues/1029#issuecomment-998915436
    - export CI_MERGE_REQUEST_IID=${CI_OPEN_MERGE_REQUESTS#*!}
    - npx danger ci
  except:
    variables:
      - $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
  allow_failure: true

lint-js:
  stage: test
  script: yarn lint:js
  only:
    changes:
      - "**/*.js"
      - "**/*.jsx"
      - "**/*.cjs"
      - "**/*.mjs"
      - "**/*.ts"
      - "**/*.tsx"
      - ".eslintignore"
      - ".eslintrc.cjs"

lint-sass:
  stage: test
  script: yarn lint:sass
  only:
    changes:
      - "**/*.scss"
      - "**/*.css"
      - ".stylelintrc.json"

jest:
  stage: test
  script: yarn test:coverage --runInBand
  only:
    changes:
      - "**/*.js"
      - "**/*.json"
      - "app/soapbox/**/*"
      - "webpack/**/*"
      - "custom/**/*"
      - "jest.config.cjs"
      - "package.json"
      - "yarn.lock"
      - ".gitlab-ci.yml"
  coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: .coverage/cobertura-coverage.xml

nginx-test:
  stage: test
  image: nginx:latest
  before_script:
    - cp installation/mastodon.conf /etc/nginx/conf.d/default.conf
  script: nginx -t
  only:
    changes:
      - "installation/mastodon.conf"

build-production:
  stage: test
  script:
    - yarn build
    - yarn manage:translations en
    # Fail if files got changed.
    # https://stackoverflow.com/a/9066385
    - git diff --quiet
  variables:
    NODE_ENV: production
  artifacts:
    paths:
     - static

docs-deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add curl
  script:
    - curl -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' https://gitlab.com/api/v4/projects/15685485/trigger/pipeline
  only:
    variables:
      - $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
    changes:
      - "docs/**/*"

review:
  stage: deploy
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.git.soapbox.pub
  script:
    - npx -y surge static $CI_COMMIT_REF_SLUG.git.soapbox.pub
  allow_failure: true

pages:
  stage: deploy
  before_script: []
  script:
    # artifacts are kept between jobs
    - mv static public
  variables:
    NODE_ENV: production
  artifacts:
    paths:
    - public
  only:
    variables:
      - $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME

docker:
  stage: deploy
  image: docker:23.0.0
  services:
    - docker:23.0.0-dind
  tags:
    - dind
  # https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df
  script:
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
  rules:
    - if: $CI_COMMIT_TAG
  interruptible: false

release:
  stage: release
  rules:
    - if: $CI_COMMIT_TAG
  script:
    - npx ts-node ./scripts/do-release.ts
  interruptible: false

include:
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml
  - template: Security/License-Scanning.gitlab-ci.yml