name: Rust

on:
  pull_request:
  push:
    branches:
      - master

jobs:
  fmt:
    runs-on: ubuntu-latest
    steps:
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - uses: actions/checkout@v2
    - name: cargo fmt
      run: cargo fmt -- --check

  unit_tests:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macOS-latest, windows-latest]
    steps:
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - uses: actions/checkout@v2
    - name: Run tests
      run: cargo test -- --skip=feature_tests

  e2e_tests:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macOS-latest, windows-latest]
    steps:
    - name: Install Fish and Zsh using brew
      if: "startsWith(matrix.os, 'macOS')"
      run: brew install fish zsh
    - name: Install Fish and Zsh using apt
      if: "startsWith(matrix.os, 'ubuntu')"
      run: sudo apt-get install -y fish zsh
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - uses: actions/checkout@v2
    - name: Run tests
      run: cargo test -- feature_tests

  build_release:
    runs-on: windows-latest
    name: "Release build for Windows"
    steps:
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - uses: actions/checkout@v2
    - name: Build release binary
      run: cargo build --release
      env:
        RUSTFLAGS: "-C target-feature=+crt-static"
    - uses: actions/upload-artifact@v2
      with:
        name: fnm-windows
        path: target/release/fnm.exe

  build_macos_release:
    runs-on: macOS-latest
    name: "Release build for macOS"
    steps:
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - uses: actions/checkout@v2
    - name: Build release binary
      run: cargo build --release
      env:
        LZMA_API_STATIC: "true"
    - name: Strip binary from debug symbols
      run: strip target/release/fnm
    - name: List dynamically linked libraries
      run: otool -L target/release/fnm
    - uses: actions/upload-artifact@v2
      with:
        name: fnm-macos
        path: target/release/fnm

  build_static_linux_binary:
    name: "Build static Linux binary"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Build static binary
      run: |
        sudo chown -R 1000:1000 .
        docker run --rm -v "$(pwd)":/home/rust/src ekidd/rust-musl-builder:stable \
          cargo build --target x86_64-unknown-linux-gnu --release
        sudo chown -R $(whoami):$(whoami) .
    - uses: actions/upload-artifact@v2
      with:
        name: fnm-linux
        path: target/x86_64-unknown-linux-gnu/release/fnm

  build_static_arm_binary:
    name: "Build ARM binary"
    strategy:
      matrix:
        include:
          - arch: arm64
            rust_target: aarch64-unknown-linux-musl
            docker_image: arm64v8/ubuntu
            docker_platform: aarch64
          - arch: arm32
            rust_target: armv7-unknown-linux-gnueabihf
            docker_image: arm32v7/ubuntu
            docker_platform: armv7
    runs-on: ubuntu-latest
    env:
      RUST_TARGET: ${{ matrix.rust_target }}
    steps:
    - name: Set up QEMU
      id: qemu
      uses: docker/setup-qemu-action@v1
    - uses: hecrj/setup-rust-action@v1
      with:
        rust-version: stable
    - name: 'Download `cross` crate'
      run: cargo install cross
    - uses: actions/checkout@v2
    - name: "Build release"
      run: cross build --target $RUST_TARGET --release
    - name: Compress binary using UPX
      run: |
        sudo apt-get install -y upx
        upx target/$RUST_TARGET/release/fnm
    - uses: uraimo/run-on-arch-action@v2.1.1
      name: Sanity test
      with:
        arch: ${{matrix.docker_platform}}
        distro: ubuntu18.04

        # Not required, but speeds up builds by storing container images in
        # a GitHub package registry.
        githubToken: ${{ github.token }}

        env: |
          RUST_LOG: fnm=debug

        dockerRunArgs: |
            --volume "${PWD}/target/${{matrix.rust_target}}/release:/artifacts"

        # Set an output parameter `uname` for use in subsequent steps
        run: |
          echo "Hello from $(uname -a)"
          /artifacts/fnm --version
          echo "fnm install 12.0.0"
          /artifacts/fnm install 12.0.0
          echo "fnm exec --using=12 -- node --version"
          /artifacts/fnm exec --using=12 -- node --version

    - uses: actions/upload-artifact@v2
      with:
        name: fnm-${{ matrix.arch }}
        path: target/${{ env.RUST_TARGET }}/release/fnm

  ensure_commands_markdown_is_up_to_date:
    runs-on: ubuntu-latest
    name: Ensure command docs are up-to-date
    needs: [build_static_linux_binary]
    steps:
      - uses: actions/checkout@v2
      - name: Download a single artifact
        uses: actions/download-artifact@v2
        with:
          name: fnm-linux
      - name: Make the binary runnable
        run: |
          sudo install fnm /bin
          fnm --version
      - name: Print fnm version
        run: fnm --version
      - run: fnm install
      - name: Install Node deps
        run: fnm exec -- yarn
      - name: Generate command markdown
        run: |
          fnm exec -- yarn generate-command-docs --check --binary-path=$(which fnm)