name: CI

on:
  push:
    branches:
      - "master"
  pull_request:
    branches:
      - "*"

defaults:
  run:
    shell: bash

env:
  # go needs absolute directories, using the $HOME variable doesn't work here.
  GOCACHE: /home/runner/work/go/pkg/build
  GOPATH: /home/runner/work/go
  BITCOIN_VERSION: "22.0"

  # If you change this value, please change it in the following files as well:
  # /.travis.yml
  # /Dockerfile
  # /dev.Dockerfile
  # /make/builder.Dockerfile
  # /.github/workflows/release.yml
  GO_VERSION: 1.17.3

jobs:
  ########################
  # RPC and mobile compilation check
  ########################
  rpc-check:
    name: RPC and mobile compilation check
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: run check
        run: make rpc-check

      - name: run JSON/WASM stub compilation check
        run: make rpc-js-compile

      - name: build mobile RPC bindings
        run: make mobile-rpc

      - name: build mobile specific code
        run: go build --tags="mobile" ./mobile

  ########################
  # check commits
  ########################
  check-commits:
    name: check commits
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: fetch and rebase on master
        run: |
          git remote add upstream https://github.com/lightningnetwork/lnd
          git fetch upstream
          export GIT_COMMITTER_EMAIL="lnd-ci@example.com"
          export GIT_COMMITTER_NAME="LND CI"
          git rebase upstream/master

      - name: check commits
        run: scripts/check-each-commit.sh upstream/master

  ########################
  # check submodules
  ########################
  check-submodules:
    name: check submodules
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: fetch and rebase on master
        run: |
          git remote add upstream https://github.com/lightningnetwork/lnd
          git fetch upstream
          export GIT_COMMITTER_EMAIL="lnd-ci@example.com"
          export GIT_COMMITTER_NAME="LND CI"
          git rebase upstream/master

      - name: check submodules
        run: scripts/check-submodule-version.sh upstream/master

  ########################
  # lint code
  ########################
  lint:
    name: lint code
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: Fetch all history for linter
        run: git fetch --prune --unshallow

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: lint
        run: GOGC=50 make lint

  ########################
  # cross compilation
  ########################
  cross-compile:
    name: cross compilation
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: build release for all architectures
        run: make release

  ########################
  # sample configuration check
  ########################
  sample-conf-check:
    name: sample configuration check
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: check all command line flags exist in sample-lnd.conf file
        run: make sample-conf-check

  ########################
  # run unit tests
  ########################
  unit-test:
    name: run unit tests
    runs-on: ubuntu-latest
    strategy:
      # Allow other tests in the matrix to continue if one fails.
      fail-fast: false
      matrix:
        unit_type:
          - btcd unit-cover
          - unit tags="kvdb_etcd"
          - unit tags="kvdb_postgres"
          - btcd unit-race
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: install bitcoind
        run: ./scripts/install_bitcoind.sh

      - name: run ${{ matrix.unit_type }}
        run: make ${{ matrix.unit_type }}

      - name: Send coverage
        uses: shogo82148/actions-goveralls@v1
        if: matrix.unit_type == 'btcd unit-cover'
        with:
          path-to-profile: coverage.txt
          parallel: true

  ########################
  # run integration tests
  ########################
  integration-test:
    name: run itests
    runs-on: ubuntu-latest
    strategy:
      # Allow other tests in the matrix to continue if one fails.
      fail-fast: false
      matrix:
        include:
          - name: btcd
            args: backend=btcd
          - name: bitcoind
            args: backend=bitcoind
          - name: bitcoind-notxindex
            args: backend="bitcoind notxindex"
          - name: bitcoind-etcd
            args: backend=bitcoind dbbackend=etcd
          - name: bitcoind-postgres
            args: backend=bitcoind dbbackend=postgres
          - name: neutrino
            args: backend=neutrino
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: /home/runner/work/go
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: install bitcoind
        run: ./scripts/install_bitcoind.sh

      - name: run ${{ matrix.name }}
        run: make itest-parallel ${{ matrix.args }}

      - name: Zip log files on failure
        if: ${{ failure() }}
        run: 7z a logs-itest-${{ matrix.name }}.zip lntest/itest/**/*.log

      - name: Upload log files on failure
        uses: actions/upload-artifact@v2.2.4
        if: ${{ failure() }}
        with:
          name: logs-itest-${{ matrix.name }}
          path: logs-itest-${{ matrix.name }}.zip
          retention-days: 5

  ########################
  # run windows integration test
  ########################
  windows-integration-test:
    name: run windows itest
    runs-on: windows-latest
    env:
      GOCACHE: ${{ github.workspace }}/go/pkg/build
      GOPATH: ${{ github.workspace }}/go
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: go cache
        uses: actions/cache@v1
        with:
          path: ${{ env.GOPATH }}
          key: lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-${{ hashFiles('**/go.sum') }}
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ github.job }}-
            lnd-${{ runner.os }}-go-${{ env.GO_VERSION }}-
            lnd-${{ runner.os }}-go-

      - name: setup go ${{ env.GO_VERSION }}
        uses: actions/setup-go@v2
        with:
          go-version: '${{ env.GO_VERSION }}'

      - name: run itest
        run: make itest-parallel windows=1 tranches=2 parallel=2

      - name: Zip log files on failure
        if: ${{ failure() }}
        run: 7z a logs-itest-windows.zip lntest/itest/**/*.log

      - name: Upload log files on failure
        uses: actions/upload-artifact@v2
        if: ${{ failure() }}
        with:
          name: logs-itest-windows
          path: logs-itest-windows.zip
          retention-days: 5

  ########################
  # check pinned dependencies
  ########################
  dep-pin:
    name: check pinned dependencies
    runs-on: ubuntu-latest
    strategy:
      # Allow other tests in the matrix to continue if one fails.
      fail-fast: false
      matrix:
        pinned_dep:
          - google.golang.org/grpc v1.38.0
          - github.com/golang/protobuf v1.5.2

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

      - name: ensure dependences at correct version
        run: if ! grep -q "${{ matrix.pinned_dep }}" go.mod; then echo dependency ${{ matrix.pinned_dep }} should not be altered ; exit 1 ; fi

  ########################
  # check PR updates release notes
  ########################
  milestone-check:
    name: check release notes updated
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v2

      - name: release notes check
        run: scripts/check-release-notes.sh
