release-please 13.0.0-candidate.5 → 13.0.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +33 -131
  3. package/build/src/bin/release-please.js +12 -1
  4. package/build/src/changelog-notes.d.ts +1 -0
  5. package/build/src/changelog-notes.js +24 -0
  6. package/build/src/commit.d.ts +1 -1
  7. package/build/src/commit.js +14 -1
  8. package/build/src/github.d.ts +41 -7
  9. package/build/src/github.js +51 -14
  10. package/build/src/manifest.js +76 -20
  11. package/build/src/plugins/cargo-workspace.js +2 -2
  12. package/build/src/plugins/merge.js +4 -1
  13. package/build/src/plugins/node-workspace.js +2 -2
  14. package/build/src/pull-request.d.ts +8 -8
  15. package/build/src/release-pull-request.d.ts +6 -6
  16. package/build/src/strategies/base.d.ts +108 -0
  17. package/build/src/strategies/base.js +253 -0
  18. package/build/src/strategies/dart.d.ts +2 -2
  19. package/build/src/strategies/dart.js +2 -2
  20. package/build/src/strategies/elixir.d.ts +2 -2
  21. package/build/src/strategies/elixir.js +2 -2
  22. package/build/src/strategies/go-yoshi.d.ts +3 -3
  23. package/build/src/strategies/go-yoshi.js +2 -2
  24. package/build/src/strategies/go.d.ts +2 -2
  25. package/build/src/strategies/go.js +2 -2
  26. package/build/src/strategies/helm.d.ts +2 -2
  27. package/build/src/strategies/helm.js +2 -2
  28. package/build/src/strategies/java-yoshi.d.ts +3 -3
  29. package/build/src/strategies/java-yoshi.js +2 -2
  30. package/build/src/strategies/krm-blueprint.d.ts +2 -2
  31. package/build/src/strategies/krm-blueprint.js +3 -3
  32. package/build/src/strategies/node.d.ts +2 -2
  33. package/build/src/strategies/node.js +2 -2
  34. package/build/src/strategies/ocaml.d.ts +2 -2
  35. package/build/src/strategies/ocaml.js +2 -2
  36. package/build/src/strategies/php-yoshi.d.ts +3 -3
  37. package/build/src/strategies/php-yoshi.js +2 -2
  38. package/build/src/strategies/php.d.ts +3 -3
  39. package/build/src/strategies/php.js +2 -2
  40. package/build/src/strategies/python.d.ts +2 -2
  41. package/build/src/strategies/python.js +2 -2
  42. package/build/src/strategies/ruby-yoshi.d.ts +3 -3
  43. package/build/src/strategies/ruby-yoshi.js +7 -2
  44. package/build/src/strategies/ruby.d.ts +3 -3
  45. package/build/src/strategies/ruby.js +2 -2
  46. package/build/src/strategies/rust.d.ts +2 -2
  47. package/build/src/strategies/rust.js +2 -2
  48. package/build/src/strategies/simple.d.ts +2 -2
  49. package/build/src/strategies/simple.js +2 -2
  50. package/build/src/strategies/terraform-module.d.ts +2 -2
  51. package/build/src/strategies/terraform-module.js +2 -2
  52. package/build/src/strategy.d.ts +8 -73
  53. package/build/src/strategy.js +0 -233
  54. package/build/src/updaters/rust/cargo-toml.js +5 -1
  55. package/build/src/util/commit-split.js +3 -0
  56. package/build/src/util/pull-request-title.js +1 -0
  57. package/build/src/version.d.ts +28 -5
  58. package/build/src/version.js +26 -0
  59. package/build/src/versioning-strategies/always-bump-patch.d.ts +4 -0
  60. package/build/src/versioning-strategies/always-bump-patch.js +4 -0
  61. package/build/src/versioning-strategies/default.d.ts +31 -0
  62. package/build/src/versioning-strategies/default.js +31 -0
  63. package/build/src/versioning-strategies/dependency-manifest.d.ts +8 -0
  64. package/build/src/versioning-strategies/dependency-manifest.js +8 -0
  65. package/build/src/versioning-strategies/java-add-snapshot.d.ts +4 -0
  66. package/build/src/versioning-strategies/java-add-snapshot.js +6 -5
  67. package/build/src/versioning-strategies/java-snapshot.d.ts +4 -0
  68. package/build/src/versioning-strategies/java-snapshot.js +4 -1
  69. package/build/src/versioning-strategies/service-pack.d.ts +5 -0
  70. package/build/src/versioning-strategies/service-pack.js +10 -3
  71. package/build/src/versioning-strategy.d.ts +67 -5
  72. package/build/src/versioning-strategy.js +37 -10
  73. package/package.json +3 -3
  74. package/build/src/release-notes.d.ts +0 -29
  75. package/build/src/release-notes.js +0 -71
@@ -58,6 +58,7 @@ class Manifest {
58
58
  * pull request. Defaults to `[autorelease: tagged]`
59
59
  */
60
60
  constructor(github, targetBranch, repositoryConfig, releasedVersions, manifestOptions) {
61
+ var _a;
61
62
  this.repository = github.repository;
62
63
  this.github = github;
63
64
  this.targetBranch = targetBranch;
@@ -65,7 +66,7 @@ class Manifest {
65
66
  this.releasedVersions = releasedVersions;
66
67
  this.manifestPath =
67
68
  (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.manifestPath) || exports.DEFAULT_RELEASE_PLEASE_MANIFEST;
68
- this.separatePullRequests = (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.separatePullRequests) || false;
69
+ this.separatePullRequests = (_a = manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.separatePullRequests) !== null && _a !== void 0 ? _a : Object.keys(repositoryConfig).length === 1;
69
70
  this.plugins = (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.plugins) || [];
70
71
  this.fork = (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.fork) || false;
71
72
  this.signoffUser = manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.signoff;
@@ -131,7 +132,10 @@ class Manifest {
131
132
  if (latestVersion) {
132
133
  releasedVersions[path] = latestVersion;
133
134
  }
134
- return new Manifest(github, targetBranch, repositoryConfig, releasedVersions, manifestOptions);
135
+ return new Manifest(github, targetBranch, repositoryConfig, releasedVersions, {
136
+ separatePullRequests: true,
137
+ ...manifestOptions,
138
+ });
135
139
  }
136
140
  /**
137
141
  * Build all candidate pull requests for this repository.
@@ -154,7 +158,9 @@ class Manifest {
154
158
  const releaseShasByPath = {};
155
159
  // Releases by path
156
160
  const releasesByPath = {};
157
- for await (const release of this.github.releaseIterator(400)) {
161
+ for await (const release of this.github.releaseIterator({
162
+ maxResults: 400,
163
+ })) {
158
164
  // logger.debug(release);
159
165
  const tagName = tag_name_1.TagName.parse(release.tagName);
160
166
  if (!tagName) {
@@ -198,7 +204,10 @@ class Manifest {
198
204
  // seen all release commits
199
205
  logger_1.logger.info('Collecting commits since all latest releases');
200
206
  const commits = [];
201
- const commitGenerator = this.github.mergeCommitIterator(this.targetBranch, 500);
207
+ const commitGenerator = this.github.mergeCommitIterator(this.targetBranch, {
208
+ maxResults: 500,
209
+ backfillFiles: true,
210
+ });
202
211
  const releaseShas = new Set(Object.values(releaseShasByPath));
203
212
  logger_1.logger.debug(releaseShas);
204
213
  const expectedShas = releaseShas.size;
@@ -262,6 +271,7 @@ class Manifest {
262
271
  const strategy = strategiesByPath[path];
263
272
  let latestRelease = releasesByPath[path];
264
273
  if (!latestRelease &&
274
+ this.releasedVersions[path] &&
265
275
  this.releasedVersions[path].toString() !== '0.0.0') {
266
276
  const version = this.releasedVersions[path];
267
277
  const component = await strategy.getComponent();
@@ -534,7 +544,7 @@ exports.Manifest = Manifest;
534
544
  */
535
545
  function extractReleaserConfig(config) {
536
546
  return {
537
- releaseType: config['release-type'] || 'node',
547
+ releaseType: config['release-type'],
538
548
  bumpMinorPreMajor: config['bump-minor-pre-major'],
539
549
  bumpPatchForMinorPreMajor: config['bump-patch-for-minor-pre-major'],
540
550
  changelogSections: config['changelog-sections'],
@@ -607,11 +617,15 @@ async function latestReleaseVersion(github, targetBranch, prefix, pullRequestTit
607
617
  : prefix
608
618
  : undefined;
609
619
  logger_1.logger.info(`Looking for latest release on branch: ${targetBranch} with prefix: ${prefix}`);
620
+ // collect set of recent commit SHAs seen to verify that the release
621
+ // is in the current branch
622
+ const commitShas = new Set();
610
623
  // only look at the last 250 or so commits to find the latest tag - we
611
624
  // don't want to scan the entire repository history if this repo has never
612
625
  // been released
613
- const generator = github.mergeCommitIterator(targetBranch, 250);
626
+ const generator = github.mergeCommitIterator(targetBranch, { maxResults: 250 });
614
627
  for await (const commitWithPullRequest of generator) {
628
+ commitShas.add(commitWithPullRequest.sha);
615
629
  const mergedPullRequest = commitWithPullRequest.pullRequest;
616
630
  if (!mergedPullRequest) {
617
631
  continue;
@@ -636,23 +650,65 @@ async function latestReleaseVersion(github, targetBranch, prefix, pullRequestTit
636
650
  }
637
651
  return version;
638
652
  }
639
- return;
653
+ // If not found from recent pull requests, look at releases. Iterate
654
+ // through releases finding valid tags, then cross reference
655
+ const releaseGenerator = github.releaseIterator();
656
+ const candidateReleaseVersions = [];
657
+ for await (const release of releaseGenerator) {
658
+ const tagName = tag_name_1.TagName.parse(release.tagName);
659
+ if (!tagName) {
660
+ continue;
661
+ }
662
+ if (tagName.component === branchPrefix) {
663
+ logger_1.logger.debug(`found release for ${prefix}`, tagName.version);
664
+ if (!commitShas.has(release.sha)) {
665
+ logger_1.logger.debug(`SHA not found in recent commits to branch ${targetBranch}, skipping`);
666
+ continue;
667
+ }
668
+ candidateReleaseVersions.push(tagName.version);
669
+ }
670
+ }
671
+ logger_1.logger.debug(`found ${candidateReleaseVersions.length} possible releases.`, candidateReleaseVersions);
672
+ if (candidateReleaseVersions.length > 0) {
673
+ // Find largest release number (sort descending then return first)
674
+ return candidateReleaseVersions.sort((a, b) => b.compare(a))[0];
675
+ }
676
+ // If not found from recent pull requests or releases, look at tags. Iterate
677
+ // through tags and cross reference against SHAs in this branch
678
+ const tagGenerator = github.tagIterator();
679
+ const candidateTagVersion = [];
680
+ for await (const tag of tagGenerator) {
681
+ const tagName = tag_name_1.TagName.parse(tag.name);
682
+ if (!tagName) {
683
+ continue;
684
+ }
685
+ if (tagName.component === branchPrefix) {
686
+ if (!commitShas.has(tag.sha)) {
687
+ logger_1.logger.debug(`SHA not found in recent commits to branch ${targetBranch}, skipping`);
688
+ continue;
689
+ }
690
+ candidateTagVersion.push(tagName.version);
691
+ }
692
+ }
693
+ logger_1.logger.debug(`found ${candidateTagVersion.length} possible tags.`, candidateTagVersion);
694
+ // Find largest release number (sort descending then return first)
695
+ return candidateTagVersion.sort((a, b) => b.compare(a))[0];
640
696
  }
641
697
  function mergeReleaserConfig(defaultConfig, pathConfig) {
642
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
698
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
643
699
  return {
644
- releaseType: (_a = pathConfig.releaseType) !== null && _a !== void 0 ? _a : defaultConfig.releaseType,
645
- bumpMinorPreMajor: (_b = pathConfig.bumpMinorPreMajor) !== null && _b !== void 0 ? _b : defaultConfig.bumpMinorPreMajor,
646
- bumpPatchForMinorPreMajor: (_c = pathConfig.bumpPatchForMinorPreMajor) !== null && _c !== void 0 ? _c : defaultConfig.bumpPatchForMinorPreMajor,
647
- changelogSections: (_d = pathConfig.changelogSections) !== null && _d !== void 0 ? _d : defaultConfig.changelogSections,
648
- changelogPath: (_e = pathConfig.changelogPath) !== null && _e !== void 0 ? _e : defaultConfig.changelogPath,
649
- releaseAs: (_f = pathConfig.releaseAs) !== null && _f !== void 0 ? _f : defaultConfig.releaseAs,
650
- skipGithubRelease: (_g = pathConfig.skipGithubRelease) !== null && _g !== void 0 ? _g : defaultConfig.skipGithubRelease,
651
- draft: (_h = pathConfig.draft) !== null && _h !== void 0 ? _h : defaultConfig.draft,
652
- component: (_j = pathConfig.component) !== null && _j !== void 0 ? _j : defaultConfig.component,
653
- packageName: (_k = pathConfig.packageName) !== null && _k !== void 0 ? _k : defaultConfig.packageName,
654
- versionFile: (_l = pathConfig.versionFile) !== null && _l !== void 0 ? _l : defaultConfig.versionFile,
655
- extraFiles: (_m = pathConfig.extraFiles) !== null && _m !== void 0 ? _m : defaultConfig.extraFiles,
700
+ releaseType: (_b = (_a = pathConfig.releaseType) !== null && _a !== void 0 ? _a : defaultConfig.releaseType) !== null && _b !== void 0 ? _b : 'node',
701
+ bumpMinorPreMajor: (_c = pathConfig.bumpMinorPreMajor) !== null && _c !== void 0 ? _c : defaultConfig.bumpMinorPreMajor,
702
+ bumpPatchForMinorPreMajor: (_d = pathConfig.bumpPatchForMinorPreMajor) !== null && _d !== void 0 ? _d : defaultConfig.bumpPatchForMinorPreMajor,
703
+ changelogSections: (_e = pathConfig.changelogSections) !== null && _e !== void 0 ? _e : defaultConfig.changelogSections,
704
+ changelogPath: (_f = pathConfig.changelogPath) !== null && _f !== void 0 ? _f : defaultConfig.changelogPath,
705
+ releaseAs: (_g = pathConfig.releaseAs) !== null && _g !== void 0 ? _g : defaultConfig.releaseAs,
706
+ skipGithubRelease: (_h = pathConfig.skipGithubRelease) !== null && _h !== void 0 ? _h : defaultConfig.skipGithubRelease,
707
+ draft: (_j = pathConfig.draft) !== null && _j !== void 0 ? _j : defaultConfig.draft,
708
+ component: (_k = pathConfig.component) !== null && _k !== void 0 ? _k : defaultConfig.component,
709
+ packageName: (_l = pathConfig.packageName) !== null && _l !== void 0 ? _l : defaultConfig.packageName,
710
+ versionFile: (_m = pathConfig.versionFile) !== null && _m !== void 0 ? _m : defaultConfig.versionFile,
711
+ extraFiles: (_o = pathConfig.extraFiles) !== null && _o !== void 0 ? _o : defaultConfig.extraFiles,
656
712
  };
657
713
  }
658
714
  /**
@@ -25,6 +25,7 @@ const changelog_1 = require("../updaters/changelog");
25
25
  const pull_request_title_1 = require("../util/pull-request-title");
26
26
  const pull_request_body_1 = require("../util/pull-request-body");
27
27
  const branch_name_1 = require("../util/branch-name");
28
+ const versioning_strategy_1 = require("../versioning-strategy");
28
29
  /**
29
30
  * The plugin analyzed a cargo workspace and will bump dependencies
30
31
  * of managed packages if those dependencies are being updated.
@@ -84,8 +85,7 @@ class CargoWorkspace extends workspace_1.WorkspacePlugin {
84
85
  }
85
86
  bumpVersion(pkg) {
86
87
  const version = version_1.Version.parse(pkg.version);
87
- version.patch += 1;
88
- return version;
88
+ return new versioning_strategy_1.PatchVersionUpdate().bump(version);
89
89
  }
90
90
  updateCandidate(existingCandidate, pkg, updatedVersions) {
91
91
  const version = updatedVersions.get(pkg.name);
@@ -28,7 +28,7 @@ const composite_1 = require("../updaters/composite");
28
28
  */
29
29
  class Merge extends plugin_1.ManifestPlugin {
30
30
  async run(candidates) {
31
- if (candidates.length < 2) {
31
+ if (candidates.length < 1) {
32
32
  return candidates;
33
33
  }
34
34
  const updatesByPath = {};
@@ -44,6 +44,9 @@ class Merge extends plugin_1.ManifestPlugin {
44
44
  updatesByPath[update.path] = [update];
45
45
  }
46
46
  }
47
+ for (const label of pullRequest.labels) {
48
+ labels.add(label);
49
+ }
47
50
  releaseData.push(...pullRequest.body.releaseData);
48
51
  }
49
52
  const updates = [];
@@ -26,6 +26,7 @@ const branch_name_1 = require("../util/branch-name");
26
26
  const json_stringify_1 = require("../util/json-stringify");
27
27
  const changelog_1 = require("../updaters/changelog");
28
28
  const workspace_1 = require("./workspace");
29
+ const versioning_strategy_1 = require("../versioning-strategy");
29
30
  class Package extends package_1.Package {
30
31
  constructor(rawContent, location, pkg) {
31
32
  super(pkg !== null && pkg !== void 0 ? pkg : JSON.parse(rawContent), location);
@@ -92,8 +93,7 @@ class NodeWorkspace extends workspace_1.WorkspacePlugin {
92
93
  }
93
94
  bumpVersion(pkg) {
94
95
  const version = version_1.Version.parse(pkg.version);
95
- version.patch += 1;
96
- return version;
96
+ return new versioning_strategy_1.PatchVersionUpdate().bump(version);
97
97
  }
98
98
  updateCandidate(existingCandidate, pkg, updatedVersions) {
99
99
  var _a;
@@ -1,10 +1,10 @@
1
1
  export interface PullRequest {
2
- headBranchName: string;
3
- baseBranchName: string;
4
- number: number;
5
- title: string;
6
- body: string;
7
- labels: string[];
8
- files: string[];
9
- sha?: string;
2
+ readonly headBranchName: string;
3
+ readonly baseBranchName: string;
4
+ readonly number: number;
5
+ readonly title: string;
6
+ readonly body: string;
7
+ readonly labels: string[];
8
+ readonly files: string[];
9
+ readonly sha?: string;
10
10
  }
@@ -3,11 +3,11 @@ import { Version } from './version';
3
3
  import { PullRequestBody } from './util/pull-request-body';
4
4
  import { PullRequestTitle } from './util/pull-request-title';
5
5
  export interface ReleasePullRequest {
6
- title: PullRequestTitle;
7
- body: PullRequestBody;
6
+ readonly title: PullRequestTitle;
7
+ readonly body: PullRequestBody;
8
+ readonly labels: string[];
9
+ readonly headRefName: string;
10
+ readonly version?: Version;
11
+ readonly draft: boolean;
8
12
  updates: Update[];
9
- labels: string[];
10
- headRefName: string;
11
- version?: Version;
12
- draft: boolean;
13
13
  }
@@ -0,0 +1,108 @@
1
+ import { Strategy } from '../strategy';
2
+ import { GitHub } from '../github';
3
+ import { VersioningStrategy } from '../versioning-strategy';
4
+ import { Repository } from '../repository';
5
+ import { ChangelogNotes, ChangelogSection } from '../changelog-notes';
6
+ import { Update } from '../update';
7
+ import { ConventionalCommit, Commit } from '../commit';
8
+ import { Version, VersionsMap } from '../version';
9
+ import { TagName } from '../util/tag-name';
10
+ import { Release } from '../release';
11
+ import { ReleasePullRequest } from '../release-pull-request';
12
+ import { PullRequest } from '../pull-request';
13
+ export interface BuildUpdatesOptions {
14
+ changelogEntry: string;
15
+ newVersion: Version;
16
+ versionsMap: VersionsMap;
17
+ latestVersion?: Version;
18
+ }
19
+ export interface BaseStrategyOptions {
20
+ path?: string;
21
+ bumpMinorPreMajor?: boolean;
22
+ bumpPatchForMinorPreMajor?: boolean;
23
+ github: GitHub;
24
+ component?: string;
25
+ packageName?: string;
26
+ versioningStrategy?: VersioningStrategy;
27
+ targetBranch: string;
28
+ changelogPath?: string;
29
+ changelogSections?: ChangelogSection[];
30
+ commitPartial?: string;
31
+ headerPartial?: string;
32
+ mainTemplate?: string;
33
+ tagSeparator?: string;
34
+ skipGitHubRelease?: boolean;
35
+ releaseAs?: string;
36
+ changelogNotes?: ChangelogNotes;
37
+ includeComponentInTag?: boolean;
38
+ pullRequestTitlePattern?: string;
39
+ }
40
+ /**
41
+ * A strategy is responsible for determining which files are
42
+ * necessary to update in a release pull request.
43
+ */
44
+ export declare abstract class BaseStrategy implements Strategy {
45
+ readonly path: string;
46
+ protected github: GitHub;
47
+ protected component?: string;
48
+ protected packageName?: string;
49
+ readonly versioningStrategy: VersioningStrategy;
50
+ protected targetBranch: string;
51
+ protected repository: Repository;
52
+ protected changelogPath: string;
53
+ protected tagSeparator?: string;
54
+ private skipGitHubRelease;
55
+ private releaseAs?;
56
+ private includeComponentInTag;
57
+ private pullRequestTitlePattern?;
58
+ readonly changelogNotes: ChangelogNotes;
59
+ protected changelogSections?: ChangelogSection[];
60
+ constructor(options: BaseStrategyOptions);
61
+ /**
62
+ * Specify the files necessary to update in a release pull request.
63
+ * @param {BuildUpdatesOptions} options
64
+ */
65
+ protected abstract buildUpdates(options: BuildUpdatesOptions): Promise<Update[]>;
66
+ /**
67
+ * Return the component for this strategy. This may be a computed field.
68
+ * @returns {string}
69
+ */
70
+ getComponent(): Promise<string | undefined>;
71
+ getDefaultComponent(): Promise<string | undefined>;
72
+ getDefaultPackageName(): Promise<string | undefined>;
73
+ protected normalizeComponent(component: string | undefined): string;
74
+ /**
75
+ * Override this method to post process commits
76
+ * @param {ConventionalCommit[]} commits parsed commits
77
+ * @returns {ConventionalCommit[]} modified commits
78
+ */
79
+ protected postProcessCommits(commits: ConventionalCommit[]): ConventionalCommit[];
80
+ protected buildReleaseNotes(conventionalCommits: ConventionalCommit[], newVersion: Version, newVersionTag: TagName, latestRelease?: Release): Promise<string>;
81
+ /**
82
+ * Builds a candidate release pull request
83
+ * @param {Commit[]} commits Raw commits to consider for this release.
84
+ * @param {Release} latestRelease Optional. The last release for this
85
+ * component if available.
86
+ * @param {boolean} draft Optional. Whether or not to create the pull
87
+ * request as a draft. Defaults to `false`.
88
+ * @returns {ReleasePullRequest | undefined} The release pull request to
89
+ * open for this path/component. Returns undefined if we should not
90
+ * open a pull request.
91
+ */
92
+ buildReleasePullRequest(commits: Commit[], latestRelease?: Release, draft?: boolean, labels?: string[]): Promise<ReleasePullRequest | undefined>;
93
+ protected changelogEmpty(changelogEntry: string): boolean;
94
+ protected updateVersionsMap(versionsMap: VersionsMap, conventionalCommits: ConventionalCommit[]): Promise<VersionsMap>;
95
+ protected buildNewVersion(conventionalCommits: ConventionalCommit[], latestRelease?: Release): Promise<Version>;
96
+ protected buildVersionsMap(_conventionalCommits: ConventionalCommit[]): Promise<VersionsMap>;
97
+ /**
98
+ * Given a merged pull request, build the candidate release.
99
+ * @param {PullRequest} mergedPullRequest The merged release pull request.
100
+ * @returns {Release} The candidate release.
101
+ */
102
+ buildRelease(mergedPullRequest: PullRequest): Promise<Release | undefined>;
103
+ /**
104
+ * Override this to handle the initial version of a new library.
105
+ */
106
+ protected initialReleaseVersion(): Version;
107
+ protected addPath(file: string): string;
108
+ }
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ // Copyright 2021 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.BaseStrategy = void 0;
17
+ const manifest_1 = require("../manifest");
18
+ const default_1 = require("../versioning-strategies/default");
19
+ const default_2 = require("../changelog-notes/default");
20
+ const commit_1 = require("../commit");
21
+ const version_1 = require("../version");
22
+ const tag_name_1 = require("../util/tag-name");
23
+ const logger_1 = require("../util/logger");
24
+ const pull_request_title_1 = require("../util/pull-request-title");
25
+ const branch_name_1 = require("../util/branch-name");
26
+ const pull_request_body_1 = require("../util/pull-request-body");
27
+ const DEFAULT_CHANGELOG_PATH = 'CHANGELOG.md';
28
+ /**
29
+ * A strategy is responsible for determining which files are
30
+ * necessary to update in a release pull request.
31
+ */
32
+ class BaseStrategy {
33
+ constructor(options) {
34
+ var _a;
35
+ this.path = options.path || manifest_1.ROOT_PROJECT_PATH;
36
+ this.github = options.github;
37
+ this.packageName = options.packageName;
38
+ this.component =
39
+ options.component || this.normalizeComponent(this.packageName);
40
+ this.versioningStrategy =
41
+ options.versioningStrategy || new default_1.DefaultVersioningStrategy({});
42
+ this.targetBranch = options.targetBranch;
43
+ this.repository = options.github.repository;
44
+ this.changelogPath = options.changelogPath || DEFAULT_CHANGELOG_PATH;
45
+ this.changelogSections = options.changelogSections;
46
+ this.tagSeparator = options.tagSeparator;
47
+ this.skipGitHubRelease = options.skipGitHubRelease || false;
48
+ this.releaseAs = options.releaseAs;
49
+ this.changelogNotes =
50
+ options.changelogNotes || new default_2.DefaultChangelogNotes(options);
51
+ this.includeComponentInTag = (_a = options.includeComponentInTag) !== null && _a !== void 0 ? _a : true;
52
+ this.pullRequestTitlePattern = options.pullRequestTitlePattern;
53
+ }
54
+ /**
55
+ * Return the component for this strategy. This may be a computed field.
56
+ * @returns {string}
57
+ */
58
+ async getComponent() {
59
+ if (!this.includeComponentInTag) {
60
+ return '';
61
+ }
62
+ return this.component || (await this.getDefaultComponent());
63
+ }
64
+ async getDefaultComponent() {
65
+ return this.normalizeComponent(await this.getDefaultPackageName());
66
+ }
67
+ async getDefaultPackageName() {
68
+ return '';
69
+ }
70
+ normalizeComponent(component) {
71
+ if (!component) {
72
+ return '';
73
+ }
74
+ return component;
75
+ }
76
+ /**
77
+ * Override this method to post process commits
78
+ * @param {ConventionalCommit[]} commits parsed commits
79
+ * @returns {ConventionalCommit[]} modified commits
80
+ */
81
+ postProcessCommits(commits) {
82
+ return commits;
83
+ }
84
+ async buildReleaseNotes(conventionalCommits, newVersion, newVersionTag, latestRelease) {
85
+ var _a;
86
+ return await this.changelogNotes.buildNotes(conventionalCommits, {
87
+ owner: this.repository.owner,
88
+ repository: this.repository.repo,
89
+ version: newVersion.toString(),
90
+ previousTag: (_a = latestRelease === null || latestRelease === void 0 ? void 0 : latestRelease.tag) === null || _a === void 0 ? void 0 : _a.toString(),
91
+ currentTag: newVersionTag.toString(),
92
+ targetBranch: this.targetBranch,
93
+ changelogSections: this.changelogSections,
94
+ });
95
+ }
96
+ /**
97
+ * Builds a candidate release pull request
98
+ * @param {Commit[]} commits Raw commits to consider for this release.
99
+ * @param {Release} latestRelease Optional. The last release for this
100
+ * component if available.
101
+ * @param {boolean} draft Optional. Whether or not to create the pull
102
+ * request as a draft. Defaults to `false`.
103
+ * @returns {ReleasePullRequest | undefined} The release pull request to
104
+ * open for this path/component. Returns undefined if we should not
105
+ * open a pull request.
106
+ */
107
+ async buildReleasePullRequest(commits, latestRelease, draft, labels = []) {
108
+ const conventionalCommits = this.postProcessCommits(commit_1.parseConventionalCommits(commits));
109
+ const newVersion = await this.buildNewVersion(conventionalCommits, latestRelease);
110
+ const versionsMap = await this.updateVersionsMap(await this.buildVersionsMap(conventionalCommits), conventionalCommits);
111
+ const component = await this.getComponent();
112
+ logger_1.logger.debug('component:', component);
113
+ const newVersionTag = new tag_name_1.TagName(newVersion, this.includeComponentInTag ? component : undefined, this.tagSeparator);
114
+ logger_1.logger.warn('pull request title pattern:', this.pullRequestTitlePattern);
115
+ const pullRequestTitle = pull_request_title_1.PullRequestTitle.ofComponentTargetBranchVersion(component || '', this.targetBranch, newVersion, this.pullRequestTitlePattern);
116
+ const branchName = component
117
+ ? branch_name_1.BranchName.ofComponentTargetBranch(component, this.targetBranch)
118
+ : branch_name_1.BranchName.ofTargetBranch(this.targetBranch);
119
+ const releaseNotesBody = await this.buildReleaseNotes(conventionalCommits, newVersion, newVersionTag, latestRelease);
120
+ if (this.changelogEmpty(releaseNotesBody)) {
121
+ logger_1.logger.info(`No user facing commits found since ${latestRelease ? latestRelease.sha : 'beginning of time'} - skipping`);
122
+ return undefined;
123
+ }
124
+ const updates = await this.buildUpdates({
125
+ changelogEntry: releaseNotesBody,
126
+ newVersion,
127
+ versionsMap,
128
+ latestVersion: latestRelease === null || latestRelease === void 0 ? void 0 : latestRelease.tag.version,
129
+ });
130
+ const pullRequestBody = new pull_request_body_1.PullRequestBody([
131
+ {
132
+ component,
133
+ version: newVersion,
134
+ notes: releaseNotesBody,
135
+ },
136
+ ]);
137
+ return {
138
+ title: pullRequestTitle,
139
+ body: pullRequestBody,
140
+ updates,
141
+ labels,
142
+ headRefName: branchName.toString(),
143
+ version: newVersion,
144
+ draft: draft !== null && draft !== void 0 ? draft : false,
145
+ };
146
+ }
147
+ changelogEmpty(changelogEntry) {
148
+ return changelogEntry.split('\n').length <= 1;
149
+ }
150
+ async updateVersionsMap(versionsMap, conventionalCommits) {
151
+ for (const versionKey of versionsMap.keys()) {
152
+ const version = versionsMap.get(versionKey);
153
+ if (!version) {
154
+ logger_1.logger.warn(`didn't find version for ${versionKey}`);
155
+ continue;
156
+ }
157
+ const newVersion = await this.versioningStrategy.bump(version, conventionalCommits);
158
+ versionsMap.set(versionKey, newVersion);
159
+ }
160
+ return versionsMap;
161
+ }
162
+ async buildNewVersion(conventionalCommits, latestRelease) {
163
+ if (this.releaseAs) {
164
+ logger_1.logger.warn(`Setting version for ${this.path} from release-as configuration`);
165
+ return version_1.Version.parse(this.releaseAs);
166
+ }
167
+ else if (latestRelease) {
168
+ return await this.versioningStrategy.bump(latestRelease.tag.version, conventionalCommits);
169
+ }
170
+ else {
171
+ return this.initialReleaseVersion();
172
+ }
173
+ }
174
+ async buildVersionsMap(_conventionalCommits) {
175
+ return new Map();
176
+ }
177
+ /**
178
+ * Given a merged pull request, build the candidate release.
179
+ * @param {PullRequest} mergedPullRequest The merged release pull request.
180
+ * @returns {Release} The candidate release.
181
+ */
182
+ async buildRelease(mergedPullRequest) {
183
+ if (this.skipGitHubRelease) {
184
+ logger_1.logger.info('Release skipped from strategy config');
185
+ return;
186
+ }
187
+ if (!mergedPullRequest.sha) {
188
+ logger_1.logger.error('Pull request should have been merged');
189
+ return;
190
+ }
191
+ const pullRequestTitle = pull_request_title_1.PullRequestTitle.parse(mergedPullRequest.title, this.pullRequestTitlePattern) ||
192
+ pull_request_title_1.PullRequestTitle.parse(mergedPullRequest.title, manifest_1.MANIFEST_PULL_REQUEST_TITLE_PATTERN);
193
+ if (!pullRequestTitle) {
194
+ logger_1.logger.error(`Bad pull request title: '${mergedPullRequest.title}'`);
195
+ return;
196
+ }
197
+ const branchName = branch_name_1.BranchName.parse(mergedPullRequest.headBranchName);
198
+ if (!branchName) {
199
+ logger_1.logger.error(`Bad branch name: ${mergedPullRequest.headBranchName}`);
200
+ return;
201
+ }
202
+ const pullRequestBody = pull_request_body_1.PullRequestBody.parse(mergedPullRequest.body);
203
+ if (!pullRequestBody) {
204
+ logger_1.logger.error('Could not parse pull request body as a release PR');
205
+ return;
206
+ }
207
+ const component = await this.getComponent();
208
+ logger_1.logger.info('component:', component);
209
+ const releaseData = pullRequestBody.releaseData.length === 1 &&
210
+ !pullRequestBody.releaseData[0].component
211
+ ? pullRequestBody.releaseData[0]
212
+ : pullRequestBody.releaseData.find(releaseData => {
213
+ return (this.normalizeComponent(releaseData.component) ===
214
+ this.normalizeComponent(component));
215
+ });
216
+ const notes = releaseData === null || releaseData === void 0 ? void 0 : releaseData.notes;
217
+ if (notes === undefined) {
218
+ logger_1.logger.warn('Failed to find release notes');
219
+ }
220
+ const version = pullRequestTitle.getVersion() || (releaseData === null || releaseData === void 0 ? void 0 : releaseData.version);
221
+ if (!version) {
222
+ logger_1.logger.error('Pull request should have included version');
223
+ return;
224
+ }
225
+ const tag = new tag_name_1.TagName(version, this.includeComponentInTag ? component : undefined, this.tagSeparator);
226
+ return {
227
+ tag,
228
+ notes: notes || '',
229
+ sha: mergedPullRequest.sha,
230
+ };
231
+ }
232
+ /**
233
+ * Override this to handle the initial version of a new library.
234
+ */
235
+ initialReleaseVersion() {
236
+ return version_1.Version.parse('1.0.0');
237
+ }
238
+ addPath(file) {
239
+ if (this.path === manifest_1.ROOT_PROJECT_PATH) {
240
+ return file;
241
+ }
242
+ file = file.replace(/^[/\\]/, '');
243
+ if (this.path === undefined) {
244
+ return file;
245
+ }
246
+ else {
247
+ const path = this.path.replace(/[/\\]$/, '');
248
+ return `${path}/${file}`;
249
+ }
250
+ }
251
+ }
252
+ exports.BaseStrategy = BaseStrategy;
253
+ //# sourceMappingURL=base.js.map
@@ -1,6 +1,6 @@
1
- import { Strategy, BuildUpdatesOptions } from '../strategy';
1
+ import { BaseStrategy, BuildUpdatesOptions } from './base';
2
2
  import { Update } from '../update';
3
- export declare class Dart extends Strategy {
3
+ export declare class Dart extends BaseStrategy {
4
4
  private pubspecYmlContents?;
5
5
  protected buildUpdates(options: BuildUpdatesOptions): Promise<Update[]>;
6
6
  getDefaultPackageName(): Promise<string | undefined>;
@@ -19,8 +19,8 @@ const changelog_1 = require("../updaters/changelog");
19
19
  const yaml = require("js-yaml");
20
20
  // pubspec
21
21
  const pubspec_yaml_1 = require("../updaters/dart/pubspec-yaml");
22
- const strategy_1 = require("../strategy");
23
- class Dart extends strategy_1.Strategy {
22
+ const base_1 = require("./base");
23
+ class Dart extends base_1.BaseStrategy {
24
24
  async buildUpdates(options) {
25
25
  const updates = [];
26
26
  const version = options.newVersion;
@@ -1,5 +1,5 @@
1
- import { Strategy, BuildUpdatesOptions } from '../strategy';
1
+ import { BaseStrategy, BuildUpdatesOptions } from './base';
2
2
  import { Update } from '../update';
3
- export declare class Elixir extends Strategy {
3
+ export declare class Elixir extends BaseStrategy {
4
4
  protected buildUpdates(options: BuildUpdatesOptions): Promise<Update[]>;
5
5
  }
@@ -18,8 +18,8 @@ exports.Elixir = void 0;
18
18
  const changelog_1 = require("../updaters/changelog");
19
19
  // mix.exs support
20
20
  const elixir_mix_exs_1 = require("../updaters/elixir/elixir-mix-exs");
21
- const strategy_1 = require("../strategy");
22
- class Elixir extends strategy_1.Strategy {
21
+ const base_1 = require("./base");
22
+ class Elixir extends base_1.BaseStrategy {
23
23
  async buildUpdates(options) {
24
24
  const updates = [];
25
25
  const version = options.newVersion;