release-please 16.16.0 → 16.18.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,20 @@
4
4
 
5
5
  [1]: https://www.npmjs.com/package/release-please?activeTab=versions
6
6
 
7
+ ## [16.18.0](https://github.com/googleapis/release-please/compare/v16.17.0...v16.18.0) (2025-02-27)
8
+
9
+
10
+ ### Features
11
+
12
+ * Manifest.createRelease to return PR numbers ([#2491](https://github.com/googleapis/release-please/issues/2491)) ([0f07691](https://github.com/googleapis/release-please/commit/0f076910c719b8dc8563936039b0708567811049))
13
+
14
+ ## [16.17.0](https://github.com/googleapis/release-please/compare/v16.16.0...v16.17.0) (2025-02-20)
15
+
16
+
17
+ ### Features
18
+
19
+ * allow date updating in generic strategy ([#2440](https://github.com/googleapis/release-please/issues/2440)) ([3099091](https://github.com/googleapis/release-please/commit/3099091bb6787e49fe36e289db36ac01a71af2c3))
20
+
7
21
  ## [16.16.0](https://github.com/googleapis/release-please/compare/v16.15.0...v16.16.0) (2025-02-19)
8
22
 
9
23
 
package/README.md CHANGED
@@ -194,7 +194,7 @@ Release Please automates releases for the following flavors of repositories:
194
194
  | `expo` | [An Expo based React Native repository, with a package.json, app.json and CHANGELOG.md](https://github.com/dmi3y/expo-release-please-example) |
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
- | `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 |
197
+ | `python` | [A Python repository with a pyproject.toml, <project>/\_\_init\_\_.py, CHANGELOG.md or optionally a setup.py, setup.cfg](https://github.com/googleapis/python-storage) |
198
198
  | `R` | A repository with a DESCRIPTION and a NEWS.md |
199
199
  | `ruby` | A repository with a version.rb and a CHANGELOG.md |
200
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 |
@@ -210,6 +210,10 @@ function pullRequestStrategyOptions(yargs) {
210
210
  .option('latest-tag-name', {
211
211
  describe: 'Override the detected latest tag name',
212
212
  type: 'string',
213
+ })
214
+ .option('date-format', {
215
+ describe: 'format in strftime format for updating dates',
216
+ type: 'string',
213
217
  })
214
218
  .middleware(_argv => {
215
219
  const argv = _argv;
@@ -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.16.0";
17
+ export declare const VERSION = "16.18.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.16.0';
39
+ exports.VERSION = '16.18.0';
40
40
  // x-release-please-end
41
41
  //# sourceMappingURL=index.js.map
@@ -70,6 +70,7 @@ export interface ReleaserConfig {
70
70
  releaseLabels?: string[];
71
71
  extraLabels?: string[];
72
72
  initialVersion?: string;
73
+ dateFormat?: string;
73
74
  changelogSections?: ChangelogSection[];
74
75
  changelogPath?: string;
75
76
  changelogType?: ChangelogNotesType;
@@ -122,6 +123,7 @@ interface ReleaserConfigJson {
122
123
  'skip-snapshot'?: boolean;
123
124
  'initial-version'?: string;
124
125
  'exclude-paths'?: string[];
126
+ 'date-format'?: string;
125
127
  }
126
128
  export interface ManifestOptions {
127
129
  bootstrapSha?: string;
@@ -145,6 +147,7 @@ export interface ManifestOptions {
145
147
  releaseSearchDepth?: number;
146
148
  commitSearchDepth?: number;
147
149
  logger?: Logger;
150
+ dateFormat?: string;
148
151
  }
149
152
  export interface ReleaserPackageConfig extends ReleaserConfigJson {
150
153
  'package-name'?: string;
@@ -209,6 +212,7 @@ export interface CreatedRelease extends GitHubRelease {
209
212
  major: number;
210
213
  minor: number;
211
214
  patch: number;
215
+ prNumber: number;
212
216
  }
213
217
  export declare class Manifest {
214
218
  private repository;
@@ -704,7 +704,7 @@ class Manifest {
704
704
  if (error)
705
705
  continue;
706
706
  try {
707
- githubReleases.push(await this.createRelease(release));
707
+ githubReleases.push(await this.createRelease(release, pullRequest));
708
708
  }
709
709
  catch (err) {
710
710
  if (err instanceof errors_1.DuplicateReleaseError) {
@@ -747,7 +747,7 @@ class Manifest {
747
747
  }
748
748
  return githubReleases;
749
749
  }
750
- async createRelease(release) {
750
+ async createRelease(release, pullRequest) {
751
751
  const githubRelease = await this.github.createRelease(release, {
752
752
  draft: release.draft,
753
753
  prerelease: release.prerelease,
@@ -759,6 +759,7 @@ class Manifest {
759
759
  major: release.tag.version.major,
760
760
  minor: release.tag.version.minor,
761
761
  patch: release.tag.version.patch,
762
+ prNumber: pullRequest.number,
762
763
  };
763
764
  }
764
765
  async getStrategiesByPath() {
@@ -838,6 +839,7 @@ function extractReleaserConfig(config) {
838
839
  skipSnapshot: config['skip-snapshot'],
839
840
  initialVersion: config['initial-version'],
840
841
  excludePaths: config['exclude-paths'],
842
+ dateFormat: config['date-format'],
841
843
  };
842
844
  }
843
845
  /**
@@ -1051,7 +1053,7 @@ async function latestReleaseVersion(github, targetBranch, releaseFilter, config,
1051
1053
  return candidateTagVersion.sort((a, b) => b.compare(a))[0];
1052
1054
  }
1053
1055
  function mergeReleaserConfig(defaultConfig, pathConfig) {
1054
- 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, _0, _1, _2, _3, _4, _5, _6;
1056
+ 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, _0, _1, _2, _3, _4, _5, _6, _7;
1055
1057
  return {
1056
1058
  releaseType: (_b = (_a = pathConfig.releaseType) !== null && _a !== void 0 ? _a : defaultConfig.releaseType) !== null && _b !== void 0 ? _b : 'node',
1057
1059
  bumpMinorPreMajor: (_c = pathConfig.bumpMinorPreMajor) !== null && _c !== void 0 ? _c : defaultConfig.bumpMinorPreMajor,
@@ -1083,6 +1085,7 @@ function mergeReleaserConfig(defaultConfig, pathConfig) {
1083
1085
  initialVersion: (_4 = pathConfig.initialVersion) !== null && _4 !== void 0 ? _4 : defaultConfig.initialVersion,
1084
1086
  extraLabels: (_5 = pathConfig.extraLabels) !== null && _5 !== void 0 ? _5 : defaultConfig.extraLabels,
1085
1087
  excludePaths: (_6 = pathConfig.excludePaths) !== null && _6 !== void 0 ? _6 : defaultConfig.excludePaths,
1088
+ dateFormat: (_7 = pathConfig.dateFormat) !== null && _7 !== void 0 ? _7 : defaultConfig.dateFormat,
1086
1089
  };
1087
1090
  }
1088
1091
  /**
@@ -52,6 +52,7 @@ export interface BaseStrategyOptions {
52
52
  logger?: Logger;
53
53
  initialVersion?: string;
54
54
  extraLabels?: string[];
55
+ dateFormat?: string;
55
56
  }
56
57
  /**
57
58
  * A strategy is responsible for determining which files are
@@ -80,6 +81,7 @@ export declare abstract class BaseStrategy implements Strategy {
80
81
  readonly componentNoSpace?: boolean;
81
82
  readonly extraFiles: ExtraFile[];
82
83
  readonly extraLabels: string[];
84
+ protected dateFormat: string;
83
85
  readonly changelogNotes: ChangelogNotes;
84
86
  protected changelogSections?: ChangelogSection[];
85
87
  constructor(options: BaseStrategyOptions);
@@ -119,7 +121,7 @@ export declare abstract class BaseStrategy implements Strategy {
119
121
  */
120
122
  buildReleasePullRequest(commits: ConventionalCommit[], latestRelease?: Release, draft?: boolean, labels?: string[], bumpOnlyOptions?: BumpReleaseOptions): Promise<ReleasePullRequest | undefined>;
121
123
  private extraFilePaths;
122
- protected extraFileUpdates(version: Version, versionsMap: VersionsMap): Promise<Update[]>;
124
+ protected extraFileUpdates(version: Version, versionsMap: VersionsMap, dateFormat: string): Promise<Update[]>;
123
125
  protected changelogEmpty(changelogEntry: string): boolean;
124
126
  protected updateVersionsMap(versionsMap: VersionsMap, conventionalCommits: ConventionalCommit[], _newVersion: Version): Promise<VersionsMap>;
125
127
  protected buildNewVersion(conventionalCommits: ConventionalCommit[], latestRelease?: Release): Promise<Version>;
@@ -66,6 +66,7 @@ class BaseStrategy {
66
66
  this.extraFiles = options.extraFiles || [];
67
67
  this.initialVersion = options.initialVersion;
68
68
  this.extraLabels = options.extraLabels || [];
69
+ this.dateFormat = options.dateFormat || generic_1.DEFAULT_DATE_FORMAT;
69
70
  }
70
71
  /**
71
72
  * Return the component for this strategy. This may be a computed field.
@@ -175,7 +176,7 @@ class BaseStrategy {
175
176
  latestVersion: latestRelease === null || latestRelease === void 0 ? void 0 : latestRelease.tag.version,
176
177
  commits: conventionalCommits,
177
178
  });
178
- const updatesWithExtras = (0, composite_1.mergeUpdates)(updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap))));
179
+ const updatesWithExtras = (0, composite_1.mergeUpdates)(updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap, this.dateFormat))));
179
180
  const pullRequestBody = await this.buildPullRequestBody(component, newVersion, releaseNotesBody, conventionalCommits, latestRelease, this.pullRequestHeader, this.pullRequestFooter);
180
181
  return {
181
182
  title: pullRequestTitle,
@@ -209,7 +210,7 @@ class BaseStrategy {
209
210
  return this.github.findFilesByGlobAndRef(extraFile.path, this.targetBranch, this.path);
210
211
  }
211
212
  }
212
- async extraFileUpdates(version, versionsMap) {
213
+ async extraFileUpdates(version, versionsMap, dateFormat) {
213
214
  const extraFileUpdates = [];
214
215
  for (const extraFile of this.extraFiles) {
215
216
  if (typeof extraFile === 'object') {
@@ -220,7 +221,11 @@ class BaseStrategy {
220
221
  extraFileUpdates.push({
221
222
  path: this.addPath(path),
222
223
  createIfMissing: false,
223
- updater: new generic_1.Generic({ version, versionsMap }),
224
+ updater: new generic_1.Generic({
225
+ version,
226
+ versionsMap,
227
+ dateFormat: dateFormat,
228
+ }),
224
229
  });
225
230
  break;
226
231
  case 'json':
@@ -267,21 +272,21 @@ class BaseStrategy {
267
272
  extraFileUpdates.push({
268
273
  path: this.addPath(extraFile),
269
274
  createIfMissing: false,
270
- updater: new composite_1.CompositeUpdater(new generic_json_1.GenericJson('$.version', version), new generic_1.Generic({ version, versionsMap })),
275
+ updater: new composite_1.CompositeUpdater(new generic_json_1.GenericJson('$.version', version), new generic_1.Generic({ version, versionsMap, dateFormat: dateFormat })),
271
276
  });
272
277
  }
273
278
  else if (extraFile.endsWith('.yaml') || extraFile.endsWith('.yml')) {
274
279
  extraFileUpdates.push({
275
280
  path: this.addPath(extraFile),
276
281
  createIfMissing: false,
277
- updater: new composite_1.CompositeUpdater(new generic_yaml_1.GenericYaml('$.version', version), new generic_1.Generic({ version, versionsMap })),
282
+ updater: new composite_1.CompositeUpdater(new generic_yaml_1.GenericYaml('$.version', version), new generic_1.Generic({ version, versionsMap, dateFormat: dateFormat })),
278
283
  });
279
284
  }
280
285
  else if (extraFile.endsWith('.toml')) {
281
286
  extraFileUpdates.push({
282
287
  path: this.addPath(extraFile),
283
288
  createIfMissing: false,
284
- updater: new composite_1.CompositeUpdater(new generic_toml_1.GenericToml('$.version', version), new generic_1.Generic({ version, versionsMap })),
289
+ updater: new composite_1.CompositeUpdater(new generic_toml_1.GenericToml('$.version', version), new generic_1.Generic({ version, versionsMap, dateFormat: dateFormat })),
285
290
  });
286
291
  }
287
292
  else if (extraFile.endsWith('.xml')) {
@@ -290,14 +295,14 @@ class BaseStrategy {
290
295
  createIfMissing: false,
291
296
  updater: new composite_1.CompositeUpdater(
292
297
  // Updates "version" element that is a child of the root element.
293
- new generic_xml_1.GenericXml('/*/version', version), new generic_1.Generic({ version, versionsMap })),
298
+ new generic_xml_1.GenericXml('/*/version', version), new generic_1.Generic({ version, versionsMap, dateFormat: dateFormat })),
294
299
  });
295
300
  }
296
301
  else {
297
302
  extraFileUpdates.push({
298
303
  path: this.addPath(extraFile),
299
304
  createIfMissing: false,
300
- updater: new generic_1.Generic({ version, versionsMap }),
305
+ updater: new generic_1.Generic({ version, versionsMap, dateFormat: dateFormat }),
301
306
  });
302
307
  }
303
308
  }
@@ -95,7 +95,7 @@ class Java extends base_1.BaseStrategy {
95
95
  isSnapshot: true,
96
96
  commits: [],
97
97
  });
98
- const updatesWithExtras = (0, composite_1.mergeUpdates)(updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap))));
98
+ const updatesWithExtras = (0, composite_1.mergeUpdates)(updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap, this.dateFormat))));
99
99
  return {
100
100
  title: pullRequestTitle,
101
101
  body: pullRequestBody,
@@ -1,5 +1,6 @@
1
1
  import { DefaultUpdater, UpdateOptions } from './default';
2
2
  import { Logger } from '../util/logger';
3
+ export declare const DEFAULT_DATE_FORMAT = "%Y-%m-%d";
3
4
  /**
4
5
  * Options for the Generic updater.
5
6
  */
@@ -7,6 +8,8 @@ export interface GenericUpdateOptions extends UpdateOptions {
7
8
  inlineUpdateRegex?: RegExp;
8
9
  blockStartRegex?: RegExp;
9
10
  blockEndRegex?: RegExp;
11
+ date?: Date;
12
+ dateFormat?: string;
10
13
  }
11
14
  /**
12
15
  * The Generic updater looks for well known patterns and replaces
@@ -24,17 +27,23 @@ export interface GenericUpdateOptions extends UpdateOptions {
24
27
  * 4. `x-release-please-patch` if this string is found on the line,
25
28
  * then replace an integer looking value with the next version's
26
29
  * patch
30
+ * 5. `x-release-please-date` if this string is found on the line,
31
+ * then replace the date with the date of the last commit
32
+ * 6. `x-release-please-version-date` if this string is found on the line,
33
+ * then replace the both date and version
27
34
  *
28
35
  * You can also use a block-based replacement. Content between the
29
36
  * opening `x-release-please-start-version` and `x-release-please-end` will
30
37
  * be considered for version replacement. You can also open these blocks
31
- * with `x-release-please-start-<major|minor|patch>` to replace single
32
- * numbers
38
+ * with `x-release-please-start-<major|minor|patch|version-date>` to replace
39
+ * single numbers
33
40
  */
34
41
  export declare class Generic extends DefaultUpdater {
35
42
  private readonly inlineUpdateRegex;
36
43
  private readonly blockStartRegex;
37
44
  private readonly blockEndRegex;
45
+ private readonly date;
46
+ private readonly dateFormat;
38
47
  constructor(options: GenericUpdateOptions);
39
48
  /**
40
49
  * Given initial file contents, return updated contents.
@@ -13,14 +13,16 @@
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.Generic = void 0;
16
+ exports.Generic = exports.DEFAULT_DATE_FORMAT = void 0;
17
17
  const default_1 = require("./default");
18
18
  const logger_1 = require("../util/logger");
19
19
  const VERSION_REGEX = /(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(-(?<preRelease>[\w.]+))?(\+(?<build>[-\w.]+))?/;
20
20
  const SINGLE_VERSION_REGEX = /\b\d+\b/;
21
- const INLINE_UPDATE_REGEX = /x-release-please-(?<scope>major|minor|patch|version)/;
22
- const BLOCK_START_REGEX = /x-release-please-start-(?<scope>major|minor|patch|version)/;
21
+ const INLINE_UPDATE_REGEX = /x-release-please-(?<scope>major|minor|patch|version-date|version|date)/;
22
+ const BLOCK_START_REGEX = /x-release-please-start-(?<scope>major|minor|patch|version-date|version|date)/;
23
23
  const BLOCK_END_REGEX = /x-release-please-end/;
24
+ const DATE_FORMAT_REGEX = /%[Ymd]/g;
25
+ exports.DEFAULT_DATE_FORMAT = '%Y-%m-%d';
24
26
  /**
25
27
  * The Generic updater looks for well known patterns and replaces
26
28
  * content. The well known patterns are:
@@ -37,20 +39,26 @@ const BLOCK_END_REGEX = /x-release-please-end/;
37
39
  * 4. `x-release-please-patch` if this string is found on the line,
38
40
  * then replace an integer looking value with the next version's
39
41
  * patch
42
+ * 5. `x-release-please-date` if this string is found on the line,
43
+ * then replace the date with the date of the last commit
44
+ * 6. `x-release-please-version-date` if this string is found on the line,
45
+ * then replace the both date and version
40
46
  *
41
47
  * You can also use a block-based replacement. Content between the
42
48
  * opening `x-release-please-start-version` and `x-release-please-end` will
43
49
  * be considered for version replacement. You can also open these blocks
44
- * with `x-release-please-start-<major|minor|patch>` to replace single
45
- * numbers
50
+ * with `x-release-please-start-<major|minor|patch|version-date>` to replace
51
+ * single numbers
46
52
  */
47
53
  class Generic extends default_1.DefaultUpdater {
48
54
  constructor(options) {
49
- var _a, _b, _c;
55
+ var _a, _b, _c, _d, _e;
50
56
  super(options);
51
57
  this.inlineUpdateRegex = (_a = options.inlineUpdateRegex) !== null && _a !== void 0 ? _a : INLINE_UPDATE_REGEX;
52
58
  this.blockStartRegex = (_b = options.blockStartRegex) !== null && _b !== void 0 ? _b : BLOCK_START_REGEX;
53
59
  this.blockEndRegex = (_c = options.blockEndRegex) !== null && _c !== void 0 ? _c : BLOCK_END_REGEX;
60
+ this.date = (_d = options.date) !== null && _d !== void 0 ? _d : new Date();
61
+ this.dateFormat = (_e = options.dateFormat) !== null && _e !== void 0 ? _e : exports.DEFAULT_DATE_FORMAT;
54
62
  }
55
63
  /**
56
64
  * Given initial file contents, return updated contents.
@@ -63,8 +71,28 @@ class Generic extends default_1.DefaultUpdater {
63
71
  }
64
72
  const newLines = [];
65
73
  let blockScope;
66
- function replaceVersion(line, scope, version) {
74
+ function replaceVersion(line, scope, version, date, dateFormat) {
75
+ const dateRegex = createDateRegex(dateFormat);
76
+ const formattedDate = formatDate(dateFormat, date);
67
77
  switch (scope) {
78
+ case 'date':
79
+ if (isValidDate(formattedDate, dateFormat)) {
80
+ newLines.push(line.replace(dateRegex, formattedDate));
81
+ }
82
+ else {
83
+ logger.warn(`Invalid date format: ${formattedDate}`);
84
+ newLines.push(line);
85
+ }
86
+ return;
87
+ case 'version-date':
88
+ if (isValidDate(formattedDate, dateFormat)) {
89
+ line = line.replace(dateRegex, formattedDate);
90
+ }
91
+ else {
92
+ logger.warn(`Invalid date format: ${formattedDate}`);
93
+ }
94
+ newLines.push(line.replace(VERSION_REGEX, version.toString()));
95
+ return;
68
96
  case 'major':
69
97
  newLines.push(line.replace(SINGLE_VERSION_REGEX, `${version.major}`));
70
98
  return;
@@ -87,11 +115,11 @@ class Generic extends default_1.DefaultUpdater {
87
115
  let match = line.match(this.inlineUpdateRegex);
88
116
  if (match) {
89
117
  // replace inline versions
90
- replaceVersion(line, (((_a = match.groups) === null || _a === void 0 ? void 0 : _a.scope) || 'version'), this.version);
118
+ replaceVersion(line, (((_a = match.groups) === null || _a === void 0 ? void 0 : _a.scope) || 'version'), this.version, this.date, this.dateFormat);
91
119
  }
92
120
  else if (blockScope) {
93
121
  // in a block, so try to replace versions
94
- replaceVersion(line, blockScope, this.version);
122
+ replaceVersion(line, blockScope, this.version, this.date, this.dateFormat);
95
123
  if (line.match(this.blockEndRegex)) {
96
124
  blockScope = undefined;
97
125
  }
@@ -114,4 +142,45 @@ class Generic extends default_1.DefaultUpdater {
114
142
  }
115
143
  }
116
144
  exports.Generic = Generic;
145
+ function createDateRegex(format) {
146
+ const regexString = format.replace(DATE_FORMAT_REGEX, match => {
147
+ switch (match) {
148
+ case '%Y':
149
+ return '(\\d{4})';
150
+ case '%m':
151
+ return '(\\d{2})';
152
+ case '%d':
153
+ return '(\\d{2})';
154
+ default:
155
+ return match;
156
+ }
157
+ });
158
+ return new RegExp(regexString);
159
+ }
160
+ function formatDate(format, date) {
161
+ return format.replace(DATE_FORMAT_REGEX, match => {
162
+ switch (match) {
163
+ case '%Y':
164
+ return date.getFullYear().toString();
165
+ case '%m':
166
+ return ('0' + (date.getMonth() + 1)).slice(-2);
167
+ case '%d':
168
+ return ('0' + date.getDate()).slice(-2);
169
+ default:
170
+ return match;
171
+ }
172
+ });
173
+ }
174
+ function isValidDate(dateString, format) {
175
+ const dateParts = dateString.match(/\d+/g);
176
+ if (!dateParts)
177
+ return false;
178
+ const year = parseInt(dateParts[format.indexOf('%Y') / 3], 10);
179
+ const month = parseInt(dateParts[format.indexOf('%m') / 3], 10);
180
+ const day = parseInt(dateParts[format.indexOf('%d') / 3], 10);
181
+ if (year < 1 || month < 1 || month > 12 || day < 1 || day > 31)
182
+ return false;
183
+ const daysInMonth = new Date(year, month, 0).getDate();
184
+ return day <= daysInMonth;
185
+ }
117
186
  //# sourceMappingURL=generic.js.map
@@ -70,7 +70,8 @@ function releaserConfigToJsonConfig(config) {
70
70
  'tag-separator': config.tagSeparator,
71
71
  'extra-files': config.extraFiles,
72
72
  'version-file': config.versionFile,
73
- 'snapshot-label': (_c = config.snapshotLabels) === null || _c === void 0 ? void 0 : _c.join(','), // Java-only
73
+ 'snapshot-label': (_c = config.snapshotLabels) === null || _c === void 0 ? void 0 : _c.join(','),
74
+ 'date-format': config.dateFormat,
74
75
  };
75
76
  return jsonConfig;
76
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-please",
3
- "version": "16.16.0",
3
+ "version": "16.18.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",
@@ -119,6 +119,10 @@
119
119
  "description": "Customize the separator between the component and version in the GitHub tag.",
120
120
  "type": "string"
121
121
  },
122
+ "date-format": {
123
+ "description": "Date format given as a strftime expression for the generic strategy.",
124
+ "type": "string"
125
+ },
122
126
  "extra-files": {
123
127
  "description": "Specify extra generic files to replace versions.",
124
128
  "type": "array",
@@ -476,6 +480,7 @@
476
480
  "separate-pull-requests": true,
477
481
  "always-update": true,
478
482
  "tag-separator": true,
483
+ "date-format": true,
479
484
  "extra-files": true,
480
485
  "version-file": true,
481
486
  "snapshot-label": true,