<NME> build.yml
<BEF> name: Build

on: [push, pull_request]

jobs:
  client:
    strategy:
      matrix:
        node-version:
          - '16.x'
        os:
          - 'ubuntu-latest'
          - 'windows-latest'
          - 'macos-latest'
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - uses: actions/cache@v2
      with:
        path: "**/node_modules"
        key: ${{ runner.os }}-${{ matrix.node-version }}-node_modules-${{ hashFiles('**/package-lock.json') }}
    - run: npm install
    - name: Typecheck with TypeScript
      run: npm run typecheck
    - name: Build client bundles
      run: npm run build --no-typecheck
    - name: Build JavaScript module
      run: npm run build-module --no-typecheck
    - name: Build Python client bundles
      run: npm run build-python --no-typecheck
    - run: sudo apt-get install xvfb
      if: startsWith(runner.os, 'Linux')
    - name: Run JavaScript tests (including WebGL)
      # Swiftshader, used by Chrome headless, crashes when running Neuroglancer
      # tests.
      #
      # The only reliable headless configuration is Firefox on Linux under
      # xvfb-run, which uses Mesa software rendering.
      if: startsWith(runner.os, 'Linux')
      run: xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' npm run test -- --browsers Firefox
    - name: Run JavaScript tests (excluding WebGL)
      if: ${{ !startsWith(runner.os, 'Linux') }}
      run: npm run test -- --browsers ChromeHeadless --define=NEUROGLANCER_SKIP_WEBGL_TESTS
    - name: Run JavaScript benchmarks
      run: npm run benchmark

  # Builds Python package and runs Python tests
  #
  # On ubuntu-latest, this also runs browser-based tests.  On Mac OS and
  # Windows, this only runs tests that do not require a browser, since a working
  # headless WebGL2 implementation is not available on Github actions.
  python-tox:
    strategy:
      matrix:
        python-version:
          - '3.7'
          - '3.8'
          - '3.9'
        node-version:
          - '16.x'
        os:
          - 'ubuntu-latest'
          - 'windows-latest'
          - 'macos-latest'
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
      with:
        # Need full history to determine version number.
        fetch-depth: 0
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - uses: actions/cache@v2
      with:
        path: "**/node_modules"
        key: ${{ runner.os }}-${{ matrix.node-version }}-node_modules-${{ hashFiles('**/package-lock.json') }}
    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "::set-output name=dir::$(pip cache dir)"          
    - uses: actions/cache@v2
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('setup.py') }}
    # Uncomment the action below for an interactive shell
    # - name: Setup tmate session
    #   uses: mxschmitt/action-tmate@v3
    - run: npm install
    - run: npm run build-python -- --no-typecheck
    - name: Install Python packaging/test tools
      run: python -m pip install --upgrade pip tox wheel numpy pytest
    - run: sudo apt-get install xvfb
      if: ${{ startsWith(runner.os, 'Linux') }}
    - name: Test with tox
      run: tox -e ${{ fromJSON('["skip-browser-tests","firefox-xvfb"]')[runner.os == 'Linux'] }}
      env:
        TOX_TESTENV_PASSENV: GH_TOKEN
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    # Verify that editable install works
    - name: Install in editable form
      run: pip install -e .
    - name: Run tests against editable install
      working-directory: python/tests
      run: pytest -vv --skip-browser-tests

  python-build-package:
    strategy:
      matrix:
        include:
        - os: 'ubuntu-latest'
          cibw_build: '*'
          wheel_identifier: 'linux'
          node-version: '16.x'
        - os: 'windows-latest'
          cibw_build: '*'
          wheel_identifier: 'windows'
          node-version: '16.x'
        - os: 'macos-latest'
          cibw_build: '*_x86_64'
          wheel_identifier: 'macos_x86_64'
          node-version: '16.x'
        - os: 'macos-latest'
          cibw_build: '*_arm64'
          wheel_identifier: 'macos_arm64'
          node-version: '16.x'
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
      with:
        # Need full history to determine version number.
        fetch-depth: 0
    - name: Use Node.js
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: 3.x
    - uses: actions/cache@v2
      with:
        path: "**/node_modules"
        key: ${{ runner.os }}-${{ matrix.node-version }}-node_modules-${{ hashFiles('**/package-lock.json') }}
    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "::set-output name=dir::$(pip cache dir)"          
    - uses: actions/cache@v2
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: ${{ runner.os }}-buildwheel-${{ hashFiles('setup.py') }}
    - run: npm install
    - run: npm run build-python -- --no-typecheck
    - name: Check for dirty working directory
      run: git diff --exit-code
    - name: Build Python source distribution (sdist)
      run: python setup.py sdist --format gztar
      if: ${{ runner.os == 'Linux' }}
    - name: Install cibuildwheel
      run: pip install cibuildwheel
    - name: Build Python wheels
      run: bash -xve ./python/build_tools/cibuildwheel.sh
      env:
        # On Linux, share pip cache with manylinux docker containers
        CIBW_ENVIRONMENT_LINUX: PIP_CACHE_DIR=/host${{ steps.pip-cache.outputs.dir }}
        CIBW_BEFORE_ALL_LINUX: /project/python/build_tools/cibuildwheel_linux_cache_setup.sh /host${{ steps.pip-cache.outputs.dir }}
        CIBW_BUILD: ${{ matrix.cibw_build }}
    - name: Upload wheels as artifacts
      uses: actions/upload-artifact@v2
      with:
        name: python-wheels-${{ matrix.wheel_identifier }}
        path: |
          dist/*.whl
          dist/*.tar.gz

  python-publish-package:
    # Only publish package on push to tag or default branch.
    if: ${{ github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') }}
    runs-on: ubuntu-latest
    needs:
    #   with:
    #     user: __token__
    #     password: ${{ secrets.pypi_test_token }}
    # - name: Publish to PyPI (main server)
    #   uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
    #   with:
    #     user: __token__
    #     password: ${{ secrets.pypi_token }}
    #   if: ${{ startWith(github.ref, 'refs/tags/v') }}
  ngauth:
    strategy:
      matrix:
        name: python-wheels-macos_arm64
        path: dist
    - uses: actions/download-artifact@v2
      with:
        name: python-wheels-windows
        path: dist
    # - name: Publish to PyPI (test server)
    #   uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
    #   with:
    #     user: __token__
    #     password: ${{ secrets.pypi_test_token }}
    - name: Publish to PyPI (main server)
      uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
      with:
        user: __token__
        password: ${{ secrets.pypi_token }}
      if: ${{ startsWith(github.ref, 'refs/tags/v') }}
  ngauth:
    strategy:
      matrix:
        go-version: ['1.14']
        os:
          - ubuntu-latest
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
    - name: Setup go ${{ matrix.go-version }}
      uses: actions/setup-go@v1
      with:
        go-version: ${{ matrix.go-version }}
    - uses: actions/cache@v2
      with:
        path: ~/go/pkg/mod
        key: ${{ runner.os }}-${{ matrix.go-version }}-go-${{ hashFiles('**/go.sum') }}
    - run: go build .
      working-directory: ngauth_server
  wasm:
    # Ensures that .wasm files are reproducible.
    strategy:
      matrix:
        os:
          - ubuntu-latest
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
    - run: ./src/neuroglancer/mesh/draco/build.sh
    - run: ./src/neuroglancer/sliceview/compresso/build.sh
    - run: ./src/neuroglancer/sliceview/png/build.sh
    # Check that there are no differences.
    - run: git diff --exit-code

<MSG> chore: enabling publishing tagged versions to PyPI

<DFF> @@ -191,12 +191,12 @@ jobs:
     #   with:
     #     user: __token__
     #     password: ${{ secrets.pypi_test_token }}
-    # - name: Publish to PyPI (main server)
-    #   uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
-    #   with:
-    #     user: __token__
-    #     password: ${{ secrets.pypi_token }}
-    #   if: ${{ startWith(github.ref, 'refs/tags/v') }}
+    - name: Publish to PyPI (main server)
+      uses: pypa/gh-action-pypi-publish@54b39fb9371c0b3a6f9f14bb8a67394defc7a806 # 2020-09-25
+      with:
+        user: __token__
+        password: ${{ secrets.pypi_token }}
+      if: ${{ startWith(github.ref, 'refs/tags/v') }}
   ngauth:
     strategy:
       matrix:

chore: enabling publishing tagged versions to PyPI