k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/make-rules/verify.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  # Copyright 2014 The Kubernetes Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  set -o errexit
    18  set -o nounset
    19  set -o pipefail
    20  
    21  KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../..
    22  source "${KUBE_ROOT}/hack/lib/util.sh"
    23  
    24  # If KUBE_JUNIT_REPORT_DIR is unset, and ARTIFACTS is set, then have them match.
    25  if [[ -z "${KUBE_JUNIT_REPORT_DIR:-}" && -n "${ARTIFACTS:-}" ]]; then
    26      export KUBE_JUNIT_REPORT_DIR="${ARTIFACTS}"
    27  fi
    28  
    29  # include shell2junit library
    30  source "${KUBE_ROOT}/third_party/forked/shell2junit/sh2ju.sh"
    31  
    32  # Excluded check patterns are always skipped.
    33  EXCLUDED_PATTERNS=(
    34    "verify-all.sh"                # this script calls the make rule and would cause a loop
    35    "verify-*-dockerized.sh"       # Don't run any scripts that intended to be run dockerized
    36    "verify-golangci-lint-pr.sh"       # Runs in a separate job for PRs.
    37    "verify-golangci-lint-pr-hints.sh" # Runs in a separate job for PRs.
    38    "verify-licenses.sh"           # runs in a separate job to monitor availability of the dependencies periodically
    39    "verify-openapi-docs-urls.sh"  # Spams docs URLs, don't run in CI.
    40    )
    41  
    42  # Exclude typecheck in certain cases, if they're running in a separate job.
    43  if [[ ${EXCLUDE_TYPECHECK:-} =~ ^[yY]$ ]]; then
    44    EXCLUDED_PATTERNS+=(
    45      "verify-typecheck.sh"              # runs in separate typecheck job
    46      )
    47  fi
    48  
    49  # Exclude dependency checks in certain cases, if they're running in a separate job.
    50  # From @cblecker: We can't change the variable name here, unless we update it throughout
    51  #                 test-infra (and we would need to pick it backwards).
    52  if [[ ${EXCLUDE_GODEP:-} =~ ^[yY]$ ]]; then
    53    EXCLUDED_PATTERNS+=(
    54      "verify-external-dependencies-version.sh" # runs in separate dependencies job
    55      "verify-vendor.sh"                        # runs in separate dependencies job
    56      "verify-vendor-licenses.sh"               # runs in separate dependencies job
    57      )
    58  fi
    59  
    60  # Exclude golangci-lint if requested, for example in pull-kubernetes-verify.
    61  if [[ ${EXCLUDE_GOLANGCI_LINT:-} =~ ^[yY]$ ]]; then
    62    EXCLUDED_PATTERNS+=(
    63      "verify-golangci-lint.sh"              # runs in separate pull-kubernetes-verify-lint
    64      )
    65  fi
    66  
    67  # Exclude readonly package check in certain cases, aka, in periodic jobs we don't care and a readonly package won't be touched
    68  if [[ ${EXCLUDE_READONLY_PACKAGE:-} =~ ^[yY]$ ]]; then
    69    EXCLUDED_PATTERNS+=(
    70      "verify-readonly-packages.sh"  # skip in CI, if env is set
    71      )
    72  fi
    73  
    74  # Only run known fast checks in quick mode.
    75  # These ideally run in less than 10s.
    76  QUICK_PATTERNS+=(
    77    "verify-api-groups.sh"
    78    "verify-boilerplate.sh"
    79    "verify-external-dependencies-version.sh"
    80    "verify-fieldname-docs.sh"
    81    "verify-gofmt.sh"
    82    "verify-imports.sh"
    83    "verify-non-mutating-validation.sh"
    84    "verify-pkg-names.sh"
    85    "verify-readonly-packages.sh"
    86    "verify-spelling.sh"
    87    "verify-staging-client-go.sh"
    88    "verify-staging-meta-files.sh"
    89    "verify-test-featuregates.sh"
    90    "verify-test-images.sh"
    91    "verify-vendor-licenses.sh"
    92  )
    93  
    94  while IFS='' read -r line; do EXCLUDED_CHECKS+=("$line"); done < <(ls "${EXCLUDED_PATTERNS[@]/#/${KUBE_ROOT}/hack/}" 2>/dev/null || true)
    95  while IFS='' read -r line; do QUICK_CHECKS+=("$line"); done < <(ls "${QUICK_PATTERNS[@]/#/${KUBE_ROOT}/hack/}" 2>/dev/null || true)
    96  TARGET_LIST=()
    97  IFS=" " read -r -a TARGET_LIST <<< "${WHAT:-}"
    98  
    99  function is-excluded {
   100    for e in "${EXCLUDED_CHECKS[@]}"; do
   101      if [[ $1 -ef "${e}" ]]; then
   102        return
   103      fi
   104    done
   105    return 1
   106  }
   107  
   108  function is-quick {
   109    for e in "${QUICK_CHECKS[@]}"; do
   110      if [[ $1 -ef "${e}" ]]; then
   111        return
   112      fi
   113    done
   114    return 1
   115  }
   116  
   117  function is-explicitly-chosen {
   118    local name="${1#verify-}"
   119    name="${name%.*}"
   120    index=0
   121    for e in "${TARGET_LIST[@]}"; do
   122      if [[ "${e}" == "${name}" ]]; then
   123        TARGET_LIST[index]=""
   124        return
   125      fi
   126      index=$((index + 1))
   127    done
   128    return 1
   129  }
   130  
   131  function run-cmd {
   132    local filename="${2##*/verify-}"
   133    local testname="${filename%%.*}"
   134    local output="${KUBE_JUNIT_REPORT_DIR:-/tmp/junit-results}"
   135    local tr
   136  
   137    if ${SILENT}; then
   138      juLog -output="${output}" -class="verify" -name="${testname}" -fail="^ERROR: " "$@" &> /dev/null
   139      tr=$?
   140    else
   141      juLog -output="${output}" -class="verify" -name="${testname}" -fail="^ERROR: " "$@"
   142      tr=$?
   143    fi
   144    return ${tr}
   145  }
   146  
   147  # Collect Failed tests in this Array , initialize it to nil
   148  FAILED_TESTS=()
   149  
   150  function print-failed-tests {
   151    echo -e "========================"
   152    echo -e "${color_red:?}FAILED TESTS${color_norm:?}"
   153    echo -e "========================"
   154    for t in "${FAILED_TESTS[@]}"; do
   155        echo -e "${color_red}${t}${color_norm}"
   156    done
   157  }
   158  
   159  function run-checks {
   160    local -r pattern=$1
   161    local -r runner=$2
   162  
   163    local t
   164    for t in ${pattern}
   165    do
   166      local check_name
   167      check_name="$(basename "${t}")"
   168      if [[ -n ${WHAT:-} ]]; then
   169        if ! is-explicitly-chosen "${check_name}"; then
   170          continue
   171        fi
   172      else
   173        if is-excluded "${t}" ; then
   174          echo "Skipping ${check_name}"
   175          continue
   176        fi
   177        if ${QUICK} && ! is-quick "${t}" ; then
   178          echo "Skipping ${check_name} in quick mode"
   179          continue
   180        fi
   181      fi
   182      echo -e "Verifying ${check_name}"
   183      local start
   184      start=$(date +%s)
   185      run-cmd "${runner}" "${t}" && tr=$? || tr=$?
   186      local elapsed=$(($(date +%s) - start))
   187      if [[ ${tr} -eq 0 ]]; then
   188        echo -e "${color_green:?}SUCCESS${color_norm}  ${check_name}\t${elapsed}s"
   189      else
   190        echo -e "${color_red}FAILED${color_norm}   ${check_name}\t${elapsed}s"
   191        ret=1
   192        FAILED_TESTS+=("${t}")
   193      fi
   194    done
   195  }
   196  
   197  # Check invalid targets specified in "WHAT" and mark them as failure cases
   198  function missing-target-checks {
   199    # In case WHAT is not specified
   200    [[ ${#TARGET_LIST[@]} -eq 0 ]] && return
   201  
   202    for v in "${TARGET_LIST[@]}"
   203    do
   204      [[ -z "${v}" ]] && continue
   205  
   206      FAILED_TESTS+=("${v}")
   207      ret=1
   208    done
   209  }
   210  
   211  SILENT=${SILENT:-false}
   212  QUICK=${QUICK:-false}
   213  
   214  if ${SILENT} ; then
   215    echo "Running in silent mode, run with SILENT=false if you want to see script logs."
   216  fi
   217  
   218  if ${QUICK} ; then
   219    echo "Running in quick mode (QUICK=true). Only fast checks will run."
   220  fi
   221  
   222  ret=0
   223  run-checks "${KUBE_ROOT}/hack/verify-*.sh" bash
   224  run-checks "${KUBE_ROOT}/hack/verify-*.py" python3
   225  missing-target-checks
   226  
   227  if [[ ${ret} -eq 1 ]]; then
   228      print-failed-tests
   229  fi
   230  exit ${ret}
   231  
   232  # ex: ts=2 sw=2 et filetype=sh