name: Invidious CI

on:
  schedule:
    - cron: "0 0 * * *" # Every day at 00:00
  push:
    branches:
      - "master"
      - "api-only"
  pull_request:
    branches: "*"
    paths-ignore:
      - "*.md"
      - LICENCE
      - TRANSLATION
      - invidious.service
      - .git*
      - .editorconfig

      - screenshots/*
      - assets/**
      - locales/*
      - config/**
      - .github/ISSUE_TEMPLATE/*
      - kubernetes/**

jobs:
  build:

    runs-on: ubuntu-latest

    name: "build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }}"

    continue-on-error: ${{ !matrix.stable }}

    strategy:
      fail-fast: false
      matrix:
        stable: [true]
        crystal:
          - 1.12.2
          - 1.13.3
          - 1.14.1
          - 1.15.1
          - 1.16.3
        include:
          - crystal: nightly
            stable: false

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true

      - name: Install required APT packages
        run: |
          sudo apt install -y libsqlite3-dev
        shell: bash

      - name: Install Crystal
        uses: crystal-lang/install-crystal@v1.8.2
        with:
          crystal: ${{ matrix.crystal }}

      - name: Cache Shards
        uses: actions/cache@v4
        with:
          path: |
            ./lib
            ./bin
          key: shards-${{ hashFiles('shard.lock') }}

      - name: Install Shards
        run: |
          if ! shards check; then
            shards install
          fi

      - name: Run tests
        run: crystal spec

      - name: Build
        run: crystal build --warnings all --error-on-warnings --error-trace src/invidious.cr

  build-docker:
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            name: "AMD64"
            # GitHub doesn't have a ubuntu-latest-arm runner
          - os: ubuntu-24.04-arm
            name: "ARM64"

    name: Test ${{ matrix.name }} Docker build
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - name: Use ARM64 Dockerfile if ARM64
        if: ${{ matrix.name }} == "ARM64"
        run: sed -i 's/Dockerfile/Dockerfile.arm64/' docker-compose.yml

      - name: Build Docker
        run: docker compose build

      - name: Change hmac_key on docker-compose.yml
        run: sed -i '/hmac_key/s/CHANGE_ME!!/docker-build-hmac-key/' docker-compose.yml

      - name: Run Docker
        run: docker compose up -d

      - name: Test Docker
        id: test
        run: curl -If http://localhost:3000 --retry 5 --retry-delay 1 --retry-all-errors

      - name: Print Invidious container logs
        # Tells Github Actions to always run this step regardless of whether the previous step has failed
        # Without this expression this step would simply be skipped when the previous step fails.
        if: success() || steps.test.conclusion == 'failure'
        run: docker compose logs

  lint:

    runs-on: ubuntu-latest

    continue-on-error: true

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true

      - name: Install Crystal
        id: lint_step_install_crystal
        uses: crystal-lang/install-crystal@v1.8.2
        with:
          crystal: latest

      - name: Cache Shards
        uses: actions/cache@v4
        with:
          path: |
            ./lib
            ./bin
          key: shards-${{ hashFiles('shard.lock') }}-${{ steps.lint_step_install_crystal.outputs.crystal }}

      - name: Install Shards
        run: |
          if ! shards check; then
            shards install
          fi

      - name: Check Crystal formatter compliance
        run: |
          if ! crystal tool format --check; then
            crystal tool format
            git diff
            exit 1
          fi

      - name: Run Ameba linter
        run: bin/ameba
