workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push"'
      when: always
    - when: never

default:
  image:
    name: fpco/stack-build:lts-18.0
      
variables:
  STACK_ROOT: "${CI_PROJECT_DIR}/.stack"
  CHROME_BIN: "/usr/bin/chromium-browser"
  POSTGRES_DB: uniworx_test
  POSTGRES_USER: uniworx
  POSTGRES_PASSWORD: uniworx
  MINIO_ACCESS_KEY: gOel7KvadwNKgjjy
  MINIO_SECRET_KEY: ugO5pkEla7F0JW9MdPwLi4MWLT5ZbqAL
  UPLOAD_S3_HOST: localhost
  UPLOAD_S3_PORT: 9000
  UPLOAD_S3_KEY_ID: gOel7KvadwNKgjjy
  UPLOAD_S3_KEY: ugO5pkEla7F0JW9MdPwLi4MWLT5ZbqAL
  N_PREFIX: "${HOME}/.n"
  PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/uni2work"
  
stages:
  - setup
  - frontend:build
  - yesod:build
  - lint
  - test
  - prepare release
  - upload packages
  - release
#  - deploy
  
npm install:
  cache:
    - &npm-cache
      key: default-npm
      paths:
        - .npm
        - node_modules
  
  stage: setup
  script:
    - ./.npmrc.gup
    - npm ci --cache .npm --prefer-offline
  before_script: &npm
    - rm -rvf /etc/apt/sources.list /etc/apt/sources.list.d
    - install -v -T -m 0644 ${APT_SOURCES_LIST} /etc/apt/sources.list
    - apt-get update -y
    - npm install -g n
    - n 14.8.0
    - export PATH="${N_PREFIX}/bin:$PATH"
    - npm install -g npm
    - hash -r
    - apt-get -y install openssh-client exiftool
    - install -v -m 0700 -d ~/.ssh
    - install -v -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
    - install -v -T -m 0400 ${SSH_DEPLOY_KEY} ~/.ssh/deploy && echo "IdentityFile ~/.ssh/deploy" >> ~/.ssh/config; 
  artifacts:
    paths:
      - node_modules/
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"
  retry: 2
  interruptible: true
  
frontend:build:
  cache:
    - &frontend-cache
      key: default-frontend
      paths:
        - .well-known-cache
  
  stage: frontend:build
  script:
    - npm run frontend:build
  before_script: *npm
  needs:
    - job: npm install
      artifacts: true
  artifacts:
    paths:
      - static
      - well-known
      - config/webpack.yml
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"
  retry: 2
  interruptible: true

frontend:lint:
  stage: lint
  script:
    - npm run frontend:lint
  before_script: *npm
  needs:
    - job: npm install
      artifacts: true
  retry: 2
  interruptible: true

yesod:build:dev:
  cache:
    - &stack-dev-cache
      key: default-stack-dev
      paths:
        - .stack
        - .stack-work

  stage: yesod:build
  script:
    - stack build --test --copy-bins --local-bin-path $(pwd)/bin --fast --flag uniworx:-library-only --flag uniworx:dev --flag uniworx:pedantic --no-strip --no-run-tests
    - cp $(stack path --dist-dir)/build/hlint/hlint bin/test-hlint
    - cp $(stack path --dist-dir)/build/yesod/yesod bin/test-yesod
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build
      artifacts: true
  before_script: &haskell
    - rm -rvf /etc/apt/sources.list /etc/apt/sources.list.d
    - install -v -T -m 0644 ${APT_SOURCES_LIST} /etc/apt/sources.list
    - apt-get update -y
    - apt-get install -y --no-install-recommends locales-all openssh-client git-restore-mtime
    - wget http://newmirror.rz.ifi.lmu.de/ubuntu/archive/pool/main/libs/libsodium/libsodium-dev_1.0.18-1_amd64.deb http://newmirror.rz.ifi.lmu.de/ubuntu/archive/pool/main/libs/libsodium/libsodium23_1.0.18-1_amd64.deb
    - apt install ./libsodium23_1.0.18-1_amd64.deb ./libsodium-dev_1.0.18-1_amd64.deb
    - rm -v libsodium23_1.0.18-1_amd64.deb libsodium-dev_1.0.18-1_amd64.deb
    - install -v -m 0700 -d ~/.ssh
    - install -v -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
    - install -v -T -m 0400 ${SSH_DEPLOY_KEY} ~/.ssh/deploy && echo "IdentityFile ~/.ssh/deploy" >> ~/.ssh/config; 
    - stack install happy
    - export PATH="${HOME}/.local/bin:$PATH"
    - hash -r
    - git restore-mtime
  artifacts:
    paths:
      - bin/
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /(^v[0-9].*)|((^|\/)profile($|\/))/
      when: manual
      allow_failure: true
    - when: on_success

  retry: 2
  interruptible: true
    
yesod:build:
  cache:
    - &stack-cache
      key: default-stack
      paths:
        - .stack
        - .stack-work
  
  stage: yesod:build
  script:
    - stack build --test --copy-bins --local-bin-path $(pwd)/bin --flag uniworx:-library-only --flag uniworx:-dev --flag uniworx:pedantic --no-strip --no-run-tests
    - cp $(stack path --dist-dir)/build/hlint/hlint bin/test-hlint
    - cp $(stack path --dist-dir)/build/yesod/yesod bin/test-yesod
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build
      artifacts: true
  before_script: *haskell
  artifacts:
    paths:
      - bin/
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"
    
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success
    - when: manual
      allow_failure: true

  retry: 2
  interruptible: true
  resource_group: ram
  
yesod:build:profile:
  cache:
    - &stack-profile-cache
      key: default-stack-profile
      paths:
        - .stack
        - .stack-work

  stage: yesod:build
  script:
    - stack build --profile --copy-bins --local-bin-path $(pwd)/bin --flag uniworx:-library-only --flag uniworx:-dev --flag uniworx:pedantic --no-strip
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build
      artifacts: true
  before_script: *haskell
  artifacts:
    paths:
      - bin/
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /(^|\/)profile($|\/)/
      when: on_success
    - when: manual
      allow_failure: true

  retry: 2
  interruptible: true
  resource_group: ram

yesod:test:yesod:
  stage: test
  
  services: &test-services
    - name: postgres:10.10
      alias: postgres
    - name: minio/minio:RELEASE.2020-08-27T05-16-20Z
      alias: minio
      command: ["minio", "server", "/data"]

  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build #transitive
      artifacts: false
    - job: yesod:build
      artifacts: true

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success

  script:
    - bin/test-yesod

  retry: 2
  interruptible: true

yesod:test:yesod:dev:
  stage: test
  
  services: *test-services

  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build #transitive
      artifacts: false
    - job: yesod:build:dev
      artifacts: true

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /(^v[0-9].*)|((^|\/)profile($|\/))/
      when: manual
      allow_failure: true
    - when: on_success

  script:
    - bin/test-yesod

  retry: 2
  interruptible: true
  
yesod:test:hlint:
  stage: lint
  cache: &hlint_cache
    key: hlint
    paths:
      - .stack
      - .stack-work
  
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build #transitive
      artifacts: false
    - job: yesod:build
      artifacts: false

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success

  before_script: *haskell
  script:
    - stack install hlint
    - stack exec -- hlint --cc src > gl-code-quality-report.json || jq . gl-code-quality-report.json

  artifacts:
    paths:
      - gl-code-quality-report.json
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"

    reports:
      codequality: gl-code-quality-report.json

  retry: 2
  interruptible: true
  
yesod:test:hlint:dev:
  stage: lint
  cache: *hlint_cache
  
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build #transitive
      artifacts: false
    - job: yesod:build:dev
      artifacts: false

  rules:
    - if: $CI_COMMIT_REF_NAME =~ /(^v[0-9].*)|((^|\/)profile($|\/))/
      when: manual
      allow_failure: true
    - when: on_success

  before_script: *haskell
  script:
    - stack install hlint
    - stack exec -- hlint --cc src > gl-code-quality-report.json || jq . gl-code-quality-report.json

  artifacts:
    paths:
      - gl-code-quality-report.json
    name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"

    reports:
      codequality: gl-code-quality-report.json

  retry: 2
  interruptible: true

frontend:test:
  stage: test
  script:
    - npm run frontend:test
  needs:
    - job: npm install
      artifacts: true
  before_script:
    - rm -rvf /etc/apt/sources.list /etc/apt/sources.list.d
    - install -v -T -m 0644 ${APT_SOURCES_LIST} /etc/apt/sources.list
    - apt-get update -y
    - npm install -g n
    - n 14.8.0
    - export PATH="${N_PREFIX}/bin:$PATH"
    - npm install -g npm
    - hash -r
    - apt-get install -y --no-install-recommends chromium-browser
  retry: 2
  interruptible: true

parse-changelog:
  stage: prepare release
  needs:
    - job: npm install
      artifacts: true
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success
  before_script:
    - rm -rvf /etc/apt/sources.list /etc/apt/sources.list.d
    - install -v -T -m 0644 ${APT_SOURCES_LIST} /etc/apt/sources.list
    - apt-get update -y
    - apt-get install -y --no-install-recommends jq
  script:
    - npm run parse-changelog
    - |
      jq -r '.versions[0].version' changelog.json > .current-version
    - |
      jq -r '.versions[0].body' changelog.json > .current-changelog.md
  artifacts:
    paths:
      - .current-version
      - .current-changelog.md
    name: "changelog-${CI_COMMIT_SHORT_SHA}"
    expire_in: "1 day"
  retry: 2
  interruptible: true

upload:
  variables:
    GIT_STRATEGY: none
  stage: upload packages
  image: curlimages/curl:latest
  needs:
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build # transitive
      artifacts: false
    - job: yesod:build
      artifacts: true
    - job: parse-changelog
      artifacts: true
    - job: frontend:lint # validation
      artifacts: false
    - job: frontend:test # validation
      artifacts: false
    - job: yesod:test:hlint # validation
      artifacts: false
    - job: yesod:test:yesod # validation
      artifacts: false
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success
  before_script:
    - export VERSION="$(cat .current-version)"
  script:
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/uniworx ${PACKAGE_REGISTRY_URL}/${VERSION}/uniworx
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/uniworxdb ${PACKAGE_REGISTRY_URL}/${VERSION}/uniworxdb
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/uniworxload ${PACKAGE_REGISTRY_URL}/${VERSION}/uniworxload
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file bin/uniworx-wflint ${PACKAGE_REGISTRY_URL}/${VERSION}/uniworx-wflint

release:
  variables:
    GIT_STRATEGY: none
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  needs:
    - job: upload
      artifacts: false
    - job: npm install # transitive
      artifacts: false
    - job: frontend:build # transitive
      artifacts: false
    - job: yesod:build # transitive
      artifacts: false
    - job: parse-changelog
      artifacts: true
    - job: frontend:lint # validation
      artifacts: false
    - job: frontend:test # validation
      artifacts: false
    - job: yesod:test:hlint # validation
      artifacts: false
    - job: yesod:test:yesod # validation
      artifacts: false
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
      when: on_success
  before_script:
    - export VERSION="$(cat .current-version)"
  script:
    - |
      release-cli create --name "${VERSION}" --tag-name $CI_COMMIT_TAG --description .current-changelog.md  \
        --assets-link "{\"name\":\"uniworx\",\"url\":\"${PACKAGE_REGISTRY_URL}/${VERSION}/uniworx\",\"filepath\":\"/uniworx\"}" \
        --assets-link "{\"name\":\"uniworxdb\",\"url\":\"${PACKAGE_REGISTRY_URL}/${VERSION}/uniworxdb\",\"filepath\":\"/uniworxdb\"}" \
        --assets-link "{\"name\":\"uniworxload\",\"url\":\"${PACKAGE_REGISTRY_URL}/${VERSION}/uniworxload\",\"filepath\":\"/uniworxload\"}" \
        --assets-link "{\"name\":\"uniworx-wflint\",\"url\":\"${PACKAGE_REGISTRY_URL}/${VERSION}/uniworx-wflint\",\"filepath\":\"/uniworx-wflint\"}"


# deploy:uniworx3:
#   cache: {}
#   stage: deploy
#   variables:
#     GIT_STRATEGY: none
#   script:
#     - zip -qj - bin/uniworx bin/uniworxdb | ssh root@uniworx3.ifi.lmu.de /root/bin/accept_uni2work
#   needs:
#     - yesod:build
#     - frontend:test # For sanity
#   before_script:
#     - rm -rvf /etc/apt/sources.list /etc/apt/sources.list.d
#     - install -v -T -m 0644 ${APT_SOURCES_LIST} /etc/apt/sources.list
#     - apt-get update -y
#     - apt-get install -y --no-install-recommends openssh-client
#     - install -v -m 0700 -d ~/.ssh
#     - install -v -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
#     - install -v -T -m 0400 ${SSH_PRIVATE_KEY_UNIWORX3} ~/.ssh/uniworx3; echo "IdentityFile ~/.ssh/uniworx3" >> ~/.ssh/config; 
#   dependencies:
#     - yesod:build
        
#   only:
#     variables:
#       - $CI_COMMIT_REF_NAME =~ /^v[0-9].*/
#   resource_group: uniworx3
