Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add "always-update" config option #2337

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/manifest-releaser.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ defaults (those are documented in comments)
// absence defaults to false and one pull request will be raised
"separate-pull-requests": false,

// if true, always update existing pull requests when changes are added,
// instead of only when the release notes change.
// This option may increase the number of API calls used, but can be useful
// if pull requests must not be out-of-date with the base branch.
// absence defaults to false
"always-update": true,

// sets the manifest pull request title for when releasing multiple packages
// grouped together in the one pull request.
// This option has no effect when `separate-pull-requests` is `true`.
Expand Down
5 changes: 5 additions & 0 deletions schemas/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@
"description": "Open a separate release pull request for each component. Defaults to `false`.",
"type": "boolean"
},
"always-update": {
"description": "Always update the pull request with the latest changes. Defaults to `false`.",
"type": "boolean"
},
"tag-separator": {
"description": "Customize the separator between the component and version in the GitHub tag.",
"type": "string"
Expand Down Expand Up @@ -462,6 +466,7 @@
"pull-request-header": true,
"pull-request-footer": true,
"separate-pull-requests": true,
"always-update": true,
"tag-separator": true,
"extra-files": true,
"version-file": true,
Expand Down
52 changes: 33 additions & 19 deletions src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export interface ReleaserConfig {
pullRequestFooter?: string;
tagSeparator?: string;
separatePullRequests?: boolean;
alwaysUpdate?: boolean;
labels?: string[];
releaseLabels?: string[];
extraLabels?: string[];
Expand Down Expand Up @@ -174,6 +175,7 @@ interface ReleaserConfigJson {
'pull-request-header'?: string;
'pull-request-footer'?: string;
'separate-pull-requests'?: boolean;
'always-update'?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one should be moved to ManifestConfig - ReleaserConfigJson are the per-component configurations and always-update seems to be a repository-wide configuration.

'tag-separator'?: string;
'extra-files'?: ExtraFile[];
'version-file'?: string;
Expand All @@ -200,6 +202,7 @@ export interface ManifestOptions {
draft?: boolean;
prerelease?: boolean;
draftPullRequest?: boolean;
alwaysUpdate?: boolean;
groupPullRequestTitlePattern?: string;
releaseSearchDepth?: number;
commitSearchDepth?: number;
Expand Down Expand Up @@ -293,6 +296,7 @@ export class Manifest {
readonly releasedVersions: ReleasedVersions;
private targetBranch: string;
private separatePullRequests: boolean;
private alwaysUpdate: boolean;
readonly fork: boolean;
private signoffUser?: string;
private labels: string[];
Expand Down Expand Up @@ -332,6 +336,8 @@ export class Manifest {
* plugin
* @param {boolean} manifestOptions.separatePullRequests If true, create separate pull
* requests instead of a single manifest release pull request
* @param {boolean} manifestOptions.alwaysUpdate If true, always updates pull requests instead of
* only when the release notes change
* @param {PluginType[]} manifestOptions.plugins Any plugins to use for this repository
* @param {boolean} manifestOptions.fork If true, create pull requests from a fork. Defaults
* to `false`
Expand Down Expand Up @@ -359,6 +365,7 @@ export class Manifest {
this.separatePullRequests =
manifestOptions?.separatePullRequests ??
Object.keys(repositoryConfig).length === 1;
this.alwaysUpdate = manifestOptions?.alwaysUpdate || false;
this.fork = manifestOptions?.fork || false;
this.signoffUser = manifestOptions?.signoff;
this.releaseLabels =
Expand Down Expand Up @@ -1007,7 +1014,9 @@ export class Manifest {
openPullRequest.headBranchName === pullRequest.headRefName
);
if (existing) {
return await this.maybeUpdateExistingPullRequest(existing, pullRequest);
return this.alwaysUpdate
? await this.updateExistingPullRequest(existing, pullRequest)
: await this.maybeUpdateExistingPullRequest(existing, pullRequest);
}

// look for closed, snoozed pull request
Expand All @@ -1016,7 +1025,9 @@ export class Manifest {
openPullRequest.headBranchName === pullRequest.headRefName
);
if (snoozed) {
return await this.maybeUpdateSnoozedPullRequest(snoozed, pullRequest);
return this.alwaysUpdate
? await this.updateExistingPullRequest(snoozed, pullRequest)
: await this.maybeUpdateSnoozedPullRequest(snoozed, pullRequest);
}

const body = await this.pullRequestOverflowHandler.handleOverflow(
Expand Down Expand Up @@ -1059,20 +1070,10 @@ export class Manifest {
);
return undefined;
}
const updatedPullRequest = await this.github.updatePullRequest(
existing.number,
pullRequest,
this.targetBranch,
{
fork: this.fork,
signoffUser: this.signoffUser,
pullRequestOverflowHandler: this.pullRequestOverflowHandler,
}
);
return updatedPullRequest;
return await this.updateExistingPullRequest(existing, pullRequest);
}

/// only update an snoozed pull request if it has release note changes
/// only update a snoozed pull request if it has release note changes
private async maybeUpdateSnoozedPullRequest(
snoozed: PullRequest,
pullRequest: ReleasePullRequest
Expand All @@ -1084,8 +1085,22 @@ export class Manifest {
);
return undefined;
}
const updatedPullRequest = await this.github.updatePullRequest(
snoozed.number,
const updatedPullRequest = await this.updateExistingPullRequest(
snoozed,
pullRequest
);
// TODO: consider leaving the snooze label
await this.github.removeIssueLabels([SNOOZE_LABEL], snoozed.number);
return updatedPullRequest;
}

/// force an update to an existing pull request
private async updateExistingPullRequest(
existing: PullRequest,
pullRequest: ReleasePullRequest
): Promise<PullRequest> {
return await this.github.updatePullRequest(
existing.number,
pullRequest,
this.targetBranch,
{
Expand All @@ -1094,9 +1109,6 @@ export class Manifest {
pullRequestOverflowHandler: this.pullRequestOverflowHandler,
}
);
// TODO: consider leaving the snooze label
await this.github.removeIssueLabels([SNOOZE_LABEL], snoozed.number);
return updatedPullRequest;
}

private async *findMergedReleasePullRequests() {
Expand Down Expand Up @@ -1370,6 +1382,7 @@ function extractReleaserConfig(
pullRequestFooter: config['pull-request-footer'],
tagSeparator: config['tag-separator'],
separatePullRequests: config['separate-pull-requests'],
alwaysUpdate: config['always-update'],
labels: config['label']?.split(','),
releaseLabels: config['release-label']?.split(','),
extraLabels: config['extra-label']?.split(','),
Expand Down Expand Up @@ -1418,6 +1431,7 @@ async function parseConfig(
lastReleaseSha: config['last-release-sha'],
alwaysLinkLocal: config['always-link-local'],
separatePullRequests: config['separate-pull-requests'],
alwaysUpdate: config['always-update'],
groupPullRequestTitlePattern: config['group-pull-request-title-pattern'],
plugins: config['plugins'],
signoff: config['signoff'],
Expand Down
1 change: 1 addition & 0 deletions src/updaters/release-please-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function releaserConfigToJsonConfig(
'pull-request-header': config.pullRequestHeader,
'pull-request-footer': config.pullRequestFooter,
'separate-pull-requests': config.separatePullRequests,
'always-update': config.alwaysUpdate,
'tag-separator': config.tagSeparator,
'extra-files': config.extraFiles,
'version-file': config.versionFile,
Expand Down
83 changes: 83 additions & 0 deletions test/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4114,6 +4114,89 @@ describe('Manifest', () => {
const pullRequestNumbers = await manifest.createPullRequests();
expect(pullRequestNumbers).lengthOf(0);
});

it('updates an existing pull request without changes if set to always update', async function () {
sandbox
.stub(github, 'getFileContentsOnBranch')
.withArgs('README.md', 'main')
.resolves(buildGitHubFileRaw('some-content'))
.withArgs('release-notes.md', 'my-head-branch--release-notes')
.resolves(buildGitHubFileRaw(body.toString()));
stubSuggesterWithSnapshot(sandbox, this.test!.fullTitle());
mockPullRequests(
github,
[
{
number: 22,
title: 'pr title1',
body: pullRequestBody('release-notes/overflow.txt'),
headBranchName: 'release-please/branches/main',
baseBranchName: 'main',
labels: ['autorelease: pending'],
files: [],
},
],
[]
);
sandbox
.stub(github, 'updatePullRequest')
.withArgs(
22,
sinon.match.any,
sinon.match.any,
sinon.match.has('pullRequestOverflowHandler', sinon.match.truthy)
)
.resolves({
number: 22,
title: 'pr title1',
body: 'pr body1',
headBranchName: 'release-please/branches/main',
baseBranchName: 'main',
labels: [],
files: [],
});
const manifest = new Manifest(
github,
'main',
{
'path/a': {
releaseType: 'node',
component: 'pkg1',
},
'path/b': {
releaseType: 'node',
component: 'pkg2',
},
},
{
'path/a': Version.parse('1.0.0'),
'path/b': Version.parse('0.2.3'),
},
{
separatePullRequests: true,
alwaysUpdate: true,
plugins: ['node-workspace'],
}
);
sandbox.stub(manifest, 'buildPullRequests').resolves([
{
title: PullRequestTitle.ofTargetBranch('main'),
body,
updates: [
{
path: 'README.md',
createIfMissing: false,
updater: new RawContent('some raw content'),
},
],
labels: [],
headRefName: 'release-please/branches/main',
draft: false,
},
]);
const pullRequestNumbers = await manifest.createPullRequests();
expect(pullRequestNumbers).lengthOf(1);
});
});

it('updates an existing snapshot pull request', async function () {
Expand Down
Loading