# reusable workflow
name: .test

# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
  contents: read

on:
  workflow_call:
    inputs:
      cache_scope:
        required: true
        type: string
      pkgs:
        required: true
        type: string
      kinds:
        required: true
        type: string
      tags:
        required: false
        type: string
      codecov_flags:
        required: false
        type: string
      includes:
        required: false
        type: string
      env:
        required: false
        type: string

env:
  GO_VERSION: "1.25"
  SETUP_BUILDX_VERSION: "edge"
  SETUP_BUILDKIT_IMAGE: "moby/buildkit:latest"

jobs:
  prepare:
    runs-on: ubuntu-24.04
    outputs:
      pkgs: ${{ steps.set.outputs.pkgs }}
      kinds: ${{ steps.set.outputs.kinds }}
      tags: ${{ steps.set.outputs.tags }}
      includes: ${{ steps.set.outputs.includes }}
    steps:
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          version: ${{ env.SETUP_BUILDX_VERSION }}
          driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
          buildkitd-flags: --debug
      -
        name: Deps
        run: |
          npm install js-yaml
      -
        name: Set outputs
        id: set
        uses: actions/github-script@v8
        with:
          script: |
            const yaml = require('js-yaml');
            await core.group(`Set pkgs matrix`, async () => {
              const pkgs = `${{ inputs.pkgs }}`.trim().split(/\r?\n/);
              core.info(JSON.stringify(pkgs, null, 2));
              core.setOutput('pkgs', JSON.stringify(pkgs));
            });
            await core.group(`Set kinds matrix`, async () => {
              const kinds = `${{ inputs.kinds }}`.trim().split(/\r?\n/);
              core.info(JSON.stringify(kinds, null, 2));
              core.setOutput('kinds', JSON.stringify(kinds));
            });
            await core.group(`Set tags matrix`, async () => {
              const tags = `${{ inputs.tags }}`.trim().split(/\r?\n/);
              core.info(JSON.stringify(tags, null, 2));
              core.setOutput('tags', JSON.stringify(tags));
            });
            await core.group(`Set includes`, async () => {
              const includes = yaml.load(`${{ inputs.includes }}`.trim());
              core.info(JSON.stringify(includes, null, 2));
              core.setOutput('includes', JSON.stringify(includes ?? []));
            });
      -
        name: Build
        uses: docker/bake-action@v6
        with:
          targets: integration-tests-base
          set: |
            *.cache-from=type=gha,scope=${{ inputs.cache_scope }}
            *.cache-to=type=gha,scope=${{ inputs.cache_scope }},repository=${{ github.repository }},ghtoken=${{ secrets.GITHUB_TOKEN }}

  run:
    runs-on: ubuntu-24.04
    needs:
      - prepare
    env:
      TESTFLAGS: "-v --parallel=6 --timeout=30m"
      GOTESTSUM_FORMAT: "standard-verbose"
      TEST_IMAGE_BUILD: "0"
    strategy:
      fail-fast: false
      matrix:
        worker:
          - containerd
          - containerd-rootless
          - containerd-1.7
          - containerd-2.0
          - containerd-snapshotter-stargz
          - oci
          - oci-rootless
          - oci-rootless-slirp4netns-detachnetns
          - oci-snapshotter-stargz
        pkg: ${{ fromJson(needs.prepare.outputs.pkgs) }}
        kind: ${{ fromJson(needs.prepare.outputs.kinds) }}
        tags: ${{ fromJson(needs.prepare.outputs.tags) }}
        include: ${{ fromJson(needs.prepare.outputs.includes) }}
    steps:
      -
        name: Prepare
        run: |
          for l in "${{ inputs.env }}"; do
            echo "${l?}" >> $GITHUB_ENV
          done
          echo "TEST_REPORT_NAME=${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.kind }}-${{ matrix.worker }}-${{ matrix.tags }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
          testFlags="${{ env.TESTFLAGS }}"
          if [ -n "${{ matrix.tags }}" ]; then
            testFlags="${testFlags} --tags=${{ matrix.tags }}"
          fi
          if [ -n "${{ matrix.worker }}" ]; then
            testFlags="${testFlags} --run=//worker=${{ matrix.worker }}$"
          fi
          echo "TESTFLAGS=${testFlags}" >> $GITHUB_ENV
      -
        name: Checkout
        uses: actions/checkout@v5
      -
        name: Expose GitHub Runtime
        uses: crazy-max/ghaction-github-runtime@v3
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          version: ${{ env.SETUP_BUILDX_VERSION }}
          driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
          buildkitd-flags: --debug
      -
        name: Build test image
        uses: docker/bake-action@v6
        with:
          targets: integration-tests
          set: |
            *.cache-from=type=gha,scope=${{ inputs.cache_scope }}
        env:
          BUILDKITD_TAGS: ${{ matrix.tags }}
          TEST_COVERAGE: 1
      -
        name: Test
        run: |
          ./hack/test ${{ matrix.kind }}
        env:
          TEST_REPORT_SUFFIX: -${{ env.TEST_REPORT_NAME }}
          TEST_COVERAGE: 1
          TESTPKGS: ${{ matrix.pkg }}
          SKIP_INTEGRATION_TESTS: ${{ matrix.skip-integration-tests }}
          CACHE_FROM: type=gha,scope=${{ inputs.cache_scope }}
      -
        name: Send to Codecov
        if: always()
        uses: codecov/codecov-action@v5
        with:
          directory: ./bin/testreports
          flags: ${{ matrix.codecov_flags }}
          disable_file_fixes: true
          token: ${{ secrets.CODECOV_TOKEN }}  # used to upload coverage reports: https://github.com/moby/buildkit/pull/4660#issue-2142122533
      -
        name: Generate annotations
        if: always()
        uses: crazy-max/.github/.github/actions/gotest-annotations@fa6141aedf23596fb8bdcceab9cce8dadaa31bd9
        with:
          directory: ./bin/testreports
      -
        name: Upload test reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-reports-${{ env.TEST_REPORT_NAME }}
          path: ./bin/testreports
          retention-days: 1
      -
        name: Dump context
        if: failure()
        uses: crazy-max/ghaction-dump-context@v2
