name: github-workflow

on:
  push:
    branches: [ main, 2.1.x, 3.0.x ]
  pull_request:
    branches: [ main, 2.1.x, 3.0.x ]

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      # this might get set to true if there is an existing cache of test times
      # this happens in 'matrix-bounds-on-test-times-cache-hit'
      TEST_TIMES_CACHE_PRESENT: false
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: 30

    # this job ('build') outputs a value from step 'test_times_cache_present_init', that has the name of:
    # 'test_times_cache_present'. This can later be used by other jobs. For example, we use this one
    # to skip the job responsible for running the tests, if a previous cache that has the test times is not present.
    # Same for other two variables 'number_of_matrix_instances' and 'matrix_array'.
    outputs:
      test_times_cache_present: ${{ steps.test_times_cache_present_init.outputs.test_times_cache_present }}
      number_of_matrix_instances: ${{ steps.test_times_cache_present_init.outputs.number_of_matrix_instances }}
      matrix_array: ${{ steps.test_times_cache_present_init.outputs.matrix_array }}
      average_time_per_instance: ${{ steps.test_times_cache_present_init.outputs.average_time_per_instance }}
    steps:

      - name: checkout project
        uses: actions/checkout@v2

      - name: set env variables
        uses: ./.github/workflows/composites/env-variables

      - name: setup project jdk-17
        id: jdk_17
        uses: ./.github/workflows/composites/setup-jdk17
        if: env.BASE_BRANCH == 'main' || env.BASE_BRANCH == '3.0.x'

      - name: setup project jdk-8
        uses: ./.github/workflows/composites/setup-jdk1.8
        if: env.BASE_BRANCH == '2.1.x'

      - name: cache local maven repository
        uses: ./.github/workflows/composites/cache

      - name: Show caches
        uses: actions/github-script@v6
        with:
          script: |
            const caches = await github.rest.actions.getActionsCacheList({
              owner: context.repo.owner,
              repo: context.repo.repo,
            })
            for (const cache of caches.data.actions_caches) {
              console.log(cache)
            }  

      - name: maven build with dry-run for tests
        uses: ./.github/workflows/composites/maven-build-with-dry-run-for-tests

      - name: restore test times cache if it exists
        id: restore_test_times_cache
        if: env.BASE_BRANCH != '2.1.x'
        uses: actions/cache/restore@v3
        with:
          path: /tmp/sorted.txt
          key: ${{ runner.os }}-spring-cloud-k8s-existing-test-times-cache-${{ github.run_id }}
          restore-keys: ${{ runner.os }}-spring-cloud-k8s-existing-test-times-cache-

      - name: check test times cache exists
        id: check_files
        uses: andstor/file-existence-action@v2
        with:
          files: /tmp/sorted.txt

      - name: show existing cache of test times
        if: steps.check_files.outputs.files_exists == 'true'
        shell: bash
        run: cat /tmp/sorted.txt

      - name: compute matrix related fields when cache is present
        if: steps.check_files.outputs.files_exists == 'true'
        uses: ./.github/workflows/composites/matrix-bounds-on-test-times-cache-hit

      - name: matrix related variables when cache is present
        id: test_times_cache_present_init
        run: |
          echo "test_times_cache_present=${{ env.TEST_TIMES_CACHE_PRESENT }}" >> $GITHUB_OUTPUT
          echo "number_of_matrix_instances=${{ env.NUMBER_OF_MATRIX_INSTANCES }}" >> $GITHUB_OUTPUT
          echo "matrix_array=${{ env.MATRIX_ARRAY }}" >> $GITHUB_OUTPUT
          echo "average_time_per_instance=${{ env.AVERAGE_TIME_PER_INSTANCE }}" >> $GITHUB_OUTPUT

  test_when_cache_present:
    needs: [ build ]
    runs-on: ubuntu-latest
    env:
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: 30
    # only run this one if there is a previous cache of test times
    if: needs.build.outputs.test_times_cache_present == 'true'
    timeout-minutes: 120

    strategy:
      fail-fast: true
      matrix:
        current_index: [ "${{ fromJSON(needs.build.outputs.matrix_array) }}" ]
        number_of_jobs: [ "${{ fromJSON(needs.build.outputs.number_of_matrix_instances) }}" ]
        average_time_per_instance: [ "${{ fromJSON(needs.build.outputs.average_time_per_instance) }}" ]

    steps:

      - name: checkout project
        uses: actions/checkout@v2

      - name: clean space
        uses: ./.github/workflows/composites/clean-space

      - name: set env variables
        uses: ./.github/workflows/composites/env-variables

      - name: setup project jdk-17
        uses: ./.github/workflows/composites/setup-jdk17
        if: env.BASE_BRANCH == 'main' || env.BASE_BRANCH == '3.0.x'

      - name: setup project jdk-8
        uses: ./.github/workflows/composites/setup-jdk1.8
        if: env.BASE_BRANCH == '2.1.x'

      - name: pre-test-actions
        uses: ./.github/workflows/composites/pre-test-actions

      - name: testcontainers reuse support
        shell: bash
        run: echo "testcontainers.reuse.enable=true" > ~/.testcontainers.properties

      - name: run and save test times when cache is present
        uses: ./.github/workflows/composites/run-and-save-test-times-when-cache-present
        env:
          CURRENT_INDEX: ${{ matrix.current_index }}
          NUMBER_OF_JOBS: ${{ matrix.number_of_jobs }}
          AVERAGE_TIME_PER_INSTANCE: ${{ matrix.average_time_per_instance }}

  test_when_cache_missing:
    needs: [ build ]
    runs-on: ubuntu-latest
    env:
      SEGMENT_DOWNLOAD_TIMEOUT_MINS: 30
    timeout-minutes: 120
    # only run this one if there is no previous cache of test times
    if: needs.build.outputs.test_times_cache_present == 'false'

    strategy:
      fail-fast: true
      matrix:
        current_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
        number_of_jobs: [32]

    steps:

      - name: checkout project
        uses: actions/checkout@v2

      - name: clean space
        uses: ./.github/workflows/composites/clean-space

      - name: set env variables
        uses: ./.github/workflows/composites/env-variables

      - name: setup project jdk-17
        uses: ./.github/workflows/composites/setup-jdk17
        if: env.BASE_BRANCH == 'main' || env.BASE_BRANCH == '3.0.x'

      - name: setup project jdk-8
        uses: ./.github/workflows/composites/setup-jdk1.8
        if: env.BASE_BRANCH == '2.1.x'

      - name: pre-test-actions
        uses: ./.github/workflows/composites/pre-test-actions

      - name: compute single step test bounds
        uses: ./.github/workflows/composites/test-bounds
        env:
          CURRENT_INDEX: ${{ matrix.current_index }}
          NUMBER_OF_JOBS: ${{ matrix.number_of_jobs }}

      - name: testcontainers reuse support
        shell: bash
        run: echo "testcontainers.reuse.enable=true" > ~/.testcontainers.properties

      - name: run and save individual test times
        env:
          CURRENT_INDEX: ${{ matrix.current_index }}
        if: env.BASE_BRANCH != '2.1.x'
        uses: ./.github/workflows/composites/run-and-save-test-times-when-cache-missing

  save_test_times_when_cache_missing:
    runs-on: ubuntu-latest
    needs: [build, test_when_cache_missing ]

    steps:

      - name: checkout project
        uses: actions/checkout@v2

      - name: compute and save running time of tests
        if: env.BASE_BRANCH != '2.1.x'
        uses: ./.github/workflows/composites/test-times

  save_test_times_when_cache_present:
    runs-on: ubuntu-latest
    needs: [ build, test_when_cache_present ]

    steps:

      - name: checkout project
        uses: actions/checkout@v2

      - name: compute and save running time of tests
        if: env.BASE_BRANCH != '2.1.x'
        uses: ./.github/workflows/composites/test-times
