renovatebot / renovate

Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io
https://mend.io/renovate
GNU Affero General Public License v3.0
17.16k stars 2.24k forks source link

Support for dynamic repository configuration #21110

Open devversion opened 1 year ago

devversion commented 1 year ago

What would you like Renovate to be able to do?

I would like to configure renovate in my repository using a dynamically-created repository config.

Use case

In my repository, we have branches for every minor version that we publish. e.g. 14.2.x, 14.3.x, 15.0.x. In a simplified manner, we would like Renovate to only operate on the two most highest SemVer branches. This is currently not possible to achieve via a RegExp.

There are ways to achieve it by manually disabling Renovate for these older branches, but we would like to avoid manually having to maintaining this list/landing changes in older branches.

We have a script that will tell us the most recent branches that are "still in active development" and would like to use it to configure Renovate. Also with a dynamic configuration, we can have different configurations for different semantic branches. e.g.

- main   // should use active @next version of Angular
- 15.2.x // should active @latest version of Angular
- 15.1.x // no longer in active development. Would not like Renovate PRs
- 15.0.x // no longer in active development. Would not like Renovate PRs

If you have any ideas on how this should be implemented, please tell us here.

Mostly thinking of supporting a .js, .mjs, .cjs config file in a repository. Renovate would then run it via Node. It would be opt-in only for self-hosted users. The configuration file could not depend on any node_modules?

Is this a feature you are interested in implementing yourself?

Maybe

rarkins commented 1 year ago

Would that be three different types of files and ways of evaluating them?

Any reason why it can't be renovate.js/mjs/cjs. I know config is more explicit but we already tend to use renovate.x.

We could assume that this file is evaluated after clone, so the whole repo would be there, but normally we would not have node_modules at that point.

RahulGautamSingh commented 1 year ago

Is it possible to use preset for this case, where we can automatically update the baseBranches option in the preset using a script? (will help exclude outdated branches) I am not sure how we will generate config dynamically for different branches using a script. 👀

devversion commented 1 year ago

@rarkins Not really. in either case it would be like node <file-path>. I think it's just worth mentioning that .mjs or .cjs might be used to either use ESM or CommonJS. e.g. in Angular we are switching to full ESM and prefer .mjs.

Yes, we can just name it renovate.js/mjs/cjs. I'm good with that.

We could assume that this file is evaluated after clone, so the whole repo would be there, but normally we would not have node_modules at that point.

I agree. I think that makes sense.

Is it possible to use preset for this case, where we can automatically update the baseBranches option in the preset using a script? (will help exclude outdated branches) I am not sure how we will generate config dynamically for different branches using a script. 👀

@RahulGautamSingh that's a very interesting idea. I think it should be possible, but one annoyance I could see is that it would be hard to have rules like:

// renovate-config.js
const [patchBranch, nextBranch] = await determineActiveReleaseBranches();

export default {
  baseBranches: [nextBranch, patchBranch],
  packageRules: [
    {matchBaseBranches: [patchBranch], followTag: "latest"},
    {matchBaseBranches: [nextBranch],  followTag: "next"},
  ],
}
rarkins commented 1 year ago

So in short,

Not too much else to describe I think?

devversion commented 1 year ago

Yes. One follow-up question/point would be: could top-level node_modules be made available?

rarkins commented 1 year ago

That might be best handled via something new like a postCloneCommands or postCloneTasks array, with controls similar to postUpgradeTasks

devversion commented 1 year ago

good idea. That seems like a nice follow-up if we have the base functionality.

HonkingGoose commented 1 year ago

I think we're status:ready based on this scope:

So in short,

* It should have a global config option `allowDynamicRepoConfig` defaulting to `false`

* It should look for `renovate.js/mjs/cjs` and adapt as necessary based on file extension

And I created #23963 for this idea:

Yes. One follow-up question/point would be: could top-level node_modules be made available?

matzeeable commented 3 months ago

I just stumbled over this issue as I tried to create a workaround solution for https://github.com/renovatebot/renovate/discussions/29424. In general, I want to create a renovate.json from a dynamic mechanism like renovate.mjs. I would like to understand the coding of Renovate, so I could potentially create a PR, so would the following changes resolve the issue?

  1. Add renovate.mjs to

https://github.com/renovatebot/renovate/blob/4039ace0d1f30b7c0aff64dc74da5cee582308aa/lib/config/app-strings.ts#L1-L12

  1. When it comes to reading the config, it runs

https://github.com/renovatebot/renovate/blob/4039ace0d1f30b7c0aff64dc74da5cee582308aa/lib/config-validator.ts#L90-L97

  1. Add a switch case for mjs and import() the module

https://github.com/renovatebot/renovate/blob/4039ace0d1f30b7c0aff64dc74da5cee582308aa/lib/workers/global/config/parse/file.ts#L12-L27

rarkins commented 3 months ago

It's more complicated than you describe because of the need to control whether it's allowed or not. For many or most Renovate admins, they won't want to allow arbitrary script execution by repo users.