mirror of
https://github.com/apache/druid.git
synced 2025-02-06 18:18:17 +00:00
17215cd677
All JDK 8 based CI checks have been removed. Images used in Dockerfile(s) have been updated to Java 17 based images. Documentation has been updated accordingly.
193 lines
7.6 KiB
Python
Executable File
193 lines
7.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
# this script does some primitive examination of git diff to determine if a test suite needs to be run or not
|
|
|
|
# these jobs should always be run, no matter what
|
|
always_run_jobs = ['license checks', '(openjdk17) packaging check']
|
|
|
|
# ignore changes to these files completely since they don't impact CI, if the changes are only to these files then all
|
|
# of CI can be skipped. however, jobs which are always run will still be run even if only these files are changed
|
|
ignore_prefixes = ['.github', '.idea', '.asf.yaml', '.backportrc.json', '.codecov.yml', '.dockerignore', '.gitignore',
|
|
'.lgtm.yml', 'CONTRIBUTING.md', 'setup-hooks.sh', 'upload.sh', 'dev', 'distribution/docker',
|
|
'distribution/asf-release-process-guide.md',
|
|
'owasp-dependency-check-suppressions.xml', 'licenses']
|
|
|
|
script_prefixes = ['check_test_suite.py', 'check_test_suite_test.py']
|
|
script_job = ['script checks']
|
|
|
|
# these files are docs changes
|
|
# if changes are limited to this set then we can skip web-console and java
|
|
# if no changes in this set we can skip docs
|
|
docs_prefixes = ['docs/', 'website/']
|
|
# travis docs job name
|
|
docs_jobs = ['docs']
|
|
# these files are web-console changes
|
|
# if changes are limited to this set then we can skip docs and java
|
|
# if no changes in this set we can skip web-console
|
|
web_console_prefixes = ['web-console/']
|
|
# travis web-console job name
|
|
web_console_jobs = ['web console', 'web console end-to-end test']
|
|
web_console_still_run_for_java_jobs = ['web console end-to-end test']
|
|
|
|
|
|
def check_ignore(file):
|
|
is_always_ignore = True in (file.startswith(prefix) for prefix in ignore_prefixes)
|
|
if is_always_ignore:
|
|
print("found ignorable file change: {}".format(file))
|
|
return is_always_ignore
|
|
|
|
def check_testable_script(file):
|
|
is_script = True in (file.startswith(prefix) for prefix in script_prefixes)
|
|
if is_script:
|
|
print("found script file change: {}".format(file))
|
|
return is_script
|
|
|
|
def check_docs(file):
|
|
is_docs = True in (file.startswith(prefix) for prefix in docs_prefixes)
|
|
if is_docs:
|
|
print("found docs file change: {}".format(file))
|
|
return is_docs
|
|
|
|
|
|
def check_console(file):
|
|
is_console = True in (file.startswith(prefix) for prefix in web_console_prefixes)
|
|
if is_console:
|
|
print("found web-console file change: {}".format(file))
|
|
return is_console
|
|
|
|
|
|
def check_should_run_suite(suite, diff_files):
|
|
"""
|
|
try to determine if a test suite should run or not given a set files in a diff
|
|
|
|
:param suite: travis job name
|
|
:param diff_files: files changed in git diff
|
|
:return: True if the supplied suite needs to run, False otherwise
|
|
"""
|
|
|
|
if suite in always_run_jobs:
|
|
# you gotta do what you gotta do
|
|
return True
|
|
|
|
all_ignore = True
|
|
any_docs = False
|
|
all_docs = True
|
|
any_console = False
|
|
all_console = True
|
|
any_java = False
|
|
any_testable_script = False
|
|
all_testable_script = True
|
|
|
|
# go over all of the files in the diff and collect some information about the diff contents, we'll use this later
|
|
# to decide whether or not to run the suite
|
|
for f in diff_files:
|
|
is_ignore = check_ignore(f)
|
|
all_ignore = all_ignore and is_ignore
|
|
is_docs = check_docs(f)
|
|
any_docs = any_docs or is_docs
|
|
all_docs = all_docs and is_docs
|
|
is_console = check_console(f)
|
|
any_console = any_console or is_console
|
|
all_console = all_console and is_console
|
|
is_script = check_testable_script(f)
|
|
any_testable_script = any_testable_script or is_script
|
|
all_testable_script = all_testable_script and is_script
|
|
any_java = any_java or (not is_ignore and not is_docs and not is_console and not is_script)
|
|
|
|
# if everything is ignorable, we can skip this suite
|
|
if all_ignore:
|
|
return False
|
|
# if the test suite is a doc job, return true if any of the files changed were docs
|
|
if suite in docs_jobs:
|
|
return any_docs
|
|
# if all of the changes are docs paths, but the current suite is not a docs job, we can skip
|
|
if all_docs:
|
|
return False
|
|
if suite in web_console_still_run_for_java_jobs:
|
|
return any_console or any_java
|
|
# if the test suite is a web console job, return true if any of the changes are web console files
|
|
if suite in web_console_jobs:
|
|
return any_console
|
|
# if all of the changes are web console paths, but the current suite is not a web console job, we can skip
|
|
if all_console:
|
|
return False
|
|
if suite in script_job:
|
|
return any_testable_script
|
|
if all_testable_script:
|
|
return False
|
|
|
|
# if all of the files belong to known non-java groups, we can also skip java
|
|
# note that this should probably be reworked to much more selectively run the java jobs depending on the diff
|
|
if not any_java:
|
|
return False
|
|
|
|
# we don't know we can skip for sure, so lets run it
|
|
return True
|
|
|
|
|
|
def failWithUsage():
|
|
sys.stderr.write("usage: check_test_suite.py <test-suite-name>\n")
|
|
sys.stderr.write(" e.g., check_test_suite.py docs")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
suite_name = ""
|
|
|
|
# when run by travis, we run this script without arguments, so collect the test suite name from environment
|
|
# variables. if it doesn't exist, fail
|
|
if len(sys.argv) == 1:
|
|
if 'TRAVIS_JOB_NAME' in os.environ:
|
|
suite_name = os.environ['TRAVIS_JOB_NAME']
|
|
else:
|
|
failWithUsage()
|
|
elif len(sys.argv) == 2:
|
|
# to help with testing, can explicitly pass a test suite name
|
|
suite_name = sys.argv[1]
|
|
else:
|
|
failWithUsage()
|
|
|
|
# we only selectively run CI for PR builds, branch builds such as master and releases will always run all suites
|
|
is_pr = False
|
|
if 'TRAVIS_PULL_REQUEST' in os.environ and os.environ['TRAVIS_PULL_REQUEST'] != 'false':
|
|
is_pr = True
|
|
|
|
if not is_pr:
|
|
print("Not a pull request build, need to run all test suites")
|
|
sys.exit(1)
|
|
|
|
# this looks like it only gets the last commit, but the way travis PR builds work this actually gets the complete
|
|
# diff (since all commits from the PR are rebased onto the target branch and added as a single commit)
|
|
all_changed_files_string = subprocess.check_output("git diff --name-only HEAD~1", shell=True).decode('UTF-8')
|
|
all_changed_files = all_changed_files_string.splitlines()
|
|
print("Checking if suite '{}' needs to run test on diff:\n{}".format(suite_name, all_changed_files_string))
|
|
|
|
# we should always run all test suites for builds that are not for a pull request
|
|
needs_run = check_should_run_suite(suite_name, all_changed_files)
|
|
|
|
if needs_run:
|
|
print("Changes detected, need to run test suite '{}'".format(suite_name))
|
|
sys.exit(1)
|
|
|
|
print("No applicable changes detected, can skip test suite '{}'".format(suite_name))
|
|
sys.exit(0)
|