image: tcitworld/mobilizon-ci

stages:
  - install
  - check
  - build-js
  - test
  - docker
  - package
  - upload
  - deploy

variables:
  MIX_ENV: "test"
  YARN_CACHE_FOLDER: "js/.yarn"
  # DB Variables for Postgres / Postgis
  POSTGRES_DB: mobilizon_test
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: postgres
  POSTGRES_HOST: postgres
  # DB Variables for Mobilizon
  MOBILIZON_DATABASE_USERNAME: $POSTGRES_USER
  MOBILIZON_DATABASE_PASSWORD: $POSTGRES_PASSWORD
  MOBILIZON_DATABASE_DBNAME: $POSTGRES_DB
  MOBILIZON_DATABASE_HOST: $POSTGRES_HOST
  GEOLITE_CITIES_PATH: "/usr/share/GeoIP/GeoLite2-City.mmdb"
  MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
  # Release elements
  PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}"
  ARCH: "amd64"

cache:
  key: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}"
  paths:
    - ~/.cache/Cypress
    - cache/Cypress
    - deps/
    - _build/
    - js/node_modules
    - js/.yarn

# Installed dependencies are cached across the pipeline
# So there is no need to reinstall them all the time
# It saves minutes during a pipeline build time
install:
  stage: install
  script:
    - yarn --cwd "js" install --frozen-lockfile
    - mix deps.get
    - mix compile

lint-elixir:
  stage: check
  before_script:
    - mix deps.get
  script:
    - export EXITVALUE=0
    - mix format --check-formatted --dry-run || export EXITVALUE=1
    - mix credo --strict -a || export EXITVALUE=1
    - mix sobelow --config || export EXITVALUE=1
    - exit $EXITVALUE

lint-front:
  image: node:16
  stage: check
  before_script:
    - export EXITVALUE=0
    - yarn --cwd "js" install --frozen-lockfile
  script:
    - yarn --cwd "js" run lint || export EXITVALUE=1
    - yarn --cwd "js" run prettier -c . || export EXITVALUE=1
    - exit $EXITVALUE

build-frontend:
  stage: build-js
  image: node:16
  before_script:
    - apt update
    - apt install -y --no-install-recommends python build-essential webp imagemagick gifsicle jpegoptim optipng pngquant
  script:
    - yarn --cwd "js" install --frozen-lockfile
    - yarn --cwd "js" run build
  artifacts:
    expire_in: 5 days
    paths:
      - priv/static
  needs:
    - lint-front

deps:
  stage: check
  before_script:
    - mix deps.get
  script:
    - export EXITVALUE=0
    - mix hex.outdated || export EXITVALUE=1
    - yarn --cwd "js" outdated || export EXITVALUE=1
    - exit $EXITVALUE
  allow_failure: true
  needs:
    - install

exunit-1.11:
  stage: test
  image: tcitworld/mobilizon-ci:legacy
  services:
    - name: postgis/postgis:11-3.0
      alias: postgres
  variables:
    MIX_ENV: test
  before_script:
    - mix deps.clean --all
    - mix deps.get
    - mix ecto.create
    - mix ecto.migrate
  script:
    - mix coveralls
  allow_failure: true

exunit:
  stage: test
  services:
    - name: postgis/postgis:13-3.1
      alias: postgres
  variables:
    MIX_ENV: test
  before_script:
    - mix deps.get
    - mix ecto.create
    - mix ecto.migrate
  script:
    - mix coveralls
  artifacts:
    when: always
    reports:
      junit:
        - test-junit-report.xml
    expire_in: 30 days

jest:
  stage: test
  needs:
    - lint-front
  before_script:
    - yarn --cwd "js" install --frozen-lockfile
  script:
    - yarn --cwd "js" run test:unit --no-color --ci --reporters=default --reporters=jest-junit
  artifacts:
    when: always
    paths:
      - js/coverage
    reports:
      junit:
        - js/junit.xml
    expire_in: 30 days

# cypress:
#   stage: test
#   services:
#     - name: postgis/postgis:13.3
#       alias: postgres
#   variables:
#     MIX_ENV=e2e
#   script:
#     - mix ecto.create
#     - mix ecto.migrate
#     - mix run priv/repo/e2e.seed.exs
#     - mix phx.server &
#     - cd js
#     - npx wait-on http://localhost:4000
#     - if [ -z "$CYPRESS_KEY" ]; then npx cypress run; else npx cypress run --record --parallel --key $CYPRESS_KEY; fi
#   artifacts:
#     expire_in: 2 day
#     paths:
#       - js/tests/e2e/screenshots/**/*.png
#       - js/tests/e2e/videos/**/*.mp4

pages:
  stage: deploy
  script:
    - mkdir public
    - mix deps.get
    - mix docs
    - mv doc public/backend
  #     #- yarn run --cwd "js" styleguide:build
  #     #- mv js/styleguide public/frontend
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'
  artifacts:
    expire_in: 1 hour
    paths:
      - public

.docker: &docker
  stage: docker
  cache: {}
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  before_script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > /kaniko/.docker/config.json
  script:
    - /kaniko/executor --cache=true --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docker/production/Dockerfile --destination $DOCKER_IMAGE_NAME --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP

build-docker-master:
  <<: *docker
  rules:
    - if: '$CI_PROJECT_NAMESPACE != "framasoft"'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
  variables:
    DOCKER_IMAGE_NAME: framasoft/mobilizon:master

build-docker-tag:
  <<: *docker
  rules: &tag-rules
    - if: '$CI_PROJECT_NAMESPACE != "framasoft"'
      when: never
    - if: $CI_COMMIT_TAG
  variables:
    DOCKER_IMAGE_NAME: framasoft/mobilizon:$CI_COMMIT_TAG

package-app:
  stage: package
  variables: &release-variables
    MIX_ENV: "prod"
  script: &release-script
    - mix local.hex --force
    - mix local.rebar --force
    - mix deps.get
    - mix phx.digest
    - mix release --path release/mobilizon
    - cd release/mobilizon && ln -s lib/mobilizon-*/priv priv
  only:
    - tags@framasoft/mobilizon
  artifacts:
    expire_in: 30 days
    paths:
      - release

package-app-dev:
  stage: package
  variables: *release-variables
  script: *release-script
  except:
    - tags@framasoft/mobilizon
  artifacts:
    expire_in: 2 days
    paths:
      - release

release-upload:
  stage: upload
  image: framasoft/yakforms-assets-deploy:latest
  rules: *tag-rules
  script:
    - APP_VERSION="${CI_COMMIT_TAG}"
    - APP_ASSET="${CI_PROJECT_NAME}_${APP_VERSION}_${ARCH}.tar.gz"

    - 'echo "Artifact: ${APP_ASSET}"'
    - tar czf ${APP_ASSET} -C release mobilizon
    - ls -al ${APP_ASSET}

    - eval `ssh-agent -s`
    - ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i)
    - echo "put -r ${APP_ASSET}" | sftp -o "VerifyHostKeyDNS yes" ${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
  artifacts:
    expire_in: 1 day
    when: on_success
    paths:
      - mobilizon_*.tar.gz

release-create:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  rules: *tag-rules
  before_script:
    - apk --no-cache add gawk sed grep
  script: |
    APP_VERSION="${CI_COMMIT_TAG}"
    APP_ASSET="${CI_PROJECT_NAME}_${APP_VERSION}_${ARCH}.tar.gz"
    CHANGELOG=$(awk -v version="$APP_VERSION" '/^## / { printit = $2 == version }; printit' CHANGELOG.md | grep -v "## $APP_VERSION" | sed '1{/^$/d}')
    ENDPOINT="https://packages.joinmobilizon.org"

    release-cli create  --name "$CI_COMMIT_TAG" \
                        --description "$CHANGELOG" \
                        --tag-name "$CI_COMMIT_TAG" \
                        --assets-link "{\"name\":\"${APP_ASSET}\",\"url\":\"${ENDPOINT}/${APP_ASSET}\"}"
