123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- # Copyright 2018 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Enforces luci-milo.cfg consistency.
- See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
- for more details on the presubmit API built into depot_tools.
- """
- PRESUBMIT_VERSION = '2.0.0'
- USE_PYTHON3 = True
- _IGNORE_FREEZE_FOOTER = 'Ignore-Freeze'
- # The time module's handling of timezones is abysmal, so the boundaries are
- # precomputed in UNIX time
- _FREEZE_START = 1639641600 # 2021/12/16 00:00 -0800
- _FREEZE_END = 1641196800 # 2022/01/03 00:00 -0800
- def CheckFreeze(input_api, output_api):
- if _FREEZE_START <= input_api.time.time() < _FREEZE_END:
- footers = input_api.change.GitFootersFromDescription()
- if _IGNORE_FREEZE_FOOTER not in footers:
- def convert(t):
- ts = input_api.time.localtime(t)
- return input_api.time.strftime('%Y/%m/%d %H:%M %z', ts)
- return [
- output_api.PresubmitError(
- 'There is a prod freeze in effect from {} until {},'
- ' files in //infra/config cannot be modified'.format(
- convert(_FREEZE_START), convert(_FREEZE_END)))
- ]
- return []
- def CheckTests(input_api, output_api):
- glob = input_api.os_path.join(input_api.PresubmitLocalPath(), '*_test.py')
- tests = input_api.canned_checks.GetUnitTests(input_api,
- output_api,
- input_api.glob(glob),
- run_on_python2=False,
- run_on_python3=True,
- skip_shebang_check=True)
- return input_api.RunTests(tests)
- def CheckLintLuciMilo(input_api, output_api):
- if ('infra/config/generated/luci/luci-milo.cfg' in input_api.LocalPaths()
- or 'infra/config/lint-luci-milo.py' in input_api.LocalPaths()):
- return input_api.RunTests([
- input_api.Command(
- name='lint-luci-milo',
- cmd=[input_api.python3_executable, 'lint-luci-milo.py'],
- kwargs={},
- message=output_api.PresubmitError),
- ])
- return []
- def CheckTestingBuildbot(input_api, output_api):
- if ('infra/config/generated/luci/luci-milo.cfg' in input_api.LocalPaths() or
- 'infra/config/generated/luci/luci-milo-dev.cfg' in input_api.LocalPaths()
- ):
- return input_api.RunTests([
- input_api.Command(name='testing/buildbot config checks',
- cmd=[
- input_api.python3_executable,
- input_api.os_path.join(
- '..',
- '..',
- 'testing',
- 'buildbot',
- 'generate_buildbot_json.py',
- ), '--check'
- ],
- kwargs={},
- message=output_api.PresubmitError),
- ])
- return []
- def CheckLucicfgGenOutputMain(input_api, output_api):
- return input_api.RunTests(input_api.canned_checks.CheckLucicfgGenOutput(
- input_api, output_api, 'main.star'))
- def CheckLucicfgGenOutputDev(input_api, output_api):
- return input_api.RunTests(input_api.canned_checks.CheckLucicfgGenOutput(
- input_api, output_api, 'dev.star'))
- def CheckChangedLUCIConfigs(input_api, output_api):
- return input_api.canned_checks.CheckChangedLUCIConfigs(
- input_api, output_api)
- # Footer indicating a CL that is trying to address an outage by some mechanism
- # other than those in infra/config/outages
- _OUTAGE_ACTION_FOOTER = 'Infra-Config-Outage-Action'
- # Footer acknowledging that an outages configuration is in effect when making an
- # unrelated change
- _IGNORE_OUTAGE_FOOTER = 'Infra-Config-Ignore-Outage'
- def CheckOutagesConfigOnCommit(input_api, output_api):
- outages_pyl = input_api.os_path.join(
- input_api.PresubmitLocalPath(), 'generated/outages.pyl')
- with open(outages_pyl) as f:
- outages_config = input_api.ast.literal_eval(f.read())
- if not outages_config:
- footers = input_api.change.GitFootersFromDescription()
- return [
- output_api.PresubmitError(
- 'There is no outages configuration in effect, '
- 'please remove the {} footer from your CL description.'
- .format(footer))
- for footer in (_OUTAGE_ACTION_FOOTER, _IGNORE_OUTAGE_FOOTER)
- if footer in footers
- ]
- # Any of the config files under infra/config/outages
- outages_config_files = set()
- # Any of the config files under infra/config/generated
- generated_config_files = set()
- # Any config files that are not under infra/config/outages or
- # infra/config/generated
- config_files = set()
- for p in input_api.LocalPaths():
- if p in ('README.md', 'OWNERS'):
- continue
- if p.startswith('infra/config/outages/'):
- outages_config_files.add(p)
- continue
- if p.startswith('infra/config/generated/'):
- generated_config_files.add(p)
- continue
- config_files.add(p)
- # If the only changes to non-generated config fies were the outages files,
- # assume the change was addressing an outage and that no additional mechanism
- # needs to be added
- if outages_config_files and not config_files:
- # REVIEWER: Should we prevent the footers from being here in this case?
- return []
- # If any non-generated, non-outages files were modified or if the generated
- # config files were modified without any config files being modified (lucicfg
- # change, etc.) then make sure the user knows that when the outages
- # configuration is disabled, the generated configuration may change
- if config_files or generated_config_files:
- footers = input_api.change.GitFootersFromDescription()
- has_action_footer = _OUTAGE_ACTION_FOOTER in footers
- has_ignore_footer = _IGNORE_OUTAGE_FOOTER in footers
- if has_action_footer and has_ignore_footer:
- return [
- output_api.PresubmitError(
- 'Only one of {} or {} should be present in your CL description'
- .format(_OUTAGE_ACTION_FOOTER, _IGNORE_OUTAGE_FOOTER)),
- ]
- if not has_action_footer and not has_ignore_footer:
- outages_config_lines = ['{}: {}'.format(k, v)
- for k, v in sorted(outages_config.items())]
- return [
- output_api.PresubmitError('\n'.join([
- 'The following outages configuration is in effect:\n {}'.format(
- '\n '.join(outages_config_lines)),
- ('The effect of your change may not be visible '
- 'in the generated configuration.'),
- ('If your change is addressing the outage, '
- 'please add the footer {} with a link for the outage.'
- ).format(_OUTAGE_ACTION_FOOTER),
- ('If your change is not addressing the outage '
- 'but you still wish to land it, please add the footer '
- '{} with a reason.').format(_IGNORE_OUTAGE_FOOTER),
- ('For more information on outages configuration, '
- 'see https://chromium.googlesource.com/chromium/src/+/HEAD/infra/config/outages'
- ),
- ])),
- ]
- return []
|