aliases:
  # Workflow filters
  - &filter-only-release
    branches:
      ignore: /.*/
    tags:
      only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
  - &filter-not-release-or-master
    tags:
      ignore: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
    branches:
      ignore: master
  - &filter-only-master
    branches:
      only: master

version: 2

jobs:
  mysql-integration-test:
    docker:
      - image: circleci/golang:1.11
      - image: circleci/mysql:5.6-ram
        environment:
          MYSQL_ROOT_PASSWORD: rootpass
          MYSQL_DATABASE: grafana_tests
          MYSQL_USER: grafana
          MYSQL_PASSWORD: password
    working_directory: /go/src/github.com/grafana/grafana
    steps:
        - checkout
        - run: sudo apt update
        - run: sudo apt install -y mysql-client
        - run: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s
        - run: cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h 127.0.0.1 -P 3306 -u root -prootpass
        - run:
            name: mysql integration tests
            command: 'GRAFANA_TEST_DB=mysql go test ./pkg/services/sqlstore/... ./pkg/tsdb/mysql/... '

  postgres-integration-test:
    docker:
      - image: circleci/golang:1.11
      - image: circleci/postgres:9.3-ram
        environment:
          POSTGRES_USER: grafanatest
          POSTGRES_PASSWORD: grafanatest
          POSTGRES_DB: grafanatest
    working_directory: /go/src/github.com/grafana/grafana
    steps:
        - checkout
        - run: sudo apt update
        - run: sudo apt install -y postgresql-client
        - run: dockerize -wait tcp://127.0.0.1:5432 -timeout 120s
        - run: 'PGPASSWORD=grafanatest psql -p 5432 -h 127.0.0.1 -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql'
        - run:
            name: postgres integration tests
            command: 'GRAFANA_TEST_DB=postgres go test ./pkg/services/sqlstore/... ./pkg/tsdb/postgres/...'

  codespell:
    docker:
      - image: circleci/python
    steps:
      - checkout
      - run:
          name: install codespell
          command: 'sudo pip install codespell'
      - run:
          # Important: all words have to be in lowercase, and separated by "\n".
          name: exclude known exceptions
          command: 'echo -e "unknwon" > words_to_ignore.txt'
      - run:
          name: check documentation spelling errors
          command: 'codespell -I ./words_to_ignore.txt docs/'

  gometalinter:
    docker:
      - image: circleci/golang:1.11
        environment:
          # we need CGO because of go-sqlite3
          CGO_ENABLED: 1
    working_directory: /go/src/github.com/grafana/grafana
    steps:
      - checkout
      - run: 'go get -u github.com/alecthomas/gometalinter'
      - run: 'go get -u github.com/tsenart/deadcode'
      - run: 'go get -u github.com/jgautheron/goconst/cmd/goconst'
      - run: 'go get -u github.com/gordonklaus/ineffassign'
      - run: 'go get -u github.com/opennota/check/cmd/structcheck'
      - run: 'go get -u github.com/mdempsky/unconvert'
      - run: 'go get -u github.com/opennota/check/cmd/varcheck'
      - run:
          name: run linters
          command: 'gometalinter --enable-gc --vendor --deadline 10m --disable-all --enable=deadcode --enable=goconst --enable=ineffassign --enable=structcheck --enable=unconvert --enable=varcheck ./...'
      - run:
          name: run go vet
          command: 'go vet ./pkg/...'

  test-frontend:
    docker:
      - image: circleci/node:8
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
      - run:
          name: yarn install
          command: 'yarn install --pure-lockfile --no-progress'
          no_output_timeout: 15m
      - save_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
          paths:
            - node_modules
      - run:
          name: frontend tests
          command: './scripts/circle-test-frontend.sh'

  test-backend:
    docker:
      - image: circleci/golang:1.11
    working_directory: /go/src/github.com/grafana/grafana
    steps:
      - checkout
      - run:
          name: build backend and run go tests
          command: './scripts/circle-test-backend.sh'

  build-all:
    docker:
     - image: grafana/build-container:1.2.0
    working_directory: /go/src/github.com/grafana/grafana
    steps:
      - checkout
      - run:
          name: prepare build tools
          command: '/tmp/bootstrap.sh'
      - restore_cache:
          key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
      - run:
          name: download phantomjs binaries
          command: './scripts/build/download-phantomjs.sh'
      - save_cache:
          key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
          paths:
            - /tmp/phantomjs
      - run:
          name: build and package grafana
          command: './scripts/build/build-all.sh'
      - run:
          name: sign packages
          command: './scripts/build/sign_packages.sh'
      - run:
          name: verify signed packages
          command: |
            mkdir -p ~/.rpmdb/pubkeys
            curl -s https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana > ~/.rpmdb/pubkeys/grafana.key
            ./scripts/build/verify_signed_packages.sh dist/*.rpm
      - run:
          name: sha-sum packages
          command: 'go run build.go sha-dist'
      - run:
          name: Build Grafana.com master publisher
          command: 'go build -o scripts/publish scripts/build/publish.go'
      - run:
          name: Build Grafana.com release publisher
          command: 'cd scripts/build/release_publisher && go build -o release_publisher .'
      - persist_to_workspace:
          root: .
          paths:
            - dist/grafana*
            - scripts/*.sh
            - scripts/publish
            - scripts/build/release_publisher/release_publisher
            - scripts/build/publish.sh

  build:
    docker:
     - image: grafana/build-container:1.2.0
    working_directory: /go/src/github.com/grafana/grafana
    steps:
      - checkout
      - run:
          name: prepare build tools
          command: '/tmp/bootstrap.sh'
      - run:
          name: build and package grafana
          command: './scripts/build/build.sh'
      - run:
          name: sign packages
          command: './scripts/build/sign_packages.sh'
      - run:
          name: sha-sum packages
          command: 'go run build.go sha-dist'
      - persist_to_workspace:
          root: .
          paths:
            - dist/grafana*

  grafana-docker-master:
    docker:
      - image: docker:stable-git
    steps:
      - checkout
      - attach_workspace:
          at: .
      - setup_remote_docker
      - run: docker info
      - run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
      - run: cd packaging/docker && ./build-deploy.sh "master-${CIRCLE_SHA1}"
      - run: rm packaging/docker/grafana-latest.linux-x64.tar.gz
      - run: cp enterprise-dist/grafana-enterprise-*.linux-amd64.tar.gz packaging/docker/grafana-latest.linux-x64.tar.gz
      - run: cd packaging/docker && ./build-enterprise.sh "master"


  grafana-docker-pr:
    docker:
      - image: docker:stable-git
    steps:
      - checkout
      - attach_workspace:
          at: .
      - setup_remote_docker
      - run: docker info
      - run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
      - run: cd packaging/docker && ./build.sh "${CIRCLE_SHA1}"

  grafana-docker-release:
      docker:
        - image: docker:stable-git
      steps:
        - checkout
        - attach_workspace:
            at: .
        - setup_remote_docker
        - run: docker info
        - run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
        - run: cd packaging/docker && ./build-deploy.sh "${CIRCLE_TAG}"
        - run: rm packaging/docker/grafana-latest.linux-x64.tar.gz
        - run: cp enterprise-dist/grafana-enterprise-*.linux-amd64.tar.gz packaging/docker/grafana-latest.linux-x64.tar.gz
        - run: cd packaging/docker && ./build-enterprise.sh "${CIRCLE_TAG}"

  build-enterprise:
    docker:
     - image: grafana/build-container:1.2.0
    working_directory: /go/src/github.com/grafana/grafana
    steps:
      - checkout
      - run:
          name: prepare build tools
          command: '/tmp/bootstrap.sh'
      - run:
          name: checkout enterprise
          command: './scripts/build/prepare-enterprise.sh'
      - run:
          name: test enterprise
          command: 'go test ./pkg/extensions/...'
      - run:
          name: build and package enterprise
          command: './scripts/build/build.sh -enterprise'
      - run:
          name: sign packages
          command: './scripts/build/sign_packages.sh'
      - run:
          name: sha-sum packages
          command: 'go run build.go sha-dist'
      - run:
          name: move enterprise packages into their own folder
          command: 'mv dist enterprise-dist'
      - persist_to_workspace:
          root: .
          paths:
            - enterprise-dist/grafana-enterprise*

  build-all-enterprise:
    docker:
    - image: grafana/build-container:1.2.0
    working_directory: /go/src/github.com/grafana/grafana
    steps:
    - checkout
    - run:
        name: prepare build tools
        command: '/tmp/bootstrap.sh'
    - run:
        name: checkout enterprise
        command: './scripts/build/prepare-enterprise.sh'
    - restore_cache:
        key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
    - run:
        name: download phantomjs binaries
        command: './scripts/build/download-phantomjs.sh'
    - save_cache:
        key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
        paths:
        - /tmp/phantomjs
    - run:
        name: test enterprise
        command: 'go test ./pkg/extensions/...'
    - run:
        name: build and package grafana
        command: './scripts/build/build-all.sh -enterprise'
    - run:
        name: sign packages
        command: './scripts/build/sign_packages.sh'
    - run:
        name: verify signed packages
        command: |
          mkdir -p ~/.rpmdb/pubkeys
          curl -s https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana > ~/.rpmdb/pubkeys/grafana.key
          ./scripts/build/verify_signed_packages.sh dist/*.rpm
    - run:
        name: sha-sum packages
        command: 'go run build.go sha-dist'
    - run:
        name: move enterprise packages into their own folder
        command: 'mv dist enterprise-dist'
    - persist_to_workspace:
        root: .
        paths:
        - enterprise-dist/grafana-enterprise*

  deploy-enterprise-master:
    docker:
      - image: circleci/python:2.7-stretch
    steps:
      - attach_workspace:
          at: .
      - run:
          name: install awscli
          command: 'sudo pip install awscli'
      - run:
          name: deploy to s3
          command: 'aws s3 sync ./enterprise-dist s3://$ENTERPRISE_BUCKET_NAME/master'

  deploy-enterprise-release:
    docker:
    - image: circleci/python:2.7-stretch
    steps:
    - attach_workspace:
        at: .
    - run:
        name: install awscli
        command: 'sudo pip install awscli'
    - run:
        name: deploy to s3
        command: 'aws s3 sync ./enterprise-dist s3://$ENTERPRISE_BUCKET_NAME/release'

  deploy-master:
    docker:
      - image: circleci/python:2.7-stretch
    steps:
      - attach_workspace:
          at: .
      - run:
          name: install awscli
          command: 'sudo pip install awscli'
      - run:
          name: deploy to s3
          command: |
            # Also
            cp dist/grafana-latest.linux-x64.tar.gz dist/grafana-master-$(echo "${CIRCLE_SHA1}" | cut -b1-7).linux-x64.tar.gz
            aws s3 sync ./dist s3://$BUCKET_NAME/master
      - run:
          name: Trigger Windows build
          command: './scripts/trigger_windows_build.sh ${APPVEYOR_TOKEN} ${CIRCLE_SHA1} master'
      - run:
          name: Publish to Grafana.com
          command: |
            rm dist/grafana-master-$(echo "${CIRCLE_SHA1}" | cut -b1-7).linux-x64.tar.gz
            ./scripts/publish -apiKey ${GRAFANA_COM_API_KEY}

  deploy-release:
    docker:
      - image: circleci/python:2.7-stretch
    steps:
      - attach_workspace:
          at: .
      - run:
          name: install awscli
          command: 'sudo pip install awscli'
      - run:
          name: deploy to s3
          command: 'aws s3 sync ./dist s3://$BUCKET_NAME/release'
      - run:
          name: Deploy to Grafana.com
          command: './scripts/build/publish.sh'

workflows:
  version: 2
  build-master:
    jobs:
      - build-all:
          filters: *filter-only-master
      - build-all-enterprise:
          filters: *filter-only-master
      - codespell:
          filters: *filter-only-master
      - gometalinter:
          filters: *filter-only-master
      - test-frontend:
          filters: *filter-only-master
      - test-backend:
          filters: *filter-only-master
      - mysql-integration-test:
          filters: *filter-only-master
      - postgres-integration-test:
          filters: *filter-only-master
      - deploy-master:
          requires:
            - build-all
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
          filters: *filter-only-master
      - grafana-docker-master:
          requires:
            - build-all
            - build-all-enterprise
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
          filters: *filter-only-master
      - deploy-enterprise-master:
          requires:
            - build-all
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
            - build-all-enterprise
          filters: *filter-only-master

  release:
    jobs:
      - build-all:
          filters: *filter-only-release
      - build-all-enterprise:
          filters: *filter-only-release
      - codespell:
          filters: *filter-only-release
      - gometalinter:
          filters: *filter-only-release
      - test-frontend:
          filters: *filter-only-release
      - test-backend:
          filters: *filter-only-release
      - mysql-integration-test:
          filters: *filter-only-release
      - postgres-integration-test:
          filters: *filter-only-release
      - deploy-release:
          requires:
            - build-all
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
          filters: *filter-only-release
      - deploy-enterprise-release:
          requires:
            - build-all
            - build-all-enterprise
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
          filters: *filter-only-release
      - grafana-docker-release:
          requires:
            - build-all
            - test-backend
            - test-frontend
            - codespell
            - gometalinter
            - mysql-integration-test
            - postgres-integration-test
          filters: *filter-only-release

  build-branches-and-prs:
      jobs:
        - build:
            filters: *filter-not-release-or-master
        - codespell:
            filters: *filter-not-release-or-master
        - gometalinter:
            filters: *filter-not-release-or-master
        - test-frontend:
            filters: *filter-not-release-or-master
        - test-backend:
            filters: *filter-not-release-or-master
        - mysql-integration-test:
            filters: *filter-not-release-or-master
        - postgres-integration-test:
            filters: *filter-not-release-or-master
        - grafana-docker-pr:
            requires:
              - build
              - test-backend
              - test-frontend
              - codespell
              - gometalinter
              - mysql-integration-test
              - postgres-integration-test
            filters: *filter-not-release-or-master
