release-please 13.21.0 → 14.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,48 @@
4
4
 
5
5
  [1]: https://www.npmjs.com/package/release-please?activeTab=versions
6
6
 
7
+ ## [14.1.1](https://github.com/googleapis/release-please/compare/v14.1.0...v14.1.1) (2022-08-23)
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * add REST API call to fetch pull requests without files ([#1591](https://github.com/googleapis/release-please/issues/1591)) ([b875a1f](https://github.com/googleapis/release-please/commit/b875a1f437889a46f8cb6e86648073b51401ab9e))
13
+
14
+ ## [14.1.0](https://github.com/googleapis/release-please/compare/v14.0.0...v14.1.0) (2022-08-19)
15
+
16
+
17
+ ### Features
18
+
19
+ * Allow $schema key in manifest config schema ([#1584](https://github.com/googleapis/release-please/issues/1584)) ([d0d43a0](https://github.com/googleapis/release-please/commit/d0d43a0f15d44941c2338f3c8e8c9f972fb45938))
20
+ * customize pr body header ([#1579](https://github.com/googleapis/release-please/issues/1579)) ([92e1366](https://github.com/googleapis/release-please/commit/92e13664bc5a7c4b849f3cea367944280e20b894))
21
+ * use file-cache from git-file-utils ([#1585](https://github.com/googleapis/release-please/issues/1585)) ([e0572f8](https://github.com/googleapis/release-please/commit/e0572f899202ddbad995e8ff21621166d7aae07e))
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * convert `MissingFileError` thrown by `git-file-utils` ([#1590](https://github.com/googleapis/release-please/issues/1590)) ([cf4f0a3](https://github.com/googleapis/release-please/commit/cf4f0a3068a049cac99d191f40195c686baee413))
27
+ * correct $schema format in manifest config schema ([#1589](https://github.com/googleapis/release-please/issues/1589)) ([e25537b](https://github.com/googleapis/release-please/commit/e25537b559d56c46aedba1e83f7dda7c6825781f))
28
+ * **deps:** update git-file-utils to 1.1.0 ([297a7b7](https://github.com/googleapis/release-please/commit/297a7b7ef862b7aa5e64a6077f86d674eefc140e))
29
+ * use git-file-utils' cache for file search ([#1588](https://github.com/googleapis/release-please/issues/1588)) ([297a7b7](https://github.com/googleapis/release-please/commit/297a7b7ef862b7aa5e64a6077f86d674eefc140e))
30
+
31
+ ## [14.0.0](https://github.com/googleapis/release-please/compare/v13.21.0...v14.0.0) (2022-08-15)
32
+
33
+
34
+ ### ⚠ BREAKING CHANGES
35
+
36
+ * **deps:** update octokit packages
37
+ * drop node 12 support (#1577)
38
+
39
+ ### Bug Fixes
40
+
41
+ * **deps:** update code-suggester to v4 ([3fc0173](https://github.com/googleapis/release-please/commit/3fc0173e7342e082794c1911b2e7a6e61d810348))
42
+ * **deps:** update octokit packages ([3fc0173](https://github.com/googleapis/release-please/commit/3fc0173e7342e082794c1911b2e7a6e61d810348))
43
+
44
+
45
+ ### Build System
46
+
47
+ * drop node 12 support ([#1577](https://github.com/googleapis/release-please/issues/1577)) ([3fc0173](https://github.com/googleapis/release-please/commit/3fc0173e7342e082794c1911b2e7a6e61d810348))
48
+
7
49
  ## [13.21.0](https://github.com/googleapis/release-please/compare/v13.20.0...v13.21.0) (2022-08-11)
8
50
 
9
51
 
@@ -266,6 +266,10 @@ function taggingOptions(yargs) {
266
266
  .option('pull-request-title-pattern', {
267
267
  describe: 'Title pattern to make release PR',
268
268
  type: 'string',
269
+ })
270
+ .option('pull-request-header', {
271
+ describe: 'Header for release PR',
272
+ type: 'string',
269
273
  });
270
274
  }
271
275
  const createReleasePullRequestCommand = {
@@ -290,6 +294,7 @@ const createReleasePullRequestCommand = {
290
294
  changelogType: argv.changelogType,
291
295
  changelogHost: argv.changelogHost,
292
296
  pullRequestTitlePattern: argv.pullRequestTitlePattern,
297
+ pullRequestHeader: argv.pullRequestHeader,
293
298
  changelogSections: argv.changelogSections,
294
299
  releaseAs: argv.releaseAs,
295
300
  versioning: argv.versioningStrategy,
@@ -9,7 +9,7 @@ import { Repository } from './repository';
9
9
  import { ReleasePullRequest } from './release-pull-request';
10
10
  import { Update } from './update';
11
11
  import { Release } from './release';
12
- import { GitHubFileContents } from './util/file-cache';
12
+ import { GitHubFileContents } from '@google-automations/git-file-utils';
13
13
  declare type RequestBuilderType = typeof request;
14
14
  declare type DefaultFunctionType = RequestBuilderType['defaults'];
15
15
  declare type RequestFunctionType = ReturnType<DefaultFunctionType>;
@@ -138,12 +138,34 @@ export declare class GitHub {
138
138
  /**
139
139
  * Iterate through merged pull requests with a max number of results scanned.
140
140
  *
141
- * @param {number} maxResults maxResults - Limit the number of results searched.
142
- * Defaults to unlimited.
141
+ * @param {string} targetBranch The base branch of the pull request
142
+ * @param {string} status The status of the pull request
143
+ * @param {number} maxResults Limit the number of results searched. Defaults to
144
+ * unlimited.
145
+ * @param {boolean} includeFiles Whether to fetch the list of files included in
146
+ * the pull request. Defaults to `true`.
143
147
  * @yields {PullRequest}
144
148
  * @throws {GitHubAPIError} on an API error
145
149
  */
146
- pullRequestIterator(targetBranch: string, status?: 'OPEN' | 'CLOSED' | 'MERGED', maxResults?: number): AsyncGenerator<PullRequest, void, unknown>;
150
+ pullRequestIterator(targetBranch: string, status?: 'OPEN' | 'CLOSED' | 'MERGED', maxResults?: number, includeFiles?: boolean): AsyncGenerator<PullRequest, void, void>;
151
+ /**
152
+ * Helper implementation of pullRequestIterator that includes files via
153
+ * the graphQL API.
154
+ *
155
+ * @param {string} targetBranch The base branch of the pull request
156
+ * @param {string} status The status of the pull request
157
+ * @param {number} maxResults Limit the number of results searched
158
+ */
159
+ private pullRequestIteratorWithFiles;
160
+ /**
161
+ * Helper implementation of pullRequestIterator that excludes files
162
+ * via the REST API.
163
+ *
164
+ * @param {string} targetBranch The base branch of the pull request
165
+ * @param {string} status The status of the pull request
166
+ * @param {number} maxResults Limit the number of results searched
167
+ */
168
+ private pullRequestIteratorWithoutFiles;
147
169
  /**
148
170
  * Return a list of merged pull requests. The list is not guaranteed to be sorted
149
171
  * by merged_at, but is generally most recent first.
@@ -27,7 +27,7 @@ exports.GH_GRAPHQL_URL = 'https://api.github.com';
27
27
  const logger_1 = require("./util/logger");
28
28
  const manifest_1 = require("./manifest");
29
29
  const signoff_commit_message_1 = require("./util/signoff-commit-message");
30
- const file_cache_1 = require("./util/file-cache");
30
+ const git_file_utils_1 = require("@google-automations/git-file-utils");
31
31
  class GitHub {
32
32
  constructor(options) {
33
33
  /**
@@ -107,30 +107,7 @@ class GitHub {
107
107
  prefix = normalizePrefix(prefix);
108
108
  }
109
109
  logger_1.logger.debug(`finding files by filename: ${filename}, ref: ${ref}, prefix: ${prefix}`);
110
- const response = await this.octokit.git.getTree({
111
- owner: this.repository.owner,
112
- repo: this.repository.repo,
113
- tree_sha: ref,
114
- recursive: 'true',
115
- });
116
- return response.data.tree
117
- .filter(file => {
118
- const path = file.path;
119
- return (path &&
120
- // match the filename
121
- path.endsWith(filename) &&
122
- // match the prefix if provided
123
- (!prefix || path.startsWith(`${prefix}/`)));
124
- })
125
- .map(file => {
126
- let path = file.path;
127
- // strip the prefix if provided
128
- if (prefix) {
129
- const pfix = new RegExp(`^${prefix}[/\\\\]`);
130
- path = path.replace(pfix, '');
131
- }
132
- return path;
133
- });
110
+ return await this.fileCache.findFilesByFilename(filename, ref, prefix);
134
111
  });
135
112
  this.createPullRequest = wrapAsync(async (pullRequest, targetBranch, message, updates, options) => {
136
113
  // Update the files for the release if not already supplied
@@ -245,30 +222,7 @@ class GitHub {
245
222
  if (prefix) {
246
223
  prefix = normalizePrefix(prefix);
247
224
  }
248
- const response = await this.octokit.git.getTree({
249
- owner: this.repository.owner,
250
- repo: this.repository.repo,
251
- tree_sha: ref,
252
- recursive: 'true',
253
- });
254
- return response.data.tree
255
- .filter(file => {
256
- const path = file.path;
257
- return (path &&
258
- // match the file extension
259
- path.endsWith(`.${extension}`) &&
260
- // match the prefix if provided
261
- (!prefix || path.startsWith(`${prefix}/`)));
262
- })
263
- .map(file => {
264
- let path = file.path;
265
- // strip the prefix if provided
266
- if (prefix) {
267
- const pfix = new RegExp(`^${prefix}[/\\\\]`);
268
- path = path.replace(pfix, '');
269
- }
270
- return path;
271
- });
225
+ return this.fileCache.findFilesByExtension(extension, ref, prefix);
272
226
  });
273
227
  /**
274
228
  * Create a GitHub release
@@ -368,7 +322,7 @@ class GitHub {
368
322
  this.octokit = options.octokitAPIs.octokit;
369
323
  this.request = options.octokitAPIs.request;
370
324
  this.graphql = options.octokitAPIs.graphql;
371
- this.fileCache = new file_cache_1.RepositoryFileCache(this.octokit, this.repository);
325
+ this.fileCache = new git_file_utils_1.RepositoryFileCache(this.octokit, this.repository);
372
326
  }
373
327
  /**
374
328
  * Build a new GitHub client with auto-detected default branch.
@@ -614,12 +568,32 @@ class GitHub {
614
568
  /**
615
569
  * Iterate through merged pull requests with a max number of results scanned.
616
570
  *
617
- * @param {number} maxResults maxResults - Limit the number of results searched.
618
- * Defaults to unlimited.
571
+ * @param {string} targetBranch The base branch of the pull request
572
+ * @param {string} status The status of the pull request
573
+ * @param {number} maxResults Limit the number of results searched. Defaults to
574
+ * unlimited.
575
+ * @param {boolean} includeFiles Whether to fetch the list of files included in
576
+ * the pull request. Defaults to `true`.
619
577
  * @yields {PullRequest}
620
578
  * @throws {GitHubAPIError} on an API error
621
579
  */
622
- async *pullRequestIterator(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER) {
580
+ async *pullRequestIterator(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER, includeFiles = true) {
581
+ const generator = includeFiles
582
+ ? this.pullRequestIteratorWithFiles(targetBranch, status, maxResults)
583
+ : this.pullRequestIteratorWithoutFiles(targetBranch, status, maxResults);
584
+ for await (const pullRequest of generator) {
585
+ yield pullRequest;
586
+ }
587
+ }
588
+ /**
589
+ * Helper implementation of pullRequestIterator that includes files via
590
+ * the graphQL API.
591
+ *
592
+ * @param {string} targetBranch The base branch of the pull request
593
+ * @param {string} status The status of the pull request
594
+ * @param {number} maxResults Limit the number of results searched
595
+ */
596
+ async *pullRequestIteratorWithFiles(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER) {
623
597
  let cursor = undefined;
624
598
  let results = 0;
625
599
  while (results < maxResults) {
@@ -638,6 +612,52 @@ class GitHub {
638
612
  cursor = response.pageInfo.endCursor;
639
613
  }
640
614
  }
615
+ /**
616
+ * Helper implementation of pullRequestIterator that excludes files
617
+ * via the REST API.
618
+ *
619
+ * @param {string} targetBranch The base branch of the pull request
620
+ * @param {string} status The status of the pull request
621
+ * @param {number} maxResults Limit the number of results searched
622
+ */
623
+ async *pullRequestIteratorWithoutFiles(targetBranch, status = 'MERGED', maxResults = Number.MAX_SAFE_INTEGER) {
624
+ const statusMap = {
625
+ OPEN: 'open',
626
+ CLOSED: 'closed',
627
+ MERGED: 'closed',
628
+ };
629
+ let results = 0;
630
+ for await (const { data: pulls } of this.octokit.paginate.iterator(this.octokit.rest.pulls.list, {
631
+ state: statusMap[status],
632
+ owner: this.repository.owner,
633
+ repo: this.repository.repo,
634
+ base: targetBranch,
635
+ })) {
636
+ for (const pull of pulls) {
637
+ // The REST API does not have an option for "merged"
638
+ // pull requests - they are closed with a `merge_commit_sha`
639
+ if (status !== 'MERGED' || pull.merge_commit_sha) {
640
+ results += 1;
641
+ yield {
642
+ headBranchName: pull.head.ref,
643
+ baseBranchName: pull.base.ref,
644
+ number: pull.number,
645
+ title: pull.title,
646
+ body: pull.body || '',
647
+ labels: pull.labels.map(label => label.name),
648
+ files: [],
649
+ sha: pull.merge_commit_sha || undefined,
650
+ };
651
+ if (results >= maxResults) {
652
+ break;
653
+ }
654
+ }
655
+ }
656
+ if (results >= maxResults) {
657
+ break;
658
+ }
659
+ }
660
+ }
641
661
  /**
642
662
  * Return a list of merged pull requests. The list is not guaranteed to be sorted
643
663
  * by merged_at, but is generally most recent first.
@@ -852,7 +872,15 @@ class GitHub {
852
872
  */
853
873
  async getFileContentsOnBranch(path, branch) {
854
874
  logger_1.logger.debug(`Fetching ${path} from branch ${branch}`);
855
- return await this.fileCache.getFileContents(path, branch);
875
+ try {
876
+ return await this.fileCache.getFileContents(path, branch);
877
+ }
878
+ catch (e) {
879
+ if (e instanceof git_file_utils_1.FileNotFoundError) {
880
+ throw new errors_1.FileNotFoundError(path);
881
+ }
882
+ throw e;
883
+ }
856
884
  }
857
885
  async getFileJson(path, branch) {
858
886
  const content = await this.getFileContentsOnBranch(path, branch);
@@ -934,7 +962,7 @@ class GitHub {
934
962
  changes.set(update.path, {
935
963
  content: updatedContent,
936
964
  originalContent: (content === null || content === void 0 ? void 0 : content.parsedContent) || null,
937
- mode: (content === null || content === void 0 ? void 0 : content.mode) || file_cache_1.DEFAULT_FILE_MODE,
965
+ mode: (content === null || content === void 0 ? void 0 : content.mode) || git_file_utils_1.DEFAULT_FILE_MODE,
938
966
  });
939
967
  }
940
968
  }
@@ -43,6 +43,7 @@ export interface ReleaserConfig {
43
43
  includeComponentInTag?: boolean;
44
44
  includeVInTag?: boolean;
45
45
  pullRequestTitlePattern?: string;
46
+ pullRequestHeader?: string;
46
47
  tagSeparator?: string;
47
48
  separatePullRequests?: boolean;
48
49
  labels?: string[];
@@ -85,6 +86,7 @@ interface ReleaserConfigJson {
85
86
  'changelog-type'?: ChangelogNotesType;
86
87
  'changelog-host'?: string;
87
88
  'pull-request-title-pattern'?: string;
89
+ 'pull-request-header'?: string;
88
90
  'separate-pull-requests'?: boolean;
89
91
  'tag-separator'?: string;
90
92
  'extra-files'?: ExtraFile[];
@@ -444,7 +444,7 @@ class Manifest {
444
444
  async findOpenReleasePullRequests() {
445
445
  logger_1.logger.info('Looking for open release pull requests');
446
446
  const openPullRequests = [];
447
- const generator = this.github.pullRequestIterator(this.targetBranch, 'OPEN');
447
+ const generator = this.github.pullRequestIterator(this.targetBranch, 'OPEN', Number.MAX_SAFE_INTEGER, false);
448
448
  for await (const openPullRequest of generator) {
449
449
  if ((hasAllLabels(this.labels, openPullRequest.labels) ||
450
450
  hasAllLabels(this.snapshotLabels, openPullRequest.labels)) &&
@@ -459,7 +459,7 @@ class Manifest {
459
459
  async findSnoozedReleasePullRequests() {
460
460
  logger_1.logger.info('Looking for snoozed release pull requests');
461
461
  const snoozedPullRequests = [];
462
- const closedGenerator = this.github.pullRequestIterator(this.targetBranch, 'CLOSED');
462
+ const closedGenerator = this.github.pullRequestIterator(this.targetBranch, 'CLOSED', 200, false);
463
463
  for await (const closedPullRequest of closedGenerator) {
464
464
  if (hasAllLabels([exports.SNOOZE_LABEL], closedPullRequest.labels) &&
465
465
  branch_name_1.BranchName.parse(closedPullRequest.headBranchName) &&
@@ -518,7 +518,7 @@ class Manifest {
518
518
  }
519
519
  async *findMergedReleasePullRequests() {
520
520
  // Find merged release pull requests
521
- const pullRequestGenerator = this.github.pullRequestIterator(this.targetBranch, 'MERGED', 200);
521
+ const pullRequestGenerator = this.github.pullRequestIterator(this.targetBranch, 'MERGED', 200, false);
522
522
  for await (const pullRequest of pullRequestGenerator) {
523
523
  if (!hasAllLabels(this.labels, pullRequest.labels)) {
524
524
  continue;
@@ -730,6 +730,7 @@ function extractReleaserConfig(config) {
730
730
  includeVInTag: config['include-v-in-tag'],
731
731
  changelogType: config['changelog-type'],
732
732
  pullRequestTitlePattern: config['pull-request-title-pattern'],
733
+ pullRequestHeader: config['pull-request-header'],
733
734
  tagSeparator: config['tag-separator'],
734
735
  separatePullRequests: config['separate-pull-requests'],
735
736
  labels: (_a = config['label']) === null || _a === void 0 ? void 0 : _a.split(','),
@@ -941,7 +942,7 @@ async function latestReleaseVersion(github, targetBranch, releaseFilter, config,
941
942
  return candidateTagVersion.sort((a, b) => b.compare(a))[0];
942
943
  }
943
944
  function mergeReleaserConfig(defaultConfig, pathConfig) {
944
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
945
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
945
946
  return {
946
947
  releaseType: (_b = (_a = pathConfig.releaseType) !== null && _a !== void 0 ? _a : defaultConfig.releaseType) !== null && _b !== void 0 ? _b : 'node',
947
948
  bumpMinorPreMajor: (_c = pathConfig.bumpMinorPreMajor) !== null && _c !== void 0 ? _c : defaultConfig.bumpMinorPreMajor,
@@ -963,8 +964,9 @@ function mergeReleaserConfig(defaultConfig, pathConfig) {
963
964
  includeVInTag: (_u = pathConfig.includeVInTag) !== null && _u !== void 0 ? _u : defaultConfig.includeVInTag,
964
965
  tagSeparator: (_v = pathConfig.tagSeparator) !== null && _v !== void 0 ? _v : defaultConfig.tagSeparator,
965
966
  pullRequestTitlePattern: (_w = pathConfig.pullRequestTitlePattern) !== null && _w !== void 0 ? _w : defaultConfig.pullRequestTitlePattern,
966
- separatePullRequests: (_x = pathConfig.separatePullRequests) !== null && _x !== void 0 ? _x : defaultConfig.separatePullRequests,
967
- skipSnapshot: (_y = pathConfig.skipSnapshot) !== null && _y !== void 0 ? _y : defaultConfig.skipSnapshot,
967
+ pullRequestHeader: (_x = pathConfig.pullRequestHeader) !== null && _x !== void 0 ? _x : defaultConfig.pullRequestHeader,
968
+ separatePullRequests: (_y = pathConfig.separatePullRequests) !== null && _y !== void 0 ? _y : defaultConfig.separatePullRequests,
969
+ skipSnapshot: (_z = pathConfig.skipSnapshot) !== null && _z !== void 0 ? _z : defaultConfig.skipSnapshot,
968
970
  };
969
971
  }
970
972
  /**
@@ -9,6 +9,7 @@ import { GitHub } from '../github';
9
9
  */
10
10
  export declare class Merge extends ManifestPlugin {
11
11
  private pullRequestTitlePattern?;
12
- constructor(github: GitHub, targetBranch: string, repositoryConfig: RepositoryConfig, pullRequestTitlePattern?: string);
12
+ private pullRequestHeader?;
13
+ constructor(github: GitHub, targetBranch: string, repositoryConfig: RepositoryConfig, pullRequestTitlePattern?: string, pullRequestHeader?: string);
13
14
  run(candidates: CandidateReleasePullRequest[]): Promise<CandidateReleasePullRequest[]>;
14
15
  }
@@ -28,10 +28,11 @@ const logger_1 = require("../util/logger");
28
28
  * Release notes are broken up using `<summary>`/`<details>` blocks.
29
29
  */
30
30
  class Merge extends plugin_1.ManifestPlugin {
31
- constructor(github, targetBranch, repositoryConfig, pullRequestTitlePattern) {
31
+ constructor(github, targetBranch, repositoryConfig, pullRequestTitlePattern, pullRequestHeader) {
32
32
  super(github, targetBranch, repositoryConfig);
33
33
  this.pullRequestTitlePattern =
34
34
  pullRequestTitlePattern || manifest_1.MANIFEST_PULL_REQUEST_TITLE_PATTERN;
35
+ this.pullRequestHeader = pullRequestHeader;
35
36
  }
36
37
  async run(candidates) {
37
38
  if (candidates.length < 1) {
@@ -65,7 +66,10 @@ class Merge extends plugin_1.ManifestPlugin {
65
66
  const updates = (0, composite_1.mergeUpdates)(rawUpdates);
66
67
  const pullRequest = {
67
68
  title: pull_request_title_1.PullRequestTitle.ofComponentTargetBranchVersion(rootRelease === null || rootRelease === void 0 ? void 0 : rootRelease.pullRequest.title.component, this.targetBranch, rootRelease === null || rootRelease === void 0 ? void 0 : rootRelease.pullRequest.title.version, this.pullRequestTitlePattern),
68
- body: new pull_request_body_1.PullRequestBody(releaseData, { useComponents: true }),
69
+ body: new pull_request_body_1.PullRequestBody(releaseData, {
70
+ useComponents: true,
71
+ header: this.pullRequestHeader,
72
+ }),
69
73
  updates,
70
74
  labels: Array.from(labels),
71
75
  headRefName: branch_name_1.BranchName.ofTargetBranch(this.targetBranch).toString(),
@@ -40,6 +40,7 @@ export interface BaseStrategyOptions {
40
40
  includeComponentInTag?: boolean;
41
41
  includeVInTag?: boolean;
42
42
  pullRequestTitlePattern?: string;
43
+ pullRequestHeader?: string;
43
44
  extraFiles?: ExtraFile[];
44
45
  versionFile?: string;
45
46
  snapshotLabels?: string[];
@@ -65,6 +66,7 @@ export declare abstract class BaseStrategy implements Strategy {
65
66
  protected includeComponentInTag: boolean;
66
67
  protected includeVInTag: boolean;
67
68
  readonly pullRequestTitlePattern?: string;
69
+ readonly pullRequestHeader?: string;
68
70
  readonly extraFiles: ExtraFile[];
69
71
  readonly changelogNotes: ChangelogNotes;
70
72
  protected changelogSections?: ChangelogSection[];
@@ -91,7 +93,7 @@ export declare abstract class BaseStrategy implements Strategy {
91
93
  */
92
94
  protected postProcessCommits(commits: ConventionalCommit[]): Promise<ConventionalCommit[]>;
93
95
  protected buildReleaseNotes(conventionalCommits: ConventionalCommit[], newVersion: Version, newVersionTag: TagName, latestRelease?: Release, commits?: Commit[]): Promise<string>;
94
- protected buildPullRequestBody(component: string | undefined, newVersion: Version, releaseNotesBody: string, _conventionalCommits: ConventionalCommit[], _latestRelease?: Release): Promise<PullRequestBody>;
96
+ protected buildPullRequestBody(component: string | undefined, newVersion: Version, releaseNotesBody: string, _conventionalCommits: ConventionalCommit[], _latestRelease?: Release, pullRequestHeader?: string): Promise<PullRequestBody>;
95
97
  /**
96
98
  * Builds a candidate release pull request
97
99
  * @param {Commit[]} commits Raw commits to consider for this release.
@@ -58,6 +58,7 @@ class BaseStrategy {
58
58
  this.includeComponentInTag = (_a = options.includeComponentInTag) !== null && _a !== void 0 ? _a : true;
59
59
  this.includeVInTag = (_b = options.includeVInTag) !== null && _b !== void 0 ? _b : true;
60
60
  this.pullRequestTitlePattern = options.pullRequestTitlePattern;
61
+ this.pullRequestHeader = options.pullRequestHeader;
61
62
  this.extraFiles = options.extraFiles || [];
62
63
  }
63
64
  /**
@@ -113,14 +114,14 @@ class BaseStrategy {
113
114
  commits: commits,
114
115
  });
115
116
  }
116
- async buildPullRequestBody(component, newVersion, releaseNotesBody, _conventionalCommits, _latestRelease) {
117
+ async buildPullRequestBody(component, newVersion, releaseNotesBody, _conventionalCommits, _latestRelease, pullRequestHeader) {
117
118
  return new pull_request_body_1.PullRequestBody([
118
119
  {
119
120
  component,
120
121
  version: newVersion,
121
122
  notes: releaseNotesBody,
122
123
  },
123
- ]);
124
+ ], { header: pullRequestHeader });
124
125
  }
125
126
  /**
126
127
  * Builds a candidate release pull request
@@ -163,7 +164,7 @@ class BaseStrategy {
163
164
  latestVersion: latestRelease === null || latestRelease === void 0 ? void 0 : latestRelease.tag.version,
164
165
  });
165
166
  const updatesWithExtras = (0, composite_1.mergeUpdates)(updates.concat(...this.extraFileUpdates(newVersion, versionsMap)));
166
- const pullRequestBody = await this.buildPullRequestBody(component, newVersion, releaseNotesBody, conventionalCommits, latestRelease);
167
+ const pullRequestBody = await this.buildPullRequestBody(component, newVersion, releaseNotesBody, conventionalCommits, latestRelease, this.pullRequestHeader);
167
168
  return {
168
169
  title: pullRequestTitle,
169
170
  body: pullRequestBody,
@@ -34,15 +34,18 @@ const CHANGELOG_SECTIONS = [
34
34
  ];
35
35
  const DEFAULT_CHANGELOG_PATH = 'docs/history.md';
36
36
  const DEFAULT_PULL_REQUEST_TITLE_PATTERN = 'Release${component} version ${version}';
37
+ const DEFAULT_PULL_REQUEST_HEADER = ':robot: I have created a release *beep* *boop*';
37
38
  const RELEASE_NOTES_HEADER_PATTERN = /#{2,3} \[?(\d+\.\d+\.\d+-?[^\]]*)\]?.* \((\d{4}-\d{2}-\d{2})\)/;
38
39
  class DotnetYoshi extends base_1.BaseStrategy {
39
40
  constructor(options) {
40
- var _a, _b, _c, _d;
41
+ var _a, _b, _c, _d, _e;
41
42
  options.changelogSections = (_a = options.changelogSections) !== null && _a !== void 0 ? _a : CHANGELOG_SECTIONS;
42
43
  options.changelogPath = (_b = options.changelogPath) !== null && _b !== void 0 ? _b : DEFAULT_CHANGELOG_PATH;
43
44
  options.pullRequestTitlePattern =
44
45
  (_c = options.pullRequestTitlePattern) !== null && _c !== void 0 ? _c : DEFAULT_PULL_REQUEST_TITLE_PATTERN;
45
- options.includeVInTag = (_d = options.includeVInTag) !== null && _d !== void 0 ? _d : false;
46
+ options.pullRequestHeader =
47
+ (_d = options.pullRequestHeader) !== null && _d !== void 0 ? _d : DEFAULT_PULL_REQUEST_HEADER;
48
+ options.includeVInTag = (_e = options.includeVInTag) !== null && _e !== void 0 ? _e : false;
46
49
  super(options);
47
50
  }
48
51
  async buildReleaseNotes(conventionalCommits, newVersion, newVersionTag, latestRelease) {
@@ -1,6 +1,6 @@
1
1
  import { Update } from '../update';
2
2
  import { Version, VersionsMap } from '../version';
3
- import { GitHubFileContents } from '../util/file-cache';
3
+ import { GitHubFileContents } from '@google-automations/git-file-utils';
4
4
  import { ConventionalCommit } from '../commit';
5
5
  import { Java, JavaBuildUpdatesOption } from './java';
6
6
  export declare class JavaYoshi extends Java {
@@ -79,6 +79,7 @@ class Java extends base_1.BaseStrategy {
79
79
  ? branch_name_1.BranchName.ofComponentTargetBranch(component, this.targetBranch)
80
80
  : branch_name_1.BranchName.ofTargetBranch(this.targetBranch);
81
81
  const notes = '### Updating meta-information for bleeding-edge SNAPSHOT release.';
82
+ // TODO use pullrequest header here?
82
83
  const pullRequestBody = new pull_request_body_1.PullRequestBody([
83
84
  {
84
85
  component,
@@ -136,6 +136,7 @@ class PHPYoshi extends base_1.BaseStrategy {
136
136
  });
137
137
  }
138
138
  }
139
+ // TODO use pullrequest header here?
139
140
  const pullRequestBody = new pull_request_body_1.PullRequestBody([
140
141
  {
141
142
  component,
@@ -1,4 +1,4 @@
1
- import { GitHubFileContents } from './util/file-cache';
1
+ import { GitHubFileContents } from '@google-automations/git-file-utils';
2
2
  /**
3
3
  * An update is a collection of data that represents changes to
4
4
  * a file in a repository.
@@ -60,6 +60,7 @@ function releaserConfigToJsonConfig(config) {
60
60
  'changelog-type': config.changelogType,
61
61
  'changelog-host': config.changelogHost,
62
62
  'pull-request-title-pattern': config.pullRequestTitlePattern,
63
+ 'pull-request-header': config.pullRequestHeader,
63
64
  'separate-pull-requests': config.separatePullRequests,
64
65
  'tag-separator': config.tagSeparator,
65
66
  'extra-files': config.extraFiles,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "release-please",
3
- "version": "13.21.0",
3
+ "version": "14.1.1",
4
4
  "description": "generate release PRs based on the conventionalcommits.org spec",
5
5
  "main": "./build/src/index.js",
6
6
  "bin": "./build/src/bin/release-please.js",
7
7
  "scripts": {
8
- "test": "cross-env ENVIRONMENT=test c8 mocha --recursive --timeout=5000 build/test",
8
+ "test": "cross-env ENVIRONMENT=test LC_ALL=en c8 mocha --recursive --timeout=5000 build/test",
9
9
  "docs": "echo add docs tests",
10
- "test:snap": "SNAPSHOT_UPDATE=1 npm test",
10
+ "test:snap": "SNAPSHOT_UPDATE=1 LC_ALL=en npm test",
11
11
  "clean": "gts clean",
12
12
  "prepare": "npm run compile",
13
13
  "lint": "gts check",
@@ -38,7 +38,7 @@
38
38
  }
39
39
  },
40
40
  "devDependencies": {
41
- "@octokit/types": "^6.1.0",
41
+ "@octokit/types": "^7.0.0",
42
42
  "@types/chai": "^4.1.7",
43
43
  "@types/diff": "^5.0.2",
44
44
  "@types/iarna__toml": "^2.0.1",
@@ -56,6 +56,7 @@
56
56
  "@types/xmldom": "^0.1.31",
57
57
  "@types/yargs": "^17.0.0",
58
58
  "ajv": "^8.11.0",
59
+ "ajv-formats": "^2.1.1",
59
60
  "c8": "^7.0.0",
60
61
  "chai": "^4.2.0",
61
62
  "cross-env": "^7.0.0",
@@ -67,19 +68,20 @@
67
68
  },
68
69
  "dependencies": {
69
70
  "@conventional-commits/parser": "^0.4.1",
71
+ "@google-automations/git-file-utils": "^1.1.0",
70
72
  "@iarna/toml": "^2.2.5",
71
73
  "@lerna/collect-updates": "^4.0.0",
72
74
  "@lerna/package": "^4.0.0",
73
75
  "@lerna/package-graph": "^4.0.0",
74
76
  "@lerna/run-topologically": "^4.0.0",
75
- "@octokit/graphql": "^4.3.1",
76
- "@octokit/request": "^5.6.0",
77
- "@octokit/request-error": "^2.1.0",
78
- "@octokit/rest": "^18.12.0",
77
+ "@octokit/graphql": "^5.0.0",
78
+ "@octokit/request": "^6.0.0",
79
+ "@octokit/request-error": "^3.0.0",
80
+ "@octokit/rest": "^19.0.0",
79
81
  "@types/npm-package-arg": "^6.1.0",
80
82
  "@xmldom/xmldom": "^0.8.2",
81
83
  "chalk": "^4.0.0",
82
- "code-suggester": "^3.0.0",
84
+ "code-suggester": "^4.0.0",
83
85
  "conventional-changelog-conventionalcommits": "^5.0.0",
84
86
  "conventional-changelog-writer": "^5.0.0",
85
87
  "conventional-commits-filter": "^2.0.2",
@@ -99,6 +101,6 @@
99
101
  "yargs": "^17.0.0"
100
102
  },
101
103
  "engines": {
102
- "node": ">=12.18.0"
104
+ "node": ">=14.0.0"
103
105
  }
104
106
  }
@@ -51,7 +51,7 @@
51
51
  "type": "string"
52
52
  },
53
53
  "skip-github-release": {
54
- "description": "Skip tagging GitHub releases for this package. Defaults to `false`.",
54
+ "description": "Skip tagging GitHub releases for this package. Release-Please still requires releases to be tagged, so this option should only be used if you have existing infrastructure to tag these releases.Defaults to `false`.",
55
55
  "type": "boolean"
56
56
  },
57
57
  "draft": {
@@ -95,6 +95,10 @@
95
95
  "description": "Customize the release pull request title.",
96
96
  "type": "string"
97
97
  },
98
+ "pull-request-header": {
99
+ "description": "Customize the release pull request header.",
100
+ "type": "string"
101
+ },
98
102
  "separate-pull-requests": {
99
103
  "description": "Open a separate release pull request for each component. Defaults to `false`.",
100
104
  "type": "boolean"
@@ -189,6 +193,11 @@
189
193
  },
190
194
  {
191
195
  "properties": {
196
+ "$schema": {
197
+ "description": "Path to the release-please manifest config schema",
198
+ "type": "string",
199
+ "format": "uri-reference"
200
+ },
192
201
  "packages": {
193
202
  "description": "Per-path component configuration.",
194
203
  "type": "object",
@@ -297,6 +306,7 @@
297
306
  }
298
307
  ],
299
308
  "properties": {
309
+ "$schema": true,
300
310
  "packages": true,
301
311
  "bootstrap-sha": true,
302
312
  "last-release-sha": true,
@@ -323,6 +333,7 @@
323
333
  "changelog-type": true,
324
334
  "changelog-host": true,
325
335
  "pull-request-title-pattern": true,
336
+ "pull-request-header": true,
326
337
  "separate-pull-requests": true,
327
338
  "tag-separator": true,
328
339
  "extra-files": true,
@@ -1,104 +0,0 @@
1
- import { Octokit } from '@octokit/rest';
2
- import { Repository } from '../repository';
3
- export declare const DEFAULT_FILE_MODE = "100644";
4
- export interface GitHubFileContents {
5
- sha: string;
6
- content: string;
7
- parsedContent: string;
8
- mode: string;
9
- }
10
- /**
11
- * This class is a read-through cache aimed at minimizing the
12
- * number of API requests needed to fetch file data/contents.
13
- * It lazy-caches data as it reads and will return cached data
14
- * for resources already fetched.
15
- */
16
- export declare class RepositoryFileCache {
17
- private octokit;
18
- private repository;
19
- private cache;
20
- /**
21
- * Instantiate a new loading cache instance
22
- *
23
- * @param {Octokit} octokit An authenticated octokit instance
24
- * @param {Repository} repository The repository we are fetching data for
25
- */
26
- constructor(octokit: Octokit, repository: Repository);
27
- /**
28
- * Fetch file contents for given path on a given branch. If the
29
- * data has already been fetched, return a cached copy.
30
- *
31
- * @param {string} path Path to the file
32
- * @param {string} branch Branch to fetch the file from
33
- * @returns {GitHubFileContents} The file contents
34
- */
35
- getFileContents(path: string, branch: string): Promise<GitHubFileContents>;
36
- }
37
- /**
38
- * This class is a read-through cache for a single branch aimed
39
- * at minimizing the number of API requests needed to fetch file
40
- * data/contents. It lazy-caches data as it reads and will return
41
- * cached data for resources already fetched.
42
- */
43
- export declare class BranchFileCache {
44
- private octokit;
45
- private repository;
46
- private branch;
47
- private cache;
48
- private treeCache;
49
- private treeEntries?;
50
- /**
51
- * Instantiate a new loading cache instance
52
- *
53
- * @param {Octokit} octokit An authenticated octokit instance
54
- * @param {Repository} repository The repository we are fetching data for
55
- * @param {string} branch The branch we are fetching data from
56
- */
57
- constructor(octokit: Octokit, repository: Repository, branch: string);
58
- /**
59
- * Fetch file contents for given path. If the data has already been
60
- * fetched, return the cached copy.
61
- *
62
- * @param {string} path Path to the file
63
- * @param {string} branch Branch to fetch the file from
64
- * @returns {GitHubFileContents} The file contents
65
- */
66
- getFileContents(path: string): Promise<GitHubFileContents>;
67
- /**
68
- * Actually fetch the file contents. Uses the tree API to fetch file
69
- * data.
70
- *
71
- * @param {string} path Path to the file
72
- */
73
- private fetchFileContents;
74
- /**
75
- * Return the full recursive git tree. If already fetched, return
76
- * the cached version. If the tree is too big, return null.
77
- *
78
- * @returns {TreeEntry[]} The tree entries
79
- */
80
- private getFullTree;
81
- /**
82
- * Returns the git tree for a given SHA. If already fetched, return
83
- * the cached version.
84
- *
85
- * @param {string} sha The tree SHA
86
- * @returns {TreeEntry[]} The tree entries
87
- */
88
- private getTree;
89
- /**
90
- * Fetch the git tree via the GitHub API
91
- *
92
- * @param {string} sha The tree SHA
93
- * @returns {TreeEntry[]} The tree entries
94
- */
95
- private fetchTree;
96
- /**
97
- * Fetch the git blob from the GitHub API and convert into a
98
- * GitHubFileContents object.
99
- *
100
- * @param {string} blobSha The git blob SHA
101
- * @param {TreeEntry} treeEntry The associated tree object
102
- */
103
- private fetchContents;
104
- }
@@ -1,208 +0,0 @@
1
- "use strict";
2
- // Copyright 2022 Google LLC
3
- //
4
- // Licensed under the Apache License, Version 2.0 (the "License");
5
- // you may not use this file except in compliance with the License.
6
- // You may obtain a copy of the License at
7
- //
8
- // http://www.apache.org/licenses/LICENSE-2.0
9
- //
10
- // Unless required by applicable law or agreed to in writing, software
11
- // distributed under the License is distributed on an "AS IS" BASIS,
12
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- // See the License for the specific language governing permissions and
14
- // limitations under the License.
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.BranchFileCache = exports.RepositoryFileCache = exports.DEFAULT_FILE_MODE = void 0;
17
- const logger_1 = require("./logger");
18
- const errors_1 = require("../errors");
19
- exports.DEFAULT_FILE_MODE = '100644';
20
- /**
21
- * This class is a read-through cache aimed at minimizing the
22
- * number of API requests needed to fetch file data/contents.
23
- * It lazy-caches data as it reads and will return cached data
24
- * for resources already fetched.
25
- */
26
- class RepositoryFileCache {
27
- /**
28
- * Instantiate a new loading cache instance
29
- *
30
- * @param {Octokit} octokit An authenticated octokit instance
31
- * @param {Repository} repository The repository we are fetching data for
32
- */
33
- constructor(octokit, repository) {
34
- this.octokit = octokit;
35
- this.repository = repository;
36
- this.cache = new Map();
37
- }
38
- /**
39
- * Fetch file contents for given path on a given branch. If the
40
- * data has already been fetched, return a cached copy.
41
- *
42
- * @param {string} path Path to the file
43
- * @param {string} branch Branch to fetch the file from
44
- * @returns {GitHubFileContents} The file contents
45
- */
46
- async getFileContents(path, branch) {
47
- let fileCache = this.cache.get(branch);
48
- if (!fileCache) {
49
- fileCache = new BranchFileCache(this.octokit, this.repository, branch);
50
- this.cache.set(branch, fileCache);
51
- }
52
- return await fileCache.getFileContents(path);
53
- }
54
- }
55
- exports.RepositoryFileCache = RepositoryFileCache;
56
- /**
57
- * This class is a read-through cache for a single branch aimed
58
- * at minimizing the number of API requests needed to fetch file
59
- * data/contents. It lazy-caches data as it reads and will return
60
- * cached data for resources already fetched.
61
- */
62
- class BranchFileCache {
63
- /**
64
- * Instantiate a new loading cache instance
65
- *
66
- * @param {Octokit} octokit An authenticated octokit instance
67
- * @param {Repository} repository The repository we are fetching data for
68
- * @param {string} branch The branch we are fetching data from
69
- */
70
- constructor(octokit, repository, branch) {
71
- this.octokit = octokit;
72
- this.repository = repository;
73
- this.branch = branch;
74
- this.cache = new Map();
75
- this.treeCache = new Map();
76
- }
77
- /**
78
- * Fetch file contents for given path. If the data has already been
79
- * fetched, return the cached copy.
80
- *
81
- * @param {string} path Path to the file
82
- * @param {string} branch Branch to fetch the file from
83
- * @returns {GitHubFileContents} The file contents
84
- */
85
- async getFileContents(path) {
86
- const cached = this.cache.get(path);
87
- if (cached) {
88
- return cached;
89
- }
90
- const fetched = await this.fetchFileContents(path);
91
- this.cache.set(path, fetched);
92
- return fetched;
93
- }
94
- /**
95
- * Actually fetch the file contents. Uses the tree API to fetch file
96
- * data.
97
- *
98
- * @param {string} path Path to the file
99
- */
100
- async fetchFileContents(path) {
101
- // try to use the entire git tree if it's not too big
102
- const treeEntries = await this.getFullTree();
103
- if (treeEntries) {
104
- logger_1.logger.debug(`Using full tree to find ${path}`);
105
- const found = treeEntries.find(entry => entry.path === path);
106
- if (found === null || found === void 0 ? void 0 : found.sha) {
107
- return await this.fetchContents(found.sha, found);
108
- }
109
- throw new errors_1.FileNotFoundError(path);
110
- }
111
- // full tree is too big, use data API to fetch
112
- const parts = path.split('/');
113
- let treeSha = this.branch;
114
- let found;
115
- for (const part of parts) {
116
- const tree = await this.getTree(treeSha);
117
- found = tree.find(item => item.path === part);
118
- if (!(found === null || found === void 0 ? void 0 : found.sha)) {
119
- throw new errors_1.FileNotFoundError(path);
120
- }
121
- treeSha = found.sha;
122
- }
123
- if (found === null || found === void 0 ? void 0 : found.sha) {
124
- return await this.fetchContents(found.sha, found);
125
- }
126
- throw new errors_1.FileNotFoundError(path);
127
- }
128
- /**
129
- * Return the full recursive git tree. If already fetched, return
130
- * the cached version. If the tree is too big, return null.
131
- *
132
- * @returns {TreeEntry[]} The tree entries
133
- */
134
- async getFullTree() {
135
- if (this.treeEntries === undefined) {
136
- // fetch all tree entries recursively
137
- const { data: { tree, truncated }, } = await this.octokit.git.getTree({
138
- owner: this.repository.owner,
139
- repo: this.repository.repo,
140
- tree_sha: this.branch,
141
- recursive: 'true',
142
- });
143
- if (truncated) {
144
- // the full tree is too big to use, mark it as unusable
145
- this.treeEntries = null;
146
- }
147
- else {
148
- this.treeEntries = tree;
149
- }
150
- }
151
- return this.treeEntries;
152
- }
153
- /**
154
- * Returns the git tree for a given SHA. If already fetched, return
155
- * the cached version.
156
- *
157
- * @param {string} sha The tree SHA
158
- * @returns {TreeEntry[]} The tree entries
159
- */
160
- async getTree(sha) {
161
- const cached = this.treeCache.get(sha);
162
- if (cached) {
163
- return cached;
164
- }
165
- const fetched = await this.fetchTree(sha);
166
- this.treeCache.set(sha, fetched);
167
- return fetched;
168
- }
169
- /**
170
- * Fetch the git tree via the GitHub API
171
- *
172
- * @param {string} sha The tree SHA
173
- * @returns {TreeEntry[]} The tree entries
174
- */
175
- async fetchTree(sha) {
176
- const { data: { tree, truncated }, } = await this.octokit.git.getTree({
177
- owner: this.repository.owner,
178
- repo: this.repository.repo,
179
- tree_sha: sha,
180
- });
181
- if (truncated) {
182
- logger_1.logger.warn(`file list for tree sha ${sha} is truncated`);
183
- }
184
- return tree;
185
- }
186
- /**
187
- * Fetch the git blob from the GitHub API and convert into a
188
- * GitHubFileContents object.
189
- *
190
- * @param {string} blobSha The git blob SHA
191
- * @param {TreeEntry} treeEntry The associated tree object
192
- */
193
- async fetchContents(blobSha, treeEntry) {
194
- const { data: { content }, } = await this.octokit.git.getBlob({
195
- owner: this.repository.owner,
196
- repo: this.repository.repo,
197
- file_sha: blobSha,
198
- });
199
- return {
200
- sha: blobSha,
201
- mode: treeEntry.mode || exports.DEFAULT_FILE_MODE,
202
- content,
203
- parsedContent: Buffer.from(content, 'base64').toString('utf8'),
204
- };
205
- }
206
- }
207
- exports.BranchFileCache = BranchFileCache;
208
- //# sourceMappingURL=file-cache.js.map