Renovate: Support Node.js versions in .travis.yml

Created on 22 Nov 2017  路  18Comments  路  Source: renovatebot/renovate

I like to support all active/maintenance Node.js versions in many of my modules.

This currently results in the following .travis.yml:

language: node_js
node_js:
  - '8'
  - '6'
  - '4'

I don't like to just add 'node' (will test against latest Node.js) because if there is a breaking change in a new version of Node.js that shouldn't break PR builds for an unrelated reason or start breaking previously successful builds.

However it's a pain to keep this up to date manually across many repos and it would still be helpful to be notified of the break (just without breaking all builds on master).

This is something I had an idea to build a while ago but seems like it could be nicely integrated into Renovate. It would be great if you could specify which Node.js versions you wish to support (e.g latest/active/maintenance) and Renovate would open a PR to keep .travis.yml up to date when new Node.js versions are released.

Node.js/Travis is just my use case, could also support other CI environments and languages.

priority-3-normal feature

Most helpful comment

Just saw that Travis have some of their own special options:

  • node latest stable Node.js release
  • iojs latest stable io.js release
  • lts/* latest LTS Node.js release
  • 8 latest 8.x release
  • 7 latest 7.x release
  • 6 latest 6.x release
  • 5 latest 5.x release
  • 4 latest 4.x release

I think I'll still keep the proposed Renovate approach and replace whatever is in Travis config with an array of major versions.

All 18 comments

@lukechilds this is definitely something that fits nicely with Renovate - thanks for the suggestion. I also has .nvm files and package.json>engines.node on the radar too.

I had also been thinking that this feature would need a "policy" type of config such as latest / active / maintenance. I hadn't worked out how to handle unstable yet though, e.g. someone who supports 8 and 9.

Another thing I've learned is its ideal for bots like Renovate to "not ask the user to configure things that can be reasonably inferred", but then always allow the user to override. So ideally Renovate could look at your existing configs and see '4,6,8' and know that means "maintenance", '6,8' means "active" and '8' means "latest". node is such a special case that I will consider whether to just hard code some of this major release logic, at least into a json file that's part of source.

I'd also like to consider the case where people consider minor patch versions too, e.g. '8.9' instead of '8'. Even if it's not supported in the initial commit of this functionality, I want to make sure I don't have to make a breaking change to accommodate it later.

node.js version sources:

nodejs.org releases

https://nodejs.org/en/download/releases/

  • Table that needs parsing. Includes convenient links to changelogs and docs

github nodejs/node tags

https://github.com/nodejs/node/releases

  • Not semantically tagged with lts/maintenance/etc

github nodejs/releases readme

https://github.com/nodejs/Release

  • Table needs parsing.
  • Does not explicitly state in table that 8 is "current". can we infer that "current" = the last "LTS" ?

Good stuff 馃憤

I'm pretty tied up with other projects atm but would be happy to work on a PR when I have some time available. Don't let that put you or anyone else off from working on it in the mean time though, I probably won't be available for quite a while.

Does not explicitly state in table that 8 is "current". can we infer that "current" = the last "LTS" ?

Current is the latest major release version. Alternate major releases are LTS.

E.g:
LTS releases: 4, 6, 8.
Non LTS releases: 5, 7, 9.

So right now 9 is "current" (latest major release but not LTS). 8 is "active" (actively supported as an LTS release but not the latest major).

The Releases readme seems the most concise for learning which major versions numbers are maintenance/LTS/current/latest

maintenance = all versions with LTS status field "Maintenance LTS" or "Active LTS"
lts = all versions with LTS status field = "Active LTS"
active = the highest version with LTS status field = "Active LTS"
current = the highest version with LTS status field != "Pending"
latest = ... we don't use this term .. ?

For Travis, it seems usual to specify them as a list of major versions as described by @lukechilds above, however it technically supports any minor or full versions supported by nvm.

In terms of configuration, we have three possibilities available:

  1. If we can always reliably infer the user's intent with zero config, then that is best
  2. If not, can we guess at the user's intent during onboarding and suggest the right node policy there? (problem: already onboarded repos miss out and have to discover it somehow)
  3. Only do this is explicitly configured to do so

If the user today has 4,6,8 we can infer their policy is "maintenance". In April 2018, 4 will suddenly become EOL, 6 will become Maintenance LTS, and 8 will be the only Active LTS. Can we be sure the user would want to drop 4 at that point?

If the user today has 6,8 we can infer their policy is "lts". In April 2018, when the only Active LTS is 8, how can we be sure that their policy is "lts" and not "maintenance"? I think we can't, unless the config was in place already.

The above leads me to think dynamic inference is not possible at runtime, so instead needs to be done during onboarding or manually by the user. Also, during the changeover periods (e.g. April 2018) we are also likely to infer incorrectly for a lot of onboarded repositories, but I'm not sure there's any perfect way to prevent that. If we leave old logic in place then we would infer incorrectly for users who are up to date (on their own) instead.

Here's a JSON source from the same repo: https://github.com/nodejs/Release/blob/master/schedule.json

The Node.js foundation uses "current" to mean the highest active release (regardless of even or odd numbering) but on their Download page it says "Latest Current Version: 9.2.0" - i.e. they use latest AND current for that, presumably because saying "Current Version" on its own led to too much confusion amongst regular users.

It is not correct to call odd numbers "unstable". See nodesource article. Even numbers are either LTS or on track to be LTS. Odd numbers never reach LTS.

Proposal for policy names:

lts: 4,6,8
active: 6,8,9
current: 9
lts_active: 6,8
lts_latest: 8
lts_latest+current: 8,9

The first 3 terms are pretty widely accepted in node.js, assuming you accept that "maintenance LTS" is still LTS (i.e. v4).

I'm fairly happy with terms 4 and 5, but the last is a little wonky. I'd maybe leave it out it until someone says they need it.

Why not allow multiple policies?

So you don't need the 'lts_latest+current' policy, people could specify ['lts_latest', 'current'] which would resolve to 8,9 or ['lts', 'current'] which would resolve to 4,6,8,9.

Seems like that wouldn't take a lot of extra effort to implement once you've got the standard policy logic.

@lukechilds thanks for the feedback. I had been considering that idea too, although worrying the resulting configuration requirement would be too complex for users. If we make the policies additive and most people only need one, then I suppose that's almost as simple as a single string anyway.

OK, so here's how I think the implementation will go:

  • [ ] New Renovate manager type node, which goes alongside existing npm, meteor and docker manager types. It will be expanded later to add .nvmrc and package.json>engines renovation too
  • [ ] node.enabled will be false by default in config definitions. It's not possible for us to 100% infer which node versions a user might want to use
  • [ ] node.policy will be lts_active by default
  • [ ] If node.enabled is true (i.e. user has enabled it), Renovate will look for a .travis.yml in root of repository and overwrite any node_js configuration if found. Skip if none found. Ideally autodetect if 2 or 4 spaces are in use before changing anything
  • [ ] Use PR title like "Update Travis node_js versions to [4,6,8]" and branch name renovate/node-travis-yml
  • [ ] (future) Renovate Onboarding PR should suggest a enabling node + matching configuration policy if we detect .travis.yml and node_js versions already present. Add this once we think the feature works well after feedback from opt-in users

Just saw that Travis have some of their own special options:

  • node latest stable Node.js release
  • iojs latest stable io.js release
  • lts/* latest LTS Node.js release
  • 8 latest 8.x release
  • 7 latest 7.x release
  • 6 latest 6.x release
  • 5 latest 5.x release
  • 4 latest 4.x release

I think I'll still keep the proposed Renovate approach and replace whatever is in Travis config with an array of major versions.

I've got a small proof of concept working. @lukechilds I noticed you have keyv ordered like:

node_js:
  - '8'
  - '6'
  - '4'

Does putting 8 first rather than 4 change anything w.r.t. Travis? i.e. if it were 4,6,8 instead would that change behaviour? Obviously we should do a order-insensitive comparison to existing, however if we were removing or adding a version to an existing list, I want to make sure I understand if ordering matters and we need to detect it.

Just saw that Travis have some of their own special options:

These are passed directly to nvm, anything that nvm supports will work on Travis.

Does putting 8 first rather than 4 change anything w.r.t. Travis?

Nope, all builds are run in parallel.

@lukechilds I noticed that the order can have an impact in some cases. Travis has the concept of a "lead build" and sometimes logic is executed only on the first (lead) build in the matrix, e.g. deploy. So in this case it makes sense to have the latest one as lead, so I will put them in order of newest to oldest.

@rarkins Are you referring to build stages?

That's one example. Semantic release also has a function to detect if it's the build lead and only release once, regardless of whether build stages are used

@lukechilds this is now supported/live in the app. I added a documentation page here: https://renovateapp.com/docs/language-support/node

This is awesome, nice work!

I'm really tied up in a project atm but will give this a test run as soon as I get a chance.

Was this page helpful?
0 / 5 - 0 ratings