Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 6 additions & 2 deletions docs/config-file-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -490,11 +490,15 @@ Assign the same reviewers to the target pull request that were assigned to the o

#### `copySourcePRLabels`

Copies all labels from the original (source) pull request to the backport (target) pull request.
Copies labels from the original (source) pull request to the backport (target) pull request.
Can be either a boolean or an array of strings. When set to `true`, _all_ labels from the source PR are copied to the target PR.
When an array of strings is configured, each string is used as a RegEx pattern and will be compared to each label of the source PR.
If the label on the source PR matches at least one configured string, it will be copied to the target PR.

Default: `false`
```json
{
"copySourcePRLabels": false
"copySourcePRLabels": ["^Team:.*", "^:.*", "^>.*"]
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,39 @@ export async function copySourcePullRequestLabelsToTargetPullRequest(
commits: Commit[],
pullNumber: number,
) {
const labels = getNonBackportLabels(commits);
const labels = getNonBackportLabels(commits, options);
if (labels.length > 0) {
await addLabelsToPullRequest({ ...options, pullNumber, labels });
}
}

function getNonBackportLabels(commits: Commit[]) {
function getNonBackportLabels(commits: Commit[], options: ValidConfigOptions) {
return commits.flatMap((commit) => {
if (!commit.sourcePullRequest) {
return [];
}

const backportLabels = commit.targetPullRequestStates.map((pr) => pr.label);
const labels = commit.sourcePullRequest.labels.filter(
(label) => !backportLabels.includes(label),
);
const labels = commit.sourcePullRequest.labels.filter((label) => {
// If `copySourcePRLabels` is a boolean, it must be true to reach this method.
// Therefore, we simply copy all labels from the source PR that aren't already on the target PR.
const copySourcePRLabels = options.copySourcePRLabels;
if (typeof copySourcePRLabels === 'boolean') {
return !backportLabels.includes(label);
}
// Otherwise, it's an array of regex patterns.
if (
typeof copySourcePRLabels === 'object' &&
copySourcePRLabels.constructor === Array
) {
return copySourcePRLabels.some((sourceLabel) =>
label.match(new RegExp(sourceLabel)),
);
}
throw new Error(
'Unexpected type of copySourcePRLabels, must be boolean or array',
);
});

return labels;
});
Expand Down
2 changes: 1 addition & 1 deletion src/options/ConfigOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type Options = Partial<{
cherrypickRef: boolean;
commitConflicts: boolean;
commitPaths: string[];
copySourcePRLabels: boolean;
copySourcePRLabels: boolean | string[];
Copy link
Author

Choose a reason for hiding this comment

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

I wasn't able to figure out a way to make this change in cliArgs.ts. We could also define a new option instead of allowing two types in the existing option, if that's preferred. Let me know what you think.

copySourcePRReviewers: boolean;
details: boolean;
dir: string;
Expand Down