release-please 16.14.4 → 16.16.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@
4
4
 
5
5
  [1]: https://www.npmjs.com/package/release-please?activeTab=versions
6
6
 
7
+ ## [16.16.0](https://github.com/googleapis/release-please/compare/v16.15.0...v16.16.0) (2025-02-19)
8
+
9
+
10
+ ### Features
11
+
12
+ * add strategy for R packages ([#2436](https://github.com/googleapis/release-please/issues/2436)) ([2b5ff3b](https://github.com/googleapis/release-please/commit/2b5ff3b5d7b5c8546bb112149908e150e9eba680))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **deps:** bump dependency versions ([#2486](https://github.com/googleapis/release-please/issues/2486)) ([6db2fb4](https://github.com/googleapis/release-please/commit/6db2fb48adcdf60f1779601fb36f982e2fb7f6f7))
18
+
19
+ ## [16.15.0](https://github.com/googleapis/release-please/compare/v16.14.4...v16.15.0) (2024-11-13)
20
+
21
+
22
+ ### Features
23
+
24
+ * add `always-update` option to push to always push to release branch ([72d40df](https://github.com/googleapis/release-please/commit/72d40df677b08fd52654a4c3b320649f63b9c635))
25
+
7
26
  ## [16.14.4](https://github.com/googleapis/release-please/compare/v16.14.3...v16.14.4) (2024-11-12)
8
27
 
9
28
 
package/README.md CHANGED
@@ -195,6 +195,7 @@ Release Please automates releases for the following flavors of repositories:
195
195
  | `ocaml` | [An OCaml repository, containing 1 or more opam or esy files and a CHANGELOG.md](https://github.com/grain-lang/binaryen.ml) |
196
196
  | `php` | A repository with a composer.json and a CHANGELOG.md |
197
197
  | `python` | [A Python repository, with a setup.py, setup.cfg, CHANGELOG.md](https://github.com/googleapis/python-storage) and optionally a pyproject.toml and a <project>/\_\_init\_\_.py |
198
+ | `R` | A repository with a DESCRIPTION and a NEWS.md |
198
199
  | `ruby` | A repository with a version.rb and a CHANGELOG.md |
199
200
  | `rust` | A Rust repository, with a Cargo.toml (either as a crate or workspace, although note that workspaces require a [manifest driven release](https://github.com/googleapis/release-please/blob/main/docs/manifest-releaser.md) and the "cargo-workspace" plugin) and a CHANGELOG.md |
200
201
  | `sfdx` | A repository with a [sfdx-project.json](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) and a CHANGELOG.md |
@@ -49,6 +49,7 @@ const ocaml_1 = require("./strategies/ocaml");
49
49
  const php_1 = require("./strategies/php");
50
50
  const php_yoshi_1 = require("./strategies/php-yoshi");
51
51
  const python_1 = require("./strategies/python");
52
+ const r_1 = require("./strategies/r");
52
53
  const ruby_1 = require("./strategies/ruby");
53
54
  const ruby_yoshi_1 = require("./strategies/ruby-yoshi");
54
55
  const rust_1 = require("./strategies/rust");
@@ -91,6 +92,7 @@ const releasers = {
91
92
  php: options => new php_1.PHP(options),
92
93
  'php-yoshi': options => new php_yoshi_1.PHPYoshi(options),
93
94
  python: options => new python_1.Python(options),
95
+ r: options => new r_1.R(options),
94
96
  ruby: options => new ruby_1.Ruby(options),
95
97
  'ruby-yoshi': options => new ruby_yoshi_1.RubyYoshi(options),
96
98
  rust: options => new rust_1.Rust(options),
@@ -14,4 +14,4 @@ export { Logger, setLogger } from './util/logger';
14
14
  export { GitHub } from './github';
15
15
  export declare const configSchema: any;
16
16
  export declare const manifestSchema: any;
17
- export declare const VERSION = "16.14.4";
17
+ export declare const VERSION = "16.16.0";
@@ -36,6 +36,6 @@ Object.defineProperty(exports, "GitHub", { enumerable: true, get: function () {
36
36
  exports.configSchema = require('../../schemas/config.json');
37
37
  exports.manifestSchema = require('../../schemas/manifest.json');
38
38
  // x-release-please-start-version
39
- exports.VERSION = '16.14.4';
39
+ exports.VERSION = '16.16.0';
40
40
  // x-release-please-end
41
41
  //# sourceMappingURL=index.js.map
@@ -140,6 +140,7 @@ export interface ManifestOptions {
140
140
  draft?: boolean;
141
141
  prerelease?: boolean;
142
142
  draftPullRequest?: boolean;
143
+ alwaysUpdate?: boolean;
143
144
  groupPullRequestTitlePattern?: string;
144
145
  releaseSearchDepth?: number;
145
146
  commitSearchDepth?: number;
@@ -188,6 +189,7 @@ export interface ManifestConfig extends ReleaserConfigJson {
188
189
  'release-search-depth'?: number;
189
190
  'commit-search-depth'?: number;
190
191
  'sequential-calls'?: boolean;
192
+ 'always-update'?: boolean;
191
193
  }
192
194
  export type ReleasedVersions = Record<string, Version>;
193
195
  export type RepositoryConfig = Record<string, ReleaserConfig>;
@@ -215,6 +217,7 @@ export declare class Manifest {
215
217
  readonly releasedVersions: ReleasedVersions;
216
218
  private targetBranch;
217
219
  private separatePullRequests;
220
+ private alwaysUpdate;
218
221
  readonly fork: boolean;
219
222
  private signoffUser?;
220
223
  private labels;
@@ -253,6 +256,8 @@ export declare class Manifest {
253
256
  * plugin
254
257
  * @param {boolean} manifestOptions.separatePullRequests If true, create separate pull
255
258
  * requests instead of a single manifest release pull request
259
+ * @param {boolean} manifestOptions.alwaysUpdate If true, always updates pull requests instead of
260
+ * only when the release notes change
256
261
  * @param {PluginType[]} manifestOptions.plugins Any plugins to use for this repository
257
262
  * @param {boolean} manifestOptions.fork If true, create pull requests from a fork. Defaults
258
263
  * to `false`
@@ -325,6 +330,7 @@ export declare class Manifest {
325
330
  private createOrUpdatePullRequest;
326
331
  private maybeUpdateExistingPullRequest;
327
332
  private maybeUpdateSnoozedPullRequest;
333
+ private updateExistingPullRequest;
328
334
  private findMergedReleasePullRequests;
329
335
  /**
330
336
  * Find merged, untagged releases and build candidate releases to tag.
@@ -57,6 +57,8 @@ class Manifest {
57
57
  * plugin
58
58
  * @param {boolean} manifestOptions.separatePullRequests If true, create separate pull
59
59
  * requests instead of a single manifest release pull request
60
+ * @param {boolean} manifestOptions.alwaysUpdate If true, always updates pull requests instead of
61
+ * only when the release notes change
60
62
  * @param {PluginType[]} manifestOptions.plugins Any plugins to use for this repository
61
63
  * @param {boolean} manifestOptions.fork If true, create pull requests from a fork. Defaults
62
64
  * to `false`
@@ -78,6 +80,7 @@ class Manifest {
78
80
  (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.manifestPath) || exports.DEFAULT_RELEASE_PLEASE_MANIFEST;
79
81
  this.separatePullRequests =
80
82
  (_a = manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.separatePullRequests) !== null && _a !== void 0 ? _a : Object.keys(repositoryConfig).length === 1;
83
+ this.alwaysUpdate = (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.alwaysUpdate) || false;
81
84
  this.fork = (manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.fork) || false;
82
85
  this.signoffUser = manifestOptions === null || manifestOptions === void 0 ? void 0 : manifestOptions.signoff;
83
86
  this.releaseLabels =
@@ -539,12 +542,16 @@ class Manifest {
539
542
  // look for existing, open pull request
540
543
  const existing = openPullRequests.find(openPullRequest => openPullRequest.headBranchName === pullRequest.headRefName);
541
544
  if (existing) {
542
- return await this.maybeUpdateExistingPullRequest(existing, pullRequest);
545
+ return this.alwaysUpdate
546
+ ? await this.updateExistingPullRequest(existing, pullRequest)
547
+ : await this.maybeUpdateExistingPullRequest(existing, pullRequest);
543
548
  }
544
549
  // look for closed, snoozed pull request
545
550
  const snoozed = snoozedPullRequests.find(openPullRequest => openPullRequest.headBranchName === pullRequest.headRefName);
546
551
  if (snoozed) {
547
- return await this.maybeUpdateSnoozedPullRequest(snoozed, pullRequest);
552
+ return this.alwaysUpdate
553
+ ? await this.updateExistingPullRequest(snoozed, pullRequest)
554
+ : await this.maybeUpdateSnoozedPullRequest(snoozed, pullRequest);
548
555
  }
549
556
  const body = await this.pullRequestOverflowHandler.handleOverflow(pullRequest);
550
557
  const message = this.signoffUser
@@ -571,28 +578,27 @@ class Manifest {
571
578
  this.logger.info(`PR https://github.com/${this.repository.owner}/${this.repository.repo}/pull/${existing.number} remained the same`);
572
579
  return undefined;
573
580
  }
574
- const updatedPullRequest = await this.github.updatePullRequest(existing.number, pullRequest, this.targetBranch, {
575
- fork: this.fork,
576
- signoffUser: this.signoffUser,
577
- pullRequestOverflowHandler: this.pullRequestOverflowHandler,
578
- });
579
- return updatedPullRequest;
581
+ return await this.updateExistingPullRequest(existing, pullRequest);
580
582
  }
581
- /// only update an snoozed pull request if it has release note changes
583
+ /// only update a snoozed pull request if it has release note changes
582
584
  async maybeUpdateSnoozedPullRequest(snoozed, pullRequest) {
583
585
  // If unchanged, no need to push updates
584
586
  if (snoozed.body === pullRequest.body.toString()) {
585
587
  this.logger.info(`PR https://github.com/${this.repository.owner}/${this.repository.repo}/pull/${snoozed.number} remained the same`);
586
588
  return undefined;
587
589
  }
588
- const updatedPullRequest = await this.github.updatePullRequest(snoozed.number, pullRequest, this.targetBranch, {
590
+ const updatedPullRequest = await this.updateExistingPullRequest(snoozed, pullRequest);
591
+ // TODO: consider leaving the snooze label
592
+ await this.github.removeIssueLabels([exports.SNOOZE_LABEL], snoozed.number);
593
+ return updatedPullRequest;
594
+ }
595
+ /// force an update to an existing pull request
596
+ async updateExistingPullRequest(existing, pullRequest) {
597
+ return await this.github.updatePullRequest(existing.number, pullRequest, this.targetBranch, {
589
598
  fork: this.fork,
590
599
  signoffUser: this.signoffUser,
591
600
  pullRequestOverflowHandler: this.pullRequestOverflowHandler,
592
601
  });
593
- // TODO: consider leaving the snooze label
594
- await this.github.removeIssueLabels([exports.SNOOZE_LABEL], snoozed.number);
595
- return updatedPullRequest;
596
602
  }
597
603
  async *findMergedReleasePullRequests() {
598
604
  // Find merged release pull requests
@@ -865,6 +871,7 @@ async function parseConfig(github, configFile, branch, onlyPath, releaseAs) {
865
871
  lastReleaseSha: config['last-release-sha'],
866
872
  alwaysLinkLocal: config['always-link-local'],
867
873
  separatePullRequests: config['separate-pull-requests'],
874
+ alwaysUpdate: config['always-update'],
868
875
  groupPullRequestTitlePattern: config['group-pull-request-title-pattern'],
869
876
  plugins: config['plugins'],
870
877
  signoff: config['signoff'],
@@ -0,0 +1,8 @@
1
+ import { BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions } from './base';
2
+ import { Update } from '../update';
3
+ import { Version } from '../version';
4
+ export declare class R extends BaseStrategy {
5
+ constructor(options: BaseStrategyOptions);
6
+ protected buildUpdates(options: BuildUpdatesOptions): Promise<Update[]>;
7
+ protected initialReleaseVersion(): Version;
8
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ // Copyright 2025 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.R = void 0;
17
+ const base_1 = require("./base");
18
+ const news_1 = require("../updaters/r/news");
19
+ const version_1 = require("../version");
20
+ const description_1 = require("../updaters/r/description");
21
+ const CHANGELOG_SECTIONS = [
22
+ { type: 'feat', section: 'Features' },
23
+ { type: 'fix', section: 'Bug Fixes' },
24
+ { type: 'perf', section: 'Performance Improvements' },
25
+ { type: 'deps', section: 'Dependencies' },
26
+ { type: 'revert', section: 'Reverts' },
27
+ { type: 'docs', section: 'Documentation' },
28
+ { type: 'style', section: 'Styles', hidden: true },
29
+ { type: 'chore', section: 'Miscellaneous Chores', hidden: true },
30
+ { type: 'refactor', section: 'Code Refactoring', hidden: true },
31
+ { type: 'test', section: 'Tests', hidden: true },
32
+ { type: 'build', section: 'Build System', hidden: true },
33
+ { type: 'ci', section: 'Continuous Integration', hidden: true },
34
+ ];
35
+ class R extends base_1.BaseStrategy {
36
+ constructor(options) {
37
+ var _a, _b;
38
+ options.changelogPath = (_a = options.changelogPath) !== null && _a !== void 0 ? _a : 'NEWS.md';
39
+ options.changelogSections = (_b = options.changelogSections) !== null && _b !== void 0 ? _b : CHANGELOG_SECTIONS;
40
+ super(options);
41
+ }
42
+ async buildUpdates(options) {
43
+ const updates = [];
44
+ const version = options.newVersion;
45
+ updates.push({
46
+ path: this.addPath(this.changelogPath),
47
+ createIfMissing: true,
48
+ updater: new news_1.News({
49
+ version,
50
+ changelogEntry: options.changelogEntry,
51
+ }),
52
+ });
53
+ updates.push({
54
+ path: this.addPath('DESCRIPTION'),
55
+ createIfMissing: false,
56
+ updater: new description_1.DescriptionUpdater({
57
+ version,
58
+ }),
59
+ });
60
+ return updates;
61
+ }
62
+ initialReleaseVersion() {
63
+ return version_1.Version.parse('0.1.0');
64
+ }
65
+ }
66
+ exports.R = R;
67
+ //# sourceMappingURL=r.js.map
@@ -7,7 +7,7 @@ interface ChangelogJsonOptions extends UpdateOptions {
7
7
  commits: ConventionalCommit[];
8
8
  }
9
9
  /**
10
- * Maintians a machine readable CHANGELOG in chnagelog.json.
10
+ * Maintains a machine readable CHANGELOG in chnagelog.json.
11
11
  * See: https://gist.github.com/bcoe/50ef0a0024bbf107cd5bc0adbdc04758
12
12
  */
13
13
  export declare class ChangelogJson extends DefaultUpdater {
@@ -21,7 +21,7 @@ const BREAKING_CHANGE_TITLE = 'BREAKING CHANGE';
21
21
  const COMMIT_PREFIX = /^[^:]+: ?/;
22
22
  const PR_SUFFIX_REGEX = / ?\(#(?<pr>[0-9]+)\)$/;
23
23
  /**
24
- * Maintians a machine readable CHANGELOG in chnagelog.json.
24
+ * Maintains a machine readable CHANGELOG in chnagelog.json.
25
25
  * See: https://gist.github.com/bcoe/50ef0a0024bbf107cd5bc0adbdc04758
26
26
  */
27
27
  class ChangelogJson extends default_1.DefaultUpdater {
@@ -0,0 +1,12 @@
1
+ import { DefaultUpdater } from '../default';
2
+ /**
3
+ * Updates the DESCRIPTION file of an R package.
4
+ */
5
+ export declare class DescriptionUpdater extends DefaultUpdater {
6
+ /**
7
+ * Given initial file contents, return updated contents.
8
+ * @param {string} content The initial content
9
+ * @returns {string} The updated content
10
+ */
11
+ updateContent(content: string): string;
12
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ // Copyright 2025 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.DescriptionUpdater = void 0;
17
+ const default_1 = require("../default");
18
+ /**
19
+ * Updates the DESCRIPTION file of an R package.
20
+ */
21
+ class DescriptionUpdater extends default_1.DefaultUpdater {
22
+ /**
23
+ * Given initial file contents, return updated contents.
24
+ * @param {string} content The initial content
25
+ * @returns {string} The updated content
26
+ */
27
+ updateContent(content) {
28
+ return content.replace(/^Version:\s*[0-9]+\.[0-9]+\.[0-9]+(?:\.[0-9]+)?\s*$/m, `Version: ${this.version}`);
29
+ }
30
+ }
31
+ exports.DescriptionUpdater = DescriptionUpdater;
32
+ //# sourceMappingURL=description.js.map
@@ -0,0 +1,12 @@
1
+ import { DefaultUpdater, UpdateOptions } from '../default';
2
+ interface ChangelogOptions extends UpdateOptions {
3
+ changelogEntry: string;
4
+ versionHeaderRegex?: string;
5
+ }
6
+ export declare class News extends DefaultUpdater {
7
+ changelogEntry: string;
8
+ readonly versionHeaderRegex: RegExp;
9
+ constructor(options: ChangelogOptions);
10
+ updateContent(content: string | undefined): string;
11
+ }
12
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ // Copyright 2025 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.News = void 0;
17
+ const default_1 = require("../default");
18
+ const DEFAULT_VERSION_HEADER_REGEX = '\n### v?[0-9[]';
19
+ class News extends default_1.DefaultUpdater {
20
+ constructor(options) {
21
+ var _a;
22
+ super(options);
23
+ this.changelogEntry = options.changelogEntry;
24
+ this.versionHeaderRegex = new RegExp((_a = options.versionHeaderRegex) !== null && _a !== void 0 ? _a : DEFAULT_VERSION_HEADER_REGEX, 's');
25
+ }
26
+ updateContent(content) {
27
+ content = content || '';
28
+ const lastEntryIndex = content.search(this.versionHeaderRegex);
29
+ if (lastEntryIndex === -1) {
30
+ if (content) {
31
+ return `${this.changelogEntry}\n\n${adjustHeaders(content).trim()}\n`;
32
+ }
33
+ else {
34
+ return `${this.changelogEntry}\n`;
35
+ }
36
+ }
37
+ else {
38
+ const before = content.slice(0, lastEntryIndex);
39
+ const after = content.slice(lastEntryIndex);
40
+ return `${before}\n${this.changelogEntry}\n${after}`.trim() + '\n';
41
+ }
42
+ }
43
+ }
44
+ exports.News = News;
45
+ // Helper to increase markdown H1 headers to H2
46
+ function adjustHeaders(content) {
47
+ return content.replace(/^#(\s)/gm, '##$1');
48
+ }
49
+ //# sourceMappingURL=news.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-please",
3
- "version": "16.14.4",
3
+ "version": "16.16.0",
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",
@@ -45,7 +45,7 @@
45
45
  "@types/inquirer": "^9.0.3",
46
46
  "@types/js-yaml": "^4.0.0",
47
47
  "@types/jsonpath": "^0.2.0",
48
- "@types/mocha": "^9.0.0",
48
+ "@types/mocha": "^10.0.0",
49
49
  "@types/node": "^18.0.0",
50
50
  "@types/npmlog": "^7.0.0",
51
51
  "@types/pino": "^7.0.0",
@@ -111,6 +111,10 @@
111
111
  "description": "Open a separate release pull request for each component. Defaults to `false`.",
112
112
  "type": "boolean"
113
113
  },
114
+ "always-update": {
115
+ "description": "Always update the pull request with the latest changes. Defaults to `false`.",
116
+ "type": "boolean"
117
+ },
114
118
  "tag-separator": {
115
119
  "description": "Customize the separator between the component and version in the GitHub tag.",
116
120
  "type": "string"
@@ -470,6 +474,7 @@
470
474
  "pull-request-header": true,
471
475
  "pull-request-footer": true,
472
476
  "separate-pull-requests": true,
477
+ "always-update": true,
473
478
  "tag-separator": true,
474
479
  "extra-files": true,
475
480
  "version-file": true,