version: 2.1

commands:
    # Command based on instructions from CircleCI blog for avoiding fork secret leakage or failures
    # https://circleci.com/blog/managing-secrets-when-you-have-pull-requests-from-outside-contributors/
    early-return-forks:
        description: >-
          If this build is from a fork, stop executing the current job and return success.
          This is useful to avoid steps that will fail due to missing credentials.
        steps:
            - run:
                name: Early return if this build is from a forked PR
                command: |
                    if [ -n "$CIRCLE_PR_NUMBER" ]; then
                        echo "Nothing to do for forked PRs, so marking this step successful"
                        circleci step halt
                    fi

    install-and-test:
        description: >-
            Install everything required to run the test suite, then run it.
        steps:
            - checkout
            - restore_cache:
                key: dependency-cache-{{ checksum "package.json" }}
            - run:
                name: Update npm
                command: 'sudo npm install -g npm@latest'
            - run:
                name: Install npm dependencies
                command: npm install
            - save_cache:
                key: dependency-cache-{{ checksum "package.json" }}
                paths:
                    - node_modules
            - run: 
                name: Tests
                command: npx jest --ci --coverage
            - early-return-forks
            - run: 
                name: Report Coverage
                command: npx coveralls < coverage/lcov.info

jobs:
    node-latest:
        docker:
            - image: circleci/node:latest
        steps:
            - install-and-test

    node-11:
        docker:
            - image: circleci/node:11
        steps:
            - install-and-test

    node-10:
        docker:
            - image: circleci/node:10
        steps:
            - install-and-test

    node-8:
        docker:
            - image: circleci/node:8
        steps:
            - install-and-test

    build:
        machine: true
        steps:
            - checkout
            - run: 
                name: Lint Dockerfile
                command: docker run --rm -i hadolint/hadolint < Dockerfile
            - run: 
                name: Attempt Docker Build
                command: docker build .

    push-docker:
        machine: true
        environment:
            - DOCKER_REPOSITORY: wework/speccy
        steps:
            - checkout
            - early-return-forks
            - run: 
                name: 
                command: |
                
                    docker_tag=$DOCKER_REPOSITORY:$(echo $CIRCLE_SHA1 | cut -c1-7)
                    
                    docker build -t $docker_tag .
                    docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD

                    if [[ -n "$CIRCLE_TAG" ]]; then
                        version_number=$(echo $CIRCLE_TAG | sed "s/^v//")
                
                        patch_tag=$DOCKER_REPOSITORY:$version_number
                        docker tag $docker_tag $patch_tag
                    
                        major_tag=$DOCKER_REPOSITORY:$(echo $version_number | cut -d . -f 1)
                        docker tag $docker_tag $major_tag
                    
                        minor_tag=$DOCKER_REPOSITORY:$(echo $version_number | cut -d . -f 1-2)
                        docker tag $docker_tag $minor_tag

                        docker tag $docker_tag $DOCKER_REPOSITORY:latest
                    else
                        tag=$DOCKER_REPOSITORY:$(echo $CIRCLE_BRANCH | sed "s|/|-|g")
                        docker tag $docker_tag $tag
                    fi

                    docker push $DOCKER_REPOSITORY

workflows:
    version: 2
    commit:
        jobs:
            - build
            - node-latest
            - node-11
            - node-10
            - node-8

    deploy:
        jobs:
            - push-docker:
                filters:
                    tags:
                        only: /^v.*/

