name: CI

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

env:
  GO_DEV_VERSION: "1.15" # Recommended Go version for development.
  GOLANGCI_LINT_VERSION: "v1.31.0"
  NODE_VERSION: "14"

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        go: ["1.15"]
        pkger: [false, true]
    name: Go ${{ matrix.go }} (${{ matrix.pkger && 'static' || 'live' }})

    steps:
      - uses: actions/checkout@v2

      - name: Cache Go modules
        uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}

      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: ${{ matrix.go }}

      - name: Download Go modules
        run: go mod download

      - name: Run pkger
        if: ${{ matrix.pkger }}
        run: |
          mkdir frontend/build # Ensure this exists; the tests won't use it.
          go run github.com/markbates/pkger/cmd/pkger list
          go run github.com/markbates/pkger/cmd/pkger -o internal/pkger

      - name: Run tests
        run: go test -race -covermode=atomic -coverprofile=coverage.txt ./...

      - name: Run 1x benchmarks
        run: go test -run=- -bench . -benchtime=1x ./...

  style:
    name: Style
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Cache Go modules
        uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_DEV_VERSION }}-${{ hashFiles('**/go.sum') }}

      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_DEV_VERSION }}

      - name: Check go.mod tidyness
        run: |
          go mod tidy
          git diff --exit-code go.mod go.sum

      - name: golangci-lint
        run: |
          curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin $GOLANGCI_LINT_VERSION
          $(go env GOPATH)/bin/golangci-lint run --timeout 10m

  generate:
    name: go generate
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Cache Go modules
        uses: actions/cache@v2
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_DEV_VERSION }}-${{ hashFiles('**/go.sum') }}

      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_DEV_VERSION }}

      - name: go generate
        run: |
          go generate ./...
          git diff --exit-code

  build_frontend:
    name: Build frontend
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: frontend

    steps:
      - uses: actions/checkout@v2

      - uses: actions/setup-node@v2-beta
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - uses: actions/cache@v2
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: yarn install
        run: yarn install --frozen-lockfile

      - name: yarn build
        run: yarn build

  docker:
    name: Docker
    runs-on: ubuntu-latest
    needs: [test, style, generate, build_frontend]

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Get version
        run: |
          export CODIES_VERSION="r$(git rev-list --count HEAD).$(git rev-parse --short HEAD)"
          echo Version $CODIES_VERSION
          echo CODIES_VERSION=$CODIES_VERSION >> $GITHUB_ENV

      - name: Turnstyle
        if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
        uses: softprops/turnstyle@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build / push image
        uses: whoan/docker-build-with-cache-action@v4
        with:
          username: "${{ secrets.DOCKER_USERNAME }}"
          password: "${{ secrets.DOCKER_PASSWORD }}"
          image_name: zikaeroh/codies
          image_tag: "latest,${{ env.CODIES_VERSION }}"
          build_extra_args: "--build-arg=version=${{ env.CODIES_VERSION }}"
          push_image_and_stages: ${{ github.repository == 'zikaeroh/codies' && github.event_name == 'push' && github.ref == 'refs/heads/master' }}
