From 4bce21358da8584db93314f83d041e6caaf8e4f1 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Wed, 30 Sep 2020 14:32:19 -0700 Subject: [PATCH] feat(dev-infra): add a command to verify NgBot YAML config syntax (#39071) This commit adds a new command to the `ng-dev` suite, which verifies that the NgBot YAML config is correct. It also adds this command to the `lint` CircleCI job so that we execute this check while running CI. This should help prevent syntax errors similar to the one introduced in: https://github.com/angular/angular/commit/393ce5574b76ad1344554a6aa9e2e8a6c3591ac9 PR Close #39071 --- .circleci/config.yml | 1 + dev-infra/BUILD.bazel | 1 + dev-infra/cli.ts | 2 ++ dev-infra/ngbot/BUILD.bazel | 19 +++++++++++++++++++ dev-infra/ngbot/cli.ts | 19 +++++++++++++++++++ dev-infra/ngbot/verify.ts | 31 +++++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 dev-infra/ngbot/BUILD.bazel create mode 100644 dev-infra/ngbot/cli.ts create mode 100644 dev-infra/ngbot/verify.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index d75e1f9b4f..f83c13c575 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -273,6 +273,7 @@ jobs: - run: yarn -s ng-dev format changed $CI_GIT_BASE_REVISION --check - run: yarn -s ts-circular-deps:check - run: yarn -s ng-dev pullapprove verify + - run: yarn -s ng-dev ngbot verify - run: yarn -s ng-dev commit-message validate-range --range $CI_COMMIT_RANGE test: diff --git a/dev-infra/BUILD.bazel b/dev-infra/BUILD.bazel index 065f6efad7..4a421226ec 100644 --- a/dev-infra/BUILD.bazel +++ b/dev-infra/BUILD.bazel @@ -11,6 +11,7 @@ ts_library( "//dev-infra/caretaker", "//dev-infra/commit-message", "//dev-infra/format", + "//dev-infra/ngbot", "//dev-infra/pr", "//dev-infra/pullapprove", "//dev-infra/release", diff --git a/dev-infra/cli.ts b/dev-infra/cli.ts index 5ec25a6245..c83db4117c 100644 --- a/dev-infra/cli.ts +++ b/dev-infra/cli.ts @@ -15,6 +15,7 @@ import {buildReleaseParser} from './release/cli'; import {buildPrParser} from './pr/cli'; import {captureLogOutputForCommand} from './utils/console'; import {buildCaretakerParser} from './caretaker/cli'; +import {buildNgbotParser} from './ngbot/cli'; yargs.scriptName('ng-dev') .middleware(captureLogOutputForCommand) @@ -27,6 +28,7 @@ yargs.scriptName('ng-dev') .command('release ', '', buildReleaseParser) .command('ts-circular-deps ', '', tsCircularDependenciesBuilder) .command('caretaker ', '', buildCaretakerParser) + .command('ngbot ', false, buildNgbotParser) .wrap(120) .strict() .parse(); diff --git a/dev-infra/ngbot/BUILD.bazel b/dev-infra/ngbot/BUILD.bazel new file mode 100644 index 0000000000..2f472476ae --- /dev/null +++ b/dev-infra/ngbot/BUILD.bazel @@ -0,0 +1,19 @@ +load("@npm_bazel_typescript//:index.bzl", "ts_library") + +ts_library( + name = "ngbot", + srcs = [ + "cli.ts", + "verify.ts", + ], + module_name = "@angular/dev-infra-private/ngbot", + visibility = ["//dev-infra:__subpackages__"], + deps = [ + "//dev-infra/utils", + "@npm//@types/node", + "@npm//@types/yaml", + "@npm//@types/yargs", + "@npm//yaml", + "@npm//yargs", + ], +) diff --git a/dev-infra/ngbot/cli.ts b/dev-infra/ngbot/cli.ts new file mode 100644 index 0000000000..9a881ee92e --- /dev/null +++ b/dev-infra/ngbot/cli.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import * as yargs from 'yargs'; +import {verify} from './verify'; + +/** Build the parser for the NgBot commands. */ +export function buildNgbotParser(localYargs: yargs.Argv) { + return localYargs.help().strict().demandCommand().command( + 'verify', 'Verify the NgBot config', {}, () => verify()); +} + +if (require.main === module) { + buildNgbotParser(yargs).parse(); +} diff --git a/dev-infra/ngbot/verify.ts b/dev-infra/ngbot/verify.ts new file mode 100644 index 0000000000..a5c2449376 --- /dev/null +++ b/dev-infra/ngbot/verify.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import {readFileSync} from 'fs'; +import {resolve} from 'path'; +import {parse as parseYaml} from 'yaml'; + +import {getRepoBaseDir} from '../utils/config'; +import {error, green, info, red} from '../utils/console'; + +export function verify() { + /** Full path to NgBot config file */ + const NGBOT_CONFIG_YAML_PATH = resolve(getRepoBaseDir(), '.github/angular-robot.yml'); + + /** The NgBot config file */ + const ngBotYaml = readFileSync(NGBOT_CONFIG_YAML_PATH, 'utf8'); + + try { + // Try parsing the config file to verify that the syntax is correct. + parseYaml(ngBotYaml); + info(`${green('√')} Valid NgBot YAML config`); + } catch (e) { + error(`${red('!')} Invalid NgBot YAML config`); + error(e); + process.exitCode = 1; + } +}