New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: helm requirements.yaml support #3805
Conversation
* Change fileMatch in definitions.js from Chart.ya?ml to requirements.ya?ml
* Fix some unrelated test failures
* Get test coverage to 100%
* index.yaml is cached for every helm repository for 10 minutes * rename repository field to helmRepository in order to avoid conflict with existing configuration field
@nchashch thanks for this contribution. Can you educate me a little on how this works? I had assumed that Helm charts would just reference Docker images, so was surprised to see a new datasource. When I look at the extract function, it appears to reference only other charts. Can you describe to me how it all works? |
@rarkins There is a Helm datasource downloads and caches the From the docs I have read it looks like an image (or images) can be specified with a docker container name and tag in It might be possible to also update docker images for helm charts (maybe in a separate manager?), but I think it would be pretty difficult, because it looks like |
Thanks, I understand better now. As you suggest, we may need to do the image renovating for Helm in another PR |
lib/config/definitions.js
Outdated
stage: 'package', | ||
type: 'object', | ||
default: { | ||
fileMatch: ['(^|/)requirements.ya?ml$'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fileMatch: ['(^|/)requirements.ya?ml$'], | |
fileMatch: ['(^|/)requirements\\.ya?ml$'], |
lib/datasource/helm/index.js
Outdated
getPkgReleases, | ||
}; | ||
|
||
async function getPkgReleases({ lookupName, helmRepository }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this custom new helmRepository
field, can we reuse our existing registryUrls
concept?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be multiple repositories in a single requirements.yaml
file, and each dependency is associated with it's own repository. So if registryUrls
is used, we will have to pass helmRepository
with every dependency anyway in order to identify which registry url to use.
Getting index.yaml
for every registry in registryUrls
and searching for lookupName
in them without helmRepository
wouldn't work, because packages can be duplicated in repositories, and there is no guarantee that the right one will be found. Also it would be more expensive.
lib/datasource/helm/index.js
Outdated
if (!res || !res.body) { | ||
logger.warn( | ||
{ dependency: lookupName }, | ||
`Received invalid index.yaml from ${helmRepository}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically we haven't tried parsing the yaml yet so this message might confuse people.
lib/datasource/helm/index.js
Outdated
} | ||
} | ||
let doc; | ||
if (!cachedIndex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the second if (!cachedIndex)
check in this block, they should probably be combined
lib/manager/helm/extract.js
Outdated
deps = doc.dependencies.map(dep => ({ | ||
depName: dep.name, | ||
currentValue: dep.version, | ||
helmRepository: dep.repository, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switch to registryUrls
here
lib/manager/helm/extract.js
Outdated
depName: dep.name, | ||
currentValue: dep.version, | ||
helmRepository: dep.repository, | ||
datasource: 'helm', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any possibility of non-helm datasources here? If not then datasource: 'helm'
could be pushed one level up into the response, rather than be inside each dep.
@nchashch could you also make sure that the data we are caching is the most efficient/optimal dataset? e.g. if the file is 5MB raw, then it's probably even more when parsed, but we maybe only need 200kb of it and could cache only that. |
I'm still trying to consider if we should have one package manager (helm) or two eventually (helm-charts and helm-images). Also, I'm wondering if instead of looking for What do you think? |
* Factor out retrieving index.yaml into getRepositoryData function
… into feat/helm-manager-3414
@rarkins This PR is ready for review. Now only versions are cached by the datasource, instead of the whole parsed |
@nchashch can you suggest some demo repos I can fork and test against? |
@pharindoko @rarkins any updates? |
Sorry I do not have the time to test it. |
I'm testing this against the
|
@@ -0,0 +1,123 @@ | |||
import { extractPackageFile } from '../../../lib/manager/helm-requirements/extract'; | |||
|
|||
const platform: any = global.platform; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to
import { platform as _platform } from '../../../lib/platform';
const platform: any = _platform;
@nchashch If you're interested in getting this merged, there should be just a few changes required:
You can see how it works on my fork of the helm/charts repo here. As for the unsupported version messages I mentioned above, I realise now that your changes don't have support for version ranges. We open an issue for that, and add it later. |
* platform is no longer global, and has to be imported * Import platform in extract.spec.js
@JamieMagee I have merged master, and added |
@nchashch Thanks for the update. I'll review this a little more thoroughly tomorrow, but initially this looks fine. We can open another issue to support pinning/version ranges and I can do the TypeScript conversion for |
@JamieMagee Thanks! |
lib/datasource/helm/index.js
Outdated
} | ||
if ( | ||
gotErr.statusCode === 429 || | ||
(gotErr.statusCode > 500 && gotErr.statusCode < 600) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(gotErr.statusCode > 500 && gotErr.statusCode < 600) | |
(gotErr.statusCode >= 500 && gotErr.statusCode < 600) |
lib/datasource/helm/index.js
Outdated
}); | ||
const cacheMinutes = 20; | ||
await renovateCache.set(cacheNamespace, cacheKey, result, cacheMinutes); | ||
} catch (yamlErr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} catch (yamlErr) { | |
} catch (err) { |
Also add a logger.warn
here with text about loading YAML, and logger.debug
with the full error
lib/datasource/helm/index.js
Outdated
logger.warn(`Received invalid response from ${repository}`); | ||
return null; | ||
} | ||
} catch (gotErr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} catch (gotErr) { | |
} catch (err) { |
const searchString = `${oldVersion}`; | ||
const newString = `${newValue}`; | ||
let newFileContent = fileContent; | ||
// Search starts at 'dependencies' instaed of `${depName}` because fields in a YAML record |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Search starts at 'dependencies' instaed of `${depName}` because fields in a YAML record | |
// Search starts at 'dependencies' instead of `${depName}` because fields in a YAML record |
searchString, | ||
newString | ||
); | ||
// Compare the parsed toml structure of old and new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TOML or YAML?
* Treat 500 response as server error in getRepositoryData in helm datasource
🎉 This PR is included in version 19.61.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Todo
extractPackageFile
updateDependencies
This PR adds helm manager.
Closes #3414