version: 2

references:
  install_test_dependencies: &install_test_dependencies
    run:
      name: Install dependencies
      command: |
        scversion="v0.5.0"
        wget "https://storage.googleapis.com/shellcheck/shellcheck-$scversion.linux.x86_64.tar.xz"
        tar --xz -xvf "shellcheck-$scversion.linux.x86_64.tar.xz"
        mv shellcheck-$scversion/shellcheck /usr/bin/shellcheck
        chmod +x /usr/bin/shellcheck
        touch /tmp/libc.so.6
        export LD_LIBRARY_PATH=/tmp # hack to work around a bug with a statically linked lib https://github.com/koalaman/shellcheck/issues/1053
        shellcheck --version

  npm_install: &npm_install
    run:
      name: Test npm install
      command: npm install -g git://github.com/reactiveops/rok8s-scripts.git#${CIRCLE_SHA1}

  pip_install: &pip_install
    run:
      name: Test pip install
      command: pip install .

  run_shellcheck: &run_shellcheck
    run:
      name: Run Shellcheck
      command: |
        cd bin
        export LD_LIBRARY_PATH=/tmp # hack to work around a bug with a statically linked lib https://github.com/koalaman/shellcheck/issues/1053
        shellcheck -x docker-* \
          install-rok8s-requirements \
          k8s-apply \
          verify-deployment \
          k8s-lint \
          prepare-* \
          helm-*

  run_basic_linting: &run_basic_linting
    run:
      name: Run basic linting
      command: |
        cd examples/production-ready
        k8s-lint -f staging.config
        k8s-lint -f production.config

  check_setup_py_version: &check_setup_py_version
    run:
      name: Check setup.py version number against git release tag
      command: |
        pip install semver
        latest_release="$(git describe --abbrev=0 --tags)"
        latest_release="${latest_release#*v}"
        setup_py_version="$(python setup.py --version)"

        if ! python -c "import semver, sys; sys.exit(0 if semver.match('${setup_py_version}', '>=${latest_release}') else 1)"; then
          echo "Repo setup.py version is stale: $setup_py_version Latest Git tag release: $latest_release"
          exit 1
        fi

  docker_login: &docker_login
    run:
      name: Docker login
      command: docker login -u="reactiveops+circleci" -p="${QUAY_TOKEN}" quay.io

  load_supported_docker_bases: &load_supported_docker_bases
    run:
      name: Load all the base docker images we support from the ci-images dir
      command: echo "export SUPPORTED_DOCKER_BASES=\"$(ls ci-images)\"" >> $BASH_ENV

  docker_build: &docker_build
    run:
      name: Docker build
      command: |
        for docker_base in ${SUPPORTED_DOCKER_BASES}; do
          docker build -f ci-images/${docker_base}/Dockerfile -t quay.io/reactiveops/ci-images:$DOCKER_BASE_TAG-${docker_base} .
        done

  docker_push: &docker_push
    run:
      name: Docker push
      command: |
        if [[ "${DOCKER_BASE_TAG}" =~ ^v[0-9]+ ]]; then
          for docker_base in ${SUPPORTED_DOCKER_BASES}; do
            echo "Pushing ${docker_base}"
            docker tag quay.io/reactiveops/ci-images:{$DOCKER_BASE_TAG,$DOCKER_MAJOR_TAG}-${docker_base}
            docker tag quay.io/reactiveops/ci-images:{$DOCKER_BASE_TAG,$DOCKER_MINOR_TAG}-${docker_base}
            docker push quay.io/reactiveops/ci-images:$DOCKER_BASE_TAG-${docker_base}
            docker push quay.io/reactiveops/ci-images:$DOCKER_MAJOR_TAG-${docker_base}
            docker push quay.io/reactiveops/ci-images:$DOCKER_MINOR_TAG-${docker_base}
          done
        elif [[ "${DOCKER_BASE_TAG}" =~ ^dev- ]]; then
          for docker_base in ${SUPPORTED_DOCKER_BASES}; do
            docker push quay.io/reactiveops/ci-images:$DOCKER_BASE_TAG-${docker_base}
          done
        else
          echo "Skipping the docker push because '\$DOCKER_BASE_TAG: $DOCKER_BASE_TAG' does not start with dev- or v[0-9]+."
        fi

  npm_release: &npm_release
    run:
      name: NPM release
      command: |
        echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
        echo $CIRCLE_TAG | xargs npm version --no-git-tag-version
        npm publish

  github_release: &github_release
    run:
      name: GitHub release
      command: |
        git fetch --tags
        curl -O https://raw.githubusercontent.com/reactiveops/release.sh/v0.0.2/release
        /bin/bash release

  build_docker_tags: &build_docker_tags
    run:
      name: Generate major & minor tags
      command: |
        echo "export DOCKER_MAJOR_TAG=$(echo ${DOCKER_BASE_TAG} | sed -r 's/^(v[0-9]+)(\.[0-9]+)(\.[0-9]+)$/\1/')" >> $BASH_ENV
        echo "export DOCKER_MINOR_TAG=$(echo ${DOCKER_BASE_TAG} | sed -r 's/^(v[0-9]+)(\.[0-9]+)(\.[0-9]+)$/\1\2/')" >> $BASH_ENV

jobs:
  test_npm:
    docker:
      - image: node:8.9.4
    steps:
      - checkout
      - *install_test_dependencies
      - *npm_install
      - *run_shellcheck
      - *run_basic_linting

  test_pip:
    docker:
      - image: python:2.7
    steps:
      - checkout
      - *install_test_dependencies
      - *pip_install
      - *run_shellcheck
      - *check_setup_py_version
      - *run_basic_linting

  build:
    docker:
      - image: circleci/buildpack-deps:jessie
    steps:
      - checkout
      - *load_supported_docker_bases
      - setup_remote_docker
      - run: echo 'export DOCKER_BASE_TAG=dev-$CIRCLE_SHA1' >> $BASH_ENV
      - *docker_login
      - *docker_build
      - *docker_push

  release:
    docker:
      - image: circleci/node:boron-stretch
    steps:
      - checkout
      - *load_supported_docker_bases
      - setup_remote_docker
      - run: echo 'export GITHUB_ORGANIZATION=$CIRCLE_PROJECT_USERNAME' >> $BASH_ENV
      - run: echo 'export GITHUB_REPOSITORY=$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV
      - run: echo 'export DOCKER_BASE_TAG=$CIRCLE_TAG' >> $BASH_ENV
      - *github_release
      - *build_docker_tags
      - *docker_login
      - *docker_build
      - *docker_push
      - *npm_release


workflows:
  version: 2
  build_and_test:
    jobs:
      - test_npm
      - test_pip
      - build
  release:
    jobs:
      - release:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
