Skip to content

Commit

Permalink
feat: allow templating of the extends field (#27955)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
  • Loading branch information
3 people committed May 14, 2024
1 parent 8d78ca2 commit 91e8a86
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
34 changes: 34 additions & 0 deletions docs/usage/config-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,40 @@ Parameters are supported similar to other methods:
}
```

## Templating presets

You can use [Handlebars](https://handlebarsjs.com/) templates to be flexible with your presets.
This can be handy when you want to include presets conditionally.

<!-- prettier-ignore -->
!!! note
The template only supports a small subset of options, but you can extend them via `customEnvVariables`.

Read the [templates](./templates.md) section to learn more.

### Example use-case

The following example shows a self-hosted Renovate preset located in a GitLab repository called `renovate/presets`.

```json
{
"extends": ["local>renovate/presets"]
}
```

Usually you want to validate the preset before you put it in your Renovate configuration
Here is an example of how you can use templating to validate and load the preset on a branch level:

```javascript
// config.js
module.exports = {
customEnvVariables: {
GITLAB_REF: process.env.CI_COMMIT_REF_NAME || 'main',
},
extends: ['local>renovate/presets#{{ env.GITLAB_REF }}'],
};
```

## Contributing to presets

Have you configured a rule that could help others?
Expand Down
15 changes: 15 additions & 0 deletions lib/config/presets/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,21 @@ describe('config/presets/index', () => {
expect(res).toMatchSnapshot();
});

it('resolves self-hosted preset with templating', async () => {
GlobalConfig.set({ customEnvVariables: { GIT_REF: 'abc123' } });
config.extends = ['local>username/preset-repo#{{ env.GIT_REF }}'];
local.getPreset.mockImplementationOnce(({ tag }) =>
tag === 'abc123'
? Promise.resolve({ labels: ['self-hosted with template resolved'] })
: Promise.reject(new Error('Failed to resolve self-hosted preset')),
);

const res = await presets.resolveConfigPresets(config);

expect(res.labels).toEqual(['self-hosted with template resolved']);
expect(local.getPreset).toHaveBeenCalledOnce();
});

it('resolves self-hosted transitive presets without baseConfig', async () => {
config.platform = 'gitlab';
config.endpoint = 'https://dummy.example.com/api/v4';
Expand Down
5 changes: 5 additions & 0 deletions lib/config/presets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as packageCache from '../../util/cache/package';
import { getTtlOverride } from '../../util/cache/package/decorator';
import { clone } from '../../util/clone';
import { regEx } from '../../util/regex';
import * as template from '../../util/template';
import { GlobalConfig } from '../global';
import * as massage from '../massage';
import * as migration from '../migration';
Expand Down Expand Up @@ -320,6 +321,10 @@ export async function resolveConfigPresets(
let config: AllConfig = {};
// First, merge all the preset configs from left to right
if (inputConfig.extends?.length) {
// Compile templates
inputConfig.extends = inputConfig.extends.map((tmpl) =>
template.compile(tmpl, {}),
);
for (const preset of inputConfig.extends) {
if (shouldResolvePreset(preset, existingPresets, ignorePresets)) {
logger.trace(`Resolving preset "${preset}"`);
Expand Down

0 comments on commit 91e8a86

Please sign in to comment.