name: Smoke Tests

on:
  workflow_call: # allows to reuse this workflow
    inputs:
      ref:
        description: The branch or tag to run the workflow on
        required: true
        type: string
      go-libddwaf-ref:
        description: A git ref to update github.com/DataDog/go-libddwaf/v4 to. No-op if empty.
        required: false
        type: string
  push:
    branches:
      - release-v*
      - main
    tags-ignore:
      - 'contrib/**'
      - 'instrumentation/**'
      - 'internal/**'
      - 'orchestrion/**'
      - 'scripts/**'
  schedule: # nightly
    - cron: "0 0 * * *"
  workflow_dispatch: { } # manually

env:
  TEST_RESULTS: /tmp/test-results # path to where test results will be saved
  GOEXPERIMENT: synctest # TODO: remove once go1.25 is the minimum supported version

permissions:
  contents: read

jobs:
  setup-env:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.matrix.outputs.matrix }}
    env:
      PACKAGES: ./internal/... ./ddtrace/... ./profiler/... ./appsec/... ./instrumentation/...
    steps:
      - name: Checkout
        uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
        with:
          ref: ${{ inputs.ref || github.ref }}
          repository: DataDog/dd-trace-go

      - name: Setup Go and development tools
        uses: ./.github/actions/setup-go
        with:
          go-version: stable
          tools-dir: ${{ github.workspace }}/_tools
          tools-bin: ${{ github.workspace }}/bin

      - name: go get -u
        run: |-
          mkdir -p "$TEST_RESULTS"
          # shellcheck disable=SC2086
          go get -u -t $PACKAGES
          go mod tidy
          find . -iname go.mod -exec dirname {} \; | while read -r d; do pushd "$d" && go mod tidy && popd; done

      - name: Install requested go-libddwaf version
        if: github.event_name == 'workflow_call' && inputs.go-libddwaf-ref != ''
        run: |-
          go get -u -t github.com/DataDog/go-libddwaf/v4@${{ inputs.go-libddwaf-ref }}
          go mod tidy

      - name: Compile dd-trace-go
        run: |
          # shellcheck disable=SC2086
          go build $PACKAGES

      - name: Compute Matrix
        id: matrix
        run: |-
          echo -n "matrix="                      >> "${GITHUB_OUTPUT}"
          go run ./scripts/ci_contrib_matrix.go  >> "${GITHUB_OUTPUT}"

  go-get-u:
    #  Run go get -u to upgrade dd-trace-go dependencies to their
    #  latest minor version and see if dd-trace-go still compiles.
    #  Related to issue https://github.com/DataDog/dd-trace-go/issues/1607
    name: 'go get -u smoke test'
    needs: setup-env
    strategy:
      fail-fast: false
      matrix:
        chunk: ${{ fromJson(needs.setup-env.outputs.matrix) }}
    runs-on: ubuntu-latest
    if: github.repository_owner == 'DataDog' # only run on DataDog's repository, not in forks
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
        with:
          ref: ${{ inputs.ref || github.ref }}
          # Manually specify the repository, which is necessary in the workflow_call situation, as the default is
          # otherwise the repository where the caller workflow started from. In this case, we need to check out the
          # repository where the called workflow is (i.e, this repository); but I don't know of a more elegant way to
          # obtain its name than hard-coding it.
          repository: DataDog/dd-trace-go
      - name: Setup Go and development tools
        uses: ./.github/actions/setup-go
        with:
          go-version: stable
          tools-dir: ${{ github.workspace }}/_tools
          tools-bin: ${{ github.workspace }}/bin
      - name: Test contribs
        # It needs to run before "Test dd-trace-go" to avoid TestTelemetryEnabled tests to fail.
        run: |-
          export PATH="${{ github.workspace }}/bin:${PATH}"
          ./scripts/ci_test_contrib.sh smoke ${{ toJson(matrix.chunk) }}

  smoke-test-tracer:
    name: Test dd-trace-go
    runs-on: ubuntu-latest
    env:
      PACKAGES: ./internal/... ./ddtrace/... ./profiler/... ./appsec/... ./instrumentation/...
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
        with:
          ref: ${{ inputs.ref || github.ref }}
          repository: DataDog/dd-trace-go
      - run: |
          # shellcheck disable=SC2086
          go test $PACKAGES
      # Check for changes in the supported_configurations.json file
      - name: Supported Configurations Diff Check
        if: always()
        uses: ./.github/actions/supported_configurations_validation

  check-gen-files:
    name: Check generated files and go mod files are up-to-date.
    runs-on: ubuntu-latest
    if: inputs.go-libddwaf-ref == ''
    env:
      # Users may build our library with GOTOOLCHAIN=local. If they do, and our
      # go.mod file specifies a newer Go version than their local toolchain, their
      # build will break. Run our tests with GOTOOLCHAIN=local to ensure that
      # our library builds with all of the Go versions we claim to support,
      # without having to download a newer one.
      GOTOOLCHAIN: local
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
        with:
          ref: ${{ inputs.ref || github.ref }}
      - name: Setup Go and development tools
        uses: ./.github/actions/setup-go
        with:
          go-version: "1.24"
          tools-dir: ${{ github.workspace }}/_tools
          tools-bin: ${{ github.workspace }}/bin
      - name: Run generate scripts and check diff
        run: |-
          export PATH="${{ github.workspace }}/bin:${PATH}"
          ./scripts/generate.sh
          ./scripts/fix_modules.sh
          git diff --exit-code

  # TODO: macos setup requirements (xcode tools installation, etc.)
  setup-requirements-linux:
    # Build and deployment setup smoke test of linux containers built from the
    # golang docker image to test that dd-trace-go doesn't need more than the
    # "out-of-the-box" images. It is expected require a few more tools when CGO
    # is enabled, but nothing more than gcc and the C library, but nothing more.
    # Anything more than this "standard Go build and deployment requirements"
    # must be considered breaking changes.
    name: 'Build and deployment requirements smoke tests'
    runs-on: ubuntu-latest
    if: github.repository_owner == 'DataDog' # only run on DataDog's repository, not in forks
    strategy:
      fail-fast: false
      matrix:
        # TODO: cross-compilation from/to different hardware architectures once
        #       github provides native ARM runners.
        go: [ "1.25", "1.24" ]
        build-env: [ alpine, trixie, bookworm ]
        build-with-cgo: [ 0, 1 ]
        deployment-env: [ alpine, debian12, debian13, al2, al2023, busybox, scratchy ]
        include:
          # GitHub limits the number of matrix jobs to 256, so we need to reduce
          # it a bit, and we can reduce redundant tests.
          # 1. Building with `go mod vendoring` is not worth it on all the
          #    possible build and deployment envs.
          - build-env: alpine
            build-with-vendoring: y
            build-with-cgo: 1 # cgo's build tag can impact the vendored files
            deployment-env: alpine
          - build-env: alpine
            build-with-vendoring: y
            build-with-cgo: 0 # cgo's build tag can impact the vendored files
            deployment-env: alpine
          # 2. Given the low blast radius of the busybox deployment environment
          #    this is the only one where we accept the libdl.so.2 requirement.
          #    For this reason, we add the datadog.no_waf build tag in this only
          #    case to avoid the libdl.so.2 dependency.
          - deployment-env: busybox
            build-with-cgo: 1
            build-tags: "datadog.no_waf"

        exclude:
          # Exclude "out of the box" cases requiring extra setup:
          # 1. Building with CGO enabled on alpine but deploying to a non-alpine
          #    environment: the C library isn't located at the same place.
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: debian12
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: debian13
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: al2
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: al2023
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: busybox
          - build-env: alpine
            build-with-cgo: 1
            deployment-env: scratchy
          # 2. Too old glibc on the deployment environment than on the build env
          - build-env: bookworm
            deployment-env: al2
          - build-env: trixie
            deployment-env: al2
          # 3. Build with CGO enabled and deploying to a scratch/busybox docker
          #    image requires copying the dynamic lib dependencies (full example
          #    provided at https://github.com/DataDog/appsec-go-test-app/blob/main/examples/docker/scratch/Dockerfile)
          - build-with-cgo: 1
            deployment-env: scratchy

    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
        with:
          ref: ${{ inputs.ref || github.ref }}
          # Manually specify the repository, which is necessary in the workflow_call situation, as the default is
          # otherwise the repository where the caller workflow started from. In this case, we need to check out the
          # repository where the called workflow is (i.e, this repository); but I don't know of a more elegant way to
          # obtain its name than hard-coding it.
          repository: DataDog/dd-trace-go
      - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
      - name: Build
        uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
        with:
          context: .
          file: ./internal/setup-smoke-test/Dockerfile
          push: false
          load: true
          tags: smoke-test
          build-args: |
            go=${{ matrix.go }}
            build_env=${{ matrix.build-env }}
            build_tags=${{ matrix.build-tags }}
            build_with_vendoring=${{ matrix.build-with-vendoring }}
            build_with_cgo=${{ matrix.build-with-cgo }}
            deployment_env=${{ matrix.deployment-env }}
            go_libddwaf_ref=${{ inputs.go-libddwaf-ref }}
      - name: Test
        run: docker run -p7777:7777 --rm smoke-test

  smoke-tests-done:
    name: Smoke Tests
    needs: setup-requirements-linux
    runs-on: ubuntu-latest
    if: success() || failure()
    steps:
      - name: Success
        if: needs.setup-requirements-linux.result == 'success'
        run: echo "Success!"
      - name: Failure
        if: needs.setup-requirements-linux.result != 'success'
        run: echo "Failure!" && exit 1
