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

fix(platform): trim labels #32015

Merged
merged 11 commits into from
Oct 21, 2024
10 changes: 10 additions & 0 deletions docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ With the above config:
- ESLint dependencies will have the label `linting`
- All other dependencies will have the label `dependencies`

<!-- prettier-ignore -->
!!! note
rarkins marked this conversation as resolved.
Show resolved Hide resolved
Keep your labels within the maximum character limit for your Git hosting platform.
Renovate usually truncates labels to 50 characters, except for GitLab, which has a 255 character limit.

## additionalBranchPrefix

By default, the value for this config option is an empty string.
Expand Down Expand Up @@ -2200,6 +2205,11 @@ Behavior details:
The `labels` array is non-mergeable, meaning if multiple `packageRules` match then Renovate uses the last value for `labels`.
If you want to add/combine labels, use the `addLabels` config option, which is mergeable.

<!-- prettier-ignore -->
!!! note
rarkins marked this conversation as resolved.
Show resolved Hide resolved
Keep your labels within the maximum character limit for your Git hosting platform.
Renovate usually truncates labels to 50 characters, except for GitLab, which has a 255 character limit.

## lockFileMaintenance

You can use `lockFileMaintenance` to refresh lock files to keep them up-to-date.
Expand Down
1 change: 1 addition & 0 deletions lib/modules/platform/gitlab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const defaults = {
};

export const id = 'gitlab';
export const labelCharLimit = 255;

const DRAFT_PREFIX = 'Draft: ';
const DRAFT_PREFIX_DEPRECATED = 'WIP: ';
Expand Down
1 change: 1 addition & 0 deletions lib/modules/platform/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export interface Platform {
expandGroupMembers?(reviewersOrAssignees: string[]): Promise<string[]>;

maxBodyLength(): number;
labelCharLimit?: number;
}

export interface PlatformScm {
Expand Down
41 changes: 41 additions & 0 deletions lib/workers/repository/update/pr/labels.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { platform } from '../../../../../test/util';
import {
areLabelsModified,
getChangedLabels,
Expand All @@ -6,6 +7,10 @@ import {
} from './labels';

describe('workers/repository/update/pr/labels', () => {
beforeEach(() => {
platform.labelCharLimit = 50;
});

describe('prepareLabels(config)', () => {
it('returns empty array if no labels are configured', () => {
const result = prepareLabels({});
Expand Down Expand Up @@ -82,6 +87,42 @@ describe('workers/repository/update/pr/labels', () => {
expect(result).toBeArrayOfSize(0);
expect(result).toEqual([]);
});

describe('trim labels that go over the max char limit', () => {
const labels = [
'All',
'The quick brown fox jumped over the lazy sleeping dog', // len: 51
// len: 256
'Torem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla erat eu lectus gravida varius. Maecenas suscipit risus nec erat mollis tempus. Vestibulum cursus urna et faucibus tempor. Nam eleifend libero in enim sodales, eu placerat enim dice rep!',
];

it('github', () => {
platform.labelCharLimit = undefined as never; // coverage
expect(prepareLabels({ labels })).toEqual([
'All',
'The quick brown fox jumped over the lazy sleeping', // len: 50
'Torem ipsum dolor sit amet, consectetur adipiscing', // len: 50
]);
});

it('gitlab', () => {
platform.labelCharLimit = 255;
expect(prepareLabels({ labels })).toEqual([
'All',
'The quick brown fox jumped over the lazy sleeping dog', // len: 51
// len: 255
'Torem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla erat eu lectus gravida varius. Maecenas suscipit risus nec erat mollis tempus. Vestibulum cursus urna et faucibus tempor. Nam eleifend libero in enim sodales, eu placerat enim dice rep',
]);
});

it('gitea', () => {
expect(prepareLabels({ labels })).toEqual([
'All',
'The quick brown fox jumped over the lazy sleeping', // len: 50
'Torem ipsum dolor sit amet, consectetur adipiscing', // len: 50
]);
});
});
});

describe('getChangedLabels', () => {
Expand Down
14 changes: 14 additions & 0 deletions lib/workers/repository/update/pr/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@ import is from '@sindresorhus/is';
import { dequal } from 'dequal';
import type { RenovateConfig } from '../../../../config/types';
import { logger } from '../../../../logger';
import { platform } from '../../../../modules/platform';
import * as template from '../../../../util/template';

/**
* Filter labels that go over the maximum char limit, based on platform limits.
*/
function trimLabel(label: string, limit: number): string {
if (label.length > limit) {
return label.trim().slice(0, limit).trim();
}

return label.trim();
RahulGautamSingh marked this conversation as resolved.
Show resolved Hide resolved
}

export function prepareLabels(config: RenovateConfig): string[] {
const labelCharLimit = platform.labelCharLimit ?? 50;
RahulGautamSingh marked this conversation as resolved.
Show resolved Hide resolved
const labels = config.labels ?? [];
const addLabels = config.addLabels ?? [];
return [...new Set([...labels, ...addLabels])]
.filter(is.nonEmptyStringAndNotWhitespace)
.map((label) => template.compile(label, config))
.filter(is.nonEmptyStringAndNotWhitespace)
.map((label) => trimLabel(label, labelCharLimit))
.sort();
}

Expand Down
Loading