include:
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Coverage-Fuzzing.gitlab-ci.yml
- template: Security/SAST.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml

# Overriding 'Dependency-Scanning.gitlab-ci.yml' template, because
# we need to replace the rules with our own, the same
# as in `.merge_request_pipelines` template.
gemnasium-dependency_scanning:
  rules: !reference [".rules:merge_request_pipelines:no_docs", rules]

# Overriding 'License-Scanning.gitlab-ci.yml' template, because
# we need to replace the rules with our own, the same
# as in `.merge_request_pipelines` template.
license_scanning:
  variables:
    LICENSE_FINDER_CLI_OPTS: '--decisions-file=.gitlab/dependency_decisions.yml'
  rules: !reference [".rules:merge_request_pipelines:no_docs", rules]

# Overriding 'SAST.gitlab-ci.yml' template, because
# we need to replace the rules with our own, the same
# as in `.merge_request_pipelines` template.
gosec-sast:
  rules: !reference [".rules:merge_request_pipelines:no_docs", rules]

check version definition:
  stage: test
  extends:
  - .rules:merge_request_pipelines
  needs: []
  script:
  - grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' VERSION

# Perform documentation linting on Markdown files
docs lint markdown:
  image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.16-vale-2.20.2-markdownlint-0.32.2-markdownlint2-0.5.1
  stage: test
  extends:
  - .rules:merge_request_pipelines
  - .no_cache_and_dependencies
  needs: []
  script:
  # Lint prose and Markdown
  - make lint-docs VALE_MIN_ALERT_LEVEL=error

# Perform link checks on published HTML files
docs check links:
  image: registry.gitlab.com/gitlab-org/gitlab-docs/lint-html:alpine-3.16-ruby-2.7.6-0088e238
  stage: test
  extends:
  - .rules:merge_request_pipelines
  - .no_cache_and_dependencies
  needs: []
  script:
  # Prepare docs for build
  - mv docs/ /tmp/gitlab-docs/content/$DOCS_GITLAB_REPO_SUFFIX
  - cd /tmp/gitlab-docs
  # Build HTML from Markdown
  - bundle exec nanoc
  # Check the internal links
  - bundle exec nanoc check internal_links
  # Check the internal anchor links
  - bundle exec nanoc check internal_anchors

check feature flags docs:
  stage: test
  extends:
  - .rules:merge_request_pipelines
  - .no_cache_and_dependencies
  script:
  - cp docs/configuration/feature-flags.md docs/configuration/feature-flags.md.orig
  - make update_feature_flags_docs
  - |
    diff docs/configuration/feature-flags.md.orig docs/configuration/feature-flags.md || (
      echo
      echo "Feature Flags list in documentation is not up-to-date"
      echo "Run 'make update_feature_flags_docs' to update it"
      echo
      exit 1
    )

check modules:
  stage: test
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .no_cache_and_dependencies
  needs:
  - 'prepare done'
  script:
  - make check_modules

check mocks:
  stage: test
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .no_cache_and_dependencies
  needs:
  - 'prepare done'
  script:
  - make check_mocks

check test directives:
  stage: test
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .no_cache_and_dependencies
  needs:
  - 'prepare done'
  script:
  - make check_test_directives

.check windows test ignore list:
  stage: test
  extends:
  - .rules:merge_request_pipelines:no_docs
  script:
  - ./scripts/check_windows_test_ignore_list
  needs:
  - 'prepare done'
  - 'unit test definitions'
  - 'integration test definitions'

check windows 1809 test ignore list:
  extends:
  - .check windows test ignore list
  - .windows1809_variables

check windows 2004 test ignore list:
  extends:
  - .check windows test ignore list
  - .windows2004_variables

code_quality:
  stage: test
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .no_dependencies
  # Use GOCACHE instead of GOLANGCI_LINT_CACHE
  # to avoid [false lint positives](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/2187#note_373008672)
  - .go-cache
  image: registry.gitlab.com/gitlab-org/ci-cd/runner-tools/runner-linters:1.46.2-go1.18
  needs: []
  allow_failure: true
  variables:
    REPORT_FILE: gl-code-quality-report.json
    LINT_FLAGS: "--color never --deadline 15m"
    OUT_FORMAT: code-climate
    GOLANGLINT_VERSION: "" # Don't add version suffix to Makefile's GOLANGLINT (use plain golangci-lint from image)
  before_script:
  - source ci/touch_make_dependencies
  # Ensure the goargs linter plugin is available at .tmp/goargs.so to suit .golangci.yml
  - mkdir .tmp && ln -s /usr/lib/goargs.so .tmp/goargs.so
  # Copy the Docker image's golangci-lint to the location expected by `make lint` so that it is not built
  - cp $(which golangci-lint) .tmp/golangci-lint
  script:
  # Write the code coverage report to gl-code-quality-report.json
  # and print linting issues to stdout in the format: path/to/file:line description
  - make --silent lint | tee ${REPORT_FILE}
  timeout: 15 minutes
  artifacts:
    reports:
      codequality: ${REPORT_FILE}
    paths:
    - ${REPORT_FILE}
    when: always
    expire_in: 7d

.linux test:
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .docker
  - .go-cache
  stage: test
  script:
  - source ci/touch_make_dependencies
  - make pull_images_for_tests
  # Workaround: We call the go_test_with_coverage_report script directly instead of `make parallel_test_execute`
  #   in order to preserve the script exit code (which would otherwise be returned as make error code 2)
  - eval $(make export_test_env)
  - ./scripts/go_test_with_coverage_report execute
  artifacts:
    paths:
    - .cover/
    - .testoutput/
    when: always
    expire_in: 7d

unit test:
  extends:
  - .linux test
  needs:
  - 'unit test definitions'
  - 'clone test repo'
  - 'prepare done'
  parallel: 2
  variables:
    TESTFLAGS: -cover
    TESTSDEFINITIONSPATH: unit/testsdefinitions.txt

unit test with race:
  extends:
  - unit test
  - .go-cache
  variables:
    CGO_ENABLED: "1"
    TESTFLAGS: -cover -race
  allow_failure:
    exit_codes: 99

integration test:
  extends:
  - .linux test
  needs:
  - 'integration test definitions'
  - 'clone test repo'
  - 'helper images'
  - 'prepare done'
  parallel: 4
  variables:
    TESTFLAGS: -cover -tags=integration
    TESTSDEFINITIONSPATH: integration/testsdefinitions.txt

integration test with race:
  extends:
  - integration test
  - .go-cache
  variables:
    CGO_ENABLED: "1"
    TESTFLAGS: -cover -tags=integration -race
  allow_failure:
    exit_codes: 99

fuzz variable mask:
  extends:
  - .fuzz_base
  - .rules:merge_request_pipelines:no_docs
  image: golang:$GO_VERSION
  stage: test
  variables:
    COVFUZZ_SEED_CORPUS: './helpers/trace/testdata/corpus'
  script:
  - apt update && apt install -y clang
  - go install github.com/dvyukov/go-fuzz/go-fuzz@latest && go install github.com/dvyukov/go-fuzz/go-fuzz-build@latest && go get github.com/dvyukov/go-fuzz/go-fuzz-dep@latest
  - go-fuzz-build -libfuzzer -o fuzz_variable_mask.a ./helpers/trace
  - clang -fsanitize=fuzzer fuzz_variable_mask.a -o fuzz_variable_mask
  - ./gitlab-cov-fuzz run -- ./fuzz_variable_mask -only_ascii=1 -max_len=128 -max_total_time=300

.go-cache-windows_before_script: &go-cache-windows_before_script
- New-Item -Path .gocache-$CI_COMMIT_REF_PROTECTED -Type Directory -Force

.windows test:
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .go-cache-windows
  stage: test
  parallel: 6
  before_script:
  - Set-MpPreference -DisableRealtimeMonitoring $true
  - git config --system core.longpaths true
  - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
    -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
  - go version
  - curl -o golang.msi "https://go.dev/dl/go$GO_VERSION.windows-amd64.msi"
  - Start-Process msiexec.exe -Wait -ArgumentList '/I golang.msi /quiet'
  - $env:Path = "C:\Program Files\Go\bin;$env:Path"
  - go version
  - *go-cache-windows_before_script
  script:
  - .\ci\test_windows.ps1 $TESTSDEFINITIONSPATH
  artifacts:
    paths:
    - .testoutput/
    when: always
    expire_in: 7d
  allow_failure:
    exit_codes: 1

.windows unit test:
  extends:
  - .windows test
  needs:
  - 'unit test definitions'
  - 'clone test repo'
  - 'prepare done'
  variables:
    TESTFLAGS: '-tags=!integration'
    TESTSDEFINITIONSPATH: unit\testsdefinitions.txt

.windows integration test:
  extends:
  - .windows test
  variables:
    TESTFLAGS: '-tags=integration'
    TESTSDEFINITIONSPATH: integration\testsdefinitions.txt

# Only test the oldest supported version in merge requests,
# but test all versions in the default branch.
windows 1809 unit tests:
  extends:
  - .windows unit test
  - .windows1809
  - .rules:merge_request_pipelines:no_docs

windows 21H1 unit tests:
  extends:
  - .windows unit test
  - .windows21H1
  - .rules:merge_request_pipelines:no_docs:no-community-mr

windows 1809 integration tests:
  extends:
  - .windows integration test
  - .windows1809
  - .rules:merge_request_pipelines:no_docs
  needs:
  - 'integration test definitions'
  - 'clone test repo'
  - 'prepare done'
  - job: 'development servercore1809 helper docker images'
    optional: true
  - job: 'bleeding edge servercore1809 helper docker images'
    optional: true
  - job: 'stable servercore1809 helper docker images'
    optional: true

windows 2004 integration tests:
  extends:
  - .windows integration test
  - .windows2004
  - .rules:merge_request_pipelines:no_docs:no-community-mr
  needs:
  - 'integration test definitions'
  - 'clone test repo'
  - 'prepare done'
  - job: 'development servercore2004 helper docker images'
    optional: true
  - job: 'bleeding edge servercore2004 helper docker images'
    optional: true
  - job: 'stable servercore2004 helper docker images'
    optional: true

windows 20H2 integration tests:
  extends:
  - .windows integration test
  - .windows20H2
  - .rules:merge_request_pipelines:no_docs:no-community-mr
  needs:
  - 'integration test definitions'
  - 'clone test repo'
  - 'prepare done'
  - job: 'development servercore20H2 helper docker images'
    optional: true
  - job: 'bleeding edge servercore20H2 helper docker images'
    optional: true
  - job: 'stable servercore20H2 helper docker images'
    optional: true

windows 21H1 integration tests:
  extends:
  - .windows integration test
  - .windows21H1
  - .rules:merge_request_pipelines:no_docs:no-community-mr
  needs:
  - 'integration test definitions'
  - 'clone test repo'
  - 'prepare done'
  - job: 'development servercore21H1 helper docker images'
    optional: true
  - job: 'bleeding edge servercore21H1 helper docker images'
    optional: true
  - job: 'stable servercore21H1 helper docker images'
    optional: true

git 1.8.3.1:
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .go-cache
  image: centos:7
  stage: test
  variables:
    GOROOT: /usr/local/go
    GOPATH: /go
    CGO_ENABLED: 0
  before_script:
  - yum install -y -q git make patch && git version
  - curl https://storage.googleapis.com/golang/go$GO_VERSION.linux-amd64.tar.gz | tar zx -C $(dirname "$GOROOT")
  - curl -L https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-amd64-v${GIT_LFS_VERSION}.tar.gz | tar zx
  - mv git-lfs-${GIT_LFS_VERSION}/git-lfs /usr/bin
  - git-lfs install --skip-repo
  - export PATH=${GOPATH}/bin:${GOROOT}/bin:$PATH
  - source ci/touch_make_dependencies
  script:
  - make git1.8-test

integration_k8s:
  extends:
  - .rules:merge_request_pipelines:no_docs
  - .docker
  needs:
  - 'prepare done'
  stage: test
  services:
  - name: registry.gitlab.com/gitlab-org/cluster-integration/test-utils/k3s-gitlab-ci/releases/v1.16.7-k3s1
    alias: k3s
  before_script:
  - curl k3s:8081?service=k3s > k3s.yaml
  - export KUBECONFIG=$(pwd)/k3s.yaml
  - kubectl version
  - kubectl cluster-info
  script:
  # use env -i to clear parent environment variables for go test
  - ./scripts/go_test_no_env -timeout=15m -tags=integration,kubernetes -v gitlab.com/gitlab-org/gitlab-runner/executors/kubernetes
  retry: 2
