name: Build and test smart-contracts

# This job runs rustfmt and clippy linting,
# and then it runs cargo test and ./target/debug/wasm-test

on:
  push:
    branches: main

  pull_request:
    branches: main

  workflow_dispatch: # allows manual trigger

env:
  RUST_FMT: nightly-2023-04-01-x86_64-unknown-linux-gnu
  RUST_CLIPPY: 1.82

jobs:

  "wat-wasm-consistency":
    name: Ensure consistency between wat and wasm files
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Install WABT
        run: sudo apt-get update && sudo apt-get -y install wabt
      - name: Check consistency
        run: ./.diff-wat-wasm.sh

  "lint_fmt":
    name: smart-contracts/${{ matrix.build-dir }} lint:fmt
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-dir:
          - 'wasm-transform'
          - 'wasm-chain-integration'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Format
        working-directory: smart-contracts/${{ matrix.build-dir }}
        run: |
          rustup default ${{ env.RUST_FMT }}
          rustup component add rustfmt
          cargo fmt -- --color=always --check

  "lint_doc":
    name: smart-contracts/${{ matrix.build-dir }} lint:fmt
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-dir:
          - 'wasm-transform'
          - 'wasm-chain-integration'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Format
        working-directory: smart-contracts/${{ matrix.build-dir }}
        run: |
          rustup default ${{ env.RUST_CLIPPY }}
          rustup component add rust-docs
          RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features

  "lint_fmt_example_contracts":
    name: ${{ matrix.example-contract }} lint:fmt
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        example-contract:
          - 'escrow'
          - 'lockup'
          - 'use-all-host-functions'
          - 'rate-limited'
          - 'counter'
          - 'context-test'
          - 'fib'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Format
        working-directory: smart-contracts/rust-contracts/example-contracts/${{ matrix.example-contract }}
        run: |
          rustup default ${{ env.RUST_FMT }}
          rustup component add rustfmt
          cargo fmt -- --color=always --check

  "lint_clippy_wasm_transform":
    name: smart-contracts/${{ matrix.build-dir }} lint:clippy
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-dir:
          - 'wasm-transform'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Clippy
        working-directory: smart-contracts/${{ matrix.build-dir }}
        run: |
          git config --global url."https://github.com/".insteadOf "git@github.com:"
          rustup default ${{ env.RUST_CLIPPY }}
          rustup component add clippy
          cargo clippy --color=always --tests --benches -- -Dclippy::all

  "lint_clippy_wasm_chain_integration":
    name: smart-contracts/${{ matrix.build-dir }} lint:clippy
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-dir:
          - 'wasm-chain-integration'
        features:
          - 'enable-ffi'
          - 'display-state'
          - 'async'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Clippy
        working-directory: smart-contracts/${{ matrix.build-dir }}
        run: |
          git config --global url."https://github.com/".insteadOf "git@github.com:"
          rustup default ${{ env.RUST_CLIPPY }}
          rustup component add clippy
          cargo clippy --locked --features ${{ matrix.features }} --no-default-features --color=always --tests --benches -- -Dclippy::all

  "lint_clippy_example_contracts":
    name: smart-contracts/${{ matrix.example-contract }} lint:clippy
    # Don't run on draft pull requests
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        example-contract:
          - 'escrow'
          - 'lockup'
          - 'use-all-host-functions'
          - 'rate-limited'
          - 'counter'
          - 'context-test'
          - 'fib'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Clippy
        working-directory: smart-contracts/rust-contracts/example-contracts/${{ matrix.example-contract }}
        run: |
          git config --global url."https://github.com/".insteadOf "git@github.com:"
          rustup default ${{ env.RUST_CLIPPY }}
          rustup component add clippy
          rustup target add wasm32-unknown-unknown
          cargo clippy --locked --color=always --tests -- -Dclippy::all

  "cargo_test":
    name: ${{ matrix.build-dir }} cargo:test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-dir:
          - 'wasm-transform'
          - 'wasm-chain-integration'
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Test
        working-directory: smart-contracts/${{ matrix.build-dir }}
        run: |
          rustup default ${{ env.RUST_CLIPPY }}
          cargo test

  "cargo_test_example_contracts":
    name: ${{ matrix.example-contract }} cargo:test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        example-contract:
          - 'counter'
          # removed because test fail with "implement me"
          # - 'escrow'
          
          # the following 2 contracts fail to build due to:
          # error: building tests with panic=abort is not supported without `-Zpanic_abort_tests`
          # - 'fib'
          # - 'lockup'
          
          #Remaining example contracts have not yet been added to ci
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Test
        working-directory: smart-contracts/rust-contracts/example-contracts/${{ matrix.example-contract }}
        run: |
          git config --global url."https://github.com/".insteadOf "git@github.com:"
          rustup default ${{ env.RUST_CLIPPY }}
          cargo test --target x86_64-unknown-linux-gnu

  "wasm-core-spec_cargo_test":
    name: wasm-core-spec cargo:test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Test
        working-directory: smart-contracts/wasm-test
        run: |
          rustup default ${{ env.RUST_CLIPPY }}
          cargo build
          ./target/debug/wasm-test --dir ../testdata/wasm-spec-test-suite/core/