Skip to content
This repository has been archived by the owner on Dec 12, 2020. It is now read-only.

Guidance for initial default shared config? #816

Closed
ljharb opened this issue Aug 19, 2020 · 22 comments
Closed

Guidance for initial default shared config? #816

ljharb opened this issue Aug 19, 2020 · 22 comments
Labels

Comments

@ljharb
Copy link

ljharb commented Aug 19, 2020

Hi! Per https://twitter.com/rarkins/status/1295961639888592898

I'm trying to make an initial shared config. Here's what I'm hoping for:

  • when there's a new major where tests pass, I want a PR to add the major as allowed for deps/devDeps/peerDeps
  • when there's a new major where tests fail, i want either an issue or a PR that lets me get to the failed build
  • when there's a new nonmajor where tests pass, no-op. i never have lockfiles in packages, but i suppose if i had one, i'd want a PR to update the lockfile? not sure how annoying that'd be tho.
  • when there's a new nonmajor where tests fail, i ideally want both an issue/PR that shows me the failed build, and maybe also a PR that pegs the dep/devDep/peerDep to avoid the failing version.
  • when something gets an update that has peer dep requirements, i want those grouped quasi-automatically. iow, if eslint-config-airbnb updates, i'd want the PR to update it, and eslint, and eslint-config-react, etc - and i wouldn't want a PR until the "batch update" passed tests. Same for babel things, react things, etc.
  • i never want a PR that makes a previously-valid peerDep invalid
  • i'd love to customize the commit messages, so i don't have to manually rebase and edit things in order to land them

Thanks!!

@ljharb
Copy link
Author

ljharb commented Aug 19, 2020

also, rather than https://twitter.com/rarkins/status/1295945549523423232, perhaps i could add a renovate config with "extends" to the .github repo in a user/org, and this one-off backend action wouldn't be needed?

iow, potentially i could add renovate to every repo in an org all at once, without even a PR, just by adding an app after adding a config in a .github repo?

@rarkins
Copy link
Collaborator

rarkins commented Aug 19, 2020

  • when there's a new major where tests pass, I want a PR to add the major as allowed for deps/devDeps/peerDeps

Major PRs are raised by default. If you want the PR creation to wait until tests are complete, you'll want prCreation="not-pending".

  • when there's a new major where tests fail, i want either an issue or a PR that lets me get to the failed build

We create PRs, I think that's less noise than issues. So typically:

  • You'd get a major update PR
  • It would fail one or more of your tests
  • You could click through like usual to see the CI results
  • You may do some refactoring to get it passing, by adding one or more of your own commits on top
  • Renovate will stop updating the branch as soon as it sees you've added any commits
  • Eventually you merge the PR

BTW on the topic of major PRs, you might like to use the dependencyDashboardApproval feature so that branches/PRs are not automatically created, and only created once you tick a checkbox. We use this in the main Renovate repo, for example - because we're usually not in a hurry to support/take the next major release right away. I recommend this for applications, although for libraries you may prefer to get them immediately.

  • when there's a new nonmajor where tests pass, no-op.

This statement implies that you're using major and not minor ranges.

Renovate's default behavior is to not raise a PR if a new version satisfies the existing range. Some people like to "bump" the range (e.g. from ^1.0.0 to ^1.0.1, etc) and we do support that, but I don't recommend it.

  • i never have lockfiles in packages, but i suppose if i had one, i'd want a PR to update the lockfile? not sure how annoying that'd be tho.

Renovate's default behavior is again to not bump the lockfile in such a scenario, but you can opt into it with rangeStrategy=update-lockfile. I do recommend this for most but it's not the default behavior for now because too many people complain about the "noise" so I figured it's easier to let power users opt into it than to explain to complainers how to opt out of it. i.e. it's a pragmatic decision on (a) reducing noise by default, and (b) accepting there's a segment of the community that loves to dunk on dependency automation.

  • when there's a new nonmajor where tests fail, i ideally want both an issue/PR that shows me the failed build, and maybe also a PR that pegs the dep/devDep/peerDep to avoid the failing version.

This is not currently supported, I understand it's kind of the greenkeeper way though. The challenge with this is that it's got to be driven either by a state-based solution, or event-based, both of which have major downsides.

State-based: Renovate needs to have some form of state that records every version within your existing range that has been tested before, so it knows when it's time to test a new one. And even then, in theory each version should be re-tested once any ranges in your base branch change. Currently, Renovate gets by with only state within the repo itself (branches, commits, PRs, issues) and it's proven to be robust, scalable, and self-healing. It also means you can switch out between the hosted app and the open source at any time, unlike any other solution currently available.

Event-based: Instead of remembering which versions have been tested, Renovate treats new package publishing as an event that triggers tests in applicable repos. It still kind of needs state (the list of packages and ranges each repo has) but also now is dependent on events not getting lost or other ephemeral failures, including its own. Considering how often npm and GitHub go down, I really don't like this approach.

I'm open to ideas on this topic though, but probably best to discuss it as a feature in the main repo. Wrapping up:

  • If you're writing an app, I strongly recommend lock files, so this is not applicable
  • If using writing a library, I'd still prefer lock files, but if not then I also question: is it your responsibility to be mutating your package.json dependencies for every bad/breaking release of a direct dependency? I really haven't seen anyone doing that, e.g. having a dependency like ^1.0.0, != 1.0.4, != 1.2.0, != 1.5.0 (not even sure of the syntax to handle that).
  • when something gets an update that has peer dep requirements, i want those grouped quasi-automatically. iow, if eslint-config-airbnb updates, i'd want the PR to update it, and eslint, and eslint-config-react, etc - and i wouldn't want a PR until the "batch update" passed tests. Same for babel things, react things, etc.

There's a really old issue in the main repo discussing this type of thing, I think you have a few comments there already :). We haven't worked out a way to do such grouping automatically, but we do have most users group together updates for things like eslint or babel packages.

  • i never want a PR that makes a previously-valid peerDep invalid

Our default behavior for peerDependencies should be rangeStrategy=extend, which satisfies this. I haven't used or tested peerDependencies in a while though.

  • i'd love to customize the commit messages, so i don't have to manually rebase and edit things in order to land them

Commit messages are extremely composable and configurable:

image

Feel free to ask here though instead of trying to work out all the nuances yourself.

also, rather than twitter.com/rarkins/status/1295945549523423232, perhaps i could add a renovate config with "extends" to the .github repo in a user/org, and this one-off backend action wouldn't be needed?

That's a future feature, I think we have an issue somewhere for it. For now it's very quick for me to add an onboardingConfig field to your accounts. It should typically be something that never changes anyway (e.g. { "extends": ["ljharb/renovate-config"] })

iow, potentially i could add renovate to every repo in an org all at once, without even a PR, just by adding an app after adding a config in a .github repo?

Yes, that is also possible, but again something I'd need to add a rule for on the backend. It's stuff that's configurable if you self-host but has not yet been exposed via the dashboard for the hosted app.

For example it can mean that we skip the onboarding PR and renovate.json requirement for every repo in your orgs that's installed, and instead default to e.g. { "extends": ["ljharb/renovate-config"] } as the base config for each repo.

@ljharb
Copy link
Author

ljharb commented Aug 20, 2020

Thanks!

Will rangeStrategy=update-lockfile be ignored if there's no lockfile present?

is it your responsibility to be mutating your package.json dependencies for every bad/breaking release of a direct dependency?

Absolutely - if my semver range causes my downstream users to have a bug, it's my bug and my fault, even if it's due to another package. In that example, ^1.0.0, != 1.0.4, != 1.2.0, != 1.5.0, i'd represent that as 1.0.0 - 1.0.3 || ~1.0.5 || ~1.1 || ~1.2.1 || 1.2.2 - 1.4.x || ^1.5.1.

We haven't worked out a way to do such grouping automatically

Greenkeeper's approach was to make a repo of common groupings, that users could PR common groups into, and then everyone benefited from that.

default to e.g. { "extends": ["ljharb/renovate-config"] } as the base config for each repo.

That would be wonderful, yes :-) if it looked in a .github dir, theoretically that could be enabled for every org/user by default, and it'd thus be opt-in?

@rarkins
Copy link
Collaborator

rarkins commented Aug 22, 2020

Will rangeStrategy=update-lockfile be ignored if there's no lockfile present?

Yes, it should fall back to replace behavior.

Re: adding exclusions to version ranges, this is not something I anticipate Renovate doing for now, and too unlikely that we'd get it right without a bunch of false positives caused by ephemeral test failures and other challenges.

Greenkeeper's approach was to make a repo of common groupings, that users could PR common groups into, and then everyone benefited from that.

Sure, we have that. By automatic I thought you meant analyzing peer dependencies at run time and building up a list of related packages (something we have looked into and would like to do eventually). Renovate pioneered that approach Greenkeeper used of having group presets that can be PR'd. It was initially in a separate repo for us to but we internalized it recently for improved performance here: https://github.com/renovatebot/renovate/blob/master/lib/config/presets/internal/group.ts. You can see them auto-published into more easier to read documentation here: https://docs.renovatebot.com/presets-group/. Many of those are grouping package patterns defined here: https://docs.renovatebot.com/presets-packages/

In short: you can use any of those group rules we already have, you can also PR changes or new groups if you think the user base would benefit, but you can also group packages together yourself according to personal preference.

if it looked in a .github dir, theoretically that could be enabled for every org/user by default, and it'd thus be opt-in?

I have no objection to the idea but it's at least a few days of work altogether to get the experience working consistently across both the OSS CLI as well as the hosted app. Much faster for me right now to just add a line or two of config in the app backend for your manually!

Wrapping up how this would look for you:

You'd want to create a personal Renovate "preset" in a repo like github.com/ljharb/renovate-config. This can include all the settings you want applied to all repos. You can define groupings there, but if there's any you think should be available to all Renovate users then you could PR the main repo to have them added to the default presets.

Assuming that you don't want to "onboard" your repos one by one (receive a "Configure Renovate" PR with a preview of the branches/PRs that will be created, and a renovate.json file to merge), you can confirm to me which orgs and/or repos to add a rule in the backend that will:

  • Treat installed repos as enabled even if no config file is present
  • Default each repo config to {"extends":["github>ljharb/renvoate-config"]}

You would then probably install Renovate into repos one at a time until you're completely confident and then perhaps install into all repos once you are.

@ljharb
Copy link
Author

ljharb commented Aug 23, 2020

That sounds like a great approach, thanks! I'll start by creating the config, and I'll ping you with a list of orgs when i'm ready to experiment :-)

@stale
Copy link

stale bot commented Aug 29, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon if no further activity occurs.

@ljharb
Copy link
Author

ljharb commented Aug 30, 2020

bump.

@stale stale bot removed the pending-closure label Aug 30, 2020
@rarkins
Copy link
Collaborator

rarkins commented Aug 30, 2020

@ljharb are you waiting on any answers on my side right now, or just wished to keep it open in case you have follow-up questions?

@ljharb
Copy link
Author

ljharb commented Aug 30, 2020

The ball's in my court :-) just hoping to keep it open until I've got things working.

@ljharb
Copy link
Author

ljharb commented Oct 7, 2020

@rarkins thanks for your patience :-) I've created https://github.com/ljharb/renovate/blob/main/renovate.json - could we make all repos on ljharb, inspect-js, es-shims, enzymejs, nvm-sh, and jsx-eslint extend that config by default?

(perhaps we should start with enzymejs, so that i'm not overwhelmed by update PRs until i've had time to tweak things?)

@viceice
Copy link
Member

viceice commented Oct 7, 2020

@ljharb We just released a new origanization level default config feature

https://github.com/renovatebot/renovate/releases/tag/23.42.0
https://github.com/renovatebot/renovate/blob/master/docs/usage/config-presets.md#organisation-level-presets

When that goes live you can add a default.json to a renovate-config repo, after that renovate will suggest that config as onboarding config.

@ljharb
Copy link
Author

ljharb commented Oct 7, 2020

@viceice that's great! why not a renovate.json in a .github repo, since that's already the source of truth for org-wide and user-wide config?

@viceice
Copy link
Member

viceice commented Oct 7, 2020

@ljharb That was a user submission #7403 which works for all our supported platforms. Feel free to open an issue to suggest improvements,

@ljharb
Copy link
Author

ljharb commented Oct 7, 2020

Sure, #909 → renovatebot/renovate#7422.

@ljharb
Copy link
Author

ljharb commented Oct 8, 2020

@rarkins with the new changes, I've added my default config to my .github repo: https://github.com/ljharb/.github/blob/master/renovate-config.json and I enabled the renovate github app for a single repo to test it out. I got this PR: ljharb/global-cache#42 - I thought the point for a .github repo config file was that individual repos wouldn't need a config file at all. Is there a way I can activate renovate without merging that config file?

(or, perhaps, the new .github changes aren't deployed yet? if not, how do i update that PR?)

@rarkins
Copy link
Collaborator

rarkins commented Oct 12, 2020

@ljharb FYI I've applied the following config to all ljharb/* repos:

{
  "extends": ["local>ljharb/.github:renovate-config"],
  "requireConfig": false,
  "onboarding": false
}

The onboarding PR was autoclosed and an actual PR created instead: ljharb/global-cache#43

@ljharb
Copy link
Author

ljharb commented Oct 12, 2020

I'd have preferred reusing the PR rather than leaving the old PR ref permanently cluttering the repo, but this is fine, thanks :-)

I have 4 or 5 other github orgs to add once i've tested things out - is that something I can do, or do i need to ask here?

@rarkins
Copy link
Collaborator

rarkins commented Oct 12, 2020

You'll need to ask me, but I can't think of any problem if you tell me them all in advance as it won't have any effect until after you start installing repos form those orgs.

@ljharb
Copy link
Author

ljharb commented Oct 12, 2020

Regarding that specific PR, rimraf v3 has "engines" support that doesn't match my project's, so I can't ever update past v2. How would I indicate that either I don't want v3+ updates of rimraf, or better, that I don't want any updates whose engines declarations don't match my project's? (some other examples: mocha v4+, nyc 11+, semver 7+, etc)

@rarkins
Copy link
Collaborator

rarkins commented Oct 12, 2020

To ignore v3 indefinitely, you can simply close the PR and you won't get v2 -> v3 upgrades proposed anymore. But if one day you manually upgrade to v3 then you'll resume getting minor/patch updates without needing to do anything.

To permanently ignore via config, you would use allowedVersions like this:

{
  "packageRules": [{
    "packageNames": ["rimraf"],
    "allowedVersions": "<3.0.0"
  }]
}

My preference these days though is to use dependencyDashboardApproval instead of completely ignoring/disabling things, assuming you are OK with a dependency dashboard issue (example) especially if you plan to one day unignore. In the Renovate project we prefer to put all major updates behind the approval step so that we can take them as we're ready.

@rarkins
Copy link
Collaborator

rarkins commented Oct 12, 2020

Re: engines compatibility checks, here is the feature request currently open: renovatebot/renovate#4826

@ljharb
Copy link
Author

ljharb commented Oct 13, 2020

Thanks, I'd prefer using the engines feature once available, since that's automatic. I'll consider using dependencyDashboardApproval as well.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants