name: "Builds and tests"
on:
  pull_request:
  push:
    branches:
      - master
env:
  # Shared variables
  CI_TASK_DIR: ${{ github.workspace }}
  CI_ARTIFACTS_DIR: ${{ github.workspace }}/artifacts

  # macOS specific
  MACOSX_DEPLOYMENT_TARGET: "10.10"
  CI_NODE_MODULES_NTH: 1

  # Windows specific
  CI_MSYS_VERSION: MSYS_NT-10.0-17763
  MSYS2_SHELL_PATH: D:\a\_temp\msys\msys64\usr\bin
defaults:
  run:
    shell: bash
jobs:
  # Linux jobs
  swig_Windows_crosscompiled:
    name: "Lin|Build SWIG for Windows"
    runs-on: ubuntu-20.04
    env:
      swig_hash: "90cdbee6a69d13b39d734083b9f91069533b0d7b"
    steps:
      - uses: actions/checkout@v2
        with:
          repository: "swig/swig"
          ref: ${{ env.swig_hash }}
      - run: |
          mkdir -p build-static/
      - uses: actions/cache@v2
        id: swig-build-cache
        with:
          path: build-static/
          key: swig-win-3-${{ env.swig_hash }}
      - run: |
          sudo apt-get install -y --no-install-recommends autoconf automake bison build-essential mingw-w64
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          curl -sSL https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz > pcre-8.43.tar.gz
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          ./Tools/pcre-build.sh --host=x86_64-w64-mingw32
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          sh autogen.sh
          CFLAGS="-static-libgcc -static-libstdc++" \
          CXXFLAGS="-static-libgcc -static-libstdc++" \
          ./configure \
            --host=x86_64-w64-mingw32 \
            --prefix=`pwd`/build-static/ \
            --program-prefix=ds-
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make -j
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make install
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ github.job }}
          path: ${{ github.workspace }}/build-static/
  swig_Linux:
    name: "Lin|Build SWIG"
    runs-on: ubuntu-20.04
    env:
      swig_hash: "90cdbee6a69d13b39d734083b9f91069533b0d7b"
    steps:
      - uses: actions/checkout@v2
        with:
          repository: "swig/swig"
          ref: ${{ env.swig_hash }}
      - run: |
          mkdir -p build-static/
      - uses: actions/cache@v2
        id: swig-build-cache
        with:
          path: build-static/
          key: swig-2-${{ runner.os }}-${{ env.swig_hash }}
      - run: |
          sudo apt-get install -y --no-install-recommends autoconf automake bison build-essential
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          curl -sSL https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz > pcre-8.43.tar.gz
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          ./Tools/pcre-build.sh
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          sh autogen.sh
          ./configure \
            --prefix=${{ github.workspace }}/build-static/ \
            --program-prefix=ds-
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make -j
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make install
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ github.job }}
          path: ${{ github.workspace }}/build-static/
  build-ctc-decoder-Linux:
    name: "Lin|Build CTC decoder Python package for testing"
    needs: [ swig_Linux ]
    runs-on: ubuntu-20.04
    if: ${{ github.event_name == 'pull_request' }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-python@v2
        with:
          python-version: 3.6
      - run: |
          python --version
          pip --version
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: 3.6
      - name: Make decoder package
        run: |
          NUMPY_BUILD_VERSION=${{ steps.get_numpy.outputs.build_version }} \
          NUMPY_DEP_VERSION=${{ steps.get_numpy.outputs.dep_version }} \
          make -C native_client/ctcdecode/ \
            NUM_PROCESSES=$(nproc) \
            bindings
      - uses: actions/upload-artifact@v2
        with:
          name: "ds_ctcdecoder-Linux-test.whl"
          path: ${{ github.workspace }}/native_client/ctcdecode/dist/*.whl
      - run: |
          make -C native_client/ctcdecode clean-keep-third-party
  train-test-model-Linux:
    name: "Lin|Train a test model"
    needs: [ "build-ctc-decoder-Linux" ]
    runs-on: ubuntu-20.04
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        bitrate: ["8k", "16k"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-python@v2
        with:
          python-version: 3.6
      - uses: actions/download-artifact@v2
        with:
          name: "ds_ctcdecoder-Linux-test.whl"
      - run: |
          python --version
          pip --version
      - run: |
          pip install --upgrade pip==19.3.1 setuptools==45.0.0 wheel==0.33.6
      - run: |
          pip install ds_ctcdecoder-*-cp36-cp36m-*_x86_64.whl
          DS_NODECODER=y pip install --upgrade .
      - run: |
          bits=""
          if [ "${{ matrix.bitrate }}" = "8k" ]; then
            bits=8000
          fi
          if [ "${{ matrix.bitrate }}" = "16k"  ]; then
            bits=16000
          fi

          # Easier to rename to that we can exercize the LDC93S1 importer code to
          # generate the CSV file.
          echo "Moving ${bits} to LDC93S1.wav"
          mv data/smoke_test/LDC93S1_pcms16le_1_${bits}.wav data/smoke_test/LDC93S1.wav

          ./bin/run-ci-ldc93s1_new.sh 249 ${bits}
          ./bin/run-ci-ldc93s1_tflite.sh ${bits}
      - run: |
          curl -vsSL https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/linux.amd64.convert_graphdef_memmapped_format.xz | xz -d > /tmp/convert_graphdef_memmapped_format
          chmod +x /tmp/convert_graphdef_memmapped_format
          /tmp/convert_graphdef_memmapped_format --in_graph=/tmp/train/output_graph.pb --out_graph=/tmp/train/output_graph.pbmm
      - run: |
          tar -cf - \
            -C /tmp/ckpt/ . \
            | xz -9 -T0 > /tmp/checkpoint.tar.xz
      - run: |
          mkdir -p ${{ github.workspace }}/tmp/
          cp /tmp/train*/output_graph.* /tmp/checkpoint.tar.xz ${{ github.workspace }}/tmp/
      - run: |
          ls -hal /tmp/ ${{ github.workspace }}/tmp/
      - uses: actions/upload-artifact@v2
        with:
          name: "test-model.tf-${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/output_graph.pb*
      - uses: actions/upload-artifact@v2
        with:
          name: "test-model.tflite-${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/output_graph.tflite
      - uses: actions/upload-artifact@v2
        with:
          name: "test-checkpoint.${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/checkpoint.tar.xz
  tensorflow_opt-Linux:
    name: "Lin|Check TensorFlow cache"
    runs-on: ubuntu-20.04
    outputs:
      status: ${{ steps.check_artifact_exists.outputs.status }}
      cache_key: ${{ steps.get_cache_key.outputs.key }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - id: get_cache_key
        uses: ./.github/actions/get_cache_key
        with:
          extras: "2"
      - id: check_artifact_exists
        uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ steps.get_cache_key.outputs.key }}
  build-tensorflow-Linux:
    name: "Lin|Build TensorFlow (opt)"
    needs: tensorflow_opt-Linux
    runs-on: ubuntu-20.04
    steps:
      - run: true
        if: needs.tensorflow_opt-Linux.outputs.status == 'found'
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          submodules: 'recursive'
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - run: |
          sudo apt-get install -y --no-install-recommends pixz
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - uses: ./.github/actions/setup-tensorflow
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - uses: ./.github/actions/build-tensorflow
        with:
          flavor: "--linux-cpu"
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - uses: ./.github/actions/package-tensorflow
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-Linux.outputs.cache_key }}
          path: ${{ github.workspace }}/artifacts/home.tar.xz
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
  build-lib_Linux:
    name: "Lin|Build libdeepspeech+client"
    runs-on: ubuntu-20.04
    needs: [ build-tensorflow-Linux, tensorflow_opt-Linux ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-Linux.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-Linux.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-Linux.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-Linux.outputs.status == 'found'
      - run: |
          tar --skip-old-files -xf ${{ github.workspace }}/home.tar.xz
          rm ${{ github.workspace }}/home.tar.xz
      - run: |
          sudo apt-get install -y --no-install-recommends make build-essential gfortran git libblas-dev liblapack-dev libsox-dev libmagic-dev libgsm1-dev libltdl-dev libpng-dev python python-dev zlib1g-dev
      - run: |
          git status
      - uses: ./.github/actions/host-build
        with:
          flavor: ${{ matrix.build-flavor }}
      - uses: ./.github/actions/package
      - uses: actions/upload-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Linux.tar.xz"
          path: ${{ github.workspace }}/artifacts/native_client.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: "libdeepspeech.${{ matrix.build-flavor }}.zip"
          path: ${{ github.workspace }}/artifacts/libdeepspeech.zip
  build-python-Linux:
    name: "Lin|Build Python bindings"
    runs-on: ubuntu-20.04
    needs: [ build-lib_Linux, swig_Linux ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
        python-version: [3.6, 3.7, 3.8, 3.9]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Linux.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: ${{ matrix.python-version }}
      - uses: ./.github/actions/python-build
        with:
          build_flavor: ${{ matrix.build-flavor }}
          numpy_build: "${{ steps.get_numpy.outputs.build_version }}"
          numpy_dep: "${{ steps.get_numpy.outputs.dep_version }}"
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-Linux.whl"
          path: ${{ github.workspace }}/wheels/*.whl
  build-nodejs-Linux:
    name: "Lin|Build NodeJS and ElectronJS"
    runs-on: ubuntu-20.04
    needs: [ build-lib_Linux, swig_Linux ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Linux.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/cache@v2
        id: node-headers-cache
        with:
          path: native_client/javascript/headers/nodejs/
          key: node-headers-10.0.0_16.0.0
      - uses: actions/cache@v2
        id: electron-headers-cache
        with:
          path: native_client/javascript/headers/electronjs/
          key: electron-headers-5.0.13_12.0.0
      - uses: ./.github/actions/node-build
        with:
          nodejs_versions: "10.0.0 11.0.0 12.7.0 13.0.0 14.0.0 15.0.0 16.0.0"
          electronjs_versions: "5.0.13 6.0.12 6.1.7 7.0.1 7.1.8 8.0.1 9.0.1 9.1.0 9.2.0 10.0.0 10.1.0 11.0.0 12.0.0"
      - uses: actions/upload-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_amd64.tar.gz"
          path: ${{ github.workspace }}/native_client/javascript/wrapper.tar.gz
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Linux.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  test-cpp-Linux:
    name: "Lin|Test C++ binary"
    runs-on: ubuntu-20.04
    needs: [ build-lib_Linux, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Linux.tar.xz"
          path: ${{ env.CI_TMP_DIR }}
      - run: |
          cd ${{ env.CI_TMP_DIR }}
          mkdir ds && cd ds && tar xf ../native_client.tar.xz
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: ./.github/actions/run-tests
        with:
          runtime: "cpp"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-py-Linux:
    name: "Lin|Test Python bindings"
    runs-on: ubuntu-20.04
    needs: [ build-python-Linux, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        python-version: [3.6, 3.7, 3.8, 3.9]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - run: |
          sudo apt-get install -y --no-install-recommends sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-Linux.whl"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          pip3 install --only-binary :all: --upgrade ${{ env.CI_TMP_DIR }}/deepspeech*.whl
      - uses: ./.github/actions/run-tests
        with:
          runtime: "python"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-nodejs-Linux:
    name: "Lin|Test NodeJS bindings"
    runs-on: ubuntu-20.04
    needs: [ build-nodejs-Linux, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 12, 14, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - run: |
          sudo apt-get install -y --no-install-recommends sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Linux.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ~/.npm/
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install --verbose ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          ls -hal node_modules/deepspeech* node_modules/.bin/
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs-Linux:
    name: "Lin|Test ElectronJS bindings"
    runs-on: ubuntu-20.04
    needs: [ build-nodejs-Linux, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 6.1.7, 7.1.8, 8.0.1, 9.2.0, 10.1.0, 11.0.0, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - run: |
          sudo apt-get install -y --no-install-recommends sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Linux.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ~/.npm/
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  # macOS jobs
  swig_macOS:
    name: "Mac|Build SWIG"
    runs-on: macos-10.15
    env:
      swig_hash: "90cdbee6a69d13b39d734083b9f91069533b0d7b"
    steps:
      - uses: actions/checkout@v2
        with:
          repository: "swig/swig"
          ref: ${{ env.swig_hash }}
      - run: |
          mkdir -p build-static/
      - uses: actions/cache@v2
        id: swig-build-cache
        with:
          path: build-static/
          key: swig-${{ runner.os }}-${{ env.swig_hash }}
      - run: |
          brew install automake
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          curl -sSL https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz > pcre-8.43.tar.gz
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          ./Tools/pcre-build.sh
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          sh autogen.sh
          ./configure \
            --prefix=${{ github.workspace }}/build-static/ \
            --program-prefix=ds-
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make -j
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - run: |
          make install
        if: steps.swig-build-cache.outputs.cache-hit != 'true'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ github.job }}
          path: ${{ github.workspace }}/build-static/
  build-ctc-decoder-macos:
    name: "Mac|Build CTC decoder Python package for testing"
    needs: [ swig_macOS ]
    runs-on: macos-10.15
    if: ${{ github.event_name == 'pull_request' }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: ./.github/actions/install-python-upstream
        with:
          version: 3.6.8
      - run: |
          python --version
          pip --version
      - uses: actions/download-artifact@v2
        with:
          name: "swig_macOS"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: 3.6.8
      - name: Make decoder package
        run: |
          NUMPY_BUILD_VERSION=${{ steps.get_numpy.outputs.build_version }} \
          NUMPY_DEP_VERSION=${{ steps.get_numpy.outputs.dep_version }} \
          make -C native_client/ctcdecode/ \
            NUM_PROCESSES=$(sysctl hw.ncpu |cut -d' ' -f2) \
            bindings
      - uses: actions/upload-artifact@v2
        with:
          name: "ds_ctcdecoder-macOS-test.whl"
          path: ${{ github.workspace }}/native_client/ctcdecode/dist/*.whl
      - run: |
          make -C native_client/ctcdecode clean-keep-third-party
  train-test-model-macOS:
    name: "Mac|Train a test model"
    needs: [ "build-ctc-decoder-macos" ]
    runs-on: macos-10.15
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        bitrate: ["8k", "16k"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-python@v2
        with:
          python-version: 3.6
      - uses: actions/download-artifact@v2
        with:
          name: "ds_ctcdecoder-macOS-test.whl"
      - run: |
          python --version
          pip --version
      - run: |
          pip install --upgrade pip==19.3.1 setuptools==45.0.0 wheel==0.33.6
      - run: |
          pip install ds_ctcdecoder-*-cp36-cp36m-*_x86_64.whl
          DS_NODECODER=y pip install --upgrade .
      - run: |
          bits=""
          if [ "${{ matrix.bitrate }}" = "8k" ]; then
            bits=8000
          fi
          if [ "${{ matrix.bitrate }}" = "16k"  ]; then
            bits=16000
          fi

          # Easier to rename to that we can exercize the LDC93S1 importer code to
          # generate the CSV file.
          echo "Moving ${bits} to LDC93S1.wav"
          mv data/smoke_test/LDC93S1_pcms16le_1_${bits}.wav data/smoke_test/LDC93S1.wav

          ./bin/run-ci-ldc93s1_new.sh 249 ${bits}
          ./bin/run-ci-ldc93s1_tflite.sh ${bits}
      - run: |
          curl -vsSL https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/macOS.amd64.convert_graphdef_memmapped_format.xz | xz -d > /tmp/convert_graphdef_memmapped_format
          chmod +x /tmp/convert_graphdef_memmapped_format
          /tmp/convert_graphdef_memmapped_format --in_graph=/tmp/train/output_graph.pb --out_graph=/tmp/train/output_graph.pbmm
      - run: |
          tar -cf - \
            -C /tmp/ckpt/ . \
            | xz -9 -T0 > /tmp/checkpoint.tar.xz
      - run: |
          mkdir -p ${{ github.workspace }}/tmp/
          cp /tmp/train*/output_graph.* /tmp/checkpoint.tar.xz ${{ github.workspace }}/tmp/
      - run: |
          ls -hal /tmp/ ${{ github.workspace }}/tmp/
      - uses: actions/upload-artifact@v2
        with:
          name: "test-model.tf-${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/output_graph.pb*
      - uses: actions/upload-artifact@v2
        with:
          name: "test-model.tflite-${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/output_graph.tflite
      - uses: actions/upload-artifact@v2
        with:
          name: "test-checkpoint.${{ matrix.bitrate }}.zip"
          path: ${{ github.workspace }}/tmp/checkpoint.tar.xz
  tensorflow_opt-macOS:
    name: "Mac|Check TensorFlow cache"
    runs-on: ubuntu-20.04
    outputs:
      status: ${{ steps.check_artifact_exists.outputs.status }}
      cache_key: ${{ steps.get_cache_key.outputs.key }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - id: get_cache_key
        uses: ./.github/actions/get_cache_key
        with:
          extras: "2"
      - id: check_artifact_exists
        uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ steps.get_cache_key.outputs.key }}
  build-tensorflow-macOS:
    name: "Mac|Build TensorFlow (opt)"
    needs: tensorflow_opt-macOS
    runs-on: macos-10.15
    steps:
      - run: true
        if: needs.tensorflow_opt-macOS.outputs.status == 'found'
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          submodules: 'recursive'
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: ./.github/actions/select-xcode
        with:
          version: "12.1.1"
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: ./.github/actions/setup-tensorflow
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: ./.github/actions/build-tensorflow
        with:
          flavor: "--darwin-cpu"
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: ./.github/actions/package-tensorflow
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-macOS.outputs.cache_key }}
          path: ${{ github.workspace }}/artifacts/home.tar.xz
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
  build-lib_macOS:
    name: "Mac|Build libdeepspeech+client"
    runs-on: macos-10.15
    needs: [ build-tensorflow-macOS, tensorflow_opt-macOS ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-macOS.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-macOS.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-macOS.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-macOS.outputs.status == 'found'
      - run: |
          tar xkf ${{ github.workspace }}/home.tar.xz
          rm ${{ github.workspace }}/home.tar.xz
      - run: |
          git status
      - uses: ./.github/actions/select-xcode
        with:
          version: "12.1.1"
      - uses: ./.github/actions/host-build
        with:
          flavor: ${{ matrix.build-flavor }}
      - uses: ./.github/actions/package
      - uses: actions/upload-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.macOS.tar.xz"
          path: ${{ github.workspace }}/artifacts/native_client.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: "libdeepspeech.${{ matrix.build-flavor }}.zip"
          path: ${{ github.workspace }}/artifacts/libdeepspeech.zip
  build-python-macOS:
    name: "Mac|Build python bindings"
    runs-on: macos-10.15
    needs: [ build-lib_macOS, swig_macOS ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
        python-version: [3.6.8, 3.7.9, 3.8.8, 3.9.2]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.macOS.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_macOS"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: ./.github/actions/install-python-upstream
        with:
          version: ${{ matrix.python-version }}
      # GitHub packaged version are limited to macOS deployment target 10.14
      #- uses: actions/setup-python@v2
      #  with:
      #    python-version: ${{ matrix.python-version }}
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: ${{ matrix.python-version }}
      - uses: ./.github/actions/python-build
        with:
          build_flavor: ${{ matrix.build-flavor }}
          numpy_build: "${{ steps.get_numpy.outputs.build_version }}"
          numpy_dep: "${{ steps.get_numpy.outputs.dep_version }}"
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-macOS.whl"
          path: ${{ github.workspace }}/wheels/*.whl
  build-nodejs-macOS:
    name: "Mac|Build NodeJS and ElectronJS"
    runs-on: macos-10.15
    needs: [ build-lib_macOS, swig_macOS ]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.macOS.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_macOS"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/cache@v2
        id: node-headers-cache
        with:
          path: native_client/javascript/headers/nodejs/
          key: node-headers-10.0.0_16.0.0
      - uses: actions/cache@v2
        id: electron-headers-cache
        with:
          path: native_client/javascript/headers/electronjs/
          key: electron-headers-5.0.13_12.0.0
      - uses: ./.github/actions/node-build
        with:
          nodejs_versions: "10.0.0 11.0.0 12.7.0 13.0.0 14.0.0 15.0.0 16.0.0"
          electronjs_versions: "5.0.13 6.0.12 6.1.7 7.0.1 7.1.8 8.0.1 9.0.1 9.1.0 9.2.0 10.0.0 10.1.0 11.0.0 12.0.0"
      - uses: actions/upload-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-macOS_amd64.tar.gz"
          path: ${{ github.workspace }}/native_client/javascript/wrapper.tar.gz
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-macOS.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  test-cpp-macOS:
    name: "Mac|Test C++ binary"
    runs-on: macos-10.15
    needs: [ build-lib_macOS, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.macOS.tar.xz"
          path: ${{ env.CI_TMP_DIR }}
      - run: |
          cd ${{ env.CI_TMP_DIR }}
          mkdir ds && cd ds && tar xf ../native_client.tar.xz
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: ./.github/actions/run-tests
        with:
          runtime: "cpp"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-py-macOS:
    name: "Mac|Test Python bindings"
    runs-on: macos-10.15
    needs: [ build-python-macOS, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        python-version: [3.6.8, 3.7.9, 3.8.8, 3.9.2]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-macOS.whl"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          pip3 install --only-binary :all: --upgrade ${{ env.CI_TMP_DIR }}/deepspeech*.whl
      - uses: ./.github/actions/run-tests
        with:
          runtime: "python"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-nodejs-macOS:
    name: "Mac|Test NodeJS bindings"
    runs-on: macos-10.15
    needs: [ build-nodejs-macOS, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 12, 14, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-macOS.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ~/.npm/
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install --verbose ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          ls -hal node_modules/deepspeech* node_modules/.bin/
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs-macOS:
    name: "Mac|Test ElectronJS bindings"
    runs-on: macos-10.15
    needs: [ build-nodejs-macOS, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 6.1.7, 7.1.8, 8.0.1, 9.2.0, 10.1.0, 11.0.0, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-macOS.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ~/.npm/
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  # Windows jobs
  build-ctc-decoder-windows:
    name: "Win|Build CTC decoder Python package"
    needs: [swig_Windows_crosscompiled]
    runs-on: windows-2019
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            git
            make
      - uses: mozilla/msvc-dev-cmd@v1
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-python@v2
        with:
          python-version: 3.7.9
      - run: |
          python --version
          python -m pip --version
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Windows_crosscompiled"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          set -ex
          ls -hal native_client/ds-swig/bin
          ln -s ds-swig.exe native_client/ds-swig/bin/swig.exe
          chmod +x native_client/ds-swig/bin/ds-swig.exe native_client/ds-swig/bin/swig.exe
      - name: Remove /usr/bin/link conflicting with MSVC link.exe
        run: |
          rm /usr/bin/link
      - run: |
          make -C native_client/ctcdecode/ \
            NUM_PROCESSES=$(nproc) \
            bindings
      - uses: actions/upload-artifact@v2
        with:
          name: "ds_ctcdecoder-windows-test.whl"
          path: ${{ github.workspace }}/native_client/ctcdecode/dist/*.whl
      - run: |
          make -C native_client/ctcdecode clean-keep-third-party
  tensorflow_opt-Windows:
    name: "Win|Check TensorFlow cache"
    runs-on: ubuntu-20.04
    outputs:
      status: ${{ steps.check_artifact_exists.outputs.status }}
      cache_key: ${{ steps.get_cache_key.outputs.key }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - id: get_cache_key
        uses: ./.github/actions/get_cache_key
        with:
          extras: "7"
      - id: check_artifact_exists
        uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ steps.get_cache_key.outputs.key }}
  build-tensorflow-Windows:
    name: "Win|Build TensorFlow (opt)"
    needs: tensorflow_opt-Windows
    runs-on: windows-2019
    steps:
      - run: true
        if: needs.tensorflow_opt-Windows.outputs.status == 'found'
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            git
            patch
            tar
            unzip
            zip
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - uses: actions/setup-python@v2
        with:
          python-version: 3.7.9
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          submodules: 'recursive'
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      # It's important that this PATH change only happens *after* the checkout
      # above, because otherwise the checkout fails when persisisting the
      # credentials for submodules due to using MSYS2 Git
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - run: ./ci_scripts/tf-setup.sh
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - run: ./ci_scripts/tf-build.sh "--windows-cpu"
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - run: ./ci_scripts/tf-package.sh
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-Windows.outputs.cache_key }}
          path: ${{ github.workspace }}/artifacts/home.tar.xz
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
  build-lib_Windows:
    name: "Win|Build libdeepspeech+client"
    runs-on: windows-2019
    needs: [build-tensorflow-Windows, tensorflow_opt-Windows]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: mozilla/msvc-dev-cmd@v1
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          update: true
          install: >-
            git
            make
            patch
            pkg-config
            tar
            unzip
            zip
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-Windows.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-Windows.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-Windows.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-Windows.outputs.status == 'found'
      - run: |
          "C:/Program Files/7-Zip/7z.exe" x home.tar.xz -so | "C:/Program Files/7-Zip/7z.exe" x -aos -si -ttar -o`pwd`
          rm home.tar.xz
      - run: |
          git status
      - run: ./ci_scripts/host-build.sh ${{ matrix.build-flavor }}
      - run: ./ci_scripts/package.sh
      - uses: actions/upload-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Windows.tar.xz"
          path: ${{ github.workspace }}/artifacts/native_client.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: "libdeepspeech.${{ matrix.build-flavor }}.zip"
          path: ${{ github.workspace }}/artifacts/libdeepspeech.zip
  build-python-Windows:
    name: "Win|Build Python bindings"
    runs-on: windows-2019
    needs: [build-lib_Windows, swig_Windows_crosscompiled]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
        # Try to keep Python versions in sync with cached versions to speed things up:
        # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md
        python-version: [3.6.8, 3.7.9, 3.8.8, 3.9.4]
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            make
      - uses: mozilla/msvc-dev-cmd@v1
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Windows.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          pushd tensorflow/bazel-bin/native_client/
          "C:/Program Files/7-Zip/7z.exe" x native_client.tar.xz -so | "C:/Program Files/7-Zip/7z.exe" x -aoa -si -ttar -o`pwd`
          ls -hal
          popd
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Windows_crosscompiled"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          set -ex
          ls -hal native_client/ds-swig/bin
          ln -s ds-swig.exe native_client/ds-swig/bin/swig.exe
          chmod +x native_client/ds-swig/bin/ds-swig.exe native_client/ds-swig/bin/swig.exe
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Remove /usr/bin/link conflicting with MSVC link.exe
        run: |
          rm /usr/bin/link
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: ${{ matrix.python-version }}
      - uses: ./.github/actions/python-build
        with:
          build_flavor: ${{ matrix.build-flavor }}
          numpy_build: "${{ steps.get_numpy.outputs.build_version }}"
          numpy_dep: "${{ steps.get_numpy.outputs.dep_version }}"
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-Windows.whl"
          path: ${{ github.workspace }}/wheels/*.whl
  build-nodejs-Windows:
    name: "Win|Build NodeJS/ElectronJS"
    runs-on: windows-2019
    needs: [build-lib_Windows, swig_Windows_crosscompiled]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            make
            tar
      - uses: mozilla/msvc-dev-cmd@v1
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Windows.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          pushd tensorflow/bazel-bin/native_client/
          "C:/Program Files/7-Zip/7z.exe" x native_client.tar.xz -so | "C:/Program Files/7-Zip/7z.exe" x -aoa -si -ttar -o`pwd`
          ls -hal
          popd
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Windows_crosscompiled"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          set -ex
          ls -hal native_client/ds-swig/bin
          ln -s ds-swig.exe native_client/ds-swig/bin/swig.exe
          chmod +x native_client/ds-swig/bin/ds-swig.exe native_client/ds-swig/bin/swig.exe
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/cache@v2
        id: node-headers-cache
        with:
          path: native_client/javascript/headers/nodejs/
          key: node-headers-win-10.0.0_16.0.0
      - uses: actions/cache@v2
        id: electron-headers-cache
        with:
          path: native_client/javascript/headers/electronjs/
          key: electron-headers-win-5.0.13_12.0.0
      - uses: ./.github/actions/node-build
        with:
          nodejs_versions: "10.0.0 11.0.0 12.7.0 13.0.0 14.0.0 15.0.0 16.0.0"
          electronjs_versions: "5.0.13 6.0.12 6.1.7 7.0.1 7.1.8 8.0.1 9.0.1 9.1.0 9.2.0 10.0.0 10.1.0 11.0.0 12.0.0"
      - uses: actions/upload-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Windows_amd64.tar.gz"
          path: ${{ github.workspace }}/native_client/javascript/wrapper.tar.gz
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Windows.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  test-cpp-Windows:
    name: "Win|Test C++ binary"
    runs-on: windows-2019
    needs: [build-lib_Windows, train-test-model-Linux]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - name: Download native_client.tar.xz
        uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.Windows.tar.xz"
          path: ${{ env.CI_TMP_DIR }}
      - name: Extract native_client.tar.xz
        run: |
          mkdir -p ${{ env.CI_TMP_DIR }}/ds
          pushd ${{ env.CI_TMP_DIR }}/ds
          "C:/Program Files/7-Zip/7z.exe" x ../native_client.tar.xz -so | "C:/Program Files/7-Zip/7z.exe" x -aoa -si -ttar -o`pwd`
          ls -hal
          popd
      - name: Download trained test model
        uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-16k.zip"
          path: ${{ env.CI_TMP_DIR }}
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
      - uses: ./.github/actions/run-tests
        with:
          runtime: "cppwin"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: "16k"
          model-kind: ""
  test-py-Windows:
    name: "Win|Test Python bindings"
    runs-on: windows-2019
    needs: [ build-python-Windows, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # Try to keep Python versions in sync with cached versions to speed things up:
        # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md
        python-version: [3.6.8, 3.7.9, 3.8.8, 3.9.4]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - uses: ./.github/actions/win-install-sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-Windows.whl"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          python -m pip install --only-binary :all: --upgrade ${{ env.CI_TMP_DIR }}/deepspeech*.whl
      - uses: ./.github/actions/run-tests
        with:
          runtime: "python"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-nodejs-Windows:
    name: "Win|Test NodeJS bindings"
    runs-on: windows-2019
    needs: [ build-nodejs-Windows, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        nodejs-version: [10, 12, 14, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - uses: ./.github/actions/win-install-sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Windows.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - name: Get npm cache directory
        id: npm-cache-dir
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs-Windows:
    name: "Win|Test ElectronJS bindings"
    runs-on: windows-2019
    needs: [ build-nodejs-Windows, train-test-model-Linux ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 6.1.7, 7.1.8, 8.0.1, 9.2.0, 10.1.0, 11.0.0, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: ./.github/actions/win-install-sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-Windows.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Get npm cache directory
        id: npm-cache-dir
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  # Shared jobs (multi-platform dependencies)
  repackage-nodejs-allplatforms:
    name: "Repackage NodeJS / ElectronJS for multiplatforms"
    runs-on: ubuntu-20.04
    needs: [build-nodejs-macOS, build-nodejs-Windows, build-nodejs-Linux, build-nodejs-LinuxArmv7, build-nodejs-LinuxAarch64]
    strategy:
      matrix:
        build-flavor: ["tf", "tflite"]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - run: |
          mkdir -p /tmp/nodewrapper-${{ matrix.build-flavor }}-macOS_amd64/
          mkdir -p /tmp/nodewrapper-${{ matrix.build-flavor }}-Windows_amd64/
      - uses: actions/download-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-macOS_amd64.tar.gz"
          path: /tmp/nodewrapper-macOS_amd64/
      - uses: actions/download-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Windows_amd64.tar.gz"
          path: /tmp/nodewrapper-Windows_amd64/
      - uses: actions/download-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_amd64.tar.gz"
          path: /tmp/nodewrapper-Linux_amd64/
      - uses: actions/download-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_armv7.tar.gz"
          path: /tmp/nodewrapper-Linux_armv7/
        if: matrix.build-flavor == 'tflite'
      - uses: actions/download-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_aarch64.tar.gz"
          path: /tmp/nodewrapper-Linux_aarch64/
        if: matrix.build-flavor == 'tflite'
      - name: Extract nodewrapper archives
        run: |
          tar -C ${{ github.workspace }}/native_client/javascript -xzvf /tmp/nodewrapper-macOS_amd64/wrapper.tar.gz
          tar -C ${{ github.workspace }}/native_client/javascript -xzvf /tmp/nodewrapper-Windows_amd64/wrapper.tar.gz
          tar -C ${{ github.workspace }}/native_client/javascript -xzvf /tmp/nodewrapper-Linux_amd64/wrapper.tar.gz
      - name: Extract nodewrapper tflite-only archives
        run: |
          tar -C ${{ github.workspace }}/native_client/javascript -xzvf /tmp/nodewrapper-Linux_armv7/wrapper.tar.gz
          tar -C ${{ github.workspace }}/native_client/javascript -xzvf /tmp/nodewrapper-Linux_aarch64/wrapper.tar.gz
        if: matrix.build-flavor == 'tflite'
      - run: |
          PROJECT_NAME="deepspeech"
          if [ "${{ matrix.build-flavor }}" = "tflite" ]; then
            PROJECT_NAME="deepspeech-tflite"
          fi
          make -C native_client/javascript clean npm-pack PROJECT_NAME=$PROJECT_NAME
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  test-nodejs_all-Linux:
    name: "Lin|Test MultiArchPlatform NodeJS bindings"
    runs-on: ubuntu-20.04
    needs: [repackage-nodejs-allplatforms, train-test-model-Linux]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - run: |
          sudo apt-get install -y --no-install-recommends sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ~/.npm/
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install --verbose ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          ls -hal node_modules/deepspeech* node_modules/.bin/
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs_all-Linux:
    name: "Lin|Test MultiArchPlatform ElectronJS bindings"
    runs-on: ubuntu-20.04
    needs: [repackage-nodejs-allplatforms, train-test-model-Linux]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - run: |
          sudo apt-get install -y --no-install-recommends sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ~/.npm/
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  test-nodejs_all-macOS:
    name: "Mac|Test MultiArchPlatform NodeJS bindings"
    runs-on: macos-10.15
    needs: [ repackage-nodejs-allplatforms, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ~/.npm/
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install --verbose ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          ls -hal node_modules/deepspeech* node_modules/.bin/
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs_all-macOS:
    name: "Mac|Test MultiArchPlatform ElectronJS bindings"
    runs-on: macos-10.15
    needs: [ repackage-nodejs-allplatforms, train-test-model-macOS ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ~/.npm/
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  test-nodejs_all-Windows:
    name: "Win|Test MultiArchPlatform NodeJS bindings"
    runs-on: windows-2019
    needs: [repackage-nodejs-allplatforms, train-test-model-Linux]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 16]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.nodejs-version }}
      - uses: ./.github/actions/win-install-sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - name: Get npm cache directory
        id: npm-cache-dir
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v2
        id: node-modules-cache
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: node-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs_all-Windows:
    name: "Win|Test MultiArchPlatform ElectronJS bindings"
    runs-on: windows-2019
    needs: [repackage-nodejs-allplatforms, train-test-model-Linux]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        electronjs-version: [5.0.13, 12.0.0]
        build-flavor: ["tf", "tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: tmp/
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
    steps:
      - name: Switch git-bash shell to MSYS2 shell by adding MSYS2 path to PATH front
        run: echo "$MSYS2_SHELL_PATH" >> $GITHUB_PATH
      - uses: mozilla/setup-msys2@v2
        with:
          msystem: MSYS
          path-type: inherit
          update: true
          install: >-
            vim
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: ./.github/actions/win-install-sox
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}.tgz"
          path: ${{ env.CI_TMP_DIR }}
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: Get npm cache directory
        id: npm-cache-dir
        run: |
          echo "::set-output name=dir::$(npm config get cache)"
      - uses: actions/cache@v2
        id: electron-modules-cache
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: electron-modules-${{ matrix.build-flavor }}-${{ runner.os }}-${{ env.CI_NODE_MODULES_NTH }}
      - name: Install deepspeech package
        run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          npm install ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          npm install electron@${{ matrix.electronjs-version }}
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
  # Linux Armv7 and Aarch64 jobs
  tensorflow_opt-LinuxArmv7:
    name: "LinArmv7|Check TensorFlow cache"
    runs-on: ubuntu-20.04
    outputs:
      status: ${{ steps.check_artifact_exists.outputs.status }}
      cache_key: ${{ steps.get_cache_key.outputs.key }}
    strategy:
      matrix:
        arch: [ "armv7" ]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - id: get_cache_key
        uses: ./.github/actions/get_cache_key
        with:
          extras: "0"
      - id: check_artifact_exists
        uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ steps.get_cache_key.outputs.key }}
  tensorflow_opt-LinuxAarch64:
    name: "LinAarch64|Check TensorFlow cache"
    runs-on: ubuntu-20.04
    outputs:
      status: ${{ steps.check_artifact_exists.outputs.status }}
      cache_key: ${{ steps.get_cache_key.outputs.key }}
    strategy:
      matrix:
        arch: [ "aarch64" ]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - id: get_cache_key
        uses: ./.github/actions/get_cache_key
        with:
          extras: "0"
      - id: check_artifact_exists
        uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ steps.get_cache_key.outputs.key }}
  build-tensorflow-LinuxArmv7:
    name: "LinArmv7|Build TensorFlow (opt)"
    needs: tensorflow_opt-LinuxArmv7
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        arch: [ "armv7" ]
    steps:
      - run: true
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'found'
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          submodules: 'recursive'
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/setup-tensorflow
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/build-tensorflow
        with:
          flavor: "--linux-${{ matrix.arch }}"
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/package-tensorflow
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/artifacts/home.tar.xz
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
  build-tensorflow-LinuxAarch64:
    name: "LinAarch64|Build TensorFlow (opt)"
    needs: tensorflow_opt-LinuxAarch64
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        arch: [ "aarch64" ]
    steps:
      - run: true
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'found'
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
          submodules: 'recursive'
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/setup-tensorflow
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/build-tensorflow
        with:
          flavor: "--linux-${{ matrix.arch }}"
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/package-tensorflow
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: actions/upload-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/artifacts/home.tar.xz
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
  build-lib_LinuxArmv7:
    name: "LinArmv7|Build libdeepspeech+client"
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        build-flavor: ["tflite"]
        arch: [ "armv7" ]
    needs: [ build-tensorflow-LinuxArmv7, tensorflow_opt-LinuxArmv7 ]
    env:
      SYSTEM_TARGET: rpi3
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-raspbian-buster
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - run: |
          git status
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - uses: ./.github/actions/host-build
        with:
          arch: ${{ matrix.arch }}
          flavor: ${{ matrix.build-flavor }}
      - uses: ./.github/actions/package
      - uses: actions/upload-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/artifacts/native_client.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: "libdeepspeech.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.zip"
          path: ${{ github.workspace }}/artifacts/libdeepspeech.zip
  build-lib_LinuxAarch64:
    name: "LinAarch64|Build libdeepspeech+client"
    runs-on: ubuntu-20.04
    strategy:
      matrix: 
        build-flavor: ["tflite"]
        arch: [ "aarch64" ]
    needs: [ build-tensorflow-LinuxAarch64, tensorflow_opt-LinuxAarch64 ]
    env:
      SYSTEM_TARGET: rpi3-armv8
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-armbian64-buster
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - run: |
          git status
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - uses: ./.github/actions/host-build
        with:
          arch: ${{ matrix.arch }}
          flavor: ${{ matrix.build-flavor }}
      - uses: ./.github/actions/package
      - uses: actions/upload-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/artifacts/native_client.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: "libdeepspeech.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.zip"
          path: ${{ github.workspace }}/artifacts/libdeepspeech.zip
  build-python-LinuxArmv7:
    name: "LinArmv7|Build python bindings"
    runs-on: ubuntu-20.04
    needs: [ build-lib_LinuxArmv7, swig_Linux, tensorflow_opt-LinuxArmv7 ]
    strategy:
      matrix:
        build-flavor: ["tflite"]
        python-version: [3.7]
        arch: [ "armv7" ]
    env:
      DEBIAN_FRONTEND: "noninteractive"
      SYSTEM_TARGET: rpi3
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-raspbian-buster
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - uses: ./.github/actions/install-xldd
        with:
          target: ${{ env.SYSTEM_TARGET }}
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: ${{ matrix.python-version }}
      - uses: ./.github/actions/python-build
        with:
          build_flavor: ${{ matrix.build-flavor }}
          numpy_build: "${{ steps.get_numpy.outputs.build_version }}"
          numpy_dep: "${{ steps.get_numpy.outputs.dep_version }}"
          target: ${{ env.SYSTEM_TARGET }}
          chroot: ${{ env.SYSTEM_RASPBIAN }}
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-${{ matrix.arch }}.whl"
          path: ${{ github.workspace }}/wheels/*.whl
  build-nodejs-LinuxArmv7:
    name: "LinArmv7|Build NodeJS and ElectronJS"
    runs-on: ubuntu-20.04
    needs: [ build-lib_LinuxArmv7, swig_Linux, tensorflow_opt-LinuxArmv7 ]
    strategy:
      matrix:
        build-flavor: ["tflite"]
        arch: [ "armv7" ]
    env:
      SYSTEM_TARGET: rpi3
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-raspbian-buster
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxArmv7.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxArmv7.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - uses: ./.github/actions/install-xldd
        with:
          target: ${{ env.SYSTEM_TARGET }}
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/cache@v2
        id: node-headers-cache
        with:
          path: native_client/javascript/headers/nodejs/
          key: node-headers-10.0.0_15.0.0
      - uses: actions/cache@v2
        id: electron-headers-cache
        with:
          path: native_client/javascript/headers/electronjs/
          key: electron-headers-5.0.13_12.0.0
      - uses: ./.github/actions/node-build
        with:
          nodejs_versions: "10.0.0 11.0.0 12.7.0 13.0.0 14.0.0 15.0.0"
          electronjs_versions: "5.0.13 6.0.12 6.1.7 7.0.1 7.1.8 8.0.1 9.0.1 9.1.0 9.2.0 10.0.0 10.1.0 11.0.0 12.0.0"
          target: ${{ env.SYSTEM_TARGET }}
          chroot: ${{ env.SYSTEM_RASPBIAN }}
      - uses: actions/upload-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_${{ matrix.arch }}.tar.gz"
          path: ${{ github.workspace }}/native_client/javascript/wrapper.tar.gz
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-${{ matrix.arch }}.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  build-python-LinuxAarch64:
    name: "LinAarch64|Build python bindings"
    runs-on: ubuntu-20.04
    needs: [ build-lib_LinuxAarch64, swig_Linux, tensorflow_opt-LinuxAarch64 ]
    strategy:
      matrix:
        build-flavor: ["tflite"]
        python-version: [3.7]
        arch: [ "aarch64" ]
    env:
      DEBIAN_FRONTEND: "noninteractive"
      SYSTEM_TARGET: rpi3-armv8
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-armbian64-buster
    steps:
      - run: |
          sudo apt-get install -y --no-install-recommends
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - uses: ./.github/actions/install-xldd
        with:
          target: ${{ env.SYSTEM_TARGET }}
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - id: get_numpy
        uses: ./.github/actions/numpy_vers
        with:
          pyver: ${{ matrix.python-version }}
      - uses: ./.github/actions/python-build
        with:
          build_flavor: ${{ matrix.build-flavor }}
          numpy_build: "${{ steps.get_numpy.outputs.build_version }}"
          numpy_dep: "${{ steps.get_numpy.outputs.dep_version }}"
          target: ${{ env.SYSTEM_TARGET }}
          chroot: ${{ env.SYSTEM_RASPBIAN }}
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-${{ matrix.arch }}.whl"
          path: ${{ github.workspace }}/wheels/*.whl
  build-nodejs-LinuxAarch64:
    name: "LinAarch64|Build NodeJS and ElectronJS"
    runs-on: ubuntu-20.04
    needs: [ build-lib_LinuxAarch64, swig_Linux, tensorflow_opt-LinuxAarch64 ]
    strategy:
      matrix:
        build-flavor: ["tflite"]
        arch: [ "aarch64" ]
    env:
      SYSTEM_TARGET: rpi3-armv8
      SYSTEM_RASPBIAN: ${{ github.workspace }}/multistrap-armbian64-buster
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
      - run: |
          cd ${{ github.workspace }}/tensorflow/bazel-bin/native_client/
          tar xf native_client.tar.xz
          ls -hal
          cd ${{ github.workspace }}/
      - uses: actions/download-artifact@v2
        with:
          name: "swig_Linux"
          path: ${{ github.workspace }}/native_client/ds-swig/
      - name: Link ds-swig into swig
        run: |
          ls -hal ${{ github.workspace }}/native_client/ds-swig/bin
          ln -s ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
          chmod +x ${{ github.workspace }}/native_client/ds-swig/bin/ds-swig ${{ github.workspace }}/native_client/ds-swig/bin/swig
      - uses: actions/download-artifact@v2
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'missing'
      - uses: ./.github/actions/check_artifact_exists
        with:
          name: ${{ needs.tensorflow_opt-LinuxAarch64.outputs.cache_key }}
          path: ${{ github.workspace }}/
          download: true
        if: needs.tensorflow_opt-LinuxAarch64.outputs.status == 'found'
      - run: |
          tar -xf ${{ github.workspace }}/home.tar.xz --skip-old-files
          rm ${{ github.workspace }}/home.tar.xz
      - uses: ./.github/actions/install-xldd
        with:
          target: ${{ env.SYSTEM_TARGET }}
      - name: "Install chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
      - uses: actions/setup-node@v2
        with:
          node-version: 12
      - uses: actions/cache@v2
        id: node-headers-cache
        with:
          path: native_client/javascript/headers/nodejs/
          key: node-headers-10.0.0_15.0.0
      - uses: actions/cache@v2
        id: electron-headers-cache
        with:
          path: native_client/javascript/headers/electronjs/
          key: electron-headers-5.0.13_12.0.0
      - uses: ./.github/actions/node-build
        with:
          nodejs_versions: "10.0.0 11.0.0 12.7.0 13.0.0 14.0.0 15.0.0"
          electronjs_versions: "5.0.13 6.0.12 6.1.7 7.0.1 7.1.8 8.0.1 9.0.1 9.1.0 9.2.0 10.0.0 10.1.0 11.0.0 12.0.0"
          target: ${{ env.SYSTEM_TARGET }}
          chroot: ${{ env.SYSTEM_RASPBIAN }}
      - uses: actions/upload-artifact@v2
        with:
          name: "nodewrapper-${{ matrix.build-flavor }}-Linux_${{ matrix.arch }}.tar.gz"
          path: ${{ github.workspace }}/native_client/javascript/wrapper.tar.gz
      - uses: actions/upload-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-${{ matrix.arch }}.tgz"
          path: ${{ github.workspace }}/native_client/javascript/deepspeech-*.tgz
  build-test-chroot:
    name: "Lin|Build test chroot"
    runs-on: ubuntu-20.04
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        arch: [ "armv7", "aarch64" ]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp
      DEBIAN_FRONTEND: "noninteractive"
      SYSTEM_RASPBIAN: ${{ github.workspace }}/chroot-${{ matrix.arch }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - name: "Install and setup chroot"
        uses: ./.github/actions/multistrap
        with:
          arch: ${{ matrix.arch }}
          packages: "bash wget curl sox xxd libatlas3-base libopenblas-base ca-certificates python3 python3-pip gnupg libatk1.0-0 libatk-bridge2.0-0 libcairo2 libcups2 libdbus-1-3 libgdk-pixbuf2.0-0 libgtk-3-0 libgbm1 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libx11-xcb1 libxcb-dri3-0 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 xauth"
      - name: "Create a chroot tarball"
        run: |
          sudo tar -cf - -C ${{ env.SYSTEM_RASPBIAN }}/ --one-file-system . | xz -9 -T0 > ${{ github.workspace }}/chroot.tar.xz
      - uses: actions/upload-artifact@v2
        with:
          name: chroot-${{ matrix.arch }}
          path: ${{ github.workspace }}/chroot.tar.xz
  test-cpp-LinuxArm:
    name: "LinArm*|Test C++ binary"
    runs-on: ubuntu-20.04
    needs: [ build-lib_LinuxArmv7, build-lib_LinuxAarch64, train-test-model-Linux, build-test-chroot ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        arch: [ "armv7", "aarch64" ]
        build-flavor: ["tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp
      DEBIAN_FRONTEND: "noninteractive"
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
      SYSTEM_RASPBIAN: ${{ github.workspace }}/chroot-${{ matrix.arch }}
    steps:
      - name: "Install QEMU"
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends qemu-user-static
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "chroot-${{ matrix.arch }}"
          path: ${{ env.CI_TMP_DIR }}/
      - run: |
          mkdir ${{ env.SYSTEM_RASPBIAN }}/
          sudo tar -xf ${{ env.CI_TMP_DIR }}/chroot.tar.xz -C ${{ env.SYSTEM_RASPBIAN }}/
          rm ${{ env.CI_TMP_DIR }}/chroot.tar.xz
      - uses: actions/download-artifact@v2
        with:
          name: "native_client.${{ matrix.build-flavor }}.linux.${{ matrix.arch }}.tar.xz"
          path: ${{ env.CI_TMP_DIR }}/
      - run: |
          cd ${{ env.CI_TMP_DIR }}/
          mkdir ds && cd ds && tar xf ../native_client.tar.xz
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - name: "Check tests"
        run: |
          file ${{ env.SYSTEM_RASPBIAN }}/${{ env.CI_TMP_DIR }}/ds/*
      - uses: ./.github/actions/chroot-bind-mount
        with:
          mounts: "/dev"
      - uses: ./.github/actions/run-tests
        with:
          runtime: "cpp"
          chroot: "sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ${{ github.workspace }}"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-py-LinuxArm:
    name: "LinArm*|Test Python bindings"
    runs-on: ubuntu-20.04
    needs: [ build-python-LinuxArmv7, build-python-LinuxAarch64, train-test-model-Linux, build-test-chroot ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        arch: [ "armv7", "aarch64" ]
        python-version: [3.7]
        build-flavor: ["tflite"]
        models: ["test", "prod"]
        bitrate: ["8k", "16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp
      DEBIAN_FRONTEND: "noninteractive"
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
      SYSTEM_RASPBIAN: ${{ github.workspace }}/chroot-${{ matrix.arch }}
      PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple https://lissyx.github.io/deepspeech-python-wheels/"
    steps:
      - name: "Install QEMU"
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends qemu-user-static
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "chroot-${{ matrix.arch }}"
          path: ${{ env.CI_TMP_DIR }}/
      - run: |
          mkdir ${{ env.SYSTEM_RASPBIAN }}/
          sudo tar -xf ${{ env.CI_TMP_DIR }}/chroot.tar.xz -C ${{ env.SYSTEM_RASPBIAN }}/
          rm ${{ env.CI_TMP_DIR }}/chroot.tar.xz
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech-${{ matrix.build-flavor }}-${{ matrix.python-version }}-${{ matrix.arch }}.whl"
          path: ${{ env.CI_TMP_DIR }}/
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: ./.github/actions/chroot-bind-mount
        with:
          mounts: "/dev"
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
          ls -hal ${{ github.workspace }}/
          ls -hal ${{ env.SYSTEM_RASPBIAN }}/${{ github.workspace }}/
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ pip3 install --only-binary :all: --upgrade ${{ env.CI_TMP_DIR }}/deepspeech*.whl
      - uses: ./.github/actions/run-tests
        with:
          runtime: "python"
          chroot: "sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ${{ github.workspace }}"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-nodejs-LinuxArm:
    name: "LinArm*|Test NodeJS bindings"
    runs-on: ubuntu-20.04
    needs: [ build-nodejs-LinuxArmv7, build-nodejs-LinuxAarch64, train-test-model-Linux, build-test-chroot ]
    if: ${{ github.event_name == 'pull_request' }}
    strategy:
      matrix:
        arch: [ "armv7", "aarch64" ]
        # https://nodejs.org/en/about/releases/
        nodejs-version: [10, 12, 14, 16]
        build-flavor: ["tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp
      DEBIAN_FRONTEND: "noninteractive"
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
      SYSTEM_RASPBIAN: ${{ github.workspace }}/chroot-${{ matrix.arch }}
    steps:
      - name: "Install QEMU"
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends qemu-user-static
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "chroot-${{ matrix.arch }}"
          path: ${{ env.CI_TMP_DIR }}/
      - run: |
          mkdir ${{ env.SYSTEM_RASPBIAN }}/
          sudo tar -xf ${{ env.CI_TMP_DIR }}/chroot.tar.xz -C ${{ env.SYSTEM_RASPBIAN }}/
          rm ${{ env.CI_TMP_DIR }}/chroot.tar.xz
      - name: "Install NodeJS"
        uses: ./.github/actions/node-install
        with:
          node: ${{ matrix.nodejs-version }}
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-${{ matrix.arch }}.tgz"
          path: ${{ env.CI_TMP_DIR }}/
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: ./.github/actions/chroot-bind-mount
        with:
          mounts: "/dev"
      - name: Install deepspeech package
        run: |
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ npm install --prefix ${{ github.workspace }}/ --verbose ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - uses: ./.github/actions/run-tests
        with:
          runtime: "node"
          chroot: "sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ${{ github.workspace }}"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
  test-electronjs-LinuxArm:
    name: "LinArm*|Test ElectronJS bindings"
    runs-on: ubuntu-20.04
    needs: [ build-nodejs-LinuxArmv7, build-nodejs-LinuxAarch64, train-test-model-Linux, build-test-chroot ]
    # Disable this task because it seems qemu does not work super-well with ElectronJS
    if: ${{ github.event_name == 'disabled' }}
    strategy:
      matrix:
        arch: [ "armv7", "aarch64" ]
        electronjs-version: [5.0.13, 6.1.7, 7.1.8, 8.0.1, 9.2.0, 10.1.0, 11.0.0, 12.0.0]
        build-flavor: ["tflite"]
        models: ["test"]
        bitrate: ["16k"]
    env:
      CI_TMP_DIR: ${{ github.workspace }}/tmp
      DEBIAN_FRONTEND: "noninteractive"
      DEEPSPEECH_PROD_MODEL: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pb
      DEEPSPEECH_PROD_MODEL_MMAP: https://github.com/reuben/DeepSpeech/releases/download/v0.7.0-alpha.3/output_graph.pbmm
      DEEPSPEECH_TEST_MODEL: ${{ github.workspace }}/tmp/output_graph.pb
      EXPECTED_TENSORFLOW_VERSION: "TensorFlow: v2.3.0-6-g23ad988"
      SYSTEM_RASPBIAN: ${{ github.workspace }}/chroot-${{ matrix.arch }}
      DISPLAY: ":99.0"
    steps:
      - name: "Install QEMU"
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends qemu-user-static xvfb xauth
      - uses: actions/checkout@v2
        with:
          fetch-depth: 1
      - uses: actions/download-artifact@v2
        with:
          name: "chroot-${{ matrix.arch }}"
          path: ${{ env.CI_TMP_DIR }}/
      - run: |
          mkdir ${{ env.SYSTEM_RASPBIAN }}/
          sudo tar -xf ${{ env.CI_TMP_DIR }}/chroot.tar.xz -C ${{ env.SYSTEM_RASPBIAN }}/
          rm ${{ env.CI_TMP_DIR }}/chroot.tar.xz
      - name: "Install NodeJS"
        uses: ./.github/actions/node-install
        with:
          node: 12
      - uses: actions/download-artifact@v2
        with:
          name: "deepspeech_intermediate-${{ matrix.build-flavor }}-${{ matrix.arch }}.tgz"
          path: ${{ env.CI_TMP_DIR }}/
      - uses: actions/download-artifact@v2
        with:
          name: "test-model.${{ matrix.build-flavor }}-${{ matrix.bitrate }}.zip"
          path: ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - run: |
          ls -hal ${{ env.CI_TMP_DIR }}/
        if: matrix.models == 'test'
      - uses: ./.github/actions/chroot-bind-mount
        with:
          mounts: "/dev /proc /sys /run"
      - name: Install deepspeech package
        run: |
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ npm install --prefix ${{ github.workspace }}/ ${{ env.CI_TMP_DIR }}/deepspeech*.tgz
      - run: |
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ npm install --prefix ${{ github.workspace }}/ electron@${{ matrix.electronjs-version }}
      - name: "Fake X display"
        run: |
          sudo Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
          xvfb_process=$!
          echo $xvfb_process > ${{ env.CI_TMP_DIR }}/xvfb.pid
          cat ${{ env.CI_TMP_DIR }}/xvfb.pid
      - name: "Debug missing libs"
        run: |
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ls -hal ${{ github.workspace }}/node_modules/electron/dist/electron
          sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ldd ${{ github.workspace }}/node_modules/electron/dist/electron
      - uses: ./.github/actions/run-tests
        with:
          runtime: "electronjs"
          chroot: "sudo --preserve-env chroot --userspec=runner:docker ${{ env.SYSTEM_RASPBIAN }}/ ${{ github.workspace }}"
          build-flavor: ${{ matrix.build-flavor }}
          bitrate: ${{ matrix.bitrate }}
          model-kind: ${{ matrix.models }}
        timeout-minutes: 5
      - name: "Kill X"
        run: |
          cat ${{ env.CI_TMP_DIR }}/xvfb.pid
          sudo kill -9 $(cat ${{ env.CI_TMP_DIR }}/xvfb.pid)
