From e1c11a36c7687feb38b763c54e5269876a150e44 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Wed, 9 Sep 2020 14:37:38 +0200 Subject: [PATCH] feat(dev-infra): introduce new configuration for release tool (#38656) Introduces a new configuration for the `ng-dev release` command. This configuration will be the source of truth for all release packages and how they can be built. Additionally, in a temporary manner where each project has its own way of generating the changelog, the changelog generation can be configured. This will be removed in the future when there is canonical changelog generation in the dev-infra shared package. PR Close #38656 --- .ng-dev/config.ts | 2 + .ng-dev/release.ts | 33 +++++++++++++++ dev-infra/release/config/BUILD.bazel | 14 +++++++ dev-infra/release/config/index.ts | 63 ++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 .ng-dev/release.ts create mode 100644 dev-infra/release/config/BUILD.bazel create mode 100644 dev-infra/release/config/index.ts diff --git a/.ng-dev/config.ts b/.ng-dev/config.ts index 573b9f1847..4f059b5a6e 100644 --- a/.ng-dev/config.ts +++ b/.ng-dev/config.ts @@ -3,6 +3,7 @@ import {commitMessage} from './commit-message'; import {format} from './format'; import {github} from './github'; import {merge} from './merge'; +import {release} from './release'; module.exports = { commitMessage, @@ -10,4 +11,5 @@ module.exports = { github, merge, caretaker, + release, }; diff --git a/.ng-dev/release.ts b/.ng-dev/release.ts new file mode 100644 index 0000000000..b285ece61a --- /dev/null +++ b/.ng-dev/release.ts @@ -0,0 +1,33 @@ +import {join} from 'path'; +import {exec} from 'shelljs'; +import {ReleaseConfig} from '../dev-infra/release/config'; + +/** Configuration for the `ng-dev release` command. */ +export const release: ReleaseConfig = { + npmPackages: [ + '@angular/animations', + '@angular/bazel', + '@angular/common', + '@angular/compiler', + '@angular/compiler-cli', + '@angular/core', + '@angular/elements', + '@angular/forms', + '@angular/language-service', + '@angular/localize', + '@angular/platform-browser', + '@angular/platform-browser-dynamic', + '@angular/platform-server', + '@angular/platform-webworker', + '@angular/platform-webworker-dynamic', + '@angular/router', + '@angular/service-worker', + '@angular/upgrade', + ], + // TODO: Implement release package building here. + buildPackages: async () => [], + // TODO: This can be removed once there is a org-wide tool for changelog generation. + generateReleaseNotesForHead: async () => { + exec('yarn -s gulp changelog', {cwd: join(__dirname, '../')}); + }, +}; diff --git a/dev-infra/release/config/BUILD.bazel b/dev-infra/release/config/BUILD.bazel new file mode 100644 index 0000000000..b8f17b6bf2 --- /dev/null +++ b/dev-infra/release/config/BUILD.bazel @@ -0,0 +1,14 @@ +load("@npm_bazel_typescript//:index.bzl", "ts_library") + +ts_library( + name = "config", + srcs = glob([ + "**/*.ts", + ]), + module_name = "@angular/dev-infra-private/release/config", + visibility = ["//dev-infra:__subpackages__"], + deps = [ + "//dev-infra/utils", + "@npm//@types/semver", + ], +) diff --git a/dev-infra/release/config/index.ts b/dev-infra/release/config/index.ts new file mode 100644 index 0000000000..da1f759116 --- /dev/null +++ b/dev-infra/release/config/index.ts @@ -0,0 +1,63 @@ +/** + * @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 semver from 'semver'; + +import {assertNoErrors, getConfig, NgDevConfig} from '../../utils/config'; + +/** Interface describing a built package. */ +export interface BuiltPackage { + /** Name of the package. */ + name: string; + /** Path to the package output directory. */ + outputPath: string; +} + +/** Configuration for staging and publishing a release. */ +export interface ReleaseConfig { + /** Registry URL used for publishing release packages. Defaults to the NPM registry. */ + publishRegistry?: string; + /** List of NPM packages that are published as part of this project. */ + npmPackages: string[]; + /** Builds release packages and returns a list of paths pointing to the output. */ + buildPackages: () => Promise; + /** Generates the release notes from the most recent tag to `HEAD`. */ + generateReleaseNotesForHead: (outputPath: string) => Promise; + /** + * Gets a pattern for extracting the release notes of the a given version. + * @returns A pattern matching the notes for a given version (including the header). + */ + // TODO: Remove this in favor of a canonical changelog format across the Angular organization. + extractReleaseNotesPattern?: (version: semver.SemVer) => RegExp; +} + +/** Configuration for releases in the dev-infra configuration. */ +export type DevInfraReleaseConfig = NgDevConfig<{release: ReleaseConfig}>; + +/** Retrieve and validate the config as `ReleaseConfig`. */ +export function getReleaseConfig(config: Partial = getConfig()): + ReleaseConfig { + // List of errors encountered validating the config. + const errors: string[] = []; + + if (config.release === undefined) { + errors.push(`No configuration defined for "release"`); + } + if (config.release?.npmPackages === undefined) { + errors.push(`No "npmPackages" configured for releasing.`); + } + if (config.release?.buildPackages === undefined) { + errors.push(`No "buildPackages" function configured for releasing.`); + } + if (config.release?.generateReleaseNotesForHead === undefined) { + errors.push(`No "generateReleaseNotesForHead" function configured for releasing.`); + } + + assertNoErrors(errors); + return config.release!; +}