Files
renovate/lib/util/git/commit-trailers.ts
T
Felipe Santos ddbbb687f9 feat: add commitTrailers option (#44651)
* feat(config): add commitTrailers option

Renovate's only way to add git trailers today is `commitBody`, but it's
broken on Gerrit: Renovate appends its own `Renovate-Branch`/`Change-Id`
block after the body, so user trailers end up in a non-final message
block and are not real trailers per git-interpret-trailers rules.

This adds a `commitTrailers: string[]` option (each entry a full
`Key: value` line), standardizes Gerrit's own trailers through the same
mechanism so user trailers and platform trailers merge into one final
block, and verifies the result at runtime with `git interpret-trailers`
(commitlint's trailer-exists rule uses the same approach). The
`:gitSignOff` preset is migrated from `commitBody` to `commitTrailers`
so sign-off works correctly on Gerrit too.

* Simplify a bit

* Simplify docs even more

* Simplify another bit

* Add comment about rawExec

* Drop runtime commit trailer verification

Bypass simple-git only to emit a proactive warn log is not worth the
extra surface area. Config validation already enforces Key: value form.

* test(git): cover string commit message with trailers

Codecov patch failed on the partial ternary branch that normalizes a
string message before appending trailers.

* test(gerrit): fix trailers test after scm rework

Align the commitTrailers merge test with the post-rework Gerrit SCM:
use fakeSha helpers and drop the removed force flag.

* Improve wording on gitSignOff docs

* Validate compiled commitTrailers as well

* Improve trailers example

* Use isString instead

* Update lib/util/git/index.ts

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>

* Update lib/workers/repository/onboarding/branch/create.ts

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>

* Format code

* Fix type-check

* Fix tests

---------

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
2026-07-27 06:49:09 +00:00

36 lines
1.0 KiB
TypeScript

import { isNonEmptyArray, isString } from '@sindresorhus/is';
import { logger } from '../../logger/index.ts';
import { regEx } from '../regex.ts';
const commitTrailerRe = regEx(/^[A-Za-z0-9-]+: [^\r\n]+$/);
/**
* A valid git trailer is a single-line `Key: value` entry where the key
* contains only letters, digits and `-`, and the value is non-empty.
*/
export function isValidCommitTrailer(trailer: unknown): trailer is string {
return isString(trailer) && commitTrailerRe.test(trailer);
}
/**
* Keep only trailers that are valid single-line `Key: value` entries.
*/
export function filterValidCommitTrailers(trailers: string[]): string[] {
const valid: string[] = [];
const invalid: string[] = [];
for (const trailer of trailers) {
if (isValidCommitTrailer(trailer)) {
valid.push(trailer);
} else {
invalid.push(trailer);
}
}
if (isNonEmptyArray(invalid)) {
logger.warn(
{ invalid },
'Ignoring invalid commit trailers (must be a single-line Key: value)',
);
}
return valid;
}