Skip to content

Commit

Permalink
feat: allow plugins to skip merging in-scope pull requests (#1550)
Browse files Browse the repository at this point in the history
* test: add failing test for combining workspace and linked-versions plugin

* feat: allow configuring workspace and linked-versions plugins to skip merging

* chore: update schemas and remove logging

* docs: add documentation on using linked-versions and workspace
  • Loading branch information
chingor13 authored Aug 8, 2022
1 parent 3ce7cb7 commit 354b1dc
Show file tree
Hide file tree
Showing 13 changed files with 550 additions and 25 deletions.
52 changes: 52 additions & 0 deletions __snapshots__/cargo-workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,58 @@ Release notes for path: packages/rustA, releaseType: rust
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['CargoWorkspace plugin run can skip merging rust packages 1'] = `
:robot: I have created a release *beep* *boop*
---
Release notes for path: packages/rustA, releaseType: rust
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['CargoWorkspace plugin run can skip merging rust packages 2'] = `
:robot: I have created a release *beep* *boop*
---
### Dependencies
* The following workspace dependencies were updated
* dependencies
* pkgA bumped from 1.1.1 to 1.1.2
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['CargoWorkspace plugin run can skip merging rust packages 3'] = `
:robot: I have created a release *beep* *boop*
---
### Dependencies
* The following workspace dependencies were updated
* dependencies
* pkgB bumped from 2.2.2 to 2.2.3
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['CargoWorkspace plugin run can skip merging rust packages 4'] = `
:robot: I have created a release *beep* *boop*
---
Release notes for path: packages/rustD, releaseType: rust
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['CargoWorkspace plugin run combines rust packages 1'] = `
:robot: I have created a release *beep* *boop*
---
Expand Down
35 changes: 35 additions & 0 deletions __snapshots__/linked-versions-workspace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
exports['Plugin compatibility linked-versions and workspace should version bump dependencies together 1'] = `
:robot: I have created a release *beep* *boop*
---
<details><summary>pkgA: 1.1.0</summary>
## [1.1.0](https://github.com/fake-owner/fake-repo/compare/pkgA-v1.0.0...pkgA-v1.1.0) (1983-10-10)
### Features
* some feature ([aaaaaa](https://github.com/fake-owner/fake-repo/commit/aaaaaa))
</details>
<details><summary>pkgB: 1.1.0</summary>
## [1.1.0](https://github.com/fake-owner/fake-repo/compare/pkgB-v1.0.0...pkgB-v1.1.0) (1983-10-10)
### Miscellaneous Chores
* **pkgB:** Synchronize my group versions
### Dependencies
* The following workspace dependencies were updated
* dependencies
* pkgA bumped from 1.0.0 to 1.1.0
</details>
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`
45 changes: 45 additions & 0 deletions __snapshots__/linked-versions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
exports['LinkedVersions plugin can skip grouping pull requests 1'] = `
:robot: I have created a release *beep* *boop*
---
## [1.0.1](https://github.com/fake-owner/fake-repo/compare/pkg1-v1.0.0...pkg1-v1.0.1) (1983-10-10)
### Bug Fixes
* some bugfix ([aaaaaa](https://github.com/fake-owner/fake-repo/commit/aaaaaa))
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['LinkedVersions plugin can skip grouping pull requests 2'] = `
:robot: I have created a release *beep* *boop*
---
<details><summary>pkg2: 0.2.4</summary>
## [0.2.4](https://github.com/fake-owner/fake-repo/compare/pkg2-v0.2.3...pkg2-v0.2.4) (1983-10-10)
### Bug Fixes
* some bugfix ([bbbbbb](https://github.com/fake-owner/fake-repo/commit/bbbbbb))
</details>
<details><summary>pkg3: 0.2.4</summary>
## [0.2.4](https://github.com/fake-owner/fake-repo/compare/pkg3-v0.2.3...pkg3-v0.2.4) (1983-10-10)
### Miscellaneous Chores
* **pkg3:** Synchronize group name versions
</details>
---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
`

exports['LinkedVersions plugin should group pull requests 1'] = `
:robot: I have created a release *beep* *boop*
---
Expand Down
40 changes: 40 additions & 0 deletions docs/manifest-releaser.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,43 @@ The `maven-workspace` plugin operates similarly to the `node-workspace` plugin,
but on a multi-artifact Maven workspace. It builds a dependency graph of all
discovered `pom.xml` files that are configured in the manifest config and updates
any packages that were directly bumped by release-please.

### linked-versions

The `linked-versions` plugin allows you to "link" the versions of multiple
components in your monorepo. When any component in the specified group is
updated, we pick the highest version amongst the components and update all
group components to the same version (keeping them in sync).

Note: when combining the `linked-versions` plugin with a `workspace` plugin,
you will need to tell the `workspace` plugin to skip its own internal merge.
See #1457 for context.

Example:

```json
{
"release-type": "rust",
"packages": {
"packages/rustA": {
"component": "pkgA"
},
"packages/rustB": {
"component": "pkgB"
}
},
"plugins": [
{
"type": "cargo-workspace",
"merge": false
},
{
"type": "linked-versions",
"group-name": "my group",
"components": [
"pkgA", "pkgB"
]
}
]
}
```
23 changes: 23 additions & 0 deletions schemas/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,33 @@
"items": {
"type": "string"
}
},
"merge": {
"description": "Whether to merge in-scope pull requests into a combined release pull request. Defaults to `true`.",
"type": "boolean"
}
},
"required": ["type", "groupName", "components"]
},
{
"description": "Configuration for various `workspace` plugins.",
"type": "object",
"properties": {
"type": {
"description": "The name of the plugin.",
"type": "string",
"enum": ["cargo-workspace", "maven-workspace", "node-workspace"]
},
"updateAllPackages": {
"description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.",
"type": "boolean"
},
"merge": {
"description": "Whether to merge in-scope pull requests into a combined release pull request. Defaults to `true`.",
"type": "boolean"
}
}
},
{
"description": "Other plugins",
"type": "object",
Expand Down
5 changes: 4 additions & 1 deletion src/factories/plugin-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ export function buildPlugin(options: PluginFactoryOptions): ManifestPlugin {
if (typeof options.type === 'object') {
const builder = pluginFactories[options.type.type];
if (builder) {
return builder(options);
return builder({
...options.type,
...options,
});
}
throw new ConfigurationError(
`Unknown plugin type: ${options.type.type}`,
Expand Down
8 changes: 7 additions & 1 deletion src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,16 @@ export interface LinkedVersionPluginConfig extends ConfigurablePluginType {
type: 'linked-versions';
groupName: string;
components: string[];
merge?: boolean;
}
export interface WorkspacePluginConfig extends ConfigurablePluginType {
merge?: boolean;
}
export type PluginType =
| DirectPluginType
| ConfigurablePluginType
| LinkedVersionPluginConfig;
| LinkedVersionPluginConfig
| WorkspacePluginConfig;

/**
* This is the schema of the manifest config json
Expand Down Expand Up @@ -691,6 +696,7 @@ export class Manifest {
}

for (const plugin of plugins) {
logger.debug(`running plugin: ${plugin.constructor.name}`);
newReleasePullRequests = await plugin.run(newReleasePullRequests);
}

Expand Down
10 changes: 8 additions & 2 deletions src/plugins/cargo-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,17 @@ export class CargoWorkspace extends WorkspacePlugin<CrateInfo> {
candidates: CandidateReleasePullRequest[],
updatedVersions: VersionsMap
): CandidateReleasePullRequest[] {
const rootCandidate = candidates.find(c => c.path === ROOT_PROJECT_PATH);
let rootCandidate = candidates.find(c => c.path === ROOT_PROJECT_PATH);
if (!rootCandidate) {
throw Error('Unable to find root candidate pull request');
logger.warn('Unable to find root candidate pull request');
rootCandidate = candidates.find(c => c.config.releaseType === 'rust');
}
if (!rootCandidate) {
logger.warn('Unable to find a rust candidate pull request');
return candidates;
}

// Update the root Cargo.lock if it exists
rootCandidate.pullRequest.updates.push({
path: 'Cargo.lock',
createIfMissing: false,
Expand Down
13 changes: 12 additions & 1 deletion src/plugins/linked-versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import {Version} from '../version';
import {buildStrategy} from '../factory';
import {Merge} from './merge';

interface LinkedVersionsPluginOptions {
merge?: boolean;
}

/**
* This plugin reconfigures strategies by linking multiple components
* together.
Expand All @@ -32,17 +36,20 @@ import {Merge} from './merge';
export class LinkedVersions extends ManifestPlugin {
private groupName: string;
private components: Set<string>;
private merge: boolean;

constructor(
github: GitHub,
targetBranch: string,
repositoryConfig: RepositoryConfig,
groupName: string,
components: string[]
components: string[],
options: LinkedVersionsPluginOptions = {}
) {
super(github, targetBranch, repositoryConfig);
this.groupName = groupName;
this.components = new Set(components);
this.merge = options.merge ?? true;
}

/**
Expand Down Expand Up @@ -138,6 +145,10 @@ export class LinkedVersions extends ManifestPlugin {
async run(
candidates: CandidateReleasePullRequest[]
): Promise<CandidateReleasePullRequest[]> {
if (!this.merge) {
return candidates;
}

const [inScopeCandidates, outOfScopeCandidates] = candidates.reduce(
(collection, candidate) => {
if (!candidate.pullRequest.version) {
Expand Down
41 changes: 21 additions & 20 deletions src/plugins/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface DependencyNode<T> {
export interface WorkspacePluginOptions {
manifestPath?: string;
updateAllPackages?: boolean;
merge?: boolean;
}

export interface AllPackages<T> {
Expand All @@ -55,6 +56,7 @@ export interface AllPackages<T> {
export abstract class WorkspacePlugin<T> extends ManifestPlugin {
private updateAllPackages: boolean;
private manifestPath: string;
private merge: boolean;
constructor(
github: GitHub,
targetBranch: string,
Expand All @@ -64,6 +66,7 @@ export abstract class WorkspacePlugin<T> extends ManifestPlugin {
super(github, targetBranch, repositoryConfig);
this.manifestPath = options.manifestPath ?? DEFAULT_RELEASE_PLEASE_MANIFEST;
this.updateAllPackages = options.updateAllPackages ?? false;
this.merge = options.merge ?? true;
}
async run(
candidates: CandidateReleasePullRequest[]
Expand Down Expand Up @@ -151,28 +154,26 @@ export abstract class WorkspacePlugin<T> extends ManifestPlugin {
}
}

logger.info(`Merging ${newCandidates.length} in-scope candidates`);
const mergePlugin = new Merge(
this.github,
this.targetBranch,
this.repositoryConfig
);
newCandidates = await mergePlugin.run(newCandidates);

if (newCandidates.length === 1) {
const newUpdates = newCandidates[0].pullRequest.updates;
newUpdates.push({
path: this.manifestPath,
createIfMissing: false,
updater: new ReleasePleaseManifest({
version: newCandidates[0].pullRequest.version!,
versionsMap: updatedPathVersions,
}),
});
} else {
logger.warn(`Expected 1 merged candidate, got ${newCandidates.length}`);
if (this.merge) {
logger.info(`Merging ${newCandidates.length} in-scope candidates`);
const mergePlugin = new Merge(
this.github,
this.targetBranch,
this.repositoryConfig
);
newCandidates = await mergePlugin.run(newCandidates);
}

const newUpdates = newCandidates[0].pullRequest.updates;
newUpdates.push({
path: this.manifestPath,
createIfMissing: false,
updater: new ReleasePleaseManifest({
version: newCandidates[0].pullRequest.version!,
versionsMap: updatedPathVersions,
}),
});

logger.info(`Post-processing ${newCandidates.length} in-scope candidates`);
newCandidates = this.postProcessCandidates(newCandidates, updatedVersions);

Expand Down
Loading

0 comments on commit 354b1dc

Please sign in to comment.