run_with_build_env_vars: &run_with_build_env_vars
  environment:
    LLVM_SYS_70_PREFIX: /home/circleci/project/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/

run_install_dependencies: &run_install_dependencies
  run:
    name: install dependencies
    command: |
      sudo apt-get install -y cmake
      curl -O https://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
      tar xf clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz

version: 2
jobs:
  changelog:
    docker:
      - image: docker:stable-git
    steps:
      - checkout
      - run:
          command: ! git diff --exit-code CHANGELOG.md

  # Job used for testing
  lint:
    docker:
      - image: circleci/rust:latest
    <<: *run_with_build_env_vars
    steps:
      - checkout
      - restore_cache:
          keys:
            - v8-lint-{{ arch }}-{{ checksum "Cargo.lock" }}
      - <<: *run_install_dependencies
      - run:
          name: Install lint deps
          command: |
            git config --global --unset url."ssh://git@github.com".insteadOf || true
            rustup toolchain install nightly-2019-05-20
            rustup component add rustfmt
            rustup component add clippy --toolchain=nightly-2019-05-20 || cargo +nightly-2019-05-20 install --git https://github.com/rust-lang/rust-clippy/ --force clippy
      - run:
          name: Execute lints
          command: |
            make lint
      - save_cache:
          paths:
            - /usr/local/cargo/registry
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
          key: v8-lint-{{ arch }}-{{ checksum "Cargo.lock" }}

  test:
    docker:
      - image: circleci/rust:latest
    <<: *run_with_build_env_vars
    steps:
      - checkout
      - restore_cache:
          keys:
            - v8-test-cargo-cache-linux-stable-{{ arch }}-{{ checksum "Cargo.lock" }}
      - <<: *run_install_dependencies
      - run:
          name: Tests
          command: make test
      - run:
          name: Emscripten Tests
          command: |
            make test-emscripten-clif
            make test-emscripten-llvm
      - run:
          name: Integration Tests
          command: make integration-tests
      - save_cache:
          paths:
            - /usr/local/cargo/registry
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
          key: v8-test-cargo-cache-linux-stable-{{ arch }}-{{ checksum "Cargo.lock" }}

  test-macos:
    macos:
      xcode: "9.0"
    steps:
      - checkout
      - restore_cache:
          keys:
            - v8-cargo-cache-darwin-stable-{{ arch }}-{{ checksum "Cargo.lock" }}
      - run:
          name: Install crate dependencies
          command: |
            # Installing cmake outside of brew to improve speed
            curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Darwin-x86_64.tar.gz
            tar xf cmake-3.4.1-Darwin-x86_64.tar.gz
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            # Installing LLVM outside of brew
            curl -O https://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz
            tar xf clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz
      - run:
          name: Install Rust
          command: |
            curl -sSf https://sh.rustup.rs | sh -s -- -y
            export PATH="$HOME/.cargo/bin:$PATH"
            cargo --version
      - run:
          name: Tests
          command: |
            export PATH="$HOME/.cargo/bin:$PATH"
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            # We increase the ulimit for fixing cargo unclosed files in mac
            ulimit -n 8000
            sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
            make test
      - run:
          name: Emscripten Tests
          command: |
            export PATH="$HOME/.cargo/bin:$PATH"
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            # We increase the ulimit for fixing cargo unclosed files in mac
            ulimit -n 8000
            sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
            make test-emscripten-clif
            make test-emscripten-llvm
      - run:
          name: Integration Tests
          command: |
            export PATH="$HOME/.cargo/bin:$PATH"
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            make integration-tests
      - save_cache:
          paths:
            - ~/.cargo/registry/
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
            - target/release/.fingerprint
            - target/release/build
            - target/release/deps
          key: v8-cargo-cache-darwin-stable-{{ arch }}-{{ checksum "Cargo.lock" }}

  test-and-build:
    docker:
      - image: circleci/rust:latest
    steps:
      - checkout
      - run:
          name: "Pull dependencies"
          command: |
            git submodule init
            git submodule update
      - restore_cache:
          keys:
            - v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
      - run:
          name: Install dependencies
          command: |
            sudo apt-get install -y cmake
            curl -O https://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
            tar xf clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
      # Use rust nightly (for singlepass, for now)
      - run: rustup default nightly-2019-04-11
      - run:
          name: Tests
          command: |
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
            make test
      - run:
          name: Emscripten Tests
          command: |
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
            make test-emscripten-clif
            make test-emscripten-llvm
      - run:
          name: Debug flag checked
          command: |
            cargo check --features "debug"
      - run:
          name: Release Build
          command: |
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
            make production-release
            cargo build --release --manifest-path wapm-cli/Cargo.toml --features telemetry
            mkdir -p artifacts
            VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
            # GIT_VERSION=$(git describe --exact-match --tags)
            echo "${VERSION}" >> artifacts/version
            echo "${CIRCLE_TAG}" >> artifacts/git_version
            make build-install
            cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
      - run:
          name: Dynamic library
          command: |
            cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
            cp target/release/libwasmer_runtime_c_api.so ./artifacts
      - persist_to_workspace:
          root: .
          paths:
            - artifacts
      - save_cache:
          paths:
            - /usr/local/cargo/registry
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
            - target/release/.fingerprint
            - target/release/build
            - target/release/deps
            - wapm-cli/target/release/.fingerprint
            - wapm-cli/target/release/build
            - wapm-cli/target/release/deps
          key: v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}

  test-and-build-macos:
    macos:
      xcode: "9.0"
    steps:
      - checkout
      - run:
          name: "Pull dependencies"
          command: |
            git submodule init
            git submodule update
      - restore_cache:
          keys:
            - v8-cargo-cache-darwin-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
      - run:
          name: Install crate dependencies
          command: |
            # Installing cmake outside of brew to improve speed
            curl -O https://cmake.org/files/v3.4/cmake-3.4.1-Darwin-x86_64.tar.gz
            tar xf cmake-3.4.1-Darwin-x86_64.tar.gz
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            # Installing LLVM outside of brew
            curl -O https://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz
            tar xf clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz
      - run:
          name: Install Rust
          command: |
            curl -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly
            export PATH="$HOME/.cargo/bin:$PATH"
            cargo --version
      # Use rust nightly (for singlepass, for now)
      # - run:
      #     name: Install Rust nightly
      #     command: |
      #       export PATH="$HOME/.rustup/bin:$PATH"
      #       rustup default nightly-2019-04-11
      - run:
          name: Tests
          command: |
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export PATH="$HOME/.cargo/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            # We increase the ulimit for fixing cargo unclosed files in mac
            ulimit -n 8000
            sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
            make test
      - run:
          name: Emscripten Tests
          command: |
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export PATH="$HOME/.cargo/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            # We increase the ulimit for fixing cargo unclosed files in mac
            ulimit -n 8000
            sudo sysctl -w kern.maxfiles=655360 kern.maxfilesperproc=327680
            make test-emscripten-clif
            make test-emscripten-singlepass
      - run:
          name: Release Build
          command: |
            export PATH="`pwd`/cmake-3.4.1-Darwin-x86_64/CMake.app/Contents/bin:$PATH"
            export PATH="$HOME/.cargo/bin:$PATH"
            export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/"
            make production-release
            cargo build --release --manifest-path wapm-cli/Cargo.toml --features telemetry
            mkdir -p artifacts
            make build-install
            cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
            # VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
            # echo "${VERSION}" >> artifacts/version
      - run:
          name: Generate dynamic library for the runtime C API
          command: |
            export PATH="$HOME/.cargo/bin:$PATH"
            cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
            install_name_tool -id "@rpath/libwasmer_runtime_c_api.dylib" target/release/libwasmer_runtime_c_api.dylib
            cp target/release/libwasmer_runtime_c_api.dylib ./artifacts
      - persist_to_workspace:
          root: .
          paths:
            - artifacts
      - save_cache:
          paths:
            - ~/.cargo/registry/
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
            - target/release/.fingerprint
            - target/release/build
            - target/release/deps
            - wapm-cli/target/release/.fingerprint
            - wapm-cli/target/release/build
            - wapm-cli/target/release/deps
          key: v8-cargo-cache-darwin-nightly-{ arch }}-{{ checksum "Cargo.lock" }}

  test-rust-nightly:
    docker:
      - image: circleci/rust:latest
    steps:
      - checkout
      - restore_cache:
          keys:
            - v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}
      - run:
          name: Install dependencies
          command: |
            sudo apt-get install -y cmake
            curl -O https://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
            tar xf clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
            rustup toolchain install nightly
            rustup target add wasm32-wasi --toolchain nightly
      - run: |
          rustup default nightly
          make test-wasi-singlepass
          make test-wasi-clif
      - run: rustup default nightly-2019-04-11
      - run: |
          export LLVM_SYS_70_PREFIX="`pwd`/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04/"
          make test
          make test-singlepass
          make test-emscripten-clif
          make test-emscripten-singlepass
      - save_cache:
          paths:
            - /usr/local/cargo/registry
            - target/debug/.fingerprint
            - target/debug/build
            - target/debug/deps
          key: v8-cargo-cache-linux-nightly-{{ arch }}-{{ checksum "Cargo.lock" }}-nightly

  publish-github-release:
    docker:
      - image: cibuilds/github
    steps:
      - attach_workspace:
          at: .
      - run:
          name: "Publish Release on GitHub"
          command: |
            # go get github.com/tcnksm/ghr
            # VERSION=$(git log -1 --pretty=%B)
            # VERSION=$(./artifacts/ --version)
            VERSION=$(cat ./artifacts/version)
            # VERSION_TAG=${CIRCLE_TAG}
            VERSION_TAG=$(cat ./artifacts/git_version)
            rm ./artifacts/version
            rm ./artifacts/git_version
            # VERSION_TAG=$(git describe --exact-match --tags)
            #if [ "$VERSION" == "$VERSION_TAG" ]; then
            # echo "Versions match, publishing to Github"
            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${VERSION} ./artifacts/  || true
            #else
            #    echo "Versions don't match. Wasmer output version (wasmer --version) is ${VERSION} while Git tag is ${VERSION_TAG}"
            #    exit 1
            #fi
  trigger-benchmark-build:
    docker:
      - image: circleci/rust:latest
    steps:
      - run:
          name: "Trigger Benchmark Build"
          command: |
            if [[ -z "${CIRCLE_API_USER_TOKEN}" ]]; then
               echo "CIRCLE_API_USER_TOKEN environment variable not set"
               exit 1
            else
               echo "Triggering benchmark build"
               curl -u ${CIRCLE_API_USER_TOKEN} \
                    -d build_parameters[CIRCLE_JOB]=bench \
                    https://circleci.com/api/v1.1/project/github/wasmerio/wasmer-bench/tree/master
            fi
workflows:
  version: 2
  main:
    jobs:
      - changelog
      - lint
      - test:
          filters:
            branches:
              only:
                - trying
                - staging
      - test-macos:
          filters:
            branches:
              only:
                - trying
                - staging
      - test-and-build:
          filters:
            branches:
              only:
                - master
      - test-and-build-macos:
          filters:
            branches:
              only:
                - master
      - test-rust-nightly:
          filters:
            branches:
              only:
                - trying
                - staging
      - publish-github-release:
          requires:
            - lint
            - test-and-build
            - test-and-build-macos
          filters:
            branches:
              only: master
      - trigger-benchmark-build:
          requires:
            - test-and-build
            - lint
          filters:
            branches:
              only: master
