"""Validate the YAML files for GitHub Actions workflows. TODO: b/359303016 - convert to use unittest """ import os import re import yaml # Ensure every job is in the list of blocking jobs. with open( os.path.join(os.path.dirname(__file__), '../workflows/test_runner.yml'), 'r' ) as f: data = yaml.safe_load(f) # List of all YAML files that are used by jobs in the test_runner.yml file. yaml_files = [] # Get a list of all jobs in the test_runner, except for the blocking job and # the tag removal job, which is not always run. all_jobs = list(data['jobs'].keys()) all_jobs.remove('all-blocking-tests') all_jobs.remove('remove-tag') passed = True blocking_jobs = data['jobs']['all-blocking-tests']['needs'] for job in all_jobs: if 'uses' in data['jobs'][job]: yaml_files.append( os.path.join( os.path.dirname(__file__), '../workflows', os.path.basename(data['jobs'][job]['uses']), ) ) if job not in blocking_jobs: passed = False raise ValueError('Job %s is not in the list of blocking jobs.' % job) print('PASSED: All jobs are in the list of blocking jobs.') # Ensure every job with a continuous prefix conditions every step on whether we # are in a continuous run. for file in yaml_files: with open(file, 'r') as f: data = yaml.safe_load(f) jobs = data['jobs'] for job in jobs: if 'steps' not in jobs[job]: continue continuous_condition = 'inputs.continuous-prefix' in jobs[job]['name'] steps = jobs[job]['steps'] for step in steps: if continuous_condition and 'continuous-run' not in step.get('if', ''): raise ValueError( 'Step %s in job %s does not check the continuous-run condition' % (step['name'], job) ) if not continuous_condition and 'continuous-run' in step.get('if', ''): raise ValueError( 'Step %s in job %s checks the continuous-run condition but ' 'the job does not contain the continuous-prefix' % (step['name'], job) ) print('PASSED: All steps in all jobs check the continuous-run condition.') # Check to make sure the list of included branches matches the list of excluded # branches in staleness_check.yml. with open( os.path.join(os.path.dirname(__file__), '../workflows/staleness_check.yml'), 'r', ) as f: regex_pattern = r"'(\d+\.x)'" data = yaml.safe_load(f) matrix = data['jobs']['test']['strategy']['matrix'] included_branches = matrix['branch'] # Main should be included in all test runs included_branches.remove('main') excludes = matrix['exclude'] for entry in excludes: match = re.search(regex_pattern, entry['branch']) branch = match.group(1) if branch not in included_branches: raise ValueError( 'Branch %s is excluded for presubmit runs but is not in the list of' ' matrix branches in staleness_check.yml.' % branch ) included_branches.remove(branch) if included_branches: raise ValueError( 'Branches %s are in the list of matrix branches but do not get excluded' ' for presubmit runs in staleness_check.yml.' % included_branches ) print( 'PASSED: The list of included branches matches the list of excluded' ' branches in staleness_check.yml.' )