| from recipe_engine.post_process import MustRun, DoesNotRun, SummaryMarkdown, StatusSuccess |
| from PB.recipe_engine.result import RawResult |
| from PB.go.chromium.org.luci.buildbucket.proto import common |
| |
| PYTHON_VERSION_COMPATIBILITY = "PY3" |
| |
| # Reference: https://chromium.googlesource.com/infra/luci/recipes-py/+/HEAD/doc/ |
| |
| # All the deps get combined into an `api` variable passed in to RunSteps and |
| # GenTests. Versions and urls are specified in `recipes.cfg`. |
| DEPS = [ |
| 'depot_tools/gsutil', |
| 'infra/zip', |
| 'fuchsia/git', |
| 'recipe_engine/buildbucket', |
| 'recipe_engine/context', |
| 'recipe_engine/file', |
| 'recipe_engine/nodejs', |
| 'recipe_engine/path', |
| 'recipe_engine/raw_io', |
| 'recipe_engine/step', |
| ] |
| |
| |
| def RunSteps(api): |
| # Check out the change and run the frontend linter, type checker, and tests |
| # to verify the change as part of Change Verification (ie. CQ label). |
| |
| # Checkout the change into a special 'cleanup' folder that is cleared |
| # between runs of the recipe. |
| checkout_root = api.path.cleanup_dir / 'checkout' |
| api.file.ensure_directory("makedirs", checkout_root) |
| |
| env = _downloadChromeAndAddToPath(api) |
| with api.context(env=env, cwd=checkout_root): |
| _downloadChange(api) |
| |
| # Now run our verification in the checked out code directory. |
| |
| # Current LTS for Node.js. Version must be in CIPD packages: |
| # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/nodejs/linux-amd64/+/1cb45bwKzXjXAIzSc5CoxHP2JQr89nMIwzhrziyRFDcC |
| with api.nodejs(version='20.8.1'): |
| # Named steps to test the change. |
| # TODO: pipe output to both LUCI UI and Gerrit checks result |
| api.step('install yarn', ['npm', 'install', '-g', 'yarn']) |
| api.step('install deps', ['yarn', 'setup']) |
| api.step('run type checker', ['yarn', 'compile']) |
| api.step('run linter', ['yarn', 'lint']) |
| api.step('run tests', ['yarn', 'test']) |
| return RawResult( |
| status=common.SUCCESS, |
| summary_markdown='All checks pass!', |
| ) |
| |
| |
| def _downloadChange(api): |
| gerrit_change = api.buildbucket.build.input.gerrit_changes[0] |
| remote = "https://gerrit.googlesource.com/gerrit" |
| change_ref = "refs/changes/%02d/%d/%d" % ( |
| gerrit_change.change % 100, |
| gerrit_change.change, |
| gerrit_change.patchset, |
| ) |
| api.git.init() |
| api.git.remote_add("origin", remote) |
| api.git.fetch( |
| repository="origin", |
| refspec=change_ref, |
| tags=True, |
| recurse_submodules=True, |
| ) |
| api.git.raw_checkout(ref="FETCH_HEAD", force=True) |
| api.git.sync_submodule(recursive=True) |
| api.git.update_submodule(recursive=True) |
| |
| |
| def _downloadChromeAndAddToPath(api): |
| # Download and unzip Chrome from a cloud storage bucket, then add it to the PATH |
| # and rename it for compatibility with our test runner: |
| # https://github.com/GoogleChrome/chrome-launcher#launch-options |
| # Adapted from: |
| # https://chromium.googlesource.com/infra/infra/+/refs/heads/main/recipes/recipes/gerrit_plugins.py |
| with api.step.nest('get chrome'): |
| chrome = api.path.mkdtemp(prefix='chrome') |
| gs_bucket = 'chromium-browser-snapshots' |
| gs_path = 'Linux_x64' |
| version_file = 'LAST_CHANGE' |
| chrome_zip = 'chrome-linux.zip' |
| api.gsutil.download(gs_bucket, '%s/%s' % |
| (gs_path, version_file), chrome) |
| version = api.file.read_text('read latest chrome version', |
| chrome / version_file) |
| api.gsutil.download(gs_bucket, '%s/%s/%s' % |
| (gs_path, version, chrome_zip), chrome) |
| api.zip.unzip('unzip chrome', chrome / chrome_zip, chrome / 'zip') |
| chrome_path = chrome / 'zip' / 'chrome-linux' |
| |
| # The chrome-launcher package expects a binary named "google-chrome" rather |
| # than "chrome": |
| # https://github.com/GoogleChrome/chrome-launcher/blob/c753ba083c43a90d98b682bf9ffdfe21680e6208/src/chrome-finder.ts#L133 |
| chrome_bin = chrome_path / 'chrome' |
| google_chrome_bin = chrome_path / 'google-chrome' |
| api.step('rename to google-chrome', |
| ['mv', chrome_bin, google_chrome_bin]) |
| env = { |
| 'PATH': api.path.pathsep.join([str(chrome_path), '%(PATH)s']), |
| } |
| return env |
| |
| |
| def GenTests(api): |
| # Test the recipe and generate the expect json file. |
| yield api.test( |
| 'polygerrit-ui_changes', |
| api.buildbucket.try_build( |
| project="gerrit", |
| git_repo="https://gerrit.googlesource.com/gerrit", |
| change_number=123, |
| patch_set=4 |
| ), |
| api.post_process(MustRun, 'run type checker'), |
| api.post_process(MustRun, 'run linter'), |
| api.post_process(MustRun, 'run tests'), |
| api.post_process(StatusSuccess), |
| api.post_process(SummaryMarkdown, 'All checks pass!'), |
| ) |
| |
| yield api.test( |
| 'polygerrit-ui_changes with failed step', |
| api.buildbucket.try_build( |
| project="gerrit", |
| git_repo="https://gerrit.googlesource.com/gerrit", |
| change_number=123, |
| patch_set=4 |
| ), |
| api.override_step_data( |
| 'run linter', |
| retcode=1, |
| stdout=api.raw_io.output('Linter fail: xyz') |
| ), |
| api.post_process(MustRun, 'run type checker'), |
| api.post_process(MustRun, 'run linter'), |
| api.post_process(DoesNotRun, 'run tests'), |
| api.expect_status('FAILURE'), |
| api.post_process(SummaryMarkdown, 'Step(\'run linter\') (retcode: 1)'), |
| ) |