mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 15:01:49 +00:00
d32e38ec2b
* fix(github): include commitTrailers in platform-native commits
The GitHub platform-native commit path (platformCommit) recreates the
commit via the REST API using only message, so trailers from
commitTrailers / :gitSignOff were dropped even though prepareCommit
wrote them into the local commit.
* test: use codeBlock for multi-line commit trailer expectations
* Remove unnecessary comment
* refactor(gerrit): format commit message with shared helper
Use formatCommitMessage for Gerrit reserved trailers so the final
message is built the same way as the git and GitHub platform-native
paths, then clear trailers so prepareCommit does not append them twice.
* Revert "refactor(gerrit): format commit message with shared helper"
This reverts commit d230fa3802.
* refactor(git): fold commit trailers into the message before scm
Remove CommitFilesConfig.trailers so platforms only ever see a fully
formatted message. Workers call formatCommitMessage once; prepareCommit
and GitHub platform-native commits pass message through as-is. Gerrit
parses the existing trailer block to merge Renovate-Branch/Change-Id.
* refactor(git): drop formatCommitMessage helper
Trailers are already folded into message at the worker boundary, so the
shared formatter only re-joined strings. Inline that at the few call sites
and keep splitCommitMessage for Gerrit's reserved-trailer merge.
* revert: keep the minimal commitTrailers platform-native fix
Drop the later refactors (fold trailers into message, Gerrit changes,
splitCommitMessage). Keep formatCommitMessage shared by prepareCommit
and GitHub platform-native commits only; Gerrit is unchanged.
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { codeBlock } from 'common-tags';
|
|
import { logger } from '~test/util.ts';
|
|
import {
|
|
filterValidCommitTrailers,
|
|
formatCommitMessage,
|
|
isValidCommitTrailer,
|
|
} from './commit-trailers.ts';
|
|
|
|
describe('util/git/commit-trailers', () => {
|
|
describe('isValidCommitTrailer', () => {
|
|
it.each([
|
|
'Signed-off-by: Renovate Bot <bot@renovateapp.com>',
|
|
'Signed-off-by: {{{gitAuthor}}}',
|
|
'Co-authored-by: First Contributor <first@example.com>',
|
|
'Renovate-Update-Type: major',
|
|
'X-Custom: value with spaces',
|
|
])('accepts %j', (trailer) => {
|
|
expect(isValidCommitTrailer(trailer)).toBeTrue();
|
|
});
|
|
|
|
it.each([
|
|
'no colon',
|
|
'Bad key: value',
|
|
'Key:no-space',
|
|
'Key: multi\nline',
|
|
'Signed-off-by: ',
|
|
'Signed-off-by:',
|
|
'',
|
|
42,
|
|
null,
|
|
undefined,
|
|
])('rejects %j', (trailer) => {
|
|
expect(isValidCommitTrailer(trailer)).toBeFalse();
|
|
});
|
|
});
|
|
|
|
describe('filterValidCommitTrailers', () => {
|
|
it('returns valid trailers unchanged', () => {
|
|
const trailers = [
|
|
'Signed-off-by: Renovate Bot <bot@renovateapp.com>',
|
|
'Co-authored-by: First Contributor <first@example.com>',
|
|
];
|
|
expect(filterValidCommitTrailers(trailers)).toEqual(trailers);
|
|
expect(logger.logger.warn).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('drops invalid trailers and warns', () => {
|
|
expect(
|
|
filterValidCommitTrailers([
|
|
'Signed-off-by: Renovate Bot <bot@renovateapp.com>',
|
|
'Signed-off-by: ',
|
|
'Key: multi\nline',
|
|
]),
|
|
).toEqual(['Signed-off-by: Renovate Bot <bot@renovateapp.com>']);
|
|
expect(logger.logger.warn).toHaveBeenCalledExactlyOnceWith(
|
|
{ invalid: ['Signed-off-by: ', 'Key: multi\nline'] },
|
|
'Ignoring invalid commit trailers (must be a single-line Key: value)',
|
|
);
|
|
});
|
|
|
|
it('returns empty array when all trailers are invalid', () => {
|
|
expect(
|
|
filterValidCommitTrailers(['Signed-off-by: ', 'no colon']),
|
|
).toEqual([]);
|
|
expect(logger.logger.warn).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('formatCommitMessage', () => {
|
|
it('returns string message unchanged when there are no trailers', () => {
|
|
expect(formatCommitMessage('Update something')).toBe('Update something');
|
|
});
|
|
|
|
it('joins array message parts with blank lines', () => {
|
|
expect(formatCommitMessage(['Update something', 'Some commit body']))
|
|
.toBe(codeBlock`
|
|
Update something
|
|
|
|
Some commit body
|
|
`);
|
|
});
|
|
|
|
it('appends trailers as the final block for a string message', () => {
|
|
expect(
|
|
formatCommitMessage('Update something', [
|
|
'Signed-off-by: Renovate Bot <bot@renovateapp.com>',
|
|
'Co-authored-by: First Contributor <first@example.com>',
|
|
]),
|
|
).toBe(codeBlock`
|
|
Update something
|
|
|
|
Signed-off-by: Renovate Bot <bot@renovateapp.com>
|
|
Co-authored-by: First Contributor <first@example.com>
|
|
`);
|
|
});
|
|
|
|
it('appends trailers as the final block for an array message', () => {
|
|
expect(
|
|
formatCommitMessage(
|
|
['Update something', 'Some commit body'],
|
|
['Signed-off-by: Renovate Bot <bot@renovateapp.com>'],
|
|
),
|
|
).toBe(codeBlock`
|
|
Update something
|
|
|
|
Some commit body
|
|
|
|
Signed-off-by: Renovate Bot <bot@renovateapp.com>
|
|
`);
|
|
});
|
|
|
|
it('ignores empty trailer lists', () => {
|
|
expect(formatCommitMessage('Update something', [])).toBe(
|
|
'Update something',
|
|
);
|
|
});
|
|
});
|
|
});
|