Files
Tyler Gillson 2e1a079c7f feat(manager/helm-values): support version in sibling tag/version key (#46267)
Some charts define the image reference and its version as sibling keys
of the same object, with the parent key unrelated to the image name:

    cli:
      image: ghcr.io/fluxcd/flux-cli
      tag: v2.7.2

The walker previously extracted the `image` string via
matchesHelmValuesInlineImage but, without an embedded version, produced
a version-less dependency that could never be updated; the sibling
`tag`/`version` key was invisible because
matchesHelmValuesDockerHeuristic requires the keys to live inside an
object whose parent key ends in `image`.

When an inline reference carries no version and no digest, adopt a
sibling `tag` (preferred) or `version` string as the version, reusing
the same update mechanics as the repository/tag object form
(replaceString = version, docker versioning, `{{newValue}}` template).
Inline references with an embedded version or digest keep current
behavior, and repository/tag objects never reach the inline branch.

Discussion #46265 documents the layout with a real-world example.

Signed-off-by: Tyler Gillson <tyler.gillson@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-17 13:48:24 +00:00

68 lines
1.8 KiB
TypeScript

import { isObject, isString } from '@sindresorhus/is';
import { hasKey } from '../../../util/object.ts';
import { regEx } from '../../../util/regex.ts';
import type { HelmDockerImageDependency } from './types.ts';
const parentKeyRe = regEx(/image$/i);
/**
* Type guard to determine whether a given partial Helm values.yaml object potentially
* defines a Helm Docker dependency.
*
* There is no exact standard of how Docker dependencies are defined in Helm
* values.yaml files (as of February 26th 2021), this function defines a
* heuristic based on the most commonly used format in the Helm charts:
*
* image:
* repository: 'something'
* tag: v1.0.0
* image:
* repository: 'something'
* version: v1.0.0
* renovateImage:
* repository: 'something'
* tag: v1.0.0
*/
export function matchesHelmValuesDockerHeuristic(
parentKey: string,
data: unknown,
): data is HelmDockerImageDependency {
return !!(
parentKeyRe.test(parentKey) &&
isObject(data) &&
hasKey('repository', data) &&
(hasKey('tag', data) || hasKey('version', data))
);
}
export function matchesHelmValuesInlineImage(
parentKey: string,
data: unknown,
): data is string {
return !!(parentKeyRe.test(parentKey) && data && isString(data));
}
/**
* Returns the version defined by a sibling `tag` or `version` key of the given
* object, if any:
*
* cli:
* image: 'something'
* tag: v1.0.0
* cli:
* image: 'something'
* version: v1.0.0
*/
export function getHelmValuesSiblingVersion(
data: Record<string, unknown> | HelmDockerImageDependency,
): string | undefined {
const { tag, version } = data as Record<string, unknown>;
if (isString(tag) && tag) {
return tag;
}
if (isString(version) && version) {
return version;
}
return undefined;
}