Move the release notes tooling under its own directory under release rather than within publish, in preparation to have a release note generation command for ad-hoc release note generation. PR Close #42225
		
			
				
	
	
		
			93 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * @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 {render} from 'ejs';
 | 
						|
import * as semver from 'semver';
 | 
						|
import {CommitFromGitLog} from '../../commit-message/parse';
 | 
						|
 | 
						|
import {getCommitsInRange} from '../../commit-message/utils';
 | 
						|
import {promptInput} from '../../utils/console';
 | 
						|
import {GitClient} from '../../utils/git/index';
 | 
						|
import {DevInfraReleaseConfig, getReleaseConfig, ReleaseNotesConfig} from '../config/index';
 | 
						|
import {RenderContext} from './context';
 | 
						|
 | 
						|
import changelogTemplate from './templates/changelog';
 | 
						|
import githubReleaseTemplate from './templates/github-release';
 | 
						|
 | 
						|
/** Release note generation. */
 | 
						|
export class ReleaseNotes {
 | 
						|
  static async fromRange(version: semver.SemVer, startingRef: string, endingRef: string) {
 | 
						|
    return new ReleaseNotes(version, startingRef, endingRef);
 | 
						|
  }
 | 
						|
 | 
						|
  /** An instance of GitClient. */
 | 
						|
  private git = GitClient.getInstance();
 | 
						|
  /** The RenderContext to be used during rendering. */
 | 
						|
  private renderContext: RenderContext|undefined;
 | 
						|
  /** The title to use for the release. */
 | 
						|
  private title: string|false|undefined;
 | 
						|
  /** A promise resolving to a list of Commits since the latest semver tag on the branch. */
 | 
						|
  private commits: Promise<CommitFromGitLog[]> =
 | 
						|
      this.getCommitsInRange(this.startingRef, this.endingRef);
 | 
						|
  /** The configuration for release notes. */
 | 
						|
  private config: ReleaseNotesConfig = this.getReleaseConfig().releaseNotes;
 | 
						|
 | 
						|
  protected constructor(
 | 
						|
      public version: semver.SemVer, private startingRef: string, private endingRef: string) {}
 | 
						|
 | 
						|
  /** Retrieve the release note generated for a Github Release. */
 | 
						|
  async getGithubReleaseEntry(): Promise<string> {
 | 
						|
    return render(githubReleaseTemplate, await this.generateRenderContext(), {rmWhitespace: true});
 | 
						|
  }
 | 
						|
 | 
						|
  /** Retrieve the release note generated for a CHANGELOG entry. */
 | 
						|
  async getChangelogEntry() {
 | 
						|
    return render(changelogTemplate, await this.generateRenderContext(), {rmWhitespace: true});
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Prompt the user for a title for the release, if the project's configuration is defined to use a
 | 
						|
   * title.
 | 
						|
   */
 | 
						|
  async promptForReleaseTitle() {
 | 
						|
    if (this.title === undefined) {
 | 
						|
      if (this.config.useReleaseTitle) {
 | 
						|
        this.title = await promptInput('Please provide a title for the release:');
 | 
						|
      } else {
 | 
						|
        this.title = false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return this.title;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Build the render context data object for constructing the RenderContext instance. */
 | 
						|
  private async generateRenderContext(): Promise<RenderContext> {
 | 
						|
    if (!this.renderContext) {
 | 
						|
      this.renderContext = new RenderContext({
 | 
						|
        commits: await this.commits,
 | 
						|
        github: this.git.remoteConfig,
 | 
						|
        version: this.version.format(),
 | 
						|
        groupOrder: this.config.groupOrder,
 | 
						|
        hiddenScopes: this.config.hiddenScopes,
 | 
						|
        title: await this.promptForReleaseTitle(),
 | 
						|
      });
 | 
						|
    }
 | 
						|
    return this.renderContext;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  // These methods are used for access to the utility functions while allowing them to be
 | 
						|
  // overwritten in subclasses during testing.
 | 
						|
  protected async getCommitsInRange(from: string, to?: string) {
 | 
						|
    return getCommitsInRange(from, to);
 | 
						|
  }
 | 
						|
 | 
						|
  protected getReleaseConfig(config?: Partial<DevInfraReleaseConfig>) {
 | 
						|
    return getReleaseConfig(config);
 | 
						|
  }
 | 
						|
}
 |