Files
renovate/lib/modules/manager/mise/backends.spec.ts
Pieter Willekens 141e136869 feat(manager/mise): support gitlab backend (#44116)
* feat(manager/mise): support gitlab backend

Maps the mise `gitlab` backend (e.g. `gitlab:gitlab-org/cli`) to the gitlab-releases datasource, mirroring the github backend including version_prefix support.

* refactor(manager/mise): use optional instead of Nullish for tool options

TOML has no null type, so MiseToolOptions values are only ever a string or absent. .optional() models that exactly; Nullish only adds value for sources that can emit explicit null.

* fix(manager/mise): use RegExp.escape in gitlab backend

Main switched `createGithubToolConfig` from the `escapeRegExp` util to
`RegExp.escape` and dropped the import, which left the newly added
`createGitlabToolConfig` referencing an undefined symbol after the merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Michael Kriese <michael.kriese@mend.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 10:04:37 +00:00

456 lines
14 KiB
TypeScript

import {
createAquaToolConfig,
createCargoToolConfig,
createDotnetToolConfig,
createGemToolConfig,
createGithubToolConfig,
createGitlabToolConfig,
createGoToolConfig,
createNpmToolConfig,
createPipxToolConfig,
createSpmToolConfig,
createUbiToolConfig,
} from './backends.ts';
describe('modules/manager/mise/backends', () => {
describe('createAquaToolConfig()', () => {
it('should create a tooling config', () => {
expect(
createAquaToolConfig('BurntSushi/ripgrep', '14.1.1'),
).toStrictEqual({
packageName: 'BurntSushi/ripgrep',
datasource: 'github-tags',
currentValue: '14.1.1',
extractVersion: '^v?(?<version>.+)',
});
});
it('should trim the leading v from version', () => {
expect(
createAquaToolConfig('BurntSushi/ripgrep', 'v14.1.1'),
).toStrictEqual({
packageName: 'BurntSushi/ripgrep',
datasource: 'github-tags',
currentValue: '14.1.1',
extractVersion: '^v?(?<version>.+)',
});
});
});
describe('createCargoToolConfig()', () => {
it('should create a tooling config for crate', () => {
expect(createCargoToolConfig('eza', '')).toStrictEqual({
packageName: 'eza',
datasource: 'crate',
versioning: 'semver',
});
});
it('should create a tooling config for git tag', () => {
expect(
createCargoToolConfig('https://github.com/username/demo', 'tag:v0.1.0'),
).toStrictEqual({
packageName: 'https://github.com/username/demo',
currentValue: 'v0.1.0',
datasource: 'git-tags',
});
});
it('should provide skipReason for git branch', () => {
expect(
createCargoToolConfig(
'https://github.com/username/demo',
'branch:main',
),
).toStrictEqual({
packageName: 'https://github.com/username/demo',
currentValue: 'main',
datasource: 'git-refs',
});
});
it('should create a tooling config for git rev', () => {
expect(
createCargoToolConfig('https://github.com/username/demo', 'rev:abcdef'),
).toStrictEqual({
packageName: 'https://github.com/username/demo',
currentValue: 'abcdef',
datasource: 'git-refs',
});
});
it('should provide skipReason for invalid version', () => {
expect(
createCargoToolConfig('https://github.com/username/demo', 'v0.1.0'),
).toStrictEqual({
packageName: 'https://github.com/username/demo',
skipReason: 'invalid-version',
});
});
});
describe('createDotnetToolConfig()', () => {
it('should create a tooling config', () => {
expect(createDotnetToolConfig('GitVersion.Tool')).toStrictEqual({
packageName: 'GitVersion.Tool',
datasource: 'nuget',
});
});
});
describe('createGemToolConfig()', () => {
it('should create a tooling config', () => {
expect(createGemToolConfig('rubocop')).toStrictEqual({
packageName: 'rubocop',
datasource: 'rubygems',
});
});
});
describe('createGithubToolConfig()', () => {
it('should create a tooling config with empty options', () => {
expect(
createGithubToolConfig('BurntSushi/ripgrep', '14.1.1', {}),
).toStrictEqual({
packageName: 'BurntSushi/ripgrep',
datasource: 'github-releases',
currentValue: '14.1.1',
});
});
it('should not set extractVersion if the version has leading v', () => {
expect(createGithubToolConfig('cli/cli', 'v2.64.0', {})).toStrictEqual({
packageName: 'cli/cli',
datasource: 'github-releases',
currentValue: 'v2.64.0',
});
});
it('should set extractVersion with custom version_prefix', () => {
expect(
createGithubToolConfig('some/repo', '1.0.0', {
version_prefix: 'release-',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: '1.0.0',
extractVersion: '^\\x72elease\\x2d(?<version>.+)',
});
});
it('should set extractVersion with version_prefix even if version has leading v', () => {
expect(
createGithubToolConfig('some/repo', 'v1.0.0', {
version_prefix: 'version-',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: 'v1.0.0',
extractVersion: '^\\x76ersion\\x2d(?<version>.+)',
});
});
it('should handle empty version_prefix with version not having v', () => {
expect(
createGithubToolConfig('some/repo', '1.0.0', { version_prefix: '' }),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: '1.0.0',
});
});
it('should handle empty version_prefix with version having v', () => {
expect(
createGithubToolConfig('some/repo', 'v1.0.0', { version_prefix: '' }),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: 'v1.0.0',
});
});
it('should escape special regex characters in version_prefix', () => {
expect(
createGithubToolConfig('some/repo', '1.0.0', {
version_prefix: 'v1.0+',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: '1.0.0',
extractVersion: '^\\x761\\.0\\+(?<version>.+)',
});
});
it('should escape brackets and parentheses in version_prefix', () => {
expect(
createGithubToolConfig('some/repo', '1.0.0', {
version_prefix: 'prefix[test](v)',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'github-releases',
currentValue: '1.0.0',
extractVersion: '^\\x70refix\\[test\\]\\(v\\)(?<version>.+)',
});
});
});
describe('createGitlabToolConfig()', () => {
it('should create a tooling config with empty options', () => {
expect(
createGitlabToolConfig('gitlab-org/cli', '1.54.0', {}),
).toStrictEqual({
packageName: 'gitlab-org/cli',
datasource: 'gitlab-releases',
currentValue: '1.54.0',
});
});
it('should not set extractVersion if the version has leading v', () => {
expect(
createGitlabToolConfig('gitlab-org/cli', 'v1.54.0', {}),
).toStrictEqual({
packageName: 'gitlab-org/cli',
datasource: 'gitlab-releases',
currentValue: 'v1.54.0',
});
});
it('should set extractVersion with custom version_prefix', () => {
expect(
createGitlabToolConfig('some/repo', '1.0.0', {
version_prefix: 'release-',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'gitlab-releases',
currentValue: '1.0.0',
extractVersion: '^\\x72elease\\x2d(?<version>.+)',
});
});
it('should escape special regex characters in version_prefix', () => {
expect(
createGitlabToolConfig('some/repo', '1.0.0', {
version_prefix: 'v1.0+',
}),
).toStrictEqual({
packageName: 'some/repo',
datasource: 'gitlab-releases',
currentValue: '1.0.0',
extractVersion: '^\\x761\\.0\\+(?<version>.+)',
});
});
});
describe('createGoToolConfig()', () => {
it('should create a tooling config', () => {
expect(createGoToolConfig('github.com/DarthSim/hivemind')).toStrictEqual({
packageName: 'github.com/DarthSim/hivemind',
datasource: 'go',
});
});
});
describe('createNpmToolConfig()', () => {
it('should create a tooling config', () => {
expect(createNpmToolConfig('prettier')).toStrictEqual({
packageName: 'prettier',
datasource: 'npm',
});
});
});
describe('createPipxToolConfig()', () => {
it('should create a tooling config for pypi package', () => {
expect(createPipxToolConfig('yamllint')).toStrictEqual({
packageName: 'yamllint',
datasource: 'pypi',
});
});
it('should create a tooling config for github shorthand', () => {
expect(createPipxToolConfig('psf/black')).toStrictEqual({
packageName: 'psf/black',
datasource: 'github-tags',
});
});
it('should create a tooling config for github url', () => {
expect(
createPipxToolConfig('git+https://github.com/psf/black.git'),
).toStrictEqual({
packageName: 'psf/black',
datasource: 'github-tags',
});
});
it('should create a tooling config for git url', () => {
expect(
createPipxToolConfig('git+https://gitlab.com/user/repo.git'),
).toStrictEqual({
packageName: 'https://gitlab.com/user/repo',
datasource: 'git-refs',
});
});
it('provides skipReason for zip file url', () => {
expect(
createPipxToolConfig('https://github.com/psf/black/archive/18.9b0.zip'),
).toStrictEqual({
packageName: 'https://github.com/psf/black/archive/18.9b0.zip',
skipReason: 'unsupported-url',
});
});
});
describe('createSpmToolConfig()', () => {
it('should create a tooling config for github shorthand', () => {
expect(createSpmToolConfig('tuist/tuist')).toStrictEqual({
packageName: 'tuist/tuist',
datasource: 'github-releases',
});
});
it('should create a tooling config for github url', () => {
expect(
createSpmToolConfig('https://github.com/tuist/tuist.git'),
).toStrictEqual({
packageName: 'tuist/tuist',
datasource: 'github-releases',
});
});
it('provides skipReason for other url', () => {
expect(
createSpmToolConfig('https://gitlab.com/user/repo.git'),
).toStrictEqual({
packageName: 'https://gitlab.com/user/repo.git',
skipReason: 'unsupported-url',
});
});
});
describe('createUbiToolConfig()', () => {
it('should create a tooling config with empty options', () => {
expect(createUbiToolConfig('nekto/act', '0.2.70', {})).toStrictEqual({
packageName: 'nekto/act',
datasource: 'github-releases',
currentValue: '0.2.70',
extractVersion: '^v?(?<version>.+)',
});
});
it('should set extractVersion if the version does not have leading v', () => {
expect(createUbiToolConfig('cli/cli', '2.64.0', {})).toStrictEqual({
packageName: 'cli/cli',
datasource: 'github-releases',
currentValue: '2.64.0',
extractVersion: '^v?(?<version>.+)',
});
});
it('should not set extractVersion if the version has leading v', () => {
expect(createUbiToolConfig('cli/cli', 'v2.64.0', {})).toStrictEqual({
packageName: 'cli/cli',
datasource: 'github-releases',
currentValue: 'v2.64.0',
});
});
it('should ignore options unless tag_regex is provided', () => {
expect(
// oxlint-disable-next-line renovate/prefer-partial-in-specs -- deliberately passes an unrecognized option to verify it is ignored
createUbiToolConfig('cli/cli', '2.64.0', { exe: 'gh' } as any),
).toStrictEqual({
packageName: 'cli/cli',
datasource: 'github-releases',
currentValue: '2.64.0',
extractVersion: '^v?(?<version>.+)',
});
});
it('should set extractVersion if tag_regex is provided', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', '1.10.17', {
tag_regex: '^\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: '1.10.17',
extractVersion: '^v?(?<version>\\d+\\.\\d+\\.)',
});
});
it('should set extractVersion without v? when tag_regex is provided and version starts with v', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', 'v1.10.17', {
tag_regex: '^\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: 'v1.10.17',
extractVersion: '^(?<version>\\d+\\.\\d+\\.)',
});
});
it('should trim the leading ^ from tag_regex', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', 'v1.10.17', {
tag_regex: '^\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: 'v1.10.17',
extractVersion: '^(?<version>\\d+\\.\\d+\\.)',
});
});
it('should only trim the leading ^ from tag_regex when version starts with v', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', 'v1.10.17', {
tag_regex: '^v\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: 'v1.10.17',
extractVersion: '^(?<version>v\\d+\\.\\d+\\.)',
});
});
it('should trim the leading ^v from tag_regex', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', '1.10.17', {
tag_regex: '^v\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: '1.10.17',
extractVersion: '^v?(?<version>\\d+\\.\\d+\\.)',
});
});
it('should trim the leading ^v? from tag_regex', () => {
expect(
createUbiToolConfig('cargo-bins/cargo-binstall', '1.10.17', {
tag_regex: '^v?\\d+\\.\\d+\\.',
}),
).toStrictEqual({
packageName: 'cargo-bins/cargo-binstall',
datasource: 'github-releases',
currentValue: '1.10.17',
extractVersion: '^v?(?<version>\\d+\\.\\d+\\.)',
});
});
});
});