version: 2.1

orbs:
  win: circleci/windows@1.0.0

executors:
  bionic:
    docker:
      - image: buildpack-deps:bionic
  mac:
    environment:
      EMSDK_NOTTY: "1"
      # Without this, any `brew install` command will result in self-update of
      # brew itself which takes more than 4 minutes.
      HOMEBREW_NO_AUTO_UPDATE: "1"
    macos:
      xcode: "12.5.1"
    resource_class: macos.x86.medium.gen2
  mac_arm64:
    environment:
      EMSDK_NOTTY: "1"
      # Without this, any `brew install` command will result in self-update of
      # brew itself which takes more than 4 minutes.
      HOMEBREW_NO_AUTO_UPDATE: "1"
    macos:
      xcode: "13.4.1"
    resource_class: macos.m1.medium.gen1
  linux_arm64:
    machine:
      image: ubuntu-2004:2023.07.1
    resource_class: arm.medium

commands:
  setup-macos:
    steps:
      - checkout
      - run:
          name: Install CMake
          command: brew install cmake
  test-macos:
    steps:
      - run:
          name: test.sh
          command: test/test.sh
      - run:
          name: test.py
          command: |
            source emsdk_env.sh
            test/test.py

jobs:
  flake8:
    executor: bionic
    steps:
      - checkout
      - run:
          name: install pip
          command: |
            apt-get update -q
            apt-get install -q -y python-pip python3-pip
      - run: python2 -m pip install --upgrade pip
      - run: python3 -m pip install --upgrade pip
      - run: python2 -m pip install flake8==3.9.2
      - run: python3 -m pip install flake8==3.9.2
      - run: python2 -m flake8 --show-source --statistics --extend-exclude=./scripts
      - run: python3 -m flake8 --show-source --statistics
  test-linux:
    executor: bionic
    environment:
      EMSDK_NOTTY: "1"
      # This is needed because the old gcc-7 that is installed on debian/bionic
      # generates warnings about unused variables when doing C++17
      # destructuring:
      # https://github.com/WebAssembly/binaryen/issues/4353
      CXXFLAGS: "-Wno-unused-variable"
      # I don't know why circleci VMs pretent to have 36 cores but its a lie.
      EMSDK_NUM_CORES: "4"
    steps:
      - checkout
      - run:
          name: Install debian packages
          command: apt-get update -q && apt-get install -q -y cmake build-essential openjdk-8-jre-headless ksh zsh
      - run: test/test_node_path.sh
      - run: test/test.sh
      - run: test/test_source_env.sh
      - run:
          name: test.py
          command: |
            source emsdk_env.sh
            test/test.py
  test-linux-arm64:
    executor: linux_arm64
    steps:
      - checkout
      - run:
          name: Install debian packages
          command: sudo apt-get update -q && sudo apt-get install -q cmake build-essential openjdk-8-jre-headless
      - run: test/test.sh
  test-mac:
    executor: mac
    steps:
      - setup-macos
      - test-macos
  test-mac-arm64:
    executor: mac_arm64
    steps:
      - setup-macos
      - test-macos
  test-windows:
    executor:
      name: win/vs2019
      shell: bash.exe
    environment:
      # We need python installed before we can test anytyhing.
      # There seems to be undocument copy of python installed here. Hopefully
      # if this disappears there will be another way of getting a re-installed
      # version.
      PYTHON_BIN: "C:\\Python27amd64"
      PYTHONUNBUFFERED: "1"
      EMSDK_NOTTY: "1"
    steps:
      - checkout
      - run:
          name: Add python to bash path
          command: echo "export PATH=\"$PATH:/c/python27amd64/\"" >> $BASH_ENV
      - run:
          name: Install latest
          shell: cmd.exe
          command: test\test.bat
      - run:
          name: test.py
          command: |
            source emsdk_env.sh
            python test/test.py

      - run:
          name: flagless (process/shell) test
          shell: powershell.exe
          command: |
            test/test_activation.ps1

      - run:
          name: --permanent test
          shell: powershell.exe
          command: |
            $env:PERMANENT_FLAG="--permanent"
            test/test_activation.ps1

      - run:
          name: --system test
          shell: powershell.exe
          command: |
            $env:SYSTEM_FLAG="--system"
            test/test_activation.ps1

      - run:
          name: Process/Shell PATH preservation test
          shell: powershell.exe
          command: |
            test/test_path_preservation.ps1

      - run:
          name: User PATH preservation test
          shell: powershell.exe
          command: |
            $env:PERMANENT_FLAG="--permanent"
            test/test_path_preservation.ps1

      - run:
          name: System PATH preservation test
          shell: powershell.exe
          command: |
            $env:SYSTEM_FLAG="--system"
            test/test_path_preservation.ps1

  build-docker-image-x64:
    executor: bionic
    steps:
      - checkout
      - run:
          name: install docker
          command: apt-get update -q && apt-get install -q -y docker.io
      - setup_remote_docker
      # Build and test the tip-of-tree build of EMSDK
      - run:
          name: build
          command: make -C ./docker version=tot build
      - run:
          name: test
          command: make -C ./docker version=tot test

  publish-docker-image-x64:
    executor: bionic
    steps:
      - checkout
      - run:
          name: install docker
          command: apt-get update -q && apt-get install -q -y docker.io
      - setup_remote_docker
      - run:
          name: build
          command: make -C ./docker version=${CIRCLE_TAG} build
      - run:
          name: test
          command: make -C ./docker version=${CIRCLE_TAG} test
      - run:
          name: push image
          command: |
            docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
            make -C ./docker version=${CIRCLE_TAG} alias=latest push

  publish-docker-image-arm64:
    executor: linux_arm64
    steps:
      - checkout
      - run:
          name: check if emscripten-releases-tags.json has changed
          command: |
            CHANGED_FILES=$(git diff --name-only <<pipeline.git.base_revision>>..<<pipeline.git.revision>>)
            if [[ ! $CHANGED_FILES =~ "emscripten-releases-tags.json" ]]; then
              echo "emscripten-releases-tags.json has not changed, skipping build and publish"
              circleci-agent step halt
            fi
      - run:
          name: extract latest emscripten arm64 linux version
          command: |
            ARM64_VERSION=$(grep -oP '(?<="latest-arm64-linux": ")[^"]*' emscripten-releases-tags.json)
            ARM64_IMAGE_TAG=${ARM64_VERSION}-arm64
            echo "export ARM64_VERSION=$ARM64_VERSION" >> $BASH_ENV
            echo "export ARM64_IMAGE_TAG=$ARM64_IMAGE_TAG" >> $BASH_ENV
            echo "ARM64_VERSION=$ARM64_VERSION"
            echo "ARM64_IMAGE_TAG=$ARM64_IMAGE_TAG"
      - run:
          name: check if docker image already exists
          command: |
            if [ -z "$ARM64_VERSION" ]; then
              echo "ARM64_VERSION is empty, skipping publish"
              circleci-agent step halt
              exit 0
            fi
            DOCKER_IMAGE_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" https://hub.docker.com/v2/repositories/emscripten/emsdk/tags/$ARM64_IMAGE_TAG)
            if [ "$DOCKER_IMAGE_EXISTS" = "200" ]; then
              echo "Docker image: $ARM64_VERSION"
              echo "Docker image already exists, skipping build and publish"
              circleci-agent step halt
            fi
      - run:
          name: build
          command: make -C ./docker version=${ARM64_VERSION} build
      - run:
          name: test
          command: make -C ./docker version=${ARM64_VERSION} test
      - run:
          name: push image
          command: |
            docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
            make -C ./docker version=${ARM64_VERSION} alias=${ARM64_IMAGE_TAG} only_alias=true push

  test-bazel-linux:
    executor: bionic
    steps:
      - checkout
      - run: apt-get install -q -y curl gnupg
      - run: curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
      - run: mv bazel.gpg /etc/apt/trusted.gpg.d/
      - run: echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
      - run:
          name: install pip
          command: |
            apt-get update -q
            apt-get install -q -y python3-pip
      - run: pip3 install absl-py
      - run:
          name: install bazel
          command: |
            apt-get install -q -y bazel
      - run: test/test_bazel.sh

  test-bazel-mac:
    executor: mac
    steps:
      - checkout
      - run: brew install grep
      - run:
          name: install bazelisk
          command: |
            brew install bazelisk
      - run: test/test_bazel_mac.sh

  test-bazel-windows:
    executor:
      name: win/vs2019
      shell: powershell.exe -ExecutionPolicy Bypass
    environment:
      PYTHONUNBUFFERED: "1"
      EMSDK_NOTTY: "1"
      USE_BAZEL_VERSION: "5.4.0"
    steps:
      - checkout
      - run:
          name: Download Bazelisk
          shell: powershell.exe
          command: |
            $ProgressPreference = "SilentlyContinue"
            Invoke-WebRequest -Uri https://github.com/bazelbuild/bazelisk/releases/download/v1.10.1/bazelisk-windows-amd64.exe -OutFile ( New-Item -Path "temp\bazel\bazel.exe" -Force )
      - run:
          name: Run Tests
          shell: powershell.exe
          command: |
            $env:Path += ";C:\Python27amd64;$pwd\temp\bazel"
            .\test\test_bazel.ps1

workflows:
  flake8:
    jobs:
      - flake8
  test-linux:
    jobs:
      - test-linux
  test-linux-arm64:
    jobs:
      - test-linux-arm64
  test-mac:
    jobs:
      - test-mac
  test-mac-arm64:
    jobs:
      - test-mac-arm64
  test-windows:
    jobs:
      - test-windows
  build-docker-image:
    jobs:
      - build-docker-image-x64
      - publish-docker-image-x64:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /.*/
      - publish-docker-image-arm64:
          filters:
            branches:
              only: main
  test-bazel-linux:
    jobs:
      - test-bazel-linux
  test-bazel-mac:
    jobs:
      - test-bazel-mac
  test-bazel-windows:
    jobs:
      - test-bazel-windows
