snowchains 0.7.0

Tools for online programming contests
name: CI

on:
  schedule:
    - cron: '0 0 * * 0'
  push:
    branches:
      - master
      - staging
      - trying
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+**'
  pull_request:

jobs:
  rustfmt:
    name: Rustfmt
    runs-on: ubuntu-18.04

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup `stable-x86_64-unknown-linux-gnu`
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable-x86_64-unknown-linux-gnu
          default: true
          profile: minimal
          components: rustfmt

      - name: cargo-fmt
        uses: actions-rs/cargo@v1
        with:
          command: fmt
          args: --all -- --check

  grcov:
    name: grcov
    runs-on: ubuntu-18.04
    if: "github.repository_owner == 'qryxip' && github.ref == 'refs/heads/master'"

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Install `nightly-x86_64-unknown-linux-gnu`
        uses: actions-rs/toolchain@v1
        with:
          toolchain: nightly
          override: true

      - name: cargo-test
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --no-fail-fast --workspace --features snowchains_core/__test_with_credentials
        env:
          CARGO_INCREMENTAL: '0'
          RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off'
          RUSTDOCFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off'
          RUST_BACKTRACE: full
          ATCODER_USERNAME: ${{ secrets.ATCODER_USERNAME }}
          ATCODER_PASSWORD: ${{ secrets.ATCODER_PASSWORD }}

      - name: grcov
        id: grcov
        uses: actions-rs/grcov@v0.1

      - name: Codecov
        uses: codecov/codecov-action@v1
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          file: ${{ steps.grcov.outputs.report }}

  build:
    strategy:
      fail-fast: false
      matrix:
        name:
          - stable-x86_64-pc-windows-msvc
          - stable-x86_64-apple-darwin
          - stable-x86_64-unknown-linux-gnu
        include:
          - { name: stable-x86_64-pc-windows-msvc   , channel: stable, target-triple: x86_64-pc-windows-msvc   , host-triple: x86_64-pc-windows-msvc  , os: windows-2019 }
          - { name: stable-x86_64-apple-darwin      , channel: stable, target-triple: x86_64-apple-darwin      , host-triple: x86_64-apple-darwin     , os: macos-10.15  }
          - { name: stable-x86_64-unknown-linux-gnu , channel: stable, target-triple: x86_64-unknown-linux-gnu , host-triple: x86_64-unknown-linux-gnu, os: ubuntu-18.04 }

    name: ${{ matrix.name }}
    runs-on: ${{ matrix.os }}

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # Workaround for https://github.com/actions/cache/issues/403
      - name: Install GNU tar
        run: |
          brew install gnu-tar
          echo "PATH=/usr/local/opt/gnu-tar/libexec/gnubin:$PATH" >> $GITHUB_ENV
        if: matrix.os == 'macos-10.15'

      - name: 'Setup `${{ matrix.channel }}-${{ matrix.host-triple }}` (target: `${{ matrix.target-triple }}`)'
        id: install-toolchain
        uses: actions-rs/toolchain@v1
        with:
          toolchain: ${{ matrix.channel }}-${{ matrix.host-triple }}
          target: ${{ matrix.target-triple }}
          default: true
          profile: minimal
          components: clippy

      - name: Cache
        uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/git
            ~/.cargo/registry
            ./target
          key: build-${{ matrix.name }}-${{ steps.install-toolchain.outputs.rustc_hash }}-${{ hashFiles('./**/Cargo.*') }}

      - name: cargo-clippy (without `snowchains_core/__test_with_credentials`)
        uses: actions-rs/cargo@v1
        with:
          command: clippy
          args: --workspace --all-targets --target ${{ matrix.target-triple }} -- -D warnings

      - name: cargo-clippy (with `snowchains_core/__test_with_credentials`)
        uses: actions-rs/cargo@v1
        with:
          command: clippy
          args: --workspace --all-targets --features snowchains_core/__test_with_credentials --target ${{ matrix.target-triple }} -- -D warnings

      - name: Determine `cargo test` features
        id: cargo-test-features
        run: |
          if ${{ !!secrets.ATCODER_USERNAME }}; then
            echo '::set-output name=features::--features snowchains_core/__test_with_credentials'
          else
            echo '::set-output name=features::'
          fi
        shell: bash

      - name: cargo-test
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --no-fail-fast --workspace ${{ steps.cargo-test-features.outputs.features }} --target ${{ matrix.target-triple }}
        env:
          RUST_BACKTRACE: full
          ATCODER_USERNAME: ${{ secrets.ATCODER_USERNAME }}
          ATCODER_PASSWORD: ${{ secrets.ATCODER_PASSWORD }}

  upload:
    strategy:
      fail-fast: false
      matrix:
        target-triple:
          - x86_64-pc-windows-msvc
          - x86_64-apple-darwin
          - x86_64-unknown-linux-gnu
        include:
          - { target-triple: x86_64-pc-windows-msvc   , host-triple: x86_64-pc-windows-msvc  , os: windows-2019 }
          - { target-triple: x86_64-apple-darwin      , host-triple: x86_64-apple-darwin     , os: macos-10.15  }
          - { target-triple: x86_64-unknown-linux-gnu , host-triple: x86_64-unknown-linux-gnu, os: ubuntu-18.04 }

    name: Upload (${{ matrix.target-triple }})
    runs-on: ${{ matrix.os }}
    if: startsWith(github.ref, 'refs/tags/')

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: 'Setup `stable-${{ matrix.host-triple }}` (target: `${{ matrix.target-triple }}`)'
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable-${{ matrix.host-triple }}
          target: ${{ matrix.target-triple }}
          default: true
          profile: minimal

      - name: cargo-install
        uses: actions-rs/cargo@v1
        with:
          command: install
          args: --path . --target ${{ matrix.target-triple }} -v --locked

      - name: cargo-build
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --release --target ${{ matrix.target-triple }}

      - name: Create an asset
        id: asset
        run: |
          BIN_TARGET=snowchains
          if ${{ contains(matrix.target-triple, 'pc-windows') }}; then
            DOT_EXE=.exe
          fi
          ASSET_STEM="$BIN_TARGET-${GITHUB_REF#refs/tags/}-${{ matrix.target-triple }}"
          git archive -o "./$ASSET_STEM.tar" --prefix "$ASSET_STEM/" HEAD
          tar -xf "./$ASSET_STEM.tar"
          mv "$HOME/.cargo/bin/$BIN_TARGET$DOT_EXE" "./$ASSET_STEM/"
          if ${{ contains(matrix.target-triple, 'pc-windows') }}; then
            ASSET="$ASSET_STEM.zip"
            7z a "$ASSET" "./$ASSET_STEM"
            zipinfo "./$ASSET"
          else
            ASSET="$ASSET_STEM.tar.gz"
            tar -czvf "./$ASSET" "./$ASSET_STEM"
          fi
          echo "::set-output name=asset::$ASSET"
        shell: bash

      - name: Upload the artifact
        uses: actions/upload-artifact@v2
        with:
          name: assets
          path: ${{ steps.asset.outputs.asset }}

  release:
    name: GitHub Release
    runs-on: ubuntu-18.04
    needs: [rustfmt, build, upload]

    steps:
      - name: Download the assets
        uses: actions/download-artifact@v2
        with:
          name: assets
          path: ./assets

      - name: GH Release
        uses: softprops/action-gh-release@v1
        with:
          files: ./assets/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}