Repository: googleapis/release-please

Issue:
Add an option to disable changelog generation
Thanks for stopping by to let us know something could be better!

**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.

 **Is your feature request related to a problem? Please describe.**

I'm frustrated that Release Please always generates and commits a `CHANGELOG.md` file. It is the developer's decision to keep that file or not, and it must not be enforced by this tool. For instance, I find changelog files to be redundant and provide little use to the end consumers of my software. I use GitHub releases as the changelog, which Release Please already fills in using the same content as the changelog. 

 **Describe the solution you'd like**

A `--disable-changelog` boolean flag which, when set to `true`, skips the changelog generation phase altogether. 

 **Describe alternatives you've considered**

1. Setting `changelog-types: ""`, gets ignored by the tool.
2. Setting `changelog-path` to the path ignored in Git. No effect either.




Hints from issue comments:
@unjust: I'm using release-please with a monorepo and I prefer one changelog for the entire project, and not for the subprojects.
I've tried `"changelog-path": "",` `"changelog-path": false,` in the `config.json` in order to skip it in subprojects, but its still generated.
also adding `CHANGELOG.md` to my `.gitignore` doesnt stop the pull request from adding them, maybe oktokit bypasses the gitignore? 🤷 @chingor13: An option to disable changelog generation is feasible, but not something we're planning on implementing. We would welcome a pull request to potentially add the feature.@kettanaito: @chingor13, I'd love to help you ship it. Just, let me know what kind of API you find best to disable changelog generation. I proposed `--disable-changelog` above, do you have any opinions on that? We can also use `--no-changelog`, following the `--no` flags convention for negative expected behaviors. 

If we can agree on the API here, I will try to pen a pull request this/next week. Thanks! 
@chingor13: Thanks!

I think we want this as a manifest config option (schema: https://github.com/googleapis/release-please/blob/main/schemas/config.json). The CLI option is an optional inline interface into specifying a manifest config (but we prefer folks configure a manifest config).

As for the naming of the option, I would suggest `skip-changelog` to match `skip-release` and `skip-snapshot` configuration options.@unjust: +1 on the manifest option. It would be nice to be able to skip-change logs on packages in a repo but still keep the overall changelog. I think the manifest would allow this granularity.@unjust: @kettanaito do you have a branch for this work yet ? 👀 need a hand ?@aabouzaid: @unjust I see that you already have some WIP ... did you open a PR for it? (or willing to continue working on it?)@stan-stately: I implemented it here: https://github.com/googleapis/release-please/pull/2535. please take a look

Solution patch:
diff --git a/README.md b/README.md
index 8b980cd..2f4118e 100644
--- a/README.md
+++ b/README.md
@@ -214,13 +214,6 @@ The easiest way to run Release Please is as a GitHub action. Please see [googlea
 
 Please see [Running release-please CLI](docs/cli.md) for all the configuration options.
 
-### Install the GitHub App
-
-There is a probot application available, which allows you to deploy Release
-Please as a GitHub App. Please see 
-[github.com/googleapis/repo-automation-bots](https://github.com/googleapis/repo-automation-bots/tree/main/packages/release-please)
-for installation and configuration instructions.
-
 ## Bootstrapping your Repository
 
 Release Please looks at commits since your last release tag. It may or may not be able to find
diff --git a/docs/manifest-releaser.md b/docs/manifest-releaser.md
index 0bf9c08..9c6f107 100644
--- a/docs/manifest-releaser.md
+++ b/docs/manifest-releaser.md
@@ -205,6 +205,10 @@ defaults (those are documented in comments)
   // have existing infrastructure to tag these releases.
   "skip-github-release": true,
 
+  // Skip updating the changelog.
+  // Absence defaults to false and the changelog will still be updated.
+  "skip-changelog"
+
   // when using the `node-workspace` plugin, package discovery forces all
   // local dependencies to be linked, even if the SemVer ranges don't match.
   // this allows breaking version bumps to update during a release.
diff --git a/schemas/config.json b/schemas/config.json
index 100c16a..9b5cec4 100644
--- a/schemas/config.json
+++ b/schemas/config.json
@@ -58,6 +58,10 @@
           "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`.",
           "type": "boolean"
         },
+        "skip-changelog": {
+          "description": "Skip generating a changelog for this package. Defaults to `false`.",
+          "type": "boolean"
+        },
         "draft": {
           "description": "Create the GitHub release in draft mode. Defaults to `false`.",
           "type": "boolean"
@@ -329,10 +333,7 @@
                   "type": {
                     "description": "The name of the plugin.",
                     "type": "string",
-                    "enum": [
-                      "cargo-workspace",
-                      "maven-workspace"
-                    ]
+                    "enum": ["cargo-workspace", "maven-workspace"]
                   },
                   "updateAllPackages": {
                     "description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.",
@@ -355,9 +356,7 @@
                   "type": {
                     "description": "The name of the plugin.",
                     "type": "string",
-                    "enum": [
-                      "node-workspace"
-                    ]
+                    "enum": ["node-workspace"]
                   },
                   "updateAllPackages": {
                     "description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.",
@@ -463,6 +462,7 @@
     "changelog-sections": true,
     "release-as": true,
     "skip-github-release": true,
+    "skip-changelog": true,
     "draft": true,
     "prerelease": true,
     "draft-pull-request": true,
diff --git a/src/factory.ts b/src/factory.ts
index ae6f1bf..025cf1e 100644
--- a/src/factory.ts
+++ b/src/factory.ts
@@ -133,6 +133,7 @@ export async function buildStrategy(
   });
   const strategyOptions: BaseStrategyOptions = {
     skipGitHubRelease: options.skipGithubRelease, // Note the case difference in GitHub
+    skipChangelog: options.skipChangelog,
     ...options,
     targetBranch,
     versioningStrategy,
diff --git a/src/manifest.ts b/src/manifest.ts
index ca337cd..576ad8c 100644
--- a/src/manifest.ts
+++ b/src/manifest.ts
@@ -104,7 +104,8 @@ export interface ReleaserConfig {
 
   // Strategy options
   releaseAs?: string;
-  skipGithubRelease?: boolean; // Note this should be renamed to skipGitHubRelease in next major release
+  skipGithubRelease?: boolean; // Note this should be renamed to skipGitHubRelease in next major release\
+  skipChangelog?: boolean;
   draft?: boolean;
   prerelease?: boolean;
   draftPullRequest?: boolean;
@@ -162,6 +163,7 @@ interface ReleaserConfigJson {
   'changelog-sections'?: ChangelogSection[];
   'release-as'?: string;
   'skip-github-release'?: boolean;
+  'skip-changelog'?: boolean;
   draft?: boolean;
   prerelease?: boolean;
   'draft-pull-request'?: boolean;
@@ -1381,6 +1383,7 @@ function extractReleaserConfig(
     changelogHost: config['changelog-host'],
     releaseAs: config['release-as'],
     skipGithubRelease: config['skip-github-release'],
+    skipChangelog: config['skip-changelog'],
     draft: config.draft,
     prerelease: config.prerelease,
     draftPullRequest: config['draft-pull-request'],
@@ -1735,6 +1738,7 @@ function mergeReleaserConfig(
     releaseAs: pathConfig.releaseAs ?? defaultConfig.releaseAs,
     skipGithubRelease:
       pathConfig.skipGithubRelease ?? defaultConfig.skipGithubRelease,
+    skipChangelog: pathConfig.skipChangelog ?? defaultConfig.skipChangelog,
     draft: pathConfig.draft ?? defaultConfig.draft,
     draftPullRequest:
       pathConfig.draftPullRequest ?? defaultConfig.draftPullRequest,
diff --git a/src/strategies/base.ts b/src/strategies/base.ts
index ae759a5..fd8dbf4 100644
--- a/src/strategies/base.ts
+++ b/src/strategies/base.ts
@@ -47,6 +47,7 @@ const DEFAULT_CHANGELOG_PATH = 'CHANGELOG.md';
 
 export interface BuildUpdatesOptions {
   changelogEntry: string;
+  skipChangelog?: boolean;
   commits?: ConventionalCommit[];
   newVersion: Version;
   versionsMap: VersionsMap;
@@ -69,6 +70,7 @@ export interface BaseStrategyOptions {
   mainTemplate?: string;
   tagSeparator?: string;
   skipGitHubRelease?: boolean;
+  skipChangelog?: boolean;
   releaseAs?: string;
   changelogNotes?: ChangelogNotes;
   includeComponentInTag?: boolean;
@@ -104,6 +106,7 @@ export abstract class BaseStrategy implements Strategy {
   protected changelogHost?: string;
   protected tagSeparator?: string;
   private skipGitHubRelease: boolean;
+  protected skipChangelog: boolean;
   private releaseAs?: string;
   protected includeComponentInTag: boolean;
   protected includeVInTag: boolean;
@@ -138,6 +141,7 @@ export abstract class BaseStrategy implements Strategy {
     this.changelogSections = options.changelogSections;
     this.tagSeparator = options.tagSeparator;
     this.skipGitHubRelease = options.skipGitHubRelease || false;
+    this.skipChangelog = options.skipChangelog || false;
     this.releaseAs = options.releaseAs;
     this.changelogNotes =
       options.changelogNotes || new DefaultChangelogNotes(options);
@@ -327,6 +331,7 @@ export abstract class BaseStrategy implements Strategy {
     }
     const updates = await this.buildUpdates({
       changelogEntry: releaseNotesBody,
+      skipChangelog: this.skipChangelog,
       newVersion,
       versionsMap,
       latestVersion: latestRelease?.tag.version,
diff --git a/src/strategies/bazel.ts b/src/strategies/bazel.ts
index caef10e..349a94d 100644
--- a/src/strategies/bazel.ts
+++ b/src/strategies/bazel.ts
@@ -29,14 +29,15 @@ export class Bazel extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath(this.versionFile),
diff --git a/src/strategies/dart.ts b/src/strategies/dart.ts
index f21123e..9987f9c 100644
--- a/src/strategies/dart.ts
+++ b/src/strategies/dart.ts
@@ -32,14 +32,15 @@ export class Dart extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath('pubspec.yaml'),
diff --git a/src/strategies/dotnet-yoshi.ts b/src/strategies/dotnet-yoshi.ts
index a83dcee..13f5c5a 100644
--- a/src/strategies/dotnet-yoshi.ts
+++ b/src/strategies/dotnet-yoshi.ts
@@ -127,15 +127,16 @@ export class DotnetYoshi extends BaseStrategy {
         `Skipping changelog for ${component} via noVersionHistory configuration`
       );
     } else {
-      updates.push({
-        path: this.addPath(this.changelogPath),
-        createIfMissing: true,
-        updater: new Changelog({
-          version,
-          changelogEntry: options.changelogEntry,
-          versionHeaderRegex: '\n## Version [0-9[]+',
-        }),
-      });
+      !this.skipChangelog &&
+        updates.push({
+          path: this.addPath(this.changelogPath),
+          createIfMissing: true,
+          updater: new Changelog({
+            version,
+            changelogEntry: options.changelogEntry,
+            versionHeaderRegex: '\n## Version [0-9[]+',
+          }),
+        });
     }
 
     if (!component) {
diff --git a/src/strategies/elixir.ts b/src/strategies/elixir.ts
index 366bb8a..923f566 100644
--- a/src/strategies/elixir.ts
+++ b/src/strategies/elixir.ts
@@ -26,14 +26,15 @@ export class Elixir extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath('mix.exs'),
diff --git a/src/strategies/go-yoshi.ts b/src/strategies/go-yoshi.ts
index 568db78..d6cc223 100644
--- a/src/strategies/go-yoshi.ts
+++ b/src/strategies/go-yoshi.ts
@@ -54,14 +54,15 @@ export class GoYoshi extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
     updates.push({
       path: this.addPath('internal/version.go'),
       createIfMissing: false,
diff --git a/src/strategies/go.ts b/src/strategies/go.ts
index e90a19b..9233685 100644
--- a/src/strategies/go.ts
+++ b/src/strategies/go.ts
@@ -14,24 +14,44 @@
 
 // Generic
 import {Changelog} from '../updaters/changelog';
-import {BaseStrategy, BuildUpdatesOptions} from './base';
+import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base';
 import {Update} from '../update';
+import {VersionGo} from '../updaters/go/version-go';
 
 export class Go extends BaseStrategy {
+  readonly versionFile: string;
+
+  constructor(options: BaseStrategyOptions) {
+    super(options);
+    this.versionFile = options.versionFile ?? '';
+  }
+
   protected async buildUpdates(
     options: BuildUpdatesOptions
   ): Promise<Update[]> {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
+
+    // If a version file is specified, update it
+    if (this.versionFile) {
+      updates.push({
+        path: this.addPath(this.versionFile),
+        createIfMissing: false,
+        updater: new VersionGo({
+          version,
+        }),
+      });
+    }
 
     return updates;
   }
diff --git a/src/strategies/helm.ts b/src/strategies/helm.ts
index fbc8475..2507e39 100644
--- a/src/strategies/helm.ts
+++ b/src/strategies/helm.ts
@@ -32,14 +32,15 @@ export class Helm extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath('Chart.yaml'),
diff --git a/src/strategies/java-yoshi-mono-repo.ts b/src/strategies/java-yoshi-mono-repo.ts
index eae2838..ab6d32d 100644
--- a/src/strategies/java-yoshi-mono-repo.ts
+++ b/src/strategies/java-yoshi-mono-repo.ts
@@ -199,14 +199,15 @@ export class JavaYoshiMonoRepo extends Java {
     });
 
     if (!options.isSnapshot) {
-      updates.push({
-        path: this.addPath(this.changelogPath),
-        createIfMissing: true,
-        updater: new Changelog({
-          version,
-          changelogEntry: options.changelogEntry,
-        }),
-      });
+      !this.skipChangelog &&
+        updates.push({
+          path: this.addPath(this.changelogPath),
+          createIfMissing: true,
+          updater: new Changelog({
+            version,
+            changelogEntry: options.changelogEntry,
+          }),
+        });
 
       // Bail early if the repository has no root changelog.json.
       // This file is used to opt into machine readable commits.
diff --git a/src/strategies/java-yoshi.ts b/src/strategies/java-yoshi.ts
index f1ecac8..4e1b578 100644
--- a/src/strategies/java-yoshi.ts
+++ b/src/strategies/java-yoshi.ts
@@ -170,7 +170,7 @@ export class JavaYoshi extends Java {
       });
     });
 
-    if (!options.isSnapshot) {
+    if (!options.isSnapshot && !this.skipChangelog) {
       updates.push({
         path: this.addPath(this.changelogPath),
         createIfMissing: true,
diff --git a/src/strategies/java.ts b/src/strategies/java.ts
index 6fca522..9a097c0 100644
--- a/src/strategies/java.ts
+++ b/src/strategies/java.ts
@@ -60,7 +60,6 @@ export class Java extends BaseStrategy {
   protected readonly snapshotVersioning: VersioningStrategy;
   protected readonly snapshotLabels: string[];
   readonly skipSnapshot: boolean;
-
   constructor(options: BaseStrategyOptions) {
     options.changelogSections = options.changelogSections ?? CHANGELOG_SECTIONS;
     // wrap the configured versioning strategy with snapshotting
@@ -135,6 +134,7 @@ export class Java extends BaseStrategy {
     const updates = await this.buildUpdates({
       newVersion,
       versionsMap,
+      skipChangelog: this.skipChangelog,
       changelogEntry: notes,
       isSnapshot: true,
       commits: [],
@@ -226,14 +226,15 @@ export class Java extends BaseStrategy {
       });
 
       // Update changelog
-      updates.push({
-        path: this.addPath(this.changelogPath),
-        createIfMissing: true,
-        updater: new Changelog({
-          version,
-          changelogEntry: options.changelogEntry,
-        }),
-      });
+      !this.skipChangelog &&
+        updates.push({
+          path: this.addPath(this.changelogPath),
+          createIfMissing: true,
+          updater: new Changelog({
+            version,
+            changelogEntry: options.changelogEntry,
+          }),
+        });
     }
 
     return updates;
diff --git a/src/strategies/krm-blueprint.ts b/src/strategies/krm-blueprint.ts
index 0971eeb..ea290e9 100644
--- a/src/strategies/krm-blueprint.ts
+++ b/src/strategies/krm-blueprint.ts
@@ -33,14 +33,15 @@ export class KRMBlueprint extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     const versionsMap: VersionsMap = new Map();
     if (options.latestVersion) {
diff --git a/src/strategies/node.ts b/src/strategies/node.ts
index 52fc2c1..80dae5f 100644
--- a/src/strategies/node.ts
+++ b/src/strategies/node.ts
@@ -54,14 +54,15 @@ export class Node extends BaseStrategy {
       }),
     });
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath('package.json'),
@@ -73,7 +74,7 @@ export class Node extends BaseStrategy {
     });
 
     // If a machine readable changelog.json exists update it:
-    if (options.commits && packageName) {
+    if (options.commits && packageName && !this.skipChangelog) {
       const commits = filterCommits(options.commits, this.changelogSections);
       updates.push({
         path: 'changelog.json',
diff --git a/src/strategies/ocaml.ts b/src/strategies/ocaml.ts
index 95051d2..c946ad4 100644
--- a/src/strategies/ocaml.ts
+++ b/src/strategies/ocaml.ts
@@ -32,14 +32,15 @@ export class OCaml extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     const jsonPaths = await this.github.findFilesByExtension('json', this.path);
     for (const path of jsonPaths) {
diff --git a/src/strategies/php-yoshi.ts b/src/strategies/php-yoshi.ts
index 8bd1bfd..bbefdbc 100644
--- a/src/strategies/php-yoshi.ts
+++ b/src/strategies/php-yoshi.ts
@@ -167,6 +167,7 @@ export class PHPYoshi extends BaseStrategy {
       : BranchName.ofTargetBranch(this.targetBranch);
     const updates = await this.buildUpdates({
       changelogEntry: releaseNotesBody,
+      skipChangelog: this.skipChangelog,
       newVersion,
       versionsMap,
       latestVersion: latestRelease?.tag.version,
@@ -256,14 +257,15 @@ export class PHPYoshi extends BaseStrategy {
     const version = options.newVersion;
     const versionsMap = options.versionsMap;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     // update VERSION file
     updates.push({
diff --git a/src/strategies/php.ts b/src/strategies/php.ts
index ccf4604..6711ab1 100644
--- a/src/strategies/php.ts
+++ b/src/strategies/php.ts
@@ -48,14 +48,15 @@ export class PHP extends BaseStrategy {
     const version = options.newVersion;
     const versionsMap: VersionsMap = new Map();
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     // update composer.json
     updates.push({
diff --git a/src/strategies/python.ts b/src/strategies/python.ts
index 5287b94..bd93251 100644
--- a/src/strategies/python.ts
+++ b/src/strategies/python.ts
@@ -55,14 +55,15 @@ export class Python extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath('setup.cfg'),
@@ -138,7 +139,7 @@ export class Python extends BaseStrategy {
 
     // If a machine readable changelog.json exists update it:
     const artifactName = projectName ?? (await this.getNameFromSetupPy());
-    if (options.commits && artifactName) {
+    if (options.commits && artifactName && !this.skipChangelog) {
       const commits = filterCommits(options.commits, this.changelogSections);
       updates.push({
         path: 'changelog.json',
diff --git a/src/strategies/ruby-yoshi.ts b/src/strategies/ruby-yoshi.ts
index 3412f80..87d65b2 100644
--- a/src/strategies/ruby-yoshi.ts
+++ b/src/strategies/ruby-yoshi.ts
@@ -71,14 +71,15 @@ export class RubyYoshi extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     const versionFile: string = this.versionFile
       ? this.versionFile
diff --git a/src/strategies/ruby.ts b/src/strategies/ruby.ts
index 9b35810..893d9cf 100644
--- a/src/strategies/ruby.ts
+++ b/src/strategies/ruby.ts
@@ -38,14 +38,15 @@ export class Ruby extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     const versionFile: string = this.versionFile
       ? this.versionFile
diff --git a/src/strategies/rust.ts b/src/strategies/rust.ts
index 84d1492..ef19efb 100644
--- a/src/strategies/rust.ts
+++ b/src/strategies/rust.ts
@@ -34,14 +34,15 @@ export class Rust extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     const workspaceManifest = await this.getPackageManifest();
     const versionsMap: VersionsMap = new Map();
diff --git a/src/strategies/sfdx.ts b/src/strategies/sfdx.ts
index d1deb86..038e5ec 100644
--- a/src/strategies/sfdx.ts
+++ b/src/strategies/sfdx.ts
@@ -30,14 +30,15 @@ export class Sfdx extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath(sfdxProjectJsonFileName),
diff --git a/src/strategies/simple.ts b/src/strategies/simple.ts
index eb5eb5a..543eef3 100644
--- a/src/strategies/simple.ts
+++ b/src/strategies/simple.ts
@@ -31,14 +31,15 @@ export class Simple extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     updates.push({
       path: this.addPath(this.versionFile),
diff --git a/src/strategies/terraform-module.ts b/src/strategies/terraform-module.ts
index 71287fc..c169b85 100644
--- a/src/strategies/terraform-module.ts
+++ b/src/strategies/terraform-module.ts
@@ -29,14 +29,15 @@ export class TerraformModule extends BaseStrategy {
     const updates: Update[] = [];
     const version = options.newVersion;
 
-    updates.push({
-      path: this.addPath(this.changelogPath),
-      createIfMissing: true,
-      updater: new Changelog({
-        version,
-        changelogEntry: options.changelogEntry,
-      }),
-    });
+    !this.skipChangelog &&
+      updates.push({
+        path: this.addPath(this.changelogPath),
+        createIfMissing: true,
+        updater: new Changelog({
+          version,
+          changelogEntry: options.changelogEntry,
+        }),
+      });
 
     // Update version in README to current candidate version.
     // A module may have submodules, so find all submodules.
diff --git a/src/updaters/release-please-config.ts b/src/updaters/release-please-config.ts
index 20a3869..e3868dc 100644
--- a/src/updaters/release-please-config.ts
+++ b/src/updaters/release-please-config.ts
@@ -64,6 +64,7 @@ function releaserConfigToJsonConfig(
     'changelog-sections': config.changelogSections,
     'release-as': config.releaseAs,
     'skip-github-release': config.skipGithubRelease,
+    'skip-changelog': config.skipChangelog,
     draft: config.draft,
     prerelease: config.prerelease,
     'draft-pull-request': config.draftPullRequest,



Test patch:
diff --git a/test/fixtures/strategies/go/internal/version/version.go b/test/fixtures/strategies/go/internal/version/version.go
new file mode 100644
index 0000000..6530be3
--- /dev/null
+++ b/test/fixtures/strategies/go/internal/version/version.go
@@ -0,0 +1,18 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package version
+
+// Version is the current version of the library
+const Version = "0.1.0"
diff --git a/test/strategies/bazel.ts b/test/strategies/bazel.ts
index 7ccb9a5..754efb5 100644
--- a/test/strategies/bazel.ts
+++ b/test/strategies/bazel.ts
@@ -21,7 +21,11 @@ import {ModuleBazel} from '../../src/updaters/bazel/module-bazel';
 import {Changelog} from '../../src/updaters/changelog';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
-import {assertHasUpdate, buildMockConventionalCommit} from '../helpers';
+import {
+  assertHasUpdate,
+  assertNoHasUpdate,
+  buildMockConventionalCommit,
+} from '../helpers';
 
 const sandbox = sinon.createSandbox();
 
@@ -114,5 +118,23 @@ describe('Bazel', () => {
       assertHasUpdate(updates, 'packages/CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'packages/some-path/MODULE.bazel', ModuleBazel);
     });
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Bazel({
+        targetBranch: 'main',
+        github,
+        component: 'rules_cc',
+        versionFile: 'some-path/MODULE.bazel',
+        path: 'packages',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'packages/some-path/MODULE.bazel', ModuleBazel);
+    });
   });
 });
diff --git a/test/strategies/dart.ts b/test/strategies/dart.ts
index 8ccaa2d..4231298 100644
--- a/test/strategies/dart.ts
+++ b/test/strategies/dart.ts
@@ -18,6 +18,7 @@ import {
   buildMockConventionalCommit,
   buildGitHubFileContent,
   assertHasUpdate,
+  assertNoHasUpdate,
 } from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
@@ -142,5 +143,32 @@ describe('Dart', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'pubspec.yaml', PubspecYaml);
     });
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Dart({
+        targetBranch: 'main',
+        github,
+        component: 'some-dart-package',
+        packageName: 'some-dart-package',
+        skipChangelog: true,
+      });
+      const commits = [
+        ...buildMockConventionalCommit(
+          'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0'
+        ),
+      ];
+      const latestRelease = {
+        tag: new TagName(Version.parse('0.123.4'), 'some-dart-package'),
+        sha: 'abc123',
+        notes: 'some notes',
+      };
+      const pullRequest = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = pullRequest!.updates;
+      expect(updates).lengthOf(1);
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'pubspec.yaml', PubspecYaml);
+    });
   });
 });
diff --git a/test/strategies/dotnet-yoshi.ts b/test/strategies/dotnet-yoshi.ts
index d8e88a4..39a074c 100644
--- a/test/strategies/dotnet-yoshi.ts
+++ b/test/strategies/dotnet-yoshi.ts
@@ -153,6 +153,31 @@ describe('DotnetYoshi', () => {
       );
       assertHasUpdate(updates, 'apis/apis.json', Apis);
     });
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new DotnetYoshi({
+        targetBranch: 'main',
+        github,
+        path: 'apis/Google.Cloud.SecurityCenter.V1',
+        component: 'Google.Cloud.SecurityCenter.V1',
+        skipChangelog: true,
+      });
+      sandbox
+        .stub(github, 'getFileContentsOnBranch')
+        .withArgs('apis/apis.json', 'main')
+        .resolves(buildGitHubFileContent(fixturesPath, 'apis.json'));
+      const latestRelease = undefined;
+      const pullRequest = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = pullRequest!.updates;
+      expect(updates).lengthOf(1);
+      assertNoHasUpdate(
+        updates,
+        'apis/Google.Cloud.SecurityCenter.V1/docs/history.md'
+      );
+      assertHasUpdate(updates, 'apis/apis.json', Apis);
+    });
   });
   describe('buildRelease', () => {
     it('overrides the tag separator', async () => {
diff --git a/test/strategies/elixir.ts b/test/strategies/elixir.ts
index 9f72782..33129a2 100644
--- a/test/strategies/elixir.ts
+++ b/test/strategies/elixir.ts
@@ -14,7 +14,11 @@
 
 import {describe, it, afterEach, beforeEach} from 'mocha';
 import {Elixir} from '../../src/strategies/elixir';
-import {buildMockConventionalCommit, assertHasUpdate} from '../helpers';
+import {
+  buildMockConventionalCommit,
+  assertHasUpdate,
+  assertNoHasUpdate,
+} from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
 import {GitHub} from '../../src/github';
@@ -95,5 +99,21 @@ describe('Elixir', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'mix.exs', ElixirMixExs);
     });
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Elixir({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'mix.exs', ElixirMixExs);
+    });
   });
 });
diff --git a/test/strategies/expo.ts b/test/strategies/expo.ts
index 8c95781..fdecd15 100644
--- a/test/strategies/expo.ts
+++ b/test/strategies/expo.ts
@@ -18,6 +18,7 @@ import {
   buildMockConventionalCommit,
   buildGitHubFileContent,
   assertHasUpdate,
+  assertNoHasUpdate,
 } from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
@@ -218,5 +219,37 @@ describe('Expo', () => {
       expect(expoSDKVersion.minor).to.equal(0);
       expect(expoSDKVersion.patch).to.equal(0);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const getFileContentsStub = sandbox.stub(
+        github,
+        'getFileContentsOnBranch'
+      );
+      getFileContentsStub
+        .withArgs('package.json', 'main')
+        .resolves(buildGitHubFileContent(expoFixturesPath, 'package.json'));
+
+      const strategy = new Expo({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        packageName: 'google-cloud-automl-pkg',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'package-lock.json', PackageLockJson);
+      assertHasUpdate(updates, 'npm-shrinkwrap.json', PackageLockJson);
+      assertHasUpdate(updates, 'samples/package.json', SamplesPackageJson);
+      assertHasUpdate(updates, 'package.json', PackageJson);
+      assertHasUpdate(updates, 'app.json', AppJson);
+    });
   });
 });
diff --git a/test/strategies/go-yoshi.ts b/test/strategies/go-yoshi.ts
index 4f68256..928f04a 100644
--- a/test/strategies/go-yoshi.ts
+++ b/test/strategies/go-yoshi.ts
@@ -17,7 +17,7 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {GoYoshi} from '../../src/strategies/go-yoshi';
 import * as sinon from 'sinon';
-import {assertHasUpdate, dateSafe} from '../helpers';
+import {assertHasUpdate, dateSafe, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -97,6 +97,23 @@ describe('GoYoshi', () => {
       assertHasUpdate(updates, 'CHANGES.md', Changelog);
       assertHasUpdate(updates, 'internal/version.go', VersionGo);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new GoYoshi({
+        targetBranch: 'main',
+        github,
+        component: 'iam',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGES.md');
+      assertHasUpdate(updates, 'internal/version.go', VersionGo);
+    });
   });
   describe('buildReleasePullRequest', () => {
     it('filters out submodule commits', async () => {
diff --git a/test/strategies/go.ts b/test/strategies/go.ts
index 651e7a2..7573395 100644
--- a/test/strategies/go.ts
+++ b/test/strategies/go.ts
@@ -17,11 +17,12 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {Go} from '../../src/strategies/go';
 import * as sinon from 'sinon';
-import {assertHasUpdate} from '../helpers';
+import {assertHasUpdate, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
 import {Changelog} from '../../src/updaters/changelog';
+import {VersionGo} from '../../src/updaters/go/version-go';
 
 const sandbox = sinon.createSandbox();
 
@@ -95,6 +96,40 @@ describe('Go', () => {
       );
       const updates = release!.updates;
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
+      // Version file should not be updated when not specified
+      assertNoHasUpdate(updates, 'internal/version/version.go');
+    });
+
+    it('updates version file when version-file is set', async () => {
+      const strategy = new Go({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        versionFile: 'internal/version/version.go',
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
+      assertHasUpdate(updates, 'internal/version/version.go', VersionGo);
+    });
+    it('omits changelog if requested', async () => {
+      const strategy = new Go({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
     });
   });
 });
diff --git a/test/strategies/helm.ts b/test/strategies/helm.ts
index d9b6c21..fc6979c 100644
--- a/test/strategies/helm.ts
+++ b/test/strategies/helm.ts
@@ -18,6 +18,7 @@ import {
   buildMockConventionalCommit,
   buildGitHubFileContent,
   assertHasUpdate,
+  assertNoHasUpdate,
 } from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
@@ -127,5 +128,24 @@ describe('Helm', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'Chart.yaml', ChartYaml);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Helm({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        packageName: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      expect(updates).lengthOf(1);
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'Chart.yaml', ChartYaml);
+    });
   });
 });
diff --git a/test/strategies/java-yoshi-mono-repo.ts b/test/strategies/java-yoshi-mono-repo.ts
index 0474b5e..dd0a578 100644
--- a/test/strategies/java-yoshi-mono-repo.ts
+++ b/test/strategies/java-yoshi-mono-repo.ts
@@ -214,6 +214,31 @@ describe('JavaYoshiMonoRepo', () => {
       assertHasUpdate(updates, 'versions.txt', VersionsManifest);
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new JavaYoshiMonoRepo({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const getFileContentsStub = sandbox.stub(
+        github,
+        'getFileContentsOnBranch'
+      );
+      getFileContentsStub
+        .withArgs('versions.txt', 'main')
+        .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt'));
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'versions.txt', VersionsManifest);
+    });
+
     it('finds and updates standard files', async () => {
       const strategy = new JavaYoshiMonoRepo({
         targetBranch: 'main',
diff --git a/test/strategies/krm-blueprint.ts b/test/strategies/krm-blueprint.ts
index d32f295..1434915 100644
--- a/test/strategies/krm-blueprint.ts
+++ b/test/strategies/krm-blueprint.ts
@@ -106,6 +106,23 @@ describe('KRMBlueprint', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new KRMBlueprint({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByExtensionAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+    });
+
     it('finds and updates a yaml files', async () => {
       const strategy = new KRMBlueprint({
         targetBranch: 'main',
diff --git a/test/strategies/maven.ts b/test/strategies/maven.ts
index 78a71ff..976f347 100644
--- a/test/strategies/maven.ts
+++ b/test/strategies/maven.ts
@@ -18,6 +18,7 @@ import * as sinon from 'sinon';
 import {
   assertHasUpdate,
   assertHasUpdates,
+  assertNoHasUpdate,
   buildMockConventionalCommit,
 } from '../helpers';
 import {Changelog} from '../../src/updaters/changelog';
@@ -81,6 +82,39 @@ describe('Maven', () => {
       assertHasUpdates(updates, 'foo/bar.java', JavaReleased, Generic);
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Maven({
+        targetBranch: 'main',
+        github,
+        extraFiles: ['foo/bar.java'],
+        skipChangelog: true,
+      });
+
+      sandbox
+        .stub(github, 'findFilesByFilenameAndRef')
+        .withArgs('pom.xml', 'main')
+        .resolves(['pom.xml', 'submodule/pom.xml']);
+
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        undefined
+      );
+
+      expect(release?.version?.toString()).to.eql('1.0.0');
+
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdates(updates, 'pom.xml', PomXml, JavaReleased, Generic);
+      assertHasUpdates(
+        updates,
+        'submodule/pom.xml',
+        PomXml,
+        JavaReleased,
+        Generic
+      );
+      assertHasUpdates(updates, 'foo/bar.java', JavaReleased, Generic);
+    });
+
     it('does not update released version for snapshot bump', async () => {
       const strategy = new Maven({
         targetBranch: 'main',
diff --git a/test/strategies/node.ts b/test/strategies/node.ts
index 4579f57..e3dc566 100644
--- a/test/strategies/node.ts
+++ b/test/strategies/node.ts
@@ -18,6 +18,7 @@ import {
   buildMockConventionalCommit,
   buildGitHubFileContent,
   assertHasUpdate,
+  assertNoHasUpdate,
 } from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
@@ -245,5 +246,33 @@ describe('Node', () => {
       expect(updater.packageName).to.equal('google-cloud-automl-pkg');
       assertHasUpdate(updates, 'package.json', PackageJson);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Node({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        packageName: 'google-cloud-automl-pkg',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'package-lock.json', PackageLockJson);
+      assertHasUpdate(updates, 'npm-shrinkwrap.json', PackageLockJson);
+      const update = assertHasUpdate(
+        updates,
+        'samples/package.json',
+        SamplesPackageJson
+      );
+      const updater = update.updater as SamplesPackageJson;
+      expect(updater.packageName).to.equal('google-cloud-automl-pkg');
+      assertHasUpdate(updates, 'package.json', PackageJson);
+    });
   });
 });
diff --git a/test/strategies/ocaml.ts b/test/strategies/ocaml.ts
index e73e73e..128095b 100644
--- a/test/strategies/ocaml.ts
+++ b/test/strategies/ocaml.ts
@@ -110,6 +110,24 @@ describe('OCaml', () => {
       assertHasUpdate(updates, 'dune-project', DuneProject);
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new OCaml({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByExtension').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'dune-project', DuneProject);
+    });
+
     it('finds and updates a project files', async () => {
       const strategy = new OCaml({
         targetBranch: 'main',
diff --git a/test/strategies/php-yoshi.ts b/test/strategies/php-yoshi.ts
index a3cc8fb..7e0b6f8 100644
--- a/test/strategies/php-yoshi.ts
+++ b/test/strategies/php-yoshi.ts
@@ -17,7 +17,12 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {PHPYoshi} from '../../src/strategies/php-yoshi';
 import * as sinon from 'sinon';
-import {assertHasUpdate, buildGitHubFileRaw, dateSafe} from '../helpers';
+import {
+  assertHasUpdate,
+  assertNoHasUpdate,
+  buildGitHubFileRaw,
+  dateSafe,
+} from '../helpers';
 import {buildMockConventionalCommit, buildMockCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -156,6 +161,24 @@ describe('PHPYoshi', () => {
       assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages);
       assertHasUpdate(updates, 'VERSION', DefaultUpdater);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new PHPYoshi({
+        targetBranch: 'main',
+        github,
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages);
+      assertHasUpdate(updates, 'VERSION', DefaultUpdater);
+    });
+
     it('finds touched components', async () => {
       const strategy = new PHPYoshi({
         targetBranch: 'main',
diff --git a/test/strategies/php.ts b/test/strategies/php.ts
index 173f4c5..04db031 100644
--- a/test/strategies/php.ts
+++ b/test/strategies/php.ts
@@ -17,7 +17,7 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {PHP} from '../../src/strategies/php';
 import * as sinon from 'sinon';
-import {assertHasUpdate} from '../helpers';
+import {assertHasUpdate, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -101,5 +101,24 @@ describe('PHP', () => {
       assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages);
       assertHasUpdate(updates, 'VERSION', DefaultUpdater);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new PHP({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      expect(updates).lengthOf(2);
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages);
+      assertHasUpdate(updates, 'VERSION', DefaultUpdater);
+    });
   });
 });
diff --git a/test/strategies/python.ts b/test/strategies/python.ts
index b304cca..1a95cc0 100644
--- a/test/strategies/python.ts
+++ b/test/strategies/python.ts
@@ -17,7 +17,11 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {Python} from '../../src/strategies/python';
 import * as sinon from 'sinon';
-import {buildGitHubFileContent, assertHasUpdate} from '../helpers';
+import {
+  buildGitHubFileContent,
+  assertHasUpdate,
+  assertNoHasUpdate,
+} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {PythonFileWithVersion} from '../../src/updaters/python/python-file-with-version';
 import {TagName} from '../../src/util/tag-name';
@@ -143,6 +147,48 @@ describe('Python', () => {
       );
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Python({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      sandbox
+        .stub(github, 'getFileContentsOnBranch')
+        .resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'setup.cfg', SetupCfg);
+      assertHasUpdate(updates, 'setup.py', SetupPy);
+      assertHasUpdate(
+        updates,
+        'google-cloud-automl/__init__.py',
+        PythonFileWithVersion
+      );
+      assertHasUpdate(
+        updates,
+        'src/google-cloud-automl/__init__.py',
+        PythonFileWithVersion
+      );
+      assertHasUpdate(
+        updates,
+        'google_cloud_automl/__init__.py',
+        PythonFileWithVersion
+      );
+      assertHasUpdate(
+        updates,
+        'src/google_cloud_automl/__init__.py',
+        PythonFileWithVersion
+      );
+    });
+
     it('finds and updates a pyproject.toml', async () => {
       const strategy = new Python({
         targetBranch: 'main',
diff --git a/test/strategies/ruby-yoshi.ts b/test/strategies/ruby-yoshi.ts
index 0e2501b..691adfd 100644
--- a/test/strategies/ruby-yoshi.ts
+++ b/test/strategies/ruby-yoshi.ts
@@ -17,7 +17,7 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {RubyYoshi} from '../../src/strategies/ruby-yoshi';
 import * as sinon from 'sinon';
-import {assertHasUpdate, safeSnapshot} from '../helpers';
+import {assertHasUpdate, safeSnapshot, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -102,6 +102,25 @@ describe('RubyYoshi', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new RubyYoshi({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const pullRequest = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = pullRequest!.updates;
+      expect(updates).lengthOf(1);
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB);
+    });
+
     it('does not add summary to changelog', async () => {
       const strategy = new RubyYoshi({
         targetBranch: 'main',
diff --git a/test/strategies/ruby.ts b/test/strategies/ruby.ts
index c10704e..948b551 100644
--- a/test/strategies/ruby.ts
+++ b/test/strategies/ruby.ts
@@ -17,7 +17,7 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {Ruby} from '../../src/strategies/ruby';
 import * as sinon from 'sinon';
-import {assertHasUpdate} from '../helpers';
+import {assertHasUpdate, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -102,6 +102,26 @@ describe('Ruby', () => {
       assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB);
       assertHasUpdate(updates, 'Gemfile.lock', GemfileLock);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Ruby({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      expect(updates).lengthOf(2);
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB);
+      assertHasUpdate(updates, 'Gemfile.lock', GemfileLock);
+    });
+
     it('allows overriding version file', async () => {
       const strategy = new Ruby({
         targetBranch: 'main',
diff --git a/test/strategies/sfdx.ts b/test/strategies/sfdx.ts
index 9231683..34a4210 100644
--- a/test/strategies/sfdx.ts
+++ b/test/strategies/sfdx.ts
@@ -18,6 +18,7 @@ import {
   buildMockConventionalCommit,
   buildGitHubFileContent,
   assertHasUpdate,
+  assertNoHasUpdate,
 } from '../helpers';
 import * as nock from 'nock';
 import * as sinon from 'sinon';
@@ -181,5 +182,24 @@ describe('Sfdx', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'sfdx-project.json', SfdxProjectJson);
     });
+
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Sfdx({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        packageName: 'google-cloud-automl-pkg',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        commits,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'sfdx-project.json', SfdxProjectJson);
+    });
   });
 });
diff --git a/test/strategies/simple.ts b/test/strategies/simple.ts
index 808a3b6..97471ea 100644
--- a/test/strategies/simple.ts
+++ b/test/strategies/simple.ts
@@ -17,7 +17,7 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {Simple} from '../../src/strategies/simple';
 import * as sinon from 'sinon';
-import {assertHasUpdate} from '../helpers';
+import {assertHasUpdate, assertNoHasUpdate} from '../helpers';
 import {buildMockConventionalCommit} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
@@ -98,6 +98,22 @@ describe('Simple', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
       assertHasUpdate(updates, 'version.txt', DefaultUpdater);
     });
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new Simple({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+      assertHasUpdate(updates, 'version.txt', DefaultUpdater);
+    });
     it('allows configuring the version file', async () => {
       const strategy = new Simple({
         targetBranch: 'main',
diff --git a/test/strategies/terraform-module.ts b/test/strategies/terraform-module.ts
index e120d4b..7a48b03 100644
--- a/test/strategies/terraform-module.ts
+++ b/test/strategies/terraform-module.ts
@@ -17,7 +17,11 @@ import {expect} from 'chai';
 import {GitHub} from '../../src/github';
 import {TerraformModule} from '../../src/strategies/terraform-module';
 import * as sinon from 'sinon';
-import {assertHasUpdate, buildMockConventionalCommit} from '../helpers';
+import {
+  assertHasUpdate,
+  buildMockConventionalCommit,
+  assertNoHasUpdate,
+} from '../helpers';
 import {TagName} from '../../src/util/tag-name';
 import {Version} from '../../src/version';
 import {Changelog} from '../../src/updaters/changelog';
@@ -102,6 +106,23 @@ describe('TerraformModule', () => {
       assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
     });
 
+    it('omits changelog if skipChangelog=true', async () => {
+      const strategy = new TerraformModule({
+        targetBranch: 'main',
+        github,
+        component: 'google-cloud-automl',
+        skipChangelog: true,
+      });
+      sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
+      const latestRelease = undefined;
+      const release = await strategy.buildReleasePullRequest(
+        COMMITS,
+        latestRelease
+      );
+      const updates = release!.updates;
+      assertNoHasUpdate(updates, 'CHANGELOG.md');
+    });
+
     it('finds and updates README files', async () => {
       const strategy = new TerraformModule({
         targetBranch: 'main',