From f593ffca200b4e279cb4ca3bd9501458d9aa33a2 Mon Sep 17 00:00:00 2001 From: Timo Hankamer Date: Thu, 19 Mar 2026 11:16:52 +0100 Subject: [PATCH] feat(package-rules): support template compilation for sourceUrl (#41932) Add template compilation support for sourceUrl in package rules, allowing users to dynamically construct source URLs using template syntax. This enables use cases like OpenTofu providers where the source URL needs to be constructed from the package name. --- docs/usage/configuration-options.md | 16 +++++++++++++ lib/util/package-rules/index.spec.ts | 35 ++++++++++++++++++++++++++++ lib/util/package-rules/index.ts | 3 +++ 3 files changed, 54 insertions(+) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index e88dc62f01..49ae2a7531 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -3856,6 +3856,8 @@ Use this field to set the directory in which the package is present at the sourc Use this field to set the source URL for a package, including overriding an existing one. Source URLs are necessary to link to the source of the package and in order to look up changelogs. +The `sourceUrl` field supports template compilation, allowing you to dynamically construct URLs based on package information. + ```json title="Setting the source URL for the dummy package" { "packageRules": [ @@ -3867,6 +3869,20 @@ Source URLs are necessary to link to the source of the package and in order to l } ``` +```json title="Using templates to construct source URLs for OpenTofu providers" +{ + "packageRules": [ + { + "matchDatasources": ["terraform-provider"], + "registryUrls": ["https://registry.opentofu.org"], + "sourceUrl": "https://github.com/{{replace '/' '/terraform-provider-' packageName}}" + } + ] +} +``` + +In the example above, a package name like `hashicorp/aws` will be transformed to `https://github.com/hashicorp/terraform-provider-aws`. + ## patch Add to this object if you wish to define rules that apply only to patch updates. diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts index a146a0d90b..67b289d718 100644 --- a/lib/util/package-rules/index.spec.ts +++ b/lib/util/package-rules/index.spec.ts @@ -1282,4 +1282,39 @@ describe('util/package-rules/index', () => { expect(res.depName).toBe('node'); expect(res.packageName).toBe('docker.io/library/node'); }); + + it('compiles sourceUrl with template helper functions', async () => { + const config: TestConfig = { + datasource: 'terraform-provider', + depName: 'aws', + packageName: 'hashicorp/aws', + packageRules: [ + { + matchDatasources: ['terraform-provider'], + sourceUrl: + 'https://github.com/{{replace "/" "/terraform-provider-" packageName}}', + }, + ], + }; + const res = await applyPackageRules(config); + expect(res.sourceUrl).toBe( + 'https://github.com/hashicorp/terraform-provider-aws', + ); + }); + + it('compiles sourceUrl with template variables', async () => { + const config: TestConfig = { + datasource: 'terraform-provider', + depName: 'aws', + packageName: 'hashicorp/aws', + packageRules: [ + { + matchDatasources: ['terraform-provider'], + sourceUrl: 'https://github.com/{{packageName}}', + }, + ], + }; + const res = await applyPackageRules(config); + expect(res.sourceUrl).toBe('https://github.com/hashicorp/aws'); + }); }); diff --git a/lib/util/package-rules/index.ts b/lib/util/package-rules/index.ts index c019ca82ec..6f91bf296b 100644 --- a/lib/util/package-rules/index.ts +++ b/lib/util/package-rules/index.ts @@ -90,6 +90,9 @@ export async function applyPackageRules( ); config.packageName = compile(toApply.overridePackageName, config); } + if (isString(toApply.sourceUrl)) { + toApply.sourceUrl = compile(toApply.sourceUrl, config); + } delete toApply.overrideDatasource; delete toApply.overrideDepName; delete toApply.overridePackageName;