name: Publish dev releases to docker hub

on:
  push:
    branches:
    - dev

jobs:
  # THE LINT/TEST JOBS ARE COPIED FROM ci.yaml

  lint-clang-format:
    runs-on: ubuntu-latest
    # cpp lint job runs with esphome-lint docker image so that clang-format-*
    # doesn't have to be installed
    container: esphome/esphome-lint:latest
    steps:
      - uses: actions/checkout@v2
      # Cache platformio intermediary files (like libraries etc)
      # Note: platformio platform versions should be cached via the esphome-lint image
      - name: Cache Platformio
        uses: actions/cache@v1
        with:
          path: .pio
          key: lint-cpp-pio-${{ hashFiles('platformio.ini') }}
          restore-keys: |
            lint-cpp-pio-
      # Set up the pio project so that the cpp checks know how files are compiled
      # (build flags, libraries etc)
      - name: Set up platformio environment
        run: pio init --ide atom

      - name: Run clang-format
        run: script/clang-format -i
      - name: Suggest changes
        run: script/ci-suggest-changes

  lint-clang-tidy:
    runs-on: ubuntu-latest
    # cpp lint job runs with esphome-lint docker image so that clang-format-*
    # doesn't have to be installed
    container: esphome/esphome-lint:latest
    # Split clang-tidy check into 4 jobs. Each one will check 1/4th of the .cpp files
    strategy:
      matrix:
        split: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v2
      # Cache platformio intermediary files (like libraries etc)
      # Note: platformio platform versions should be cached via the esphome-lint image
      - name: Cache Platformio
        uses: actions/cache@v1
        with:
          path: .pio
          key: lint-cpp-pio-${{ hashFiles('platformio.ini') }}
          restore-keys: |
            lint-cpp-pio-
      # Set up the pio project so that the cpp checks know how files are compiled
      # (build flags, libraries etc)
      - name: Set up platformio environment
        run: pio init --ide atom


      - name: Register problem matchers
        run: |
          echo "::add-matcher::.github/workflows/matchers/clang-tidy.json"
          echo "::add-matcher::.github/workflows/matchers/gcc.json"
      - name: Run clang-tidy
        run: script/clang-tidy --all-headers --fix --split-num 4 --split-at ${{ matrix.split }}
      - name: Suggest changes
        run: script/ci-suggest-changes

  lint-python:
    # Don't use the esphome-lint docker image because it may contain outdated requirements.
    # This way, all dependencies are cached via the cache action.
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'
      - name: Cache pip modules
        uses: actions/cache@v1
        with:
          path: ~/.cache/pip
          key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
          restore-keys: |
            esphome-pip-3.7-
      - name: Set up python environment
        run: script/setup

      - name: Register problem matchers
        run: |
          echo "::add-matcher::.github/workflows/matchers/ci-custom.json"
          echo "::add-matcher::.github/workflows/matchers/lint-python.json"
          echo "::add-matcher::.github/workflows/matchers/python.json"
      - name: Lint Custom
        run: script/ci-custom.py
      - name: Lint Python
        run: script/lint-python
      - name: Lint CODEOWNERS
        run: script/build_codeowners.py --check

  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
          test:
          - test1
          - test2
          - test3
          - test4
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'
      - name: Cache pip modules
        uses: actions/cache@v1
        with:
          path: ~/.cache/pip
          key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
          restore-keys: |
            esphome-pip-3.7-
      # Use per test platformio cache because tests have different platform versions
      - name: Cache ~/.platformio
        uses: actions/cache@v1
        with:
          path: ~/.platformio
          key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}
          restore-keys: |
            test-home-platformio-${{ matrix.test }}-
      - name: Set up environment
        run: script/setup


      - name: Register problem matchers
        run: |
          echo "::add-matcher::.github/workflows/matchers/gcc.json"
          echo "::add-matcher::.github/workflows/matchers/python.json"
      - run: esphome tests/${{ matrix.test }}.yaml compile

  pytest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'
      - name: Cache pip modules
        uses: actions/cache@v1
        with:
          path: ~/.cache/pip
          key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
          restore-keys: |
            esphome-pip-3.7-
      - name: Set up environment
        run: script/setup
      - name: Install Github Actions annotator
        run: pip install pytest-github-actions-annotate-failures

      - name: Register problem matchers
        run: |
          echo "::add-matcher::.github/workflows/matchers/python.json"
      - name: Run pytest
        run: |
          pytest \
            -qq \
            --durations=10 \
            -o console_output_style=count \
            tests

  deploy-docker:
    name: Build and publish docker containers
    if: github.repository == 'esphome/esphome'
    runs-on: ubuntu-latest
    needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest]
    strategy:
      matrix:
        arch: [amd64, armv7, aarch64]
        # Hassio dev image doesn't use esphome/esphome-hassio-$arch and uses base directly
        build_type: ["docker"]
    steps:
      - uses: actions/checkout@v2
      - name: Set TAG
        run: |
          TAG="${GITHUB_SHA:0:7}"
          echo "::set-env name=TAG::${TAG}"
      - name: Set up env variables
        run: |
          base_version="2.4.0"

          if [[ "${{ matrix.build_type }}" == "hassio" ]]; then
            build_from="esphome/esphome-hassio-base-${{ matrix.arch }}:${base_version}"
            build_to="esphome/esphome-hassio-${{ matrix.arch }}"
            dockerfile="docker/Dockerfile.hassio"
          else
            build_from="esphome/esphome-base-${{ matrix.arch }}:${base_version}"
            build_to="esphome/esphome-${{ matrix.arch }}"
            dockerfile="docker/Dockerfile"
          fi

          echo "::set-env name=BUILD_FROM::${build_from}"
          echo "::set-env name=BUILD_TO::${build_to}"
          echo "::set-env name=DOCKERFILE::${dockerfile}"
      - name: Pull for cache
        run: |
          docker pull "${BUILD_TO}:dev" || true
      - name: Register QEMU binfmt
        run: docker run --rm --privileged multiarch/qemu-user-static:5.0.0-2 --reset -p yes
      - run: |
          docker build \
            --build-arg "BUILD_FROM=${BUILD_FROM}" \
            --build-arg "BUILD_VERSION=${TAG}" \
            --tag "${BUILD_TO}:${TAG}" \
            --tag "${BUILD_TO}:dev" \
            --cache-from "${BUILD_TO}:dev" \
            --file "${DOCKERFILE}" \
            .
      - name: Log in to docker hub
        env:
          DOCKER_USER: ${{ secrets.DOCKER_USER }}
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
        run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
      - run: |
          docker push "${BUILD_TO}:${TAG}"
          docker push "${BUILD_TO}:dev"


  deploy-docker-manifest:
    if: github.repository == 'esphome/esphome'
    runs-on: ubuntu-latest
    needs: [deploy-docker]
    steps:
    - name: Enable experimental manifest support
      run: |
        mkdir -p ~/.docker
        echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
    - name: Set TAG
      run: |
        TAG="${GITHUB_SHA:0:7}"
        echo "::set-env name=TAG::${TAG}"
    - name: Log in to docker hub
      env:
        DOCKER_USER: ${{ secrets.DOCKER_USER }}
        DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
    - name: "Create the manifest"
      run: |
        docker manifest create esphome/esphome:${TAG} \
          esphome/esphome-aarch64:${TAG} \
          esphome/esphome-amd64:${TAG} \
          esphome/esphome-armv7:${TAG}
        docker manifest push esphome/esphome:${TAG}

        docker manifest create esphome/esphome:dev \
          esphome/esphome-aarch64:${TAG} \
          esphome/esphome-amd64:${TAG} \
          esphome/esphome-armv7:${TAG}
        docker manifest push esphome/esphome:dev