name: Plugin Tests

on:
  push:
    branches:
      - stable
      - main
  pull_request:
  schedule:
    - cron: '0 */12 * * *'

concurrency:
  group: plugin-tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
  cancel-in-progress: true

jobs:
  build:
    name: ${{ matrix.build_type }}
    runs-on: ubuntu-latest
    container: discourse/discourse_test:slim${{ startsWith(matrix.build_type, 'frontend') && '-browsers' || '' }}
    timeout-minutes: 30

    env:
      DISCOURSE_HOSTNAME: www.example.com
      RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
      RAILS_ENV: test
      PGUSER: discourse
      PGPASSWORD: discourse

    strategy:
      fail-fast: false

      matrix:
        build_type: ["backend", "frontend"]

    steps:
      - uses: haya14busa/action-cond@v1
        id: discourse_branch
        with:
          cond: ${{  github.base_ref == 'stable' }}
          if_true: "stable"
          if_false: "tests-passed"

      - uses: actions/checkout@v3
        with:
          repository: discourse/discourse
          ref: ${{ steps.discourse_branch.outputs.value }}
          fetch-depth: 1

      - name: Install plugin
        uses: actions/checkout@v3
        with:
          path: plugins/${{ github.event.repository.name }}
          ref: "${{ github.head_ref }}"
          fetch-depth: 1

      - name: Setup Git
        run: |
          git config --global user.email "ci@ci.invalid"
          git config --global user.name "Discourse CI"

      - name: Start redis
        run: |
          redis-server /etc/redis/redis.conf &

      - name: Start Postgres
        run: |
          chown -R postgres /var/run/postgresql
          sudo -E -u postgres script/start_test_db.rb
          sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';"

      - name: Bundler cache
        uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-gem-

      - name: Setup gems
        run: |
          gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock)
          bundle config --local path vendor/bundle
          bundle config --local deployment true
          bundle config --local without development
          bundle install --jobs 4
          bundle clean

      - name: Lint English locale
        if: matrix.build_type == 'backend'
        run: bundle exec ruby script/i18n_lint.rb "plugins/${{ github.event.repository.name }}/locales/{client,server}.en.yml"

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

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

      - name: Yarn install
        run: yarn install

      - name: Fetch app state cache
        uses: actions/cache@v3
        id: app-cache
        with:
          path: tmp/app-cache
          key: >-
            ${{ hashFiles('.github/workflows/plugin-tests.yml') }}-
            ${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}-

      - name: Restore database from cache
        if: steps.app-cache.outputs.cache-hit == 'true'
        run: psql -f tmp/app-cache/cache.sql postgres

      - name: Restore uploads from cache
        if: steps.app-cache.outputs.cache-hit == 'true'
        run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads

      - name: Create and migrate database
        if: steps.app-cache.outputs.cache-hit != 'true'
        run: |
          bin/rake db:create
          bin/rake db:migrate

      - name: Dump database for cache
        if: steps.app-cache.outputs.cache-hit != 'true'
        run: mkdir -p tmp/app-cache && pg_dumpall > tmp/app-cache/cache.sql

      - name: Dump uploads for cache
        if: steps.app-cache.outputs.cache-hit != 'true'
        run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads

      - name: RSpec with Coverage
        if: matrix.build_type == 'backend'
        run: |
          if [ -e plugins/${{ github.event.repository.name }}/.simplecov ]
          then
            cp plugins/${{ github.event.repository.name }}/.simplecov .simplecov
            export COVERAGE=1
          fi
          bin/rake plugin:spec[${{ github.event.repository.name }}]

      - name: Wizard QUnit
        if: matrix.build_type == 'frontend'
        run: LOAD_PLUGINS=1 QUNIT_EMBER_CLI=0 QUNIT_SKIP_CORE=1 bin/rake qunit:test['600000','/w/qunit']
        timeout-minutes: 10