on: [push, pull_request]
name: CI
env:
  GO_VERSION: 1.25.x
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
  backend:
    name: GoCryptoTrader backend (${{ matrix.os }}, ${{ matrix.goarch }}, psql=${{ matrix.psql }}, skip_wrapper_tests=${{ matrix.skip_wrapper_tests}}, sonic=${{ matrix.sonic }})
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            goarch: amd64
            psql: true
            skip_wrapper_tests: false
            sonic: false
          - os: ubuntu-latest
            goarch: 386
            psql: true
            skip_wrapper_tests: true
            sonic: false
          - os: ubuntu-24.04-arm
            goarch: arm64
            psql: false # Not supported
            skip_wrapper_tests: true
            sonic: false
          - os: macos-latest
            goarch: arm64
            psql: true
            skip_wrapper_tests: true
            sonic: false
          - os: windows-latest
            goarch: amd64
            psql: true
            skip_wrapper_tests: true
            sonic: false
          - os: ubuntu-latest
            goarch: amd64
            psql: true
            skip_wrapper_tests: false
            sonic: true # Only test sonic on linux/amd64 since too many races and fatals across other archs and OS

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

    steps:
    - name: Cancel previous workflow runs
      uses: styfle/cancel-workflow-action@0.12.1
      with:
        access_token: ${{ github.token }}

    - name: Setup Postgres
      if: matrix.psql == true
      uses: ikalnytskyi/action-setup-postgres@v8
      with:
        database: gct_dev_ci
      id: postgres

    - name: Set up Postgres environment
      if: matrix.psql == true
      run: |
        echo "PSQL_USER=postgres" >> $GITHUB_ENV
        echo "PSQL_PASS=postgres" >> $GITHUB_ENV
        echo "PSQL_HOST=localhost" >> $GITHUB_ENV
        echo "PSQL_DBNAME=gct_dev_ci" >> $GITHUB_ENV
        echo "PSQL_TESTDBNAME=gct_dev_ci" >> $GITHUB_ENV
        echo "PSQL_SSLMODE=disable" >> $GITHUB_ENV
        echo "PSQL_SKIPSQLCMD=true" >> $GITHUB_ENV
      shell: bash

    - name: Checkout code
      uses: actions/checkout@v5

    - name: Setup Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ env.GO_VERSION }}

    - name: Skip additional wrapper CI tests
      if: matrix.skip_wrapper_tests == true
      run: |
        echo "SKIP_WRAPPER_CI_TESTS=true" >> $GITHUB_ENV
      shell: bash

    - name: Additional steps for 386 architecture
      if: matrix.goarch == '386'
      run: |
        sudo apt-get update
        sudo apt-get install -y gcc-multilib
      shell: bash

    - name: Set CGO_ENABLED for 386 and macos-latest
      if: matrix.goarch == '386' || matrix.os == 'macos-latest'
      run: |
        echo "CGO_ENABLED=1" >> $GITHUB_ENV
      shell: bash

    - name: Set GOFLAGS
      run: |
        if [ "${{ matrix.sonic }}" = "true" ]; then
          echo "GOFLAGS=${GOFLAGS} -tags=sonic_on" >> $GITHUB_ENV
        fi
      shell: bash

    - name: Test
      run: | # PGSERVICEFILE isn't supported by lib/pq and will cause a panic if set
        unset PGSERVICEFILE
        if [ "${{ matrix.goarch }}" = "386" ]; then
          go test -coverprofile coverage.txt -covermode atomic ./...
        else
          go test -race -coverprofile coverage.txt -covermode atomic ./...
        fi
      shell: bash
      env:
        GOARCH: ${{ matrix.goarch }}

    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v5
      env:
        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
  
  backend-docker:
    name: GoCryptoTrader backend docker (ubuntu-latest, amd64, psql=false, skip_wrapper_tests=true, sonic=false)
    runs-on: ubuntu-latest

    steps:
    - name: Cancel previous workflow runs
      uses: styfle/cancel-workflow-action@0.12.1
      with:
        access_token: ${{ github.token }}

    - name: Checkout code
      uses: actions/checkout@v5

    - name: Set up Docker buildx
      uses: docker/setup-buildx-action@v3

    - name: Cache Docker layers
      uses: actions/cache@v4
      with:
        path: /tmp/.docker-buildx-cache
        key: ${{ runner.os }}-docker-buildx-${{ hashFiles('./.github/workflows/amd64.Dockerfile') }}-${{ github.sha }}
        restore-keys: |
          ${{ runner.os }}-docker-buildx-${{ hashFiles('./.github/workflows/amd64.Dockerfile') }}-
          ${{ runner.os }}-docker-buildx-
    
    - name: Build Docker image
      run: |
        docker buildx build \
          --load \
          --cache-to=type=local,dest=/tmp/.docker-buildx-cache,mode=max \
          --cache-from=type=local,src=/tmp/.docker-buildx-cache \
          --tag gct-backend-amd64 \
          -f ./.github/workflows/amd64.Dockerfile \
          .
    
    - name: Run Docker image
      run: |
        docker run --env SKIP_WRAPPER_CI_TESTS=true --env CI=true --env GCT_DOCKER_CI=true --rm gct-backend-amd64

