version: 2.1

###
# Parameters
###
parameters:
  browser:
    type: enum
    enum: ["chrome", "firefox"]
    default: "chrome"
  bver:
    type: enum
    enum: ["stable", "beta", "unstable"]
    default: "stable"
  pr_workflow:
    type: boolean
    default: true # by default pr workflow will get executed.
  tag:
    type: string
    default: "" # use something like: "2.0.0-beta15" when invoking with parameters.
  release_workflow:
    type: boolean
    default: false
  release_command:
    type: string
    default: "echo \"no release-command specified\""

###
# Executors
###
executors:
  machine-executor:
    machine: true
  generic-executor:
    docker:
      - image: alpine:3.7
  docker-with-browser:
    parameters:
      browser:
        type: enum
        enum: ["chrome", "firefox"]
        default: "chrome"
      bver:
        type: enum
        enum: ["stable", "beta", "unstable"]
        default: "stable"
    docker:
      - image: twilio/twilio-video-browsers:<<parameters.browser>>-<<parameters.bver>>

###
# Commands
###
commands:
  get-code:
    steps:
      - checkout
      - when:
          condition: << pipeline.parameters.tag >>
          steps:
            - run: git checkout << pipeline.parameters.tag >>
  set-node-version:
    steps:
      - run:
          name: Set node to version 12
          command: |
            sudo npm install -g n
            sudo n 12
  get-code-and-dependencies:
    steps:
      - get-code
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: Installing dependencies
          command: node -v && npm install --legacy-peer-deps
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules
  build:
    steps:
      - set-node-version
      - get-code-and-dependencies
      - run:
          name: Building project
          command: npm run build
      - store_artifacts:
          path: ./dist
          prefix: ./dist
  unit-tests:
    steps:
      - build
      - run:
          name: Running unit tests
          command: npm run test:unit
  integration-tests:
    steps:
      - build
      - run:
          name: Running integration tests
          command: npm run test:integration
  network-tests:
    steps:
      - get-code
      - run:
          name: Running network tests
          command: npm run test:docker


###
# Jobs
###
jobs:
  run-unit-tests:
    executor: docker-with-browser
    steps: [unit-tests]
  run-network-tests:
    parameters:
      bver:
        type: string
      browser:
        type: string
    executor:
      name: machine-executor
    environment:
      BROWSER: << parameters.browser >>
      BVER: << parameters.bver >>
    steps: [network-tests]
  run-integration-tests:
    parameters:
      bver:
        type: string
      browser:
        type: string
    executor:
      name: docker-with-browser
    environment:
      BROWSER: << parameters.browser >>
      BVER: << parameters.bver >>
    steps: [integration-tests]
  run-release:
    parameters:
      dryRun:
        type: boolean
        default: true
    executor:
      name: docker-with-browser
    steps:
      - when:
          condition: << parameters.dryRun >>
          steps:
            - run: echo "Will run \"<< pipeline.parameters.release_command >>\""
      - unless:
          condition: << parameters.dryRun >>
          steps:
            - build
            - run: << pipeline.parameters.release_command >>

  trigger-qe-tests:
    docker:
      - image: circleci/node:latest
    steps:
      - run:
          name: Trigger QE tests
          command: |
            curl --fail --write-out "\nHTTP Response Code: %{http_code}\n" \
            -u "$CIRCLECI_PERSONAL_API_TOKEN": -X POST --header "Content-Type: application/json" \
            -d '{"branch":"'v${CIRCLE_TAG:0:1}'","parameters":{"sdk_version":"'$CIRCLE_TAG'","is_rc":true}}' \
            $SDKS_QE_CIRCLECI_VOICE_JS_SLAVE_PIPELINE_ENDPOINT

###
# Workflows
###
workflows:
  pull-request-workflow:
    when:
        and:
          - equal: [true, << pipeline.parameters.pr_workflow >>]
          - equal: [false, << pipeline.parameters.release_workflow >>]
    jobs:
      - run-unit-tests:
          context:
            - vblocks-js
          name: Unit Tests
      - run-integration-tests:
          name: Integration Tests << matrix.browser >> << matrix.bver >>
          context:
            - dockerhub-pulls
            - vblocks-js
          matrix:
            parameters:
              browser: ["chrome", "firefox"]
              bver: ["beta", "unstable", "stable"]
      - run-network-tests:
          name: Network Tests << matrix.browser >> << matrix.bver >>
          context:
            - dockerhub-pulls
            - vblocks-js
          matrix:
            parameters:
              browser: ["chrome", "firefox"]
              bver: ["stable"]
  release-workflow:
    when: << pipeline.parameters.release_workflow >>
    jobs:
      - run-unit-tests:
          context:
            - vblocks-js
          name: Unit Tests
      - run-integration-tests:
          context:
            - dockerhub-pulls
            - vblocks-js
          name: Integration Tests <<matrix.browser>> <<matrix.bver>>
          matrix:
            parameters:
              browser: ["chrome", "firefox"]
              bver: ["beta", "unstable", "stable"]
      - run-network-tests:
          context:
            - dockerhub-pulls
            - vblocks-js
          name: Network Tests <<matrix.browser>> <<matrix.bver>>
          matrix:
            parameters:
              browser: ["chrome", "firefox"]
              bver: ["stable"]
      - run-release:
          context:
            - dockerhub-pulls
            - vblocks-js
          name: Create Release Dry Run
          dryRun: true
          requires:
            - Unit Tests
            # Chrome integration tests
            - Integration Tests chrome beta
            - Integration Tests chrome unstable
            - Integration Tests chrome stable
            # Firefox integration tests
            - Integration Tests firefox beta
            - Integration Tests firefox unstable
            - Integration Tests firefox stable
            # Chrome network tests
            - Network Tests chrome stable
            # Firefox network tests
            - Network Tests firefox stable
      - hold:
          type: approval
          requires:
            - Create Release Dry Run
      - run-release:
          context:
            - dockerhub-pulls
            - vblocks-js
          name: Create Release
          dryRun: false
          requires:
            - hold
  release-candidate:
      jobs:
        - trigger-qe-tests:
            context: sdks-qe
            filters:
              tags:
                only:
                - /^\d+\.\d+\.\d+-rc\d+$/
                - /^\d+\.\d+\.\d+-preview\d+-rc\d+$/
                - /^\d+\.\d+\.\d+-beta\d+-rc\d+$/
              branches:
                ignore: /.*/
