name: Ruby Testing

on:
  push:
    branches-ignore:
      - 'dependabot/**'
      - 'renovate/**'
  pull_request:

env:
  BUNDLE_CLEAN: true
  BUNDLE_FROZEN: true

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      fail-fast: true
      matrix:
        mode:
          - production
          - test
    env:
      RAILS_ENV: ${{ matrix.mode }}
      BUNDLE_WITH: ${{ matrix.mode }}
      OTP_SECRET: precompile_placeholder
      SECRET_KEY_BASE: precompile_placeholder

    steps:
      - uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          cache: yarn
          node-version-file: '.nvmrc'

      - name: Install native Ruby dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y libicu-dev libidn11-dev

      - name: Set up bundler cache
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - run: yarn --frozen-lockfile --production
      - name: Precompile assets
        # Previously had set this, but it's not supported
        # export NODE_OPTIONS=--openssl-legacy-provider
        run: |-
          ./bin/rails assets:precompile

      - uses: actions/upload-artifact@v3
        if: matrix.mode == 'test'
        with:
          path: |-
            ./public/assets
            ./public/packs-test
          name: ${{ github.sha }}
          retention-days: 0

  test:
    runs-on: ubuntu-latest

    needs:
      - build

    services:
      postgres:
        image: postgres:14-alpine
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_USER: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    env:
      DB_HOST: localhost
      DB_USER: postgres
      DB_PASS: postgres
      DISABLE_SIMPLECOV: true
      RAILS_ENV: test
      ALLOW_NOPAM: true
      PAM_ENABLED: true
      PAM_DEFAULT_SERVICE: pam_test
      PAM_CONTROLLED_SERVICE: pam_test_controlled
      OIDC_ENABLED: true
      OIDC_SCOPE: read
      SAML_ENABLED: true
      CAS_ENABLED: true
      BUNDLE_WITH: 'pam_authentication test'
      CI_JOBS: ${{ matrix.ci_job }}/4

    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - '3.0'
          - '3.1'
          - '.ruby-version'
        ci_job:
          - 1
          - 2
          - 3
          - 4
    steps:
      - uses: actions/checkout@v3

      - uses: actions/download-artifact@v3
        with:
          path: './public'
          name: ${{ github.sha }}

      - name: Update package index
        run: sudo apt-get update

      - name: Install native Ruby dependencies
        run: sudo apt-get install -y libicu-dev libidn11-dev

      - name: Install additional system dependencies
        run: sudo apt-get install -y ffmpeg imagemagick libpam-dev

      - name: Set up bundler cache
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version}}
          bundler-cache: true

      - name: Load database schema
        run: './bin/rails db:create db:schema:load db:seed'

      - run: bundle exec rake rspec_chunked

  test-e2e:
    name: End to End testing
    runs-on: ubuntu-latest

    needs:
      - build

    services:
      postgres:
        image: postgres:14-alpine
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_USER: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    env:
      DB_HOST: localhost
      DB_USER: postgres
      DB_PASS: postgres
      DISABLE_SIMPLECOV: true
      RAILS_ENV: test
      BUNDLE_WITH: test

    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - '3.0'
          - '3.1'
          - '.ruby-version'

    steps:
      - uses: actions/checkout@v3

      - uses: actions/download-artifact@v3
        with:
          path: './public'
          name: ${{ github.sha }}

      - name: Update package index
        run: sudo apt-get update

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          cache: yarn
          node-version-file: '.nvmrc'

      - name: Install native Ruby dependencies
        run: sudo apt-get install -y libicu-dev libidn11-dev

      - name: Install additional system dependencies
        run: sudo apt-get install -y ffmpeg imagemagick

      - name: Set up bundler cache
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version}}
          bundler-cache: true

      - run: yarn --frozen-lockfile

      - name: Load database schema
        run: './bin/rails db:create db:schema:load db:seed'

      - run: bundle exec rake spec:system

      - name: Archive logs
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: e2e-logs-${{ matrix.ruby-version }}
          path: log/

      - name: Archive test screenshots
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: e2e-screenshots
          path: tmp/screenshots/

  test-search:
    name: Testing search
    runs-on: ubuntu-latest

    needs:
      - build

    services:
      postgres:
        image: postgres:14-alpine
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_USER: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

      elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:7.17.13
        env:
          discovery.type: single-node
          xpack.security.enabled: false
        options: >-
          --health-cmd "curl http://localhost:9200/_cluster/health"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 10
        ports:
          - 9200:9200

    env:
      DB_HOST: localhost
      DB_USER: postgres
      DB_PASS: postgres
      DISABLE_SIMPLECOV: true
      RAILS_ENV: test
      BUNDLE_WITH: test
      ES_ENABLED: true
      ES_HOST: localhost
      ES_PORT: 9200

    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - '3.0'
          - '3.1'
          - '.ruby-version'

    steps:
      - uses: actions/checkout@v3

      - uses: actions/download-artifact@v3
        with:
          path: './public'
          name: ${{ github.sha }}

      - name: Update package index
        run: sudo apt-get update

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          cache: yarn
          node-version-file: '.nvmrc'

      - name: Install native Ruby dependencies
        run: sudo apt-get install -y libicu-dev libidn11-dev

      - name: Install additional system dependencies
        run: sudo apt-get install -y ffmpeg imagemagick

      - name: Set up bundler cache
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version}}
          bundler-cache: true

      - run: yarn --frozen-lockfile

      - name: Load database schema
        run: './bin/rails db:create db:schema:load db:seed'

      - run: bundle exec rake spec:search

      - name: Archive logs
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: test-search-logs-${{ matrix.ruby-version }}
          path: log/

      - name: Archive test screenshots
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: test-search-screenshots
          path: tmp/screenshots/